Message ID | 20221025050608.2635173-3-quic_fenglinw@quicinc.com (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
Series | Add changes to support SPMI resource protection | expand |
On Tue, 25 Oct 2022 at 08:24, Fenglin Wu <quic_fenglinw@quicinc.com> wrote: > > From: David Collins <collinsd@codeaurora.org> > > Make the support of PMIC peripheral interrupts optional for > spmi-pmic-arb devices. This is useful in situations where > SPMI address mapping is required without the need for IRQ > support. When or why would this be needed? Please provide a description of the usecase. > > Signed-off-by: David Collins <collinsd@codeaurora.org> > Signed-off-by: Fenglin Wu <quic_fenglinw@quicinc.com> > --- > drivers/spmi/spmi-pmic-arb.c | 45 ++++++++++++++++++++++-------------- > 1 file changed, 28 insertions(+), 17 deletions(-) > > diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c > index 1e7f5a9ff4bc..c14cffd8a313 100644 > --- a/drivers/spmi/spmi-pmic-arb.c > +++ b/drivers/spmi/spmi-pmic-arb.c > @@ -1490,10 +1490,12 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) > goto err_put_ctrl; > } > > - pmic_arb->irq = platform_get_irq_byname(pdev, "periph_irq"); > - if (pmic_arb->irq < 0) { > - err = pmic_arb->irq; > - goto err_put_ctrl; > + if (of_find_property(pdev->dev.of_node, "interrupt-controller", NULL)) { Ugh. Please use platform_get_irq_byname_optional() instead. It returs -ENXIO if the irq is not present. > + pmic_arb->irq = platform_get_irq_byname(pdev, "periph_irq"); > + if (pmic_arb->irq < 0) { > + err = pmic_arb->irq; > + goto err_put_ctrl; > + } > } > > err = of_property_read_u32(pdev->dev.of_node, "qcom,channel", &channel); > @@ -1553,17 +1555,22 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) > } > } > > - dev_dbg(&pdev->dev, "adding irq domain\n"); > - pmic_arb->domain = irq_domain_add_tree(pdev->dev.of_node, > - &pmic_arb_irq_domain_ops, pmic_arb); > - if (!pmic_arb->domain) { > - dev_err(&pdev->dev, "unable to create irq_domain\n"); > - err = -ENOMEM; > - goto err_put_ctrl; > + if (pmic_arb->irq > 0) { > + dev_dbg(&pdev->dev, "adding irq domain\n"); > + pmic_arb->domain = irq_domain_add_tree(pdev->dev.of_node, > + &pmic_arb_irq_domain_ops, pmic_arb); > + if (!pmic_arb->domain) { > + dev_err(&pdev->dev, "unable to create irq_domain\n"); > + err = -ENOMEM; > + goto err_put_ctrl; > + } > + > + irq_set_chained_handler_and_data(pmic_arb->irq, > + pmic_arb_chained_irq, pmic_arb); > + } else { > + dev_dbg(&pdev->dev, "not supporting PMIC interrupts\n"); > } > > - irq_set_chained_handler_and_data(pmic_arb->irq, pmic_arb_chained_irq, > - pmic_arb); > err = spmi_controller_add(ctrl); > if (err) > goto err_domain_remove; > @@ -1571,8 +1578,10 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) > return 0; > > err_domain_remove: > - irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL); > - irq_domain_remove(pmic_arb->domain); > + if (pmic_arb->irq > 0) { > + irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL); > + irq_domain_remove(pmic_arb->domain); > + } > err_put_ctrl: > spmi_controller_put(ctrl); > return err; > @@ -1583,8 +1592,10 @@ static int spmi_pmic_arb_remove(struct platform_device *pdev) > struct spmi_controller *ctrl = platform_get_drvdata(pdev); > struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl); > spmi_controller_remove(ctrl); > - irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL); > - irq_domain_remove(pmic_arb->domain); > + if (pmic_arb->irq > 0) { > + irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL); > + irq_domain_remove(pmic_arb->domain); > + } > spmi_controller_put(ctrl); > return 0; > } > -- > 2.25.1 >
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index 1e7f5a9ff4bc..c14cffd8a313 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -1490,10 +1490,12 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) goto err_put_ctrl; } - pmic_arb->irq = platform_get_irq_byname(pdev, "periph_irq"); - if (pmic_arb->irq < 0) { - err = pmic_arb->irq; - goto err_put_ctrl; + if (of_find_property(pdev->dev.of_node, "interrupt-controller", NULL)) { + pmic_arb->irq = platform_get_irq_byname(pdev, "periph_irq"); + if (pmic_arb->irq < 0) { + err = pmic_arb->irq; + goto err_put_ctrl; + } } err = of_property_read_u32(pdev->dev.of_node, "qcom,channel", &channel); @@ -1553,17 +1555,22 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) } } - dev_dbg(&pdev->dev, "adding irq domain\n"); - pmic_arb->domain = irq_domain_add_tree(pdev->dev.of_node, - &pmic_arb_irq_domain_ops, pmic_arb); - if (!pmic_arb->domain) { - dev_err(&pdev->dev, "unable to create irq_domain\n"); - err = -ENOMEM; - goto err_put_ctrl; + if (pmic_arb->irq > 0) { + dev_dbg(&pdev->dev, "adding irq domain\n"); + pmic_arb->domain = irq_domain_add_tree(pdev->dev.of_node, + &pmic_arb_irq_domain_ops, pmic_arb); + if (!pmic_arb->domain) { + dev_err(&pdev->dev, "unable to create irq_domain\n"); + err = -ENOMEM; + goto err_put_ctrl; + } + + irq_set_chained_handler_and_data(pmic_arb->irq, + pmic_arb_chained_irq, pmic_arb); + } else { + dev_dbg(&pdev->dev, "not supporting PMIC interrupts\n"); } - irq_set_chained_handler_and_data(pmic_arb->irq, pmic_arb_chained_irq, - pmic_arb); err = spmi_controller_add(ctrl); if (err) goto err_domain_remove; @@ -1571,8 +1578,10 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) return 0; err_domain_remove: - irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL); - irq_domain_remove(pmic_arb->domain); + if (pmic_arb->irq > 0) { + irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL); + irq_domain_remove(pmic_arb->domain); + } err_put_ctrl: spmi_controller_put(ctrl); return err; @@ -1583,8 +1592,10 @@ static int spmi_pmic_arb_remove(struct platform_device *pdev) struct spmi_controller *ctrl = platform_get_drvdata(pdev); struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl); spmi_controller_remove(ctrl); - irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL); - irq_domain_remove(pmic_arb->domain); + if (pmic_arb->irq > 0) { + irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL); + irq_domain_remove(pmic_arb->domain); + } spmi_controller_put(ctrl); return 0; }