On 06/07/2018 05:55 PM, Yan, Hongliang wrote:
> Hi All,
>   I am trying to enable pinctrl-intel.c GPIO interrupt as RTDM interrupt. I 
> use rtdm_irq_request to replace devm_request_irq in probe function.
>   code is as following:
> =======================================================================
> #if 1
>     if ((ret = rtdm_irq_request(&irq_rtdm,
>                     irq, handler_interruption,
>                     0,
>                     "test", NULL)) != 0) {
>         printk("rtdm request error\n");
> }
> 
> #else
>     ret = devm_request_irq(pctrl->dev, irq, intel_gpio_irq, IRQF_SHARED,
>                    dev_name(pctrl->dev), pctrl);
>     if (ret) {
>         dev_err(pctrl->dev, "failed to request interrupt\n");
>         goto fail;
>     }
> #endif

That won't work, unless you fixed up that GPIO driver to cope with interrupt 
pipelining - which does not seem to be the case.

If you plan to implement those changes, please keep in mind that you won't be 
able to share a common IRQ line between multiple GPIO controllers unlike 
pinctrl-intel would originally allow for non-rt usage. The current I-pipe patch 
implementation does not support this.

The code below was an attempt to adapt the pinctrl-intel driver to IRQ 
pipelining, which broke in flight due to lack of time. It is very unlikely to 
work as is, not even to build properly, I have no clue whether there is a 
slightest chance this might work, but that's a starting point...to somewhere.

commit ab4493579d95de58718a8ea81ae1fffc6f2ed0f7 (wip/intel-pinctrl)
Author: Philippe Gerum <r...@xenomai.org>
Date:   Wed May 31 18:16:19 2017 +0200

    drivers: inter-pinctrl: make I-pipe aware

diff --git a/drivers/pinctrl/intel/pinctrl-intel.c 
b/drivers/pinctrl/intel/pinctrl-intel.c
index 01443762e570..f8bf54b6d485 100644
--- a/drivers/pinctrl/intel/pinctrl-intel.c
+++ b/drivers/pinctrl/intel/pinctrl-intel.c
@@ -91,7 +91,11 @@ struct intel_pinctrl_context {
  */
 struct intel_pinctrl {
        struct device *dev;
+#ifdef CONFIG_IPIPE
+       ipipe_spinlock_t lock;
+#else
        raw_spinlock_t lock;
+#endif
        struct pinctrl_desc pctldesc;
        struct pinctrl_dev *pctldev;
        struct gpio_chip chip;
@@ -647,15 +651,13 @@ static const struct gpio_chip intel_gpio_chip = {
        .set = intel_gpio_set,
 };
 
-static void intel_gpio_irq_ack(struct irq_data *d)
+static void __intel_gpio_irq_ack(struct irq_data *d)
 {
        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
        struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
        const struct intel_community *community;
        unsigned pin = irqd_to_hwirq(d);
 
-       raw_spin_lock(&pctrl->lock);
-
        community = intel_get_community(pctrl, pin);
        if (community) {
                unsigned padno = pin_to_padno(community, pin);
@@ -664,7 +666,14 @@ static void intel_gpio_irq_ack(struct irq_data *d)
 
                writel(BIT(gpp_offset), community->regs + GPI_IS + gpp * 4);
        }
+}
 
+static void intel_gpio_irq_ack(struct irq_data *d)
+{
+       struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
+
+       raw_spin_lock(&pctrl->lock);
+       __intel_gpio_irq_ack(d);
        raw_spin_unlock(&pctrl->lock);
 }
 
@@ -694,18 +703,17 @@ static void intel_gpio_irq_enable(struct irq_data *d)
                writel(value, community->regs + community->ie_offset + gpp * 4);
        }
 
+       ipipe_unlock_irq(d->irq);
+       
        raw_spin_unlock_irqrestore(&pctrl->lock, flags);
 }
 
