[RESEND,v1,2/2] spmi: pmic-arb: make interrupt support optional

Message ID 20221025050608.2635173-3-quic_fenglinw@quicinc.com
State New
Headers
Series Add changes to support SPMI resource protection |

Commit Message

Fenglin Wu Oct. 25, 2022, 5:06 a.m. UTC
  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

Dmitry Baryshkov Oct. 25, 2022, 6:25 a.m. UTC | #1
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
>
  

Patch

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;
 }