From d91703b665bfc5525c3723220e05ffb6e6aa477d Mon Sep 17 00:00:00 2001 From: Mukesh Kumar Savaliya Date: Thu, 20 May 2021 00:19:04 +0530 Subject: [PATCH] i3c: i3c-master-msm-geni: Add support to featurize IBI and hotjoin This change controls IBI and hotjoin feature based on DTSI flags. This helps where client doesn't want to enable IBI and hotjoin. Change-Id: Ie65359d5f1cf857774c89e2cbe0e3f50b05b402c Signed-off-by: Mukesh Kumar Savaliya --- drivers/i3c/master/i3c-master-msm-geni.c | 54 ++++++++++++++++-------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/drivers/i3c/master/i3c-master-msm-geni.c b/drivers/i3c/master/i3c-master-msm-geni.c index da3bd8c55a76..6ed2b98c570f 100644 --- a/drivers/i3c/master/i3c-master-msm-geni.c +++ b/drivers/i3c/master/i3c-master-msm-geni.c @@ -284,6 +284,7 @@ struct geni_i3c_dev { unsigned long newaddrslots[(I3C_ADDR_MASK + 1) / BITS_PER_LONG]; const struct geni_i3c_clk_fld *clk_fld; const struct geni_i3c_clk_fld *clk_od_fld; + bool ibi_support_disabled; struct geni_ibi ibi; struct workqueue_struct *hj_wq; struct work_struct hj_wd; @@ -554,6 +555,12 @@ static irqreturn_t geni_i3c_ibi_irq(int irq, void *dev) u32 m_stat = 0, m_stat_mask = 0; bool cmd_done = false; + if (gi3c->ibi_support_disabled) { + GENI_SE_ERR(gi3c->ipcl, false, gi3c->se.dev, + "%s: IBI is not supported by choice\n", __func__); + return IRQ_HANDLED; + } + spin_lock_irqsave(&gi3c->ibi.lock, flags); if (irq == gi3c->ibi.mngr_irq) { @@ -1899,6 +1906,14 @@ static int i3c_ibi_rsrcs_init(struct geni_i3c_dev *gi3c, struct resource *res; int ret; + gi3c->ibi_support_disabled = of_property_read_bool(pdev->dev.of_node, + "qcom,ibi-support-disabled"); + if (gi3c->ibi_support_disabled) { + GENI_SE_ERR(gi3c->ipcl, true, gi3c->se.dev, + "IBI support disabled\n"); + return 0; + } + if (of_property_read_u8(pdev->dev.of_node, "qcom,ibi-ctrl-id", &gi3c->ibi.ctrl_id)) { GENI_SE_ERR(gi3c->ipcl, true, gi3c->se.dev, @@ -2126,18 +2141,20 @@ static int geni_i3c_probe(struct platform_device *pdev) } // hot-join - gi3c->hj_wl = wakeup_source_register(gi3c->se.dev, + if (!gi3c->ibi_support_disabled) { + gi3c->hj_wl = wakeup_source_register(gi3c->se.dev, dev_name(gi3c->se.dev)); - if (!gi3c->hj_wl) { - GENI_SE_ERR(gi3c->ipcl, false, gi3c->se.dev, + if (!gi3c->hj_wl) { + GENI_SE_ERR(gi3c->ipcl, false, gi3c->se.dev, "wakeup source registration failed\n"); - se_geni_resources_off(&gi3c->se.i3c_rsc); - return -ENOMEM; - } + se_geni_resources_off(&gi3c->se.i3c_rsc); + return -ENOMEM; + } - INIT_WORK(&gi3c->hj_wd, geni_i3c_hotjoin); - gi3c->hj_wq = alloc_workqueue("%s", 0, 0, dev_name(gi3c->se.dev)); - geni_i3c_enable_hotjoin_irq(gi3c, true); + INIT_WORK(&gi3c->hj_wd, geni_i3c_hotjoin); + gi3c->hj_wq = alloc_workqueue("%s", 0, 0, dev_name(gi3c->se.dev)); + geni_i3c_enable_hotjoin_irq(gi3c, true); + } GENI_SE_ERR(gi3c->ipcl, true, gi3c->se.dev, "I3C probed:%d\n", ret); return ret; @@ -2156,16 +2173,19 @@ static int geni_i3c_remove(struct platform_device *pdev) int ret = 0, i; //Disable hot-join, until next probe happens - geni_i3c_enable_hotjoin_irq(gi3c, false); - destroy_workqueue(gi3c->hj_wq); - wakeup_source_unregister(gi3c->hj_wl); - if (gi3c->ibi.is_init) - qcom_geni_i3c_ibi_unconf(gi3c); - geni_i3c_enable_ibi_ctrl(gi3c, false); + if (!gi3c->ibi_support_disabled) { + geni_i3c_enable_hotjoin_irq(gi3c, false); + destroy_workqueue(gi3c->hj_wq); + wakeup_source_unregister(gi3c->hj_wl); - /* Potentially to be done before pinctrl change */ - geni_i3c_enable_ibi_irq(gi3c, false); + if (gi3c->ibi.is_init) + qcom_geni_i3c_ibi_unconf(gi3c); + geni_i3c_enable_ibi_ctrl(gi3c, false); + + /* Potentially to be done before pinctrl change */ + geni_i3c_enable_ibi_irq(gi3c, false); + } /*force suspend to avoid the auto suspend caused by driver removal*/ pm_runtime_force_suspend(gi3c->se.dev);