-static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
+static void __intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
 {
        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
        struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
        const struct intel_community *community;
        unsigned pin = irqd_to_hwirq(d);
-       unsigned long flags;
-
-       raw_spin_lock_irqsave(&pctrl->lock, flags);
 
        community = intel_get_community(pctrl, pin);
        if (community) {
@@ -723,20 +731,55 @@ static void intel_gpio_irq_mask_unmask(struct irq_data 
*d, bool mask)
                        value |= BIT(gpp_offset);
                writel(value, reg);
        }
-
-       raw_spin_unlock_irqrestore(&pctrl->lock, flags);
 }
 
 static void intel_gpio_irq_mask(struct irq_data *d)
 {
-       intel_gpio_irq_mask_unmask(d, true);
+       struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&pctrl->lock, flags);
+       ipipe_lock_irq(d->irq);
+       __intel_gpio_irq_mask_unmask(d, true);
+       raw_spin_unlock_irqrestore(&pctrl->lock, flags);
 }
 
 static void intel_gpio_irq_unmask(struct irq_data *d)
 {
-       intel_gpio_irq_mask_unmask(d, false);
+       struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&pctrl->lock, flags);
+       __intel_gpio_irq_mask_unmask(d, false);
+       ipipe_unlock_irq(d->irq);
+       raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+#ifdef CONFIG_IPIPE
+
+static void intel_gpio_irq_hold(struct irq_data *d)
+{
+       struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&pctrl->lock, flags);
+       __intel_gpio_irq_mask_unmask(d, true);
+       __intel_gpio_irq_ack(d);
+       raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+static void intel_gpio_irq_release(struct irq_data *d)
+{
+       struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&pctrl->lock, flags);
+       __intel_gpio_irq_mask_unmask(d, false);
+       raw_spin_unlock_irqrestore(&pctrl->lock, flags);
 }
 
+#endif
+
 static int intel_gpio_irq_type(struct irq_data *d, unsigned type)
 {
        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
@@ -837,7 +880,7 @@ static irqreturn_t intel_gpio_community_irq_handler(struct 
intel_pinctrl *pctrl,
 
                        irq = irq_find_mapping(gc->irqdomain,
                                               community->pin_base + padno);
-                       generic_handle_irq(irq);
+                       ipipe_handle_demuxed_irq(irq);
 
                        ret |= IRQ_HANDLED;
                }
@@ -862,6 +905,14 @@ static irqreturn_t intel_gpio_irq(int irq, void *data)
        return ret;
 }
 
+static void ipipe_irq_cascade(struct irq_desc *desc)
+{
+#ifdef CONFIG_IPIPE
+       intel_gpio_irq(irq_desc_get_irq(desc),
+                      irq_desc_get_handler_data(desc));
+#endif
+}
+
 static struct irq_chip intel_gpio_irqchip = {
        .name = "intel-gpio",
        .irq_enable = intel_gpio_irq_enable,
@@ -870,6 +921,10 @@ static struct irq_chip intel_gpio_irqchip = {
        .irq_unmask = intel_gpio_irq_unmask,
        .irq_set_type = intel_gpio_irq_type,
        .irq_set_wake = intel_gpio_irq_wake,
+#ifdef CONFIG_IPIPE
+       .irq_hold = intel_gpio_irq_hold,
+       .irq_release = intel_gpio_irq_release,
+#endif
 };
 
 static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
@@ -902,12 +957,17 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, 
int irq)
         * to the irq directly) because on some platforms several GPIO
         * controllers share the same interrupt line.
         */
-       ret = devm_request_irq(pctrl->dev, irq, intel_gpio_irq,
-                              IRQF_SHARED | IRQF_NO_THREAD,
-                              dev_name(pctrl->dev), pctrl);
-       if (ret) {
-               dev_err(pctrl->dev, "failed to request interrupt\n");
-               goto fail;
+       if (IS_ENABLED(CONFIG_IPIPE))
+               irq_set_chained_handler_and_data(irq,
+                                       ipipe_irq_cascade, pctrl);
+       else {
+               ret = devm_request_irq(pctrl->dev, irq, intel_gpio_irq,
+                                      IRQF_SHARED | IRQF_NO_THREAD,
+                                      dev_name(pctrl->dev), pctrl);
+               if (ret) {
+                       dev_err(pctrl->dev, "failed to request interrupt\n");
+                       goto fail;
+               }
        }
 
        ret = gpiochip_irqchip_add(&pctrl->chip, &intel_gpio_irqchip, 0,

-- 
Philippe.

_______________________________________________
Xenomai mailing list
Xenomai@xenomai.org
https://xenomai.org/mailman/listinfo/xenomai

Reply via email to