Skip to content

Commit fc87dd5

Browse files
committed
scsi: ufs: qcom: Remove the MSI descriptor abuse
The driver abuses the MSI descriptors for internal purposes. Aside of core code and MSI providers nothing has to care about their existence. They have been encapsulated with a lot of effort because this kind of abuse caused all sorts of issues including a maintainability nightmare. Rewrite the code so it uses dedicated storage to hand the required information to the interrupt handler. No functional change intended. Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/all/[email protected]
1 parent 79273d0 commit fc87dd5

File tree

1 file changed

+39
-36
lines changed

1 file changed

+39
-36
lines changed

drivers/ufs/host/ufs-qcom.c

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
17851791
static 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)
17991803
static 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

Comments
 (0)