* [PATCH] ARM: at91: add gpio suspend/resume support when using pinctrl
@ 2013-03-08 15:18 ludovic.desroches at atmel.com
2013-03-13 9:22 ` Nicolas Ferre
2013-03-13 19:05 ` Linus Walleij
0 siblings, 2 replies; 3+ messages in thread
From: ludovic.desroches at atmel.com @ 2013-03-08 15:18 UTC (permalink / raw)
To: linux-arm-kernel
From: Ludovic Desroches <ludovic.desroches@atmel.com>
gpio suspend/resume and wakeup sources where not managed when using pinctrl so
it was impossible to wake up the system with a gpio.
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
arch/arm/mach-at91/include/mach/gpio.h | 8 +++++
arch/arm/mach-at91/pm.c | 10 ++++--
drivers/pinctrl/pinctrl-at91.c | 61 +++++++++++++++++++++++++++++++++-
3 files changed, 76 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h
index eed465a..5fc2377 100644
--- a/arch/arm/mach-at91/include/mach/gpio.h
+++ b/arch/arm/mach-at91/include/mach/gpio.h
@@ -209,6 +209,14 @@ extern int at91_get_gpio_value(unsigned pin);
extern void at91_gpio_suspend(void);
extern void at91_gpio_resume(void);
+#ifdef CONFIG_PINCTRL_AT91
+extern void at91_pinctrl_gpio_suspend(void);
+extern void at91_pinctrl_gpio_resume(void);
+#else
+static inline void at91_pinctrl_gpio_suspend(void) {}
+static inline void at91_pinctrl_gpio_resume(void) {}
+#endif
+
#endif /* __ASSEMBLY__ */
#endif
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index adb6db8..73f1f25 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -201,7 +201,10 @@ extern u32 at91_slow_clock_sz;
static int at91_pm_enter(suspend_state_t state)
{
- at91_gpio_suspend();
+ if (of_have_populated_dt())
+ at91_pinctrl_gpio_suspend();
+ else
+ at91_gpio_suspend();
at91_irq_suspend();
pr_debug("AT91: PM - wake mask %08x, pm state %d\n",
@@ -286,7 +289,10 @@ static int at91_pm_enter(suspend_state_t state)
error:
target_state = PM_SUSPEND_ON;
at91_irq_resume();
- at91_gpio_resume();
+ if (of_have_populated_dt())
+ at91_pinctrl_gpio_resume();
+ else
+ at91_gpio_resume();
return 0;
}
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
index 75933a6..efb7f10 100644
--- a/drivers/pinctrl/pinctrl-at91.c
+++ b/drivers/pinctrl/pinctrl-at91.c
@@ -1277,21 +1277,80 @@ static int alt_gpio_irq_type(struct irq_data *d, unsigned type)
}
#ifdef CONFIG_PM
+
+static u32 wakeups[MAX_GPIO_BANKS];
+static u32 backups[MAX_GPIO_BANKS];
+
static int gpio_irq_set_wake(struct irq_data *d, unsigned state)
{
struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d);
unsigned bank = at91_gpio->pioc_idx;
+ unsigned mask = 1 << d->hwirq;
if (unlikely(bank >= MAX_GPIO_BANKS))
return -EINVAL;
+ if (state)
+ wakeups[bank] |= mask;
+ else
+ wakeups[bank] &= ~mask;
+
irq_set_irq_wake(at91_gpio->pioc_virq, state);
return 0;
}
+
+void at91_pinctrl_gpio_suspend(void)
+{
+ int i;
+
+ for (i = 0; i < gpio_banks; i++) {
+ void __iomem *pio;
+
+ if (!gpio_chips[i])
+ continue;
+
+ pio = gpio_chips[i]->regbase;
+
+ backups[i] = __raw_readl(pio + PIO_IMR);
+ __raw_writel(backups[i], pio + PIO_IDR);
+ __raw_writel(wakeups[i], pio + PIO_IER);
+
+ if (!wakeups[i]) {
+ clk_unprepare(gpio_chips[i]->clock);
+ clk_disable(gpio_chips[i]->clock);
+ } else {
+ printk(KERN_DEBUG "GPIO-%c may wake for %08x\n",
+ 'A'+i, wakeups[i]);
+ }
+ }
+}
+
+void at91_pinctrl_gpio_resume(void)
+{
+ int i;
+
+ for (i = 0; i < gpio_banks; i++) {
+ void __iomem *pio;
+
+ if (!gpio_chips[i])
+ continue;
+
+ pio = gpio_chips[i]->regbase;
+
+ if (!wakeups[i]) {
+ if (clk_prepare(gpio_chips[i]->clock) == 0)
+ clk_enable(gpio_chips[i]->clock);
+ }
+
+ __raw_writel(wakeups[i], pio + PIO_IDR);
+ __raw_writel(backups[i], pio + PIO_IER);
+ }
+}
+
#else
#define gpio_irq_set_wake NULL
-#endif
+#endif /* CONFIG_PM */
static struct irq_chip gpio_irqchip = {
.name = "GPIO",
--
1.7.11.3
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH] ARM: at91: add gpio suspend/resume support when using pinctrl
2013-03-08 15:18 [PATCH] ARM: at91: add gpio suspend/resume support when using pinctrl ludovic.desroches at atmel.com
@ 2013-03-13 9:22 ` Nicolas Ferre
2013-03-13 19:05 ` Linus Walleij
1 sibling, 0 replies; 3+ messages in thread
From: Nicolas Ferre @ 2013-03-13 9:22 UTC (permalink / raw)
To: linux-arm-kernel
On 03/08/2013 04:18 PM, ludovic.desroches at atmel.com :
> From: Ludovic Desroches <ludovic.desroches@atmel.com>
>
> gpio suspend/resume and wakeup sources where not managed when using pinctrl so
> it was impossible to wake up the system with a gpio.
>
> Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Nice, I queue it for "fixes" in at91-3.9-fixes.
Thanks, best regards,
> ---
> arch/arm/mach-at91/include/mach/gpio.h | 8 +++++
> arch/arm/mach-at91/pm.c | 10 ++++--
> drivers/pinctrl/pinctrl-at91.c | 61 +++++++++++++++++++++++++++++++++-
> 3 files changed, 76 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h
> index eed465a..5fc2377 100644
> --- a/arch/arm/mach-at91/include/mach/gpio.h
> +++ b/arch/arm/mach-at91/include/mach/gpio.h
> @@ -209,6 +209,14 @@ extern int at91_get_gpio_value(unsigned pin);
> extern void at91_gpio_suspend(void);
> extern void at91_gpio_resume(void);
>
> +#ifdef CONFIG_PINCTRL_AT91
> +extern void at91_pinctrl_gpio_suspend(void);
> +extern void at91_pinctrl_gpio_resume(void);
> +#else
> +static inline void at91_pinctrl_gpio_suspend(void) {}
> +static inline void at91_pinctrl_gpio_resume(void) {}
> +#endif
> +
> #endif /* __ASSEMBLY__ */
>
> #endif
> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
> index adb6db8..73f1f25 100644
> --- a/arch/arm/mach-at91/pm.c
> +++ b/arch/arm/mach-at91/pm.c
> @@ -201,7 +201,10 @@ extern u32 at91_slow_clock_sz;
>
> static int at91_pm_enter(suspend_state_t state)
> {
> - at91_gpio_suspend();
> + if (of_have_populated_dt())
> + at91_pinctrl_gpio_suspend();
> + else
> + at91_gpio_suspend();
> at91_irq_suspend();
>
> pr_debug("AT91: PM - wake mask %08x, pm state %d\n",
> @@ -286,7 +289,10 @@ static int at91_pm_enter(suspend_state_t state)
> error:
> target_state = PM_SUSPEND_ON;
> at91_irq_resume();
> - at91_gpio_resume();
> + if (of_have_populated_dt())
> + at91_pinctrl_gpio_resume();
> + else
> + at91_gpio_resume();
> return 0;
> }
>
> diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
> index 75933a6..efb7f10 100644
> --- a/drivers/pinctrl/pinctrl-at91.c
> +++ b/drivers/pinctrl/pinctrl-at91.c
> @@ -1277,21 +1277,80 @@ static int alt_gpio_irq_type(struct irq_data *d, unsigned type)
> }
>
> #ifdef CONFIG_PM
> +
> +static u32 wakeups[MAX_GPIO_BANKS];
> +static u32 backups[MAX_GPIO_BANKS];
> +
> static int gpio_irq_set_wake(struct irq_data *d, unsigned state)
> {
> struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d);
> unsigned bank = at91_gpio->pioc_idx;
> + unsigned mask = 1 << d->hwirq;
>
> if (unlikely(bank >= MAX_GPIO_BANKS))
> return -EINVAL;
>
> + if (state)
> + wakeups[bank] |= mask;
> + else
> + wakeups[bank] &= ~mask;
> +
> irq_set_irq_wake(at91_gpio->pioc_virq, state);
>
> return 0;
> }
> +
> +void at91_pinctrl_gpio_suspend(void)
> +{
> + int i;
> +
> + for (i = 0; i < gpio_banks; i++) {
> + void __iomem *pio;
> +
> + if (!gpio_chips[i])
> + continue;
> +
> + pio = gpio_chips[i]->regbase;
> +
> + backups[i] = __raw_readl(pio + PIO_IMR);
> + __raw_writel(backups[i], pio + PIO_IDR);
> + __raw_writel(wakeups[i], pio + PIO_IER);
> +
> + if (!wakeups[i]) {
> + clk_unprepare(gpio_chips[i]->clock);
> + clk_disable(gpio_chips[i]->clock);
> + } else {
> + printk(KERN_DEBUG "GPIO-%c may wake for %08x\n",
> + 'A'+i, wakeups[i]);
> + }
> + }
> +}
> +
> +void at91_pinctrl_gpio_resume(void)
> +{
> + int i;
> +
> + for (i = 0; i < gpio_banks; i++) {
> + void __iomem *pio;
> +
> + if (!gpio_chips[i])
> + continue;
> +
> + pio = gpio_chips[i]->regbase;
> +
> + if (!wakeups[i]) {
> + if (clk_prepare(gpio_chips[i]->clock) == 0)
> + clk_enable(gpio_chips[i]->clock);
> + }
> +
> + __raw_writel(wakeups[i], pio + PIO_IDR);
> + __raw_writel(backups[i], pio + PIO_IER);
> + }
> +}
> +
> #else
> #define gpio_irq_set_wake NULL
> -#endif
> +#endif /* CONFIG_PM */
>
> static struct irq_chip gpio_irqchip = {
> .name = "GPIO",
>
--
Nicolas Ferre
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH] ARM: at91: add gpio suspend/resume support when using pinctrl
2013-03-08 15:18 [PATCH] ARM: at91: add gpio suspend/resume support when using pinctrl ludovic.desroches at atmel.com
2013-03-13 9:22 ` Nicolas Ferre
@ 2013-03-13 19:05 ` Linus Walleij
1 sibling, 0 replies; 3+ messages in thread
From: Linus Walleij @ 2013-03-13 19:05 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Mar 8, 2013 at 4:18 PM, <ludovic.desroches@atmel.com> wrote:
> From: Ludovic Desroches <ludovic.desroches@atmel.com>
>
> gpio suspend/resume and wakeup sources where not managed when using pinctrl so
> it was impossible to wake up the system with a gpio.
>
> Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
I saw that Nicolas is taking care of it...
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2013-03-13 19:05 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-08 15:18 [PATCH] ARM: at91: add gpio suspend/resume support when using pinctrl ludovic.desroches at atmel.com
2013-03-13 9:22 ` Nicolas Ferre
2013-03-13 19:05 ` Linus Walleij
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).