pinctrl: msmgpio: Make the irqchip immutable
authorMarc Zyngier <maz@kernel.org>
Tue, 19 Apr 2022 14:18:43 +0000 (15:18 +0100)
committerMarc Zyngier <maz@kernel.org>
Tue, 19 Apr 2022 14:22:26 +0000 (15:22 +0100)
Prevent gpiolib from messing with the irqchip by advertising
the irq_chip structure as immutable, making it const, and adding
the various calls that gpiolib relies upon.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20220419141846.598305-8-maz@kernel.org
drivers/pinctrl/qcom/pinctrl-msm.c

index 966ea66..a2abfe9 100644 (file)
@@ -42,7 +42,6 @@
  * @chip:           gpiochip handle.
  * @desc:           pin controller descriptor
  * @restart_nb:     restart notifier block.
- * @irq_chip:       irq chip information
  * @irq:            parent irq for the TLMM irq_chip.
  * @intr_target_use_scm: route irq to application cpu using scm calls
  * @lock:           Spinlock to protect register resources as well
@@ -63,7 +62,6 @@ struct msm_pinctrl {
        struct pinctrl_desc desc;
        struct notifier_block restart_nb;
 
-       struct irq_chip irq_chip;
        int irq;
 
        bool intr_target_use_scm;
@@ -868,6 +866,8 @@ static void msm_gpio_irq_enable(struct irq_data *d)
        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
        struct msm_pinctrl *pctrl = gpiochip_get_data(gc);
 
+       gpiochip_enable_irq(gc, d->hwirq);
+
        if (d->parent_data)
                irq_chip_enable_parent(d);
 
@@ -885,6 +885,8 @@ static void msm_gpio_irq_disable(struct irq_data *d)
 
        if (!test_bit(d->hwirq, pctrl->skip_wake_irqs))
                msm_gpio_irq_mask(d);
+
+       gpiochip_disable_irq(gc, d->hwirq);
 }
 
 /**
@@ -958,6 +960,14 @@ static void msm_gpio_irq_ack(struct irq_data *d)
        raw_spin_unlock_irqrestore(&pctrl->lock, flags);
 }
 
+static void msm_gpio_irq_eoi(struct irq_data *d)
+{
+       d = d->parent_data;
+
+       if (d)
+               d->chip->irq_eoi(d);
+}
+
 static bool msm_gpio_needs_dual_edge_parent_workaround(struct irq_data *d,
                                                       unsigned int type)
 {
@@ -1255,6 +1265,26 @@ static bool msm_gpio_needs_valid_mask(struct msm_pinctrl *pctrl)
        return device_property_count_u16(pctrl->dev, "gpios") > 0;
 }
 
+static const struct irq_chip msm_gpio_irq_chip = {
+       .name                   = "msmgpio",
+       .irq_enable             = msm_gpio_irq_enable,
+       .irq_disable            = msm_gpio_irq_disable,
+       .irq_mask               = msm_gpio_irq_mask,
+       .irq_unmask             = msm_gpio_irq_unmask,
+       .irq_ack                = msm_gpio_irq_ack,
+       .irq_eoi                = msm_gpio_irq_eoi,
+       .irq_set_type           = msm_gpio_irq_set_type,
+       .irq_set_wake           = msm_gpio_irq_set_wake,
+       .irq_request_resources  = msm_gpio_irq_reqres,
+       .irq_release_resources  = msm_gpio_irq_relres,
+       .irq_set_affinity       = msm_gpio_irq_set_affinity,
+       .irq_set_vcpu_affinity  = msm_gpio_irq_set_vcpu_affinity,
+       .flags                  = (IRQCHIP_MASK_ON_SUSPEND |
+                                  IRQCHIP_SET_TYPE_MASKED |
+                                  IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND |
+                                  IRQCHIP_IMMUTABLE),
+};
+
 static int msm_gpio_init(struct msm_pinctrl *pctrl)
 {
        struct gpio_chip *chip;
@@ -1276,22 +1306,6 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
        if (msm_gpio_needs_valid_mask(pctrl))
                chip->init_valid_mask = msm_gpio_init_valid_mask;
 
-       pctrl->irq_chip.name = "msmgpio";
-       pctrl->irq_chip.irq_enable = msm_gpio_irq_enable;
-       pctrl->irq_chip.irq_disable = msm_gpio_irq_disable;
-       pctrl->irq_chip.irq_mask = msm_gpio_irq_mask;
-       pctrl->irq_chip.irq_unmask = msm_gpio_irq_unmask;
-       pctrl->irq_chip.irq_ack = msm_gpio_irq_ack;
-       pctrl->irq_chip.irq_set_type = msm_gpio_irq_set_type;
-       pctrl->irq_chip.irq_set_wake = msm_gpio_irq_set_wake;
-       pctrl->irq_chip.irq_request_resources = msm_gpio_irq_reqres;
-       pctrl->irq_chip.irq_release_resources = msm_gpio_irq_relres;
-       pctrl->irq_chip.irq_set_affinity = msm_gpio_irq_set_affinity;
-       pctrl->irq_chip.irq_set_vcpu_affinity = msm_gpio_irq_set_vcpu_affinity;
-       pctrl->irq_chip.flags = IRQCHIP_MASK_ON_SUSPEND |
-                               IRQCHIP_SET_TYPE_MASKED |
-                               IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND;
-
        np = of_parse_phandle(pctrl->dev->of_node, "wakeup-parent", 0);
        if (np) {
                chip->irq.parent_domain = irq_find_matching_host(np,
@@ -1300,7 +1314,6 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
                if (!chip->irq.parent_domain)
                        return -EPROBE_DEFER;
                chip->irq.child_to_parent_hwirq = msm_gpio_wakeirq;
-               pctrl->irq_chip.irq_eoi = irq_chip_eoi_parent;
                /*
                 * Let's skip handling the GPIOs, if the parent irqchip
                 * is handling the direct connect IRQ of the GPIO.
@@ -1313,7 +1326,7 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
        }
 
        girq = &chip->irq;
-       girq->chip = &pctrl->irq_chip;
+       gpio_irq_chip_set_chip(girq, &msm_gpio_irq_chip);
        girq->parent_handler = msm_gpio_irq_handler;
        girq->fwnode = pctrl->dev->fwnode;
        girq->num_parents = 1;