[PATCH 2/4] pinctrl: single: Add hardware specific hooks for IRQ and GPIO wake-up events
Linus Walleij
linus.walleij at linaro.org
Mon Jul 22 17:44:22 EDT 2013
On Mon, Jun 10, 2013 at 5:36 PM, Tony Lindgren <tony at atomide.com> 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 <rogerq at ti.com>.
>
> Cc: Haojian Zhuang <haojian.zhuang at gmail.com>
> Cc: Peter Ujfalusi <peter.ujfalusi at ti.com>
> Cc: devicetree-discuss at lists.ozlabs.org
> Signed-off-by: Roger Quadros <rogerq at ti.com>
> Signed-off-by: Tony Lindgren <tony at 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 :-)
> 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
More information about the linux-arm-kernel
mailing list