@@ -1782,15 +1782,19 @@ static void ufs_qcom_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg)
17821782 ufshcd_mcq_config_esi (hba , msg );
17831783}
17841784
1785+ struct ufs_qcom_irq {
1786+ unsigned int irq ;
1787+ unsigned int idx ;
1788+ struct ufs_hba * hba ;
1789+ };
1790+
17851791static irqreturn_t ufs_qcom_mcq_esi_handler (int irq , void * data )
17861792{
1787- struct msi_desc * desc = data ;
1788- struct device * dev = msi_desc_to_dev (desc );
1789- struct ufs_hba * hba = dev_get_drvdata (dev );
1790- u32 id = desc -> msi_index ;
1791- struct ufs_hw_queue * hwq = & hba -> uhq [id ];
1793+ struct ufs_qcom_irq * qi = data ;
1794+ struct ufs_hba * hba = qi -> hba ;
1795+ struct ufs_hw_queue * hwq = & hba -> uhq [qi -> idx ];
17921796
1793- ufshcd_mcq_write_cqis (hba , 0x1 , id );
1797+ ufshcd_mcq_write_cqis (hba , 0x1 , qi -> idx );
17941798 ufshcd_mcq_poll_cqe_lock (hba , hwq );
17951799
17961800 return IRQ_HANDLED ;
@@ -1799,8 +1803,7 @@ static irqreturn_t ufs_qcom_mcq_esi_handler(int irq, void *data)
17991803static int ufs_qcom_config_esi (struct ufs_hba * hba )
18001804{
18011805 struct ufs_qcom_host * host = ufshcd_get_variant (hba );
1802- struct msi_desc * desc ;
1803- struct msi_desc * failed_desc = NULL ;
1806+ struct ufs_qcom_irq * qi ;
18041807 int nr_irqs , ret ;
18051808
18061809 if (host -> esi_enabled )
@@ -1811,47 +1814,47 @@ static int ufs_qcom_config_esi(struct ufs_hba *hba)
18111814 * 2. Poll queues do not need ESI.
18121815 */
18131816 nr_irqs = hba -> nr_hw_queues - hba -> nr_queues [HCTX_TYPE_POLL ];
1817+ qi = devm_kcalloc (hba -> dev , nr_irqs , sizeof (* qi ), GFP_KERNEL );
1818+ if (qi )
1819+ return - ENOMEM ;
1820+
18141821 ret = platform_device_msi_init_and_alloc_irqs (hba -> dev , nr_irqs ,
18151822 ufs_qcom_write_msi_msg );
18161823 if (ret ) {
18171824 dev_err (hba -> dev , "Failed to request Platform MSI %d\n" , ret );
1818- return ret ;
1825+ goto cleanup ;
18191826 }
18201827
1821- msi_lock_descs (hba -> dev );
1822- msi_for_each_desc (desc , hba -> dev , MSI_DESC_ALL ) {
1823- ret = devm_request_irq (hba -> dev , desc -> irq ,
1824- ufs_qcom_mcq_esi_handler ,
1825- IRQF_SHARED , "qcom-mcq-esi" , desc );
1828+ for (int idx = 0 ; idx < nr_irqs ; idx ++ ) {
1829+ qi [idx ].irq = msi_get_virq (hba -> dev , idx );
1830+ qi [idx ].idx = idx ;
1831+ qi [idx ].hba = hba ;
1832+
1833+ ret = devm_request_irq (hba -> dev , qi [idx ].irq , ufs_qcom_mcq_esi_handler ,
1834+ IRQF_SHARED , "qcom-mcq-esi" , qi + idx );
18261835 if (ret ) {
18271836 dev_err (hba -> dev , "%s: Fail to request IRQ for %d, err = %d\n" ,
1828- __func__ , desc -> irq , ret );
1829- failed_desc = desc ;
1830- break ;
1837+ __func__ , qi [ idx ]. irq , ret );
1838+ qi [ idx ]. irq = 0 ;
1839+ goto cleanup ;
18311840 }
18321841 }
1833- msi_unlock_descs (hba -> dev );
18341842
1835- if (ret ) {
1836- /* Rewind */
1837- msi_lock_descs (hba -> dev );
1838- msi_for_each_desc (desc , hba -> dev , MSI_DESC_ALL ) {
1839- if (desc == failed_desc )
1840- break ;
1841- devm_free_irq (hba -> dev , desc -> irq , hba );
1842- }
1843- msi_unlock_descs (hba -> dev );
1844- platform_device_msi_free_irqs_all (hba -> dev );
1845- } else {
1846- if (host -> hw_ver .major == 6 && host -> hw_ver .minor == 0 &&
1847- host -> hw_ver .step == 0 )
1848- ufshcd_rmwl (hba , ESI_VEC_MASK ,
1849- FIELD_PREP (ESI_VEC_MASK , MAX_ESI_VEC - 1 ),
1850- REG_UFS_CFG3 );
1851- ufshcd_mcq_enable_esi (hba );
1852- host -> esi_enabled = true;
1843+ if (host -> hw_ver .major == 6 && host -> hw_ver .minor == 0 &&
1844+ host -> hw_ver .step == 0 ) {
1845+ ufshcd_rmwl (hba , ESI_VEC_MASK ,
1846+ FIELD_PREP (ESI_VEC_MASK , MAX_ESI_VEC - 1 ),
1847+ REG_UFS_CFG3 );
18531848 }
1849+ ufshcd_mcq_enable_esi (hba );
1850+ host -> esi_enabled = true;
1851+ return 0 ;
18541852
1853+ cleanup :
1854+ for (int idx = 0 ; qi [idx ].irq ; idx ++ )
1855+ devm_free_irq (hba -> dev , qi [idx ].irq , hba );
1856+ platform_device_msi_free_irqs_all (hba -> dev );
1857+ devm_kfree (hba -> dev , qi );
18551858 return ret ;
18561859}
18571860
0 commit comments