Skip to content

Commit 519b627

Browse files
quic-cangmartinkpetersen
authored andcommitted
scsi: ufs: qcom: Add MCQ ESI config vendor specific ops
Add MCQ ESI config vendor specific ops. Co-developed-by: Asutosh Das <[email protected]> Signed-off-by: Asutosh Das <[email protected]> Signed-off-by: Can Guo <[email protected]> Reviewed-by: Bart Van Assche <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent e02288e commit 519b627

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

drivers/ufs/host/ufs-qcom.c

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1538,6 +1538,101 @@ static int ufs_qcom_get_outstanding_cqs(struct ufs_hba *hba,
15381538
return 0;
15391539
}
15401540

1541+
#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
1542+
static void ufs_qcom_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg)
1543+
{
1544+
struct device *dev = msi_desc_to_dev(desc);
1545+
struct ufs_hba *hba = dev_get_drvdata(dev);
1546+
1547+
ufshcd_mcq_config_esi(hba, msg);
1548+
}
1549+
1550+
static irqreturn_t ufs_qcom_mcq_esi_handler(int irq, void *__hba)
1551+
{
1552+
struct ufs_hba *hba = __hba;
1553+
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
1554+
u32 id = irq - host->esi_base;
1555+
struct ufs_hw_queue *hwq = &hba->uhq[id];
1556+
1557+
ufshcd_mcq_write_cqis(hba, 0x1, id);
1558+
ufshcd_mcq_poll_cqe_nolock(hba, hwq);
1559+
1560+
return IRQ_HANDLED;
1561+
}
1562+
1563+
static int ufs_qcom_config_esi(struct ufs_hba *hba)
1564+
{
1565+
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
1566+
struct msi_desc *desc;
1567+
struct msi_desc *failed_desc = NULL;
1568+
int nr_irqs, ret;
1569+
1570+
if (host->esi_enabled)
1571+
return 0;
1572+
else if (host->esi_base < 0)
1573+
return -EINVAL;
1574+
1575+
/*
1576+
* 1. We only handle CQs as of now.
1577+
* 2. Poll queues do not need ESI.
1578+
*/
1579+
nr_irqs = hba->nr_hw_queues - hba->nr_queues[HCTX_TYPE_POLL];
1580+
ret = platform_msi_domain_alloc_irqs(hba->dev, nr_irqs,
1581+
ufs_qcom_write_msi_msg);
1582+
if (ret)
1583+
goto out;
1584+
1585+
msi_for_each_desc(desc, hba->dev, MSI_DESC_ALL) {
1586+
if (!desc->msi_index)
1587+
host->esi_base = desc->irq;
1588+
1589+
ret = devm_request_irq(hba->dev, desc->irq,
1590+
ufs_qcom_mcq_esi_handler,
1591+
IRQF_SHARED, "qcom-mcq-esi", hba);
1592+
if (ret) {
1593+
dev_err(hba->dev, "%s: Fail to request IRQ for %d, err = %d\n",
1594+
__func__, desc->irq, ret);
1595+
failed_desc = desc;
1596+
break;
1597+
}
1598+
}
1599+
1600+
if (ret) {
1601+
/* Rewind */
1602+
msi_for_each_desc(desc, hba->dev, MSI_DESC_ALL) {
1603+
if (desc == failed_desc)
1604+
break;
1605+
devm_free_irq(hba->dev, desc->irq, hba);
1606+
}
1607+
platform_msi_domain_free_irqs(hba->dev);
1608+
} else {
1609+
if (host->hw_ver.major == 6 && host->hw_ver.minor == 0 &&
1610+
host->hw_ver.step == 0) {
1611+
ufshcd_writel(hba,
1612+
ufshcd_readl(hba, REG_UFS_CFG3) | 0x1F000,
1613+
REG_UFS_CFG3);
1614+
}
1615+
ufshcd_mcq_enable_esi(hba);
1616+
}
1617+
1618+
out:
1619+
if (ret) {
1620+
host->esi_base = -1;
1621+
dev_warn(hba->dev, "Failed to request Platform MSI %d\n", ret);
1622+
} else {
1623+
host->esi_enabled = true;
1624+
}
1625+
1626+
return ret;
1627+
}
1628+
1629+
#else
1630+
static int ufs_qcom_config_esi(struct ufs_hba *hba)
1631+
{
1632+
return -EOPNOTSUPP;
1633+
}
1634+
#endif
1635+
15411636
/*
15421637
* struct ufs_hba_qcom_vops - UFS QCOM specific variant operations
15431638
*
@@ -1566,6 +1661,7 @@ static const struct ufs_hba_variant_ops ufs_hba_qcom_vops = {
15661661
.get_hba_mac = ufs_qcom_get_hba_mac,
15671662
.op_runtime_config = ufs_qcom_op_runtime_config,
15681663
.get_outstanding_cqs = ufs_qcom_get_outstanding_cqs,
1664+
.config_esi = ufs_qcom_config_esi,
15691665
};
15701666

15711667
/**
@@ -1599,6 +1695,7 @@ static int ufs_qcom_remove(struct platform_device *pdev)
15991695

16001696
pm_runtime_get_sync(&(pdev)->dev);
16011697
ufshcd_remove(hba);
1698+
platform_msi_domain_free_irqs(hba->dev);
16021699
return 0;
16031700
}
16041701

drivers/ufs/host/ufs-qcom.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ enum {
5252
* added in HW Version 3.0.0
5353
*/
5454
UFS_AH8_CFG = 0xFC,
55+
56+
REG_UFS_CFG3 = 0x271C,
5557
};
5658

5759
/* QCOM UFS host controller vendor specific debug registers */
@@ -217,6 +219,9 @@ struct ufs_qcom_host {
217219
struct gpio_desc *device_reset;
218220

219221
u32 hs_gear;
222+
223+
int esi_base;
224+
bool esi_enabled;
220225
};
221226

222227
static inline u32

0 commit comments

Comments
 (0)