@@ -1806,25 +1806,38 @@ static void ufs_qcom_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg)
18061806 ufshcd_mcq_config_esi (hba , msg );
18071807}
18081808
1809+ struct ufs_qcom_irq {
1810+ unsigned int irq ;
1811+ unsigned int idx ;
1812+ struct ufs_hba * hba ;
1813+ };
1814+
18091815static irqreturn_t ufs_qcom_mcq_esi_handler (int irq , void * data )
18101816{
1811- struct msi_desc * desc = data ;
1812- struct device * dev = msi_desc_to_dev (desc );
1813- struct ufs_hba * hba = dev_get_drvdata (dev );
1814- u32 id = desc -> msi_index ;
1815- struct ufs_hw_queue * hwq = & hba -> uhq [id ];
1817+ struct ufs_qcom_irq * qi = data ;
1818+ struct ufs_hba * hba = qi -> hba ;
1819+ struct ufs_hw_queue * hwq = & hba -> uhq [qi -> idx ];
18161820
1817- ufshcd_mcq_write_cqis (hba , 0x1 , id );
1821+ ufshcd_mcq_write_cqis (hba , 0x1 , qi -> idx );
18181822 ufshcd_mcq_poll_cqe_lock (hba , hwq );
18191823
18201824 return IRQ_HANDLED ;
18211825}
18221826
1827+ static void ufs_qcom_irq_free (struct ufs_qcom_irq * uqi )
1828+ {
1829+ for (struct ufs_qcom_irq * q = uqi ; q -> irq ; q ++ )
1830+ devm_free_irq (q -> hba -> dev , q -> irq , q -> hba );
1831+
1832+ platform_device_msi_free_irqs_all (uqi -> hba -> dev );
1833+ devm_kfree (uqi -> hba -> dev , uqi );
1834+ }
1835+
1836+ DEFINE_FREE (ufs_qcom_irq , struct ufs_qcom_irq * , if (_T ) ufs_qcom_irq_free (_T ))
1837+
18231838static int ufs_qcom_config_esi (struct ufs_hba * hba )
18241839{
18251840 struct ufs_qcom_host * host = ufshcd_get_variant (hba );
1826- struct msi_desc * desc ;
1827- struct msi_desc * failed_desc = NULL ;
18281841 int nr_irqs , ret ;
18291842
18301843 if (host -> esi_enabled )
@@ -1835,48 +1848,46 @@ static int ufs_qcom_config_esi(struct ufs_hba *hba)
18351848 * 2. Poll queues do not need ESI.
18361849 */
18371850 nr_irqs = hba -> nr_hw_queues - hba -> nr_queues [HCTX_TYPE_POLL ];
1851+
1852+ struct ufs_qcom_irq * qi __free (ufs_qcom_irq ) =
1853+ devm_kcalloc (hba -> dev , nr_irqs , sizeof (* qi ), GFP_KERNEL );
1854+ if (!qi )
1855+ return - ENOMEM ;
1856+ /* Preset so __free() has a pointer to hba in all error paths */
1857+ qi [0 ].hba = hba ;
1858+
18381859 ret = platform_device_msi_init_and_alloc_irqs (hba -> dev , nr_irqs ,
18391860 ufs_qcom_write_msi_msg );
18401861 if (ret ) {
18411862 dev_err (hba -> dev , "Failed to request Platform MSI %d\n" , ret );
18421863 return ret ;
18431864 }
18441865
1845- msi_lock_descs (hba -> dev );
1846- msi_for_each_desc (desc , hba -> dev , MSI_DESC_ALL ) {
1847- ret = devm_request_irq (hba -> dev , desc -> irq ,
1848- ufs_qcom_mcq_esi_handler ,
1849- IRQF_SHARED , "qcom-mcq-esi" , desc );
1866+ for (int idx = 0 ; idx < nr_irqs ; idx ++ ) {
1867+ qi [idx ].irq = msi_get_virq (hba -> dev , idx );
1868+ qi [idx ].idx = idx ;
1869+ qi [idx ].hba = hba ;
1870+
1871+ ret = devm_request_irq (hba -> dev , qi [idx ].irq , ufs_qcom_mcq_esi_handler ,
1872+ IRQF_SHARED , "qcom-mcq-esi" , qi + idx );
18501873 if (ret ) {
18511874 dev_err (hba -> dev , "%s: Fail to request IRQ for %d, err = %d\n" ,
1852- __func__ , desc -> irq , ret );
1853- failed_desc = desc ;
1854- break ;
1875+ __func__ , qi [ idx ]. irq , ret );
1876+ qi [ idx ]. irq = 0 ;
1877+ return ret ;
18551878 }
18561879 }
1857- msi_unlock_descs (hba -> dev );
18581880
1859- if (ret ) {
1860- /* Rewind */
1861- msi_lock_descs (hba -> dev );
1862- msi_for_each_desc (desc , hba -> dev , MSI_DESC_ALL ) {
1863- if (desc == failed_desc )
1864- break ;
1865- devm_free_irq (hba -> dev , desc -> irq , hba );
1866- }
1867- msi_unlock_descs (hba -> dev );
1868- platform_device_msi_free_irqs_all (hba -> dev );
1869- } else {
1870- if (host -> hw_ver .major == 6 && host -> hw_ver .minor == 0 &&
1871- host -> hw_ver .step == 0 )
1872- ufshcd_rmwl (hba , ESI_VEC_MASK ,
1873- FIELD_PREP (ESI_VEC_MASK , MAX_ESI_VEC - 1 ),
1874- REG_UFS_CFG3 );
1875- ufshcd_mcq_enable_esi (hba );
1876- host -> esi_enabled = true;
1877- }
1881+ retain_and_null_ptr (qi );
18781882
1879- return ret ;
1883+ if (host -> hw_ver .major == 6 && host -> hw_ver .minor == 0 &&
1884+ host -> hw_ver .step == 0 ) {
1885+ ufshcd_rmwl (hba , ESI_VEC_MASK , FIELD_PREP (ESI_VEC_MASK , MAX_ESI_VEC - 1 ),
1886+ REG_UFS_CFG3 );
1887+ }
1888+ ufshcd_mcq_enable_esi (hba );
1889+ host -> esi_enabled = true;
1890+ return 0 ;
18801891}
18811892
18821893static u32 ufs_qcom_freq_to_gear_speed (struct ufs_hba * hba , unsigned long freq )
0 commit comments