Thread (32 messages) 32 messages, 4 authors, 2013-07-29

[PATCH 2/4] pinctrl: single: Add hardware specific hooks for IRQ and GPIO wake-up events

From: Linus Walleij <hidden>
Date: 2013-07-22 21:44:22
Also in: linux-devicetree, linux-omap

On Mon, Jun 10, 2013 at 5:36 PM, Tony Lindgren [off-list ref] wrote:
At least on omaps, each board typically has at least one device
configured as wake-up capable from deeper idle modes. In the
deeper idle modes the normal interrupt wake-up path won't work
as the logic is powered off and separate wake-up hardware is
available either via IO ring or GPIO hardware.
What I do not understand is why the irq_set_wake() should
not fall through to that IO ring / GPIO hardware.

For example: a composite GPIO+irqchip driver should surely
set the wake up for a certain line for irq_set_wake()?
The wake-up
event can be device specific, or may need to be dynamically
remuxed to GPIO input for wake-up events. When the wake-up
event happens, it's IRQ need to be called so the device won't
lose interrupts.
I recognize this hardware type. The name I use for these
things are "latent interrupts".

What I think is that they should maybe be modeled as
irqchip from end to end, so that we don't orthogonally use
any pinctrl states to set this up.
Allow supporting IRQ and GPIO wake-up events if a hardware
spefific module is registered for the enable and disable
s/spefific/specific
calls.

Done in collaboration with Roger Quadros [off-list ref].

Cc: Haojian Zhuang <haojian.zhuang@gmail.com>
Cc: Peter Ujfalusi <redacted>
Cc: devicetree-discuss at lists.ozlabs.org
Signed-off-by: Roger Quadros <redacted>
Signed-off-by: Tony Lindgren <tony@atomide.com>
(...)
+- interrrupts : the interrupt that a function may have for a wake-up event
interrupts
+
+- gpios: the gpio that a function may have for a wake-up event
Is this a GPIO property or a pin property?

"wake up" is not supported by the GPIO subsystem is it?
Not in <linux/gpio.h> atleast.

This smells like shoehorning pin config stuff into the GPIO
subsystem again which is a no-no :-)
quoted hunk ↗ jump to hunk
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
@@ -1183,6 +1241,24 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
        } else {
                *num_maps = 1;
        }
+
+       if (pcs->flags & PCS_HAS_FUNCTION_IRQ)
+               function->irq = irq_of_parse_and_map(np, 0);
+
+       if (pcs->flags & PCS_HAS_FUNCTION_GPIO) {
+               function->gpio = of_get_gpio(np, 0);
+               if (function->gpio > 0 && !function->irq) {
+                       if (gpio_is_valid(function->gpio))
+                               function->irq = gpio_to_irq(function->gpio);
+               }
+       }
+
+       if (function->irq > 0 && pcs->soc && pcs->soc->reg_init) {
+               res = pcs_parse_wakeup(pcs, np, function);
+               if (res)
+                       goto free_pingroups;
+       }
So this thing here. Instead of introducing a cross reference to the
IRQ and GPIO here and
+ * @irq:       optional irq specified for wake-up for example
+ * @gpio:      optional gpio specified for wake-up for example
+ * @node:      optional list
+ */
+struct pcs_reg {
+       unsigned (*read)(void __iomem *reg);
+       void (*write)(unsigned val, void __iomem *reg);
+       void __iomem *reg;
+       unsigned val;
+       int irq;
+       int gpio;
+       struct list_head node;
+};
+
+#define PCS_HAS_FUNCTION_GPIO   (1 << 2)
+#define PCS_HAS_FUNCTION_IRQ    (1 << 1)
 #define PCS_HAS_PINCONF         (1 << 0)

 /**
  * struct pcs_soc - SoC specific interface to pinctrl-single
  * @data:      SoC specific data pointer
  * @flags:     mask of PCS_HAS_xxx values
+ * @reg_init:  SoC specific register init function
+ * @enable:    SoC specific enable function
+ * @disable:   SoC specific disable function
  */
 struct pcs_soc {
        void *data;
        unsigned flags;
+       int (*reg_init)(const struct pcs_soc *soc, struct pcs_reg *r);
+       int (*enable)(const struct pcs_soc *soc, struct pcs_reg *r);
+       void (*disable)(const struct pcs_soc *soc, struct pcs_reg *r);
Then these quirks and sub-modules ...

Why can't the irqchip/GPIO driver call down to this driver
instead?

Yours,
Linus Walleij
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help