[RESEND,v1,2/2] spmi: pmic-arb: make interrupt support optional
Commit Message
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.
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(-)
Comments
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
>
@@ -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;
}