All of lore.kernel.org
 help / color / mirror / Atom feed
From: nicolas.ferre@atmel.com (Nicolas Ferre)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] ARM: at91: add gpio suspend/resume support when using pinctrl
Date: Wed, 13 Mar 2013 10:22:18 +0100	[thread overview]
Message-ID: <5140454A.2030409@atmel.com> (raw)
In-Reply-To: <1362755901-20279-1-git-send-email-ludovic.desroches@atmel.com>

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

  reply	other threads:[~2013-03-13  9:22 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
2013-03-13 19:05 ` Linus Walleij

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5140454A.2030409@atmel.com \
    --to=nicolas.ferre@atmel.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.