Loading arch/arm/mach-omap2/pm24xx.c +2 −2 Original line number Diff line number Diff line Loading @@ -107,7 +107,7 @@ static void omap2_enter_full_retention(void) l = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0) | OMAP24XX_USBSTANDBYCTRL; omap_ctrl_writel(l, OMAP2_CONTROL_DEVCONF0); omap2_gpio_prepare_for_retention(); omap2_gpio_prepare_for_idle(PWRDM_POWER_RET); if (omap2_pm_debug) { omap2_pm_dump(0, 0, 0); Loading Loading @@ -141,7 +141,7 @@ static void omap2_enter_full_retention(void) tmp = timespec_to_ns(&ts_idle) * NSEC_PER_USEC; omap2_pm_dump(0, 1, tmp); } omap2_gpio_resume_after_retention(); omap2_gpio_resume_after_idle(); clk_enable(osc_ck); Loading arch/arm/mach-omap2/pm34xx.c +2 −2 Original line number Diff line number Diff line Loading @@ -376,7 +376,7 @@ void omap_sram_idle(void) core_next_state = pwrdm_read_next_pwrst(core_pwrdm); if (per_next_state < PWRDM_POWER_ON) { omap_uart_prepare_idle(2); omap2_gpio_prepare_for_retention(); omap2_gpio_prepare_for_idle(per_next_state); if (per_next_state == PWRDM_POWER_OFF) { if (core_next_state == PWRDM_POWER_ON) { per_next_state = PWRDM_POWER_RET; Loading Loading @@ -454,9 +454,9 @@ void omap_sram_idle(void) /* PER */ if (per_next_state < PWRDM_POWER_ON) { per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm); omap2_gpio_resume_after_idle(); if (per_prev_state == PWRDM_POWER_OFF) omap3_per_restore_context(); omap2_gpio_resume_after_retention(); omap_uart_resume_idle(2); if (per_state_modified) pwrdm_set_next_pwrst(per_pwrdm, PWRDM_POWER_OFF); Loading arch/arm/plat-omap/gpio.c +47 −130 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <mach/irqs.h> #include <mach/gpio.h> #include <asm/mach/irq.h> #include <plat/powerdomain.h> /* * OMAP1510 GPIO registers Loading Loading @@ -195,6 +196,7 @@ struct gpio_bank { struct gpio_chip chip; struct clk *dbck; u32 mod_usage; u32 dbck_enable_mask; }; #define METHOD_MPUIO 0 Loading Loading @@ -303,8 +305,6 @@ struct omap3_gpio_regs { u32 risingdetect; u32 fallingdetect; u32 dataout; u32 setwkuena; u32 setdataout; }; static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS]; Loading Loading @@ -646,6 +646,7 @@ void omap_set_gpio_debounce(int gpio, int enable) goto done; if (cpu_is_omap34xx() || cpu_is_omap44xx()) { bank->dbck_enable_mask = val; if (enable) clk_enable(bank->dbck); else Loading Loading @@ -724,15 +725,27 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, OMAP4_GPIO_IRQWAKEN0); } } else { if (trigger != 0) /* * GPIO wakeup request can only be generated on edge * transitions */ if (trigger & IRQ_TYPE_EDGE_BOTH) __raw_writel(1 << gpio, bank->base + OMAP24XX_GPIO_SETWKUENA); else __raw_writel(1 << gpio, bank->base + OMAP24XX_GPIO_CLEARWKUENA); } } else { if (trigger != 0) } /* This part needs to be executed always for OMAP34xx */ if (cpu_is_omap34xx() || (bank->non_wakeup_gpios & gpio_bit)) { /* * Log the edge gpio and manually trigger the IRQ * after resume if the input level changes * to avoid irq lost during PER RET/OFF mode * Applies for omap2 non-wakeup gpio and all omap3 gpios */ if (trigger & IRQ_TYPE_EDGE_BOTH) bank->enabled_non_wakeup_gpios |= gpio_bit; else bank->enabled_non_wakeup_gpios &= ~gpio_bit; Loading Loading @@ -1845,7 +1858,8 @@ static int __init _omap_gpio_init(void) __raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL); } if (i < ARRAY_SIZE(non_wakeup_gpios)) if (cpu_is_omap24xx() && i < ARRAY_SIZE(non_wakeup_gpios)) bank->non_wakeup_gpios = non_wakeup_gpios[i]; gpio_count = 32; } Loading Loading @@ -2028,16 +2042,27 @@ static struct sys_device omap_gpio_device = { static int workaround_enabled; void omap2_gpio_prepare_for_retention(void) void omap2_gpio_prepare_for_idle(int power_state) { int i, c = 0; int min = 0; /* Remove triggering for all non-wakeup GPIOs. Otherwise spurious * IRQs will be generated. See OMAP2420 Errata item 1.101. */ for (i = 0; i < gpio_bank_count; i++) { if (cpu_is_omap34xx()) min = 1; for (i = min; i < gpio_bank_count; i++) { struct gpio_bank *bank = &gpio_bank[i]; u32 l1, l2; if (bank->dbck_enable_mask) clk_disable(bank->dbck); if (power_state > PWRDM_POWER_OFF) continue; /* If going to OFF, remove triggering for all * non-wakeup GPIOs. Otherwise spurious IRQs will be * generated. See OMAP2420 Errata item 1.101. */ if (!(bank->enabled_non_wakeup_gpios)) continue; Loading Loading @@ -2085,16 +2110,23 @@ void omap2_gpio_prepare_for_retention(void) workaround_enabled = 1; } void omap2_gpio_resume_after_retention(void) void omap2_gpio_resume_after_idle(void) { int i; int min = 0; if (!workaround_enabled) return; for (i = 0; i < gpio_bank_count; i++) { if (cpu_is_omap34xx()) min = 1; for (i = min; i < gpio_bank_count; i++) { struct gpio_bank *bank = &gpio_bank[i]; u32 l, gen, gen0, gen1; if (bank->dbck_enable_mask) clk_enable(bank->dbck); if (!workaround_enabled) continue; if (!(bank->enabled_non_wakeup_gpios)) continue; Loading @@ -2119,7 +2151,7 @@ void omap2_gpio_resume_after_retention(void) * horribly racy, but it's the best we can do to work around * this silicon bug. */ l ^= bank->saved_datain; l &= bank->non_wakeup_gpios; l &= bank->enabled_non_wakeup_gpios; /* * No need to generate IRQs for the rising edge for gpio IRQs Loading Loading @@ -2207,10 +2239,6 @@ void omap_gpio_save_context(void) __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT); gpio_context[i].dataout = __raw_readl(bank->base + OMAP24XX_GPIO_DATAOUT); gpio_context[i].setwkuena = __raw_readl(bank->base + OMAP24XX_GPIO_SETWKUENA); gpio_context[i].setdataout = __raw_readl(bank->base + OMAP24XX_GPIO_SETDATAOUT); } } Loading Loading @@ -2243,10 +2271,6 @@ void omap_gpio_restore_context(void) bank->base + OMAP24XX_GPIO_FALLINGDETECT); __raw_writel(gpio_context[i].dataout, bank->base + OMAP24XX_GPIO_DATAOUT); __raw_writel(gpio_context[i].setwkuena, bank->base + OMAP24XX_GPIO_SETWKUENA); __raw_writel(gpio_context[i].setdataout, bank->base + OMAP24XX_GPIO_SETDATAOUT); } } #endif Loading Loading @@ -2286,110 +2310,3 @@ static int __init omap_gpio_sysinit(void) } arch_initcall(omap_gpio_sysinit); #ifdef CONFIG_DEBUG_FS #include <linux/debugfs.h> #include <linux/seq_file.h> static int dbg_gpio_show(struct seq_file *s, void *unused) { unsigned i, j, gpio; for (i = 0, gpio = 0; i < gpio_bank_count; i++) { struct gpio_bank *bank = gpio_bank + i; unsigned bankwidth = 16; u32 mask = 1; if (bank_is_mpuio(bank)) gpio = OMAP_MPUIO(0); else if (cpu_class_is_omap2() || cpu_is_omap7xx()) bankwidth = 32; for (j = 0; j < bankwidth; j++, gpio++, mask <<= 1) { unsigned irq, value, is_in, irqstat; const char *label; label = gpiochip_is_requested(&bank->chip, j); if (!label) continue; irq = bank->virtual_irq_start + j; value = gpio_get_value(gpio); is_in = gpio_is_input(bank, mask); if (bank_is_mpuio(bank)) seq_printf(s, "MPUIO %2d ", j); else seq_printf(s, "GPIO %3d ", gpio); seq_printf(s, "(%-20.20s): %s %s", label, is_in ? "in " : "out", value ? "hi" : "lo"); /* FIXME for at least omap2, show pullup/pulldown state */ irqstat = irq_desc[irq].status; #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS) if (is_in && ((bank->suspend_wakeup & mask) || irqstat & IRQ_TYPE_SENSE_MASK)) { char *trigger = NULL; switch (irqstat & IRQ_TYPE_SENSE_MASK) { case IRQ_TYPE_EDGE_FALLING: trigger = "falling"; break; case IRQ_TYPE_EDGE_RISING: trigger = "rising"; break; case IRQ_TYPE_EDGE_BOTH: trigger = "bothedge"; break; case IRQ_TYPE_LEVEL_LOW: trigger = "low"; break; case IRQ_TYPE_LEVEL_HIGH: trigger = "high"; break; case IRQ_TYPE_NONE: trigger = "(?)"; break; } seq_printf(s, ", irq-%d %-8s%s", irq, trigger, (bank->suspend_wakeup & mask) ? " wakeup" : ""); } #endif seq_printf(s, "\n"); } if (bank_is_mpuio(bank)) { seq_printf(s, "\n"); gpio = 0; } } return 0; } static int dbg_gpio_open(struct inode *inode, struct file *file) { return single_open(file, dbg_gpio_show, &inode->i_private); } static const struct file_operations debug_fops = { .open = dbg_gpio_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; static int __init omap_gpio_debuginit(void) { (void) debugfs_create_file("omap_gpio", S_IRUGO, NULL, NULL, &debug_fops); return 0; } late_initcall(omap_gpio_debuginit); #endif arch/arm/plat-omap/include/plat/gpio.h +2 −2 Original line number Diff line number Diff line Loading @@ -72,8 +72,8 @@ IH_GPIO_BASE + (nr)) extern int omap_gpio_init(void); /* Call from board init only */ extern void omap2_gpio_prepare_for_retention(void); extern void omap2_gpio_resume_after_retention(void); extern void omap2_gpio_prepare_for_idle(int power_state); extern void omap2_gpio_resume_after_idle(void); extern void omap_set_gpio_debounce(int gpio, int enable); extern void omap_set_gpio_debounce_time(int gpio, int enable); extern void omap_gpio_save_context(void); Loading Loading
arch/arm/mach-omap2/pm24xx.c +2 −2 Original line number Diff line number Diff line Loading @@ -107,7 +107,7 @@ static void omap2_enter_full_retention(void) l = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0) | OMAP24XX_USBSTANDBYCTRL; omap_ctrl_writel(l, OMAP2_CONTROL_DEVCONF0); omap2_gpio_prepare_for_retention(); omap2_gpio_prepare_for_idle(PWRDM_POWER_RET); if (omap2_pm_debug) { omap2_pm_dump(0, 0, 0); Loading Loading @@ -141,7 +141,7 @@ static void omap2_enter_full_retention(void) tmp = timespec_to_ns(&ts_idle) * NSEC_PER_USEC; omap2_pm_dump(0, 1, tmp); } omap2_gpio_resume_after_retention(); omap2_gpio_resume_after_idle(); clk_enable(osc_ck); Loading
arch/arm/mach-omap2/pm34xx.c +2 −2 Original line number Diff line number Diff line Loading @@ -376,7 +376,7 @@ void omap_sram_idle(void) core_next_state = pwrdm_read_next_pwrst(core_pwrdm); if (per_next_state < PWRDM_POWER_ON) { omap_uart_prepare_idle(2); omap2_gpio_prepare_for_retention(); omap2_gpio_prepare_for_idle(per_next_state); if (per_next_state == PWRDM_POWER_OFF) { if (core_next_state == PWRDM_POWER_ON) { per_next_state = PWRDM_POWER_RET; Loading Loading @@ -454,9 +454,9 @@ void omap_sram_idle(void) /* PER */ if (per_next_state < PWRDM_POWER_ON) { per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm); omap2_gpio_resume_after_idle(); if (per_prev_state == PWRDM_POWER_OFF) omap3_per_restore_context(); omap2_gpio_resume_after_retention(); omap_uart_resume_idle(2); if (per_state_modified) pwrdm_set_next_pwrst(per_pwrdm, PWRDM_POWER_OFF); Loading
arch/arm/plat-omap/gpio.c +47 −130 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <mach/irqs.h> #include <mach/gpio.h> #include <asm/mach/irq.h> #include <plat/powerdomain.h> /* * OMAP1510 GPIO registers Loading Loading @@ -195,6 +196,7 @@ struct gpio_bank { struct gpio_chip chip; struct clk *dbck; u32 mod_usage; u32 dbck_enable_mask; }; #define METHOD_MPUIO 0 Loading Loading @@ -303,8 +305,6 @@ struct omap3_gpio_regs { u32 risingdetect; u32 fallingdetect; u32 dataout; u32 setwkuena; u32 setdataout; }; static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS]; Loading Loading @@ -646,6 +646,7 @@ void omap_set_gpio_debounce(int gpio, int enable) goto done; if (cpu_is_omap34xx() || cpu_is_omap44xx()) { bank->dbck_enable_mask = val; if (enable) clk_enable(bank->dbck); else Loading Loading @@ -724,15 +725,27 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, OMAP4_GPIO_IRQWAKEN0); } } else { if (trigger != 0) /* * GPIO wakeup request can only be generated on edge * transitions */ if (trigger & IRQ_TYPE_EDGE_BOTH) __raw_writel(1 << gpio, bank->base + OMAP24XX_GPIO_SETWKUENA); else __raw_writel(1 << gpio, bank->base + OMAP24XX_GPIO_CLEARWKUENA); } } else { if (trigger != 0) } /* This part needs to be executed always for OMAP34xx */ if (cpu_is_omap34xx() || (bank->non_wakeup_gpios & gpio_bit)) { /* * Log the edge gpio and manually trigger the IRQ * after resume if the input level changes * to avoid irq lost during PER RET/OFF mode * Applies for omap2 non-wakeup gpio and all omap3 gpios */ if (trigger & IRQ_TYPE_EDGE_BOTH) bank->enabled_non_wakeup_gpios |= gpio_bit; else bank->enabled_non_wakeup_gpios &= ~gpio_bit; Loading Loading @@ -1845,7 +1858,8 @@ static int __init _omap_gpio_init(void) __raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL); } if (i < ARRAY_SIZE(non_wakeup_gpios)) if (cpu_is_omap24xx() && i < ARRAY_SIZE(non_wakeup_gpios)) bank->non_wakeup_gpios = non_wakeup_gpios[i]; gpio_count = 32; } Loading Loading @@ -2028,16 +2042,27 @@ static struct sys_device omap_gpio_device = { static int workaround_enabled; void omap2_gpio_prepare_for_retention(void) void omap2_gpio_prepare_for_idle(int power_state) { int i, c = 0; int min = 0; /* Remove triggering for all non-wakeup GPIOs. Otherwise spurious * IRQs will be generated. See OMAP2420 Errata item 1.101. */ for (i = 0; i < gpio_bank_count; i++) { if (cpu_is_omap34xx()) min = 1; for (i = min; i < gpio_bank_count; i++) { struct gpio_bank *bank = &gpio_bank[i]; u32 l1, l2; if (bank->dbck_enable_mask) clk_disable(bank->dbck); if (power_state > PWRDM_POWER_OFF) continue; /* If going to OFF, remove triggering for all * non-wakeup GPIOs. Otherwise spurious IRQs will be * generated. See OMAP2420 Errata item 1.101. */ if (!(bank->enabled_non_wakeup_gpios)) continue; Loading Loading @@ -2085,16 +2110,23 @@ void omap2_gpio_prepare_for_retention(void) workaround_enabled = 1; } void omap2_gpio_resume_after_retention(void) void omap2_gpio_resume_after_idle(void) { int i; int min = 0; if (!workaround_enabled) return; for (i = 0; i < gpio_bank_count; i++) { if (cpu_is_omap34xx()) min = 1; for (i = min; i < gpio_bank_count; i++) { struct gpio_bank *bank = &gpio_bank[i]; u32 l, gen, gen0, gen1; if (bank->dbck_enable_mask) clk_enable(bank->dbck); if (!workaround_enabled) continue; if (!(bank->enabled_non_wakeup_gpios)) continue; Loading @@ -2119,7 +2151,7 @@ void omap2_gpio_resume_after_retention(void) * horribly racy, but it's the best we can do to work around * this silicon bug. */ l ^= bank->saved_datain; l &= bank->non_wakeup_gpios; l &= bank->enabled_non_wakeup_gpios; /* * No need to generate IRQs for the rising edge for gpio IRQs Loading Loading @@ -2207,10 +2239,6 @@ void omap_gpio_save_context(void) __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT); gpio_context[i].dataout = __raw_readl(bank->base + OMAP24XX_GPIO_DATAOUT); gpio_context[i].setwkuena = __raw_readl(bank->base + OMAP24XX_GPIO_SETWKUENA); gpio_context[i].setdataout = __raw_readl(bank->base + OMAP24XX_GPIO_SETDATAOUT); } } Loading Loading @@ -2243,10 +2271,6 @@ void omap_gpio_restore_context(void) bank->base + OMAP24XX_GPIO_FALLINGDETECT); __raw_writel(gpio_context[i].dataout, bank->base + OMAP24XX_GPIO_DATAOUT); __raw_writel(gpio_context[i].setwkuena, bank->base + OMAP24XX_GPIO_SETWKUENA); __raw_writel(gpio_context[i].setdataout, bank->base + OMAP24XX_GPIO_SETDATAOUT); } } #endif Loading Loading @@ -2286,110 +2310,3 @@ static int __init omap_gpio_sysinit(void) } arch_initcall(omap_gpio_sysinit); #ifdef CONFIG_DEBUG_FS #include <linux/debugfs.h> #include <linux/seq_file.h> static int dbg_gpio_show(struct seq_file *s, void *unused) { unsigned i, j, gpio; for (i = 0, gpio = 0; i < gpio_bank_count; i++) { struct gpio_bank *bank = gpio_bank + i; unsigned bankwidth = 16; u32 mask = 1; if (bank_is_mpuio(bank)) gpio = OMAP_MPUIO(0); else if (cpu_class_is_omap2() || cpu_is_omap7xx()) bankwidth = 32; for (j = 0; j < bankwidth; j++, gpio++, mask <<= 1) { unsigned irq, value, is_in, irqstat; const char *label; label = gpiochip_is_requested(&bank->chip, j); if (!label) continue; irq = bank->virtual_irq_start + j; value = gpio_get_value(gpio); is_in = gpio_is_input(bank, mask); if (bank_is_mpuio(bank)) seq_printf(s, "MPUIO %2d ", j); else seq_printf(s, "GPIO %3d ", gpio); seq_printf(s, "(%-20.20s): %s %s", label, is_in ? "in " : "out", value ? "hi" : "lo"); /* FIXME for at least omap2, show pullup/pulldown state */ irqstat = irq_desc[irq].status; #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS) if (is_in && ((bank->suspend_wakeup & mask) || irqstat & IRQ_TYPE_SENSE_MASK)) { char *trigger = NULL; switch (irqstat & IRQ_TYPE_SENSE_MASK) { case IRQ_TYPE_EDGE_FALLING: trigger = "falling"; break; case IRQ_TYPE_EDGE_RISING: trigger = "rising"; break; case IRQ_TYPE_EDGE_BOTH: trigger = "bothedge"; break; case IRQ_TYPE_LEVEL_LOW: trigger = "low"; break; case IRQ_TYPE_LEVEL_HIGH: trigger = "high"; break; case IRQ_TYPE_NONE: trigger = "(?)"; break; } seq_printf(s, ", irq-%d %-8s%s", irq, trigger, (bank->suspend_wakeup & mask) ? " wakeup" : ""); } #endif seq_printf(s, "\n"); } if (bank_is_mpuio(bank)) { seq_printf(s, "\n"); gpio = 0; } } return 0; } static int dbg_gpio_open(struct inode *inode, struct file *file) { return single_open(file, dbg_gpio_show, &inode->i_private); } static const struct file_operations debug_fops = { .open = dbg_gpio_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; static int __init omap_gpio_debuginit(void) { (void) debugfs_create_file("omap_gpio", S_IRUGO, NULL, NULL, &debug_fops); return 0; } late_initcall(omap_gpio_debuginit); #endif
arch/arm/plat-omap/include/plat/gpio.h +2 −2 Original line number Diff line number Diff line Loading @@ -72,8 +72,8 @@ IH_GPIO_BASE + (nr)) extern int omap_gpio_init(void); /* Call from board init only */ extern void omap2_gpio_prepare_for_retention(void); extern void omap2_gpio_resume_after_retention(void); extern void omap2_gpio_prepare_for_idle(int power_state); extern void omap2_gpio_resume_after_idle(void); extern void omap_set_gpio_debounce(int gpio, int enable); extern void omap_set_gpio_debounce_time(int gpio, int enable); extern void omap_gpio_save_context(void); Loading