diff mbox

Allow OMAP3 GPIO wakeup from power off.

Message ID 1240860407-14883-1-git-send-email-Russ.Dill@gmail.com (mailing list archive)
State Accepted
Delegated to: Kevin Hilman
Headers show

Commit Message

Russ Dill April 27, 2009, 7:26 p.m. UTC
This patch configures the wakeup padconf registers to reflect the sysfs
power/wakeup settings. This allows a GPIO to wake the processor from
off mode.

Signed-off-by: Russ Dill <Russ.Dill@gmail.com>

---
 arch/arm/plat-omap/gpio.c |   58 ++++++++++++++++++++++++++++++--------------
 1 files changed, 39 insertions(+), 19 deletions(-)

Comments

Kevin Hilman May 13, 2009, 2:07 p.m. UTC | #1
Russ Dill <russ.dill@gmail.com> writes:

> This patch configures the wakeup padconf registers to reflect the sysfs
> power/wakeup settings. This allows a GPIO to wake the processor from
> off mode.
>
> Signed-off-by: Russ Dill <Russ.Dill@gmail.com>

Hi Russ,

This looks good for the PM branch.  For completeness, could you update
the description to include a brief example of how you're using sysfs
to test this.  That will help other folks test this feature and
also setup some automated tests.

Thanks,

Kevin

> ---
>  arch/arm/plat-omap/gpio.c |   58 ++++++++++++++++++++++++++++++--------------
>  1 files changed, 39 insertions(+), 19 deletions(-)
>
> diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
> index 64852db..3b2054b 100644
> --- a/arch/arm/plat-omap/gpio.c
> +++ b/arch/arm/plat-omap/gpio.c
> @@ -277,7 +277,14 @@ static const struct gpio_pad_range gpio_pads_config[] = {
>  	{ 170, 182, 0x1c6 },
>  	{ 0, 0, 0x1e0 },
>  	{ 186, 186, 0x1e2 },
> +	{ 187, 187, 0x238 },
> +	{ 32, 32, 0x23a },
>  	{ 12, 29, 0x5d8 },
> +	{ 1, 1, 0xa06 },
> +	{ 30, 30, 0xa08 },
> +	{ 2, 10, 0xa0a },
> +	{ 11, 11, 0xa24 },
> +	{ 31, 31, 0xa26 },
>  };
>  
>  /* GPIO -> PAD config mapping for OMAP3 */
> @@ -289,7 +296,8 @@ struct gpio_pad {
>  
>  #define OMAP34XX_GPIO_AMT	(32 * OMAP34XX_NR_GPIOS)
>  
> -struct gpio_pad *gpio_pads;
> +static struct gpio_pad *gpio_pads;
> +static u16 gpio_pad_map[OMAP34XX_GPIO_AMT];
>  #endif
>  
>  static struct gpio_bank *gpio_bank;
> @@ -1353,32 +1361,21 @@ static int __init omap3_gpio_pads_init(void)
>  {
>  	int i, j, min, max, gpio_amt;
>  	u16 offset;
> -	u16 *gpio_pad_map;
>  
>  	gpio_amt = 0;
>  
> -	gpio_pad_map = kzalloc(sizeof(u16) * OMAP34XX_GPIO_AMT, GFP_KERNEL);
> -	if (gpio_pad_map == NULL) {
> -		printk(KERN_ERR "FATAL: Failed to allocate gpio_pad_map\n");
> -		return -ENOMEM;
> -	}
> -
>  	for (i = 0; i < ARRAY_SIZE(gpio_pads_config); i++) {
>  		min = gpio_pads_config[i].min;
>  		max = gpio_pads_config[i].max;
>  		offset = gpio_pads_config[i].offset;
>  
>  		for (j = min; j <= max; j++) {
> -			/*
> -			 * Check if pad has been configured as GPIO.
> -			 * First module (gpio 0...31) is ignored as it is
> -			 * in wakeup domain and does not need special
> -			 * handling during off mode.
> -			 */
> -			if (j > 31 && (omap_ctrl_readw(offset) &
> +			/* Check if pad has been configured as GPIO. */
> +			if ((omap_ctrl_readw(offset) &
>  				OMAP34XX_MUX_MODE7) == OMAP34XX_MUX_MODE4) {
>  				gpio_pad_map[j] = offset;
> -				gpio_amt++;
> +				if (j > 31)
> +					gpio_amt++;
>  			}
>  			offset += 2;
>  		}
> @@ -1388,20 +1385,23 @@ static int __init omap3_gpio_pads_init(void)
>  
>  	if (gpio_pads == NULL) {
>  		printk(KERN_ERR "FATAL: Failed to allocate gpio_pads\n");
> -		kfree(gpio_pad_map);
>  		return -ENOMEM;
>  	}
>  
>  	gpio_amt = 0;
>  	for (i = 0; i < OMAP34XX_GPIO_AMT; i++) {
> -		if (gpio_pad_map[i] != 0) {
> +		/*
> +		 * First module (gpio 0...31) is ignored as it is
> +		 * in wakeup domain and does not need special
> +		 * handling during off mode.
> +		 */
> +		if (gpio_pad_map[i] && i > 31) {
>  			gpio_pads[gpio_amt].gpio = i;
>  			gpio_pads[gpio_amt].offset = gpio_pad_map[i];
>  			gpio_amt++;
>  		}
>  	}
>  	gpio_pads[gpio_amt].gpio = -1;
> -	kfree(gpio_pad_map);
>  	return 0;
>  }
>  late_initcall(omap3_gpio_pads_init);
> @@ -1676,6 +1676,26 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
>  		__raw_writel(0xffffffff, wake_clear);
>  		__raw_writel(bank->suspend_wakeup, wake_set);
>  		spin_unlock_irqrestore(&bank->lock, flags);
> +
> +#ifdef CONFIG_ARCH_OMAP34XX
> +		if (bank->method == METHOD_GPIO_24XX) {
> +			int j;
> +			for (j = 0; j < 32; j++) {
> +				int offset = gpio_pad_map[j + i * 32];
> +				u16 v;
> +
> +				if (!offset)
> +					continue;
> +
> +				v = omap_ctrl_readw(offset);
> +				if (bank->suspend_wakeup & (1 << j))
> +					v |= OMAP3_PADCONF_WAKEUPENABLE0;
> +				else
> +					v &= ~OMAP3_PADCONF_WAKEUPENABLE0;
> +				omap_ctrl_writew(v, offset);
> +			}
> +		}
> +#endif
>  	}
>  
>  	return 0;
> -- 
> 1.6.0.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 64852db..3b2054b 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -277,7 +277,14 @@  static const struct gpio_pad_range gpio_pads_config[] = {
 	{ 170, 182, 0x1c6 },
 	{ 0, 0, 0x1e0 },
 	{ 186, 186, 0x1e2 },
+	{ 187, 187, 0x238 },
+	{ 32, 32, 0x23a },
 	{ 12, 29, 0x5d8 },
+	{ 1, 1, 0xa06 },
+	{ 30, 30, 0xa08 },
+	{ 2, 10, 0xa0a },
+	{ 11, 11, 0xa24 },
+	{ 31, 31, 0xa26 },
 };
 
 /* GPIO -> PAD config mapping for OMAP3 */
@@ -289,7 +296,8 @@  struct gpio_pad {
 
 #define OMAP34XX_GPIO_AMT	(32 * OMAP34XX_NR_GPIOS)
 
-struct gpio_pad *gpio_pads;
+static struct gpio_pad *gpio_pads;
+static u16 gpio_pad_map[OMAP34XX_GPIO_AMT];
 #endif
 
 static struct gpio_bank *gpio_bank;
@@ -1353,32 +1361,21 @@  static int __init omap3_gpio_pads_init(void)
 {
 	int i, j, min, max, gpio_amt;
 	u16 offset;
-	u16 *gpio_pad_map;
 
 	gpio_amt = 0;
 
-	gpio_pad_map = kzalloc(sizeof(u16) * OMAP34XX_GPIO_AMT, GFP_KERNEL);
-	if (gpio_pad_map == NULL) {
-		printk(KERN_ERR "FATAL: Failed to allocate gpio_pad_map\n");
-		return -ENOMEM;
-	}
-
 	for (i = 0; i < ARRAY_SIZE(gpio_pads_config); i++) {
 		min = gpio_pads_config[i].min;
 		max = gpio_pads_config[i].max;
 		offset = gpio_pads_config[i].offset;
 
 		for (j = min; j <= max; j++) {
-			/*
-			 * Check if pad has been configured as GPIO.
-			 * First module (gpio 0...31) is ignored as it is
-			 * in wakeup domain and does not need special
-			 * handling during off mode.
-			 */
-			if (j > 31 && (omap_ctrl_readw(offset) &
+			/* Check if pad has been configured as GPIO. */
+			if ((omap_ctrl_readw(offset) &
 				OMAP34XX_MUX_MODE7) == OMAP34XX_MUX_MODE4) {
 				gpio_pad_map[j] = offset;
-				gpio_amt++;
+				if (j > 31)
+					gpio_amt++;
 			}
 			offset += 2;
 		}
@@ -1388,20 +1385,23 @@  static int __init omap3_gpio_pads_init(void)
 
 	if (gpio_pads == NULL) {
 		printk(KERN_ERR "FATAL: Failed to allocate gpio_pads\n");
-		kfree(gpio_pad_map);
 		return -ENOMEM;
 	}
 
 	gpio_amt = 0;
 	for (i = 0; i < OMAP34XX_GPIO_AMT; i++) {
-		if (gpio_pad_map[i] != 0) {
+		/*
+		 * First module (gpio 0...31) is ignored as it is
+		 * in wakeup domain and does not need special
+		 * handling during off mode.
+		 */
+		if (gpio_pad_map[i] && i > 31) {
 			gpio_pads[gpio_amt].gpio = i;
 			gpio_pads[gpio_amt].offset = gpio_pad_map[i];
 			gpio_amt++;
 		}
 	}
 	gpio_pads[gpio_amt].gpio = -1;
-	kfree(gpio_pad_map);
 	return 0;
 }
 late_initcall(omap3_gpio_pads_init);
@@ -1676,6 +1676,26 @@  static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
 		__raw_writel(0xffffffff, wake_clear);
 		__raw_writel(bank->suspend_wakeup, wake_set);
 		spin_unlock_irqrestore(&bank->lock, flags);
+
+#ifdef CONFIG_ARCH_OMAP34XX
+		if (bank->method == METHOD_GPIO_24XX) {
+			int j;
+			for (j = 0; j < 32; j++) {
+				int offset = gpio_pad_map[j + i * 32];
+				u16 v;
+
+				if (!offset)
+					continue;
+
+				v = omap_ctrl_readw(offset);
+				if (bank->suspend_wakeup & (1 << j))
+					v |= OMAP3_PADCONF_WAKEUPENABLE0;
+				else
+					v &= ~OMAP3_PADCONF_WAKEUPENABLE0;
+				omap_ctrl_writew(v, offset);
+			}
+		}
+#endif
 	}
 
 	return 0;