diff options
author | Arve Hjønnevåg <arve@android.com> | 2011-12-13 22:22:00 -0800 |
---|---|---|
committer | Arve Hjønnevåg <arve@android.com> | 2011-12-14 17:58:53 -0800 |
commit | 5a44bf340a2f8967a30da5035dfee9ae452a585a (patch) | |
tree | ee49d914c45e7379ee4e5422bf5d6bdedb489ee3 | |
parent | aa7b27cb96dbadf29308f87d5e189e46d5ca39ce (diff) | |
download | kernel_samsung_tuna-5a44bf340a2f8967a30da5035dfee9ae452a585a.zip kernel_samsung_tuna-5a44bf340a2f8967a30da5035dfee9ae452a585a.tar.gz kernel_samsung_tuna-5a44bf340a2f8967a30da5035dfee9ae452a585a.tar.bz2 |
ARM: omap4: gpio: Use pad wakeupevent to detect pulses for edge triggered gpios
When the gpio controller is off we use the pad wakeup to wake up.
The current code only detects edges if the state of the gpio when
we wake up is different from the state we read before we turned
the gpio controller off. This will miss short pulses. We now use
the pad wakeupevent status to try to detect these pulses.
If the interrupt is configured for dual edge triggering this
will generate an interrupt for any pulse detected. If the
interrupt is configured for single edge detect we only
generate an interrupt if the old state matches the starting
state for the enabled edge detect. This will still miss a
pulse when the interrupt is configured for only the second
edge in that pulse. We may also falsely generate an interrupt
if an edge of the wrong polarity occured before reading the
initial state (since the pad wakeup is enabled before then).
Change-Id: Id9a68cd97b0281a7debb2f37d845979894b63bcc
Signed-off-by: Arve Hjønnevåg <arve@android.com>
-rw-r--r-- | arch/arm/mach-omap2/mux.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-omap2/mux.h | 5 | ||||
-rw-r--r-- | drivers/gpio/gpio-omap.c | 7 |
3 files changed, 22 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index a2ed524..c7d0b21 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -968,6 +968,16 @@ void omap_mux_set_gpio(u16 val, int gpio) pr_err("%s: Could not set gpio%i\n", __func__, gpio); } +bool omap_mux_get_wakeupevent(struct omap_mux *m) +{ + u16 val; + if (IS_ERR_OR_NULL(m) || !cpu_is_omap44xx()) + return false; + + val = omap_mux_read(m->partition, m->reg_offset); + return val & OMAP_WAKEUP_EVENT; +} + /* Has no locking, don't use on a pad that is remuxed (by hwmod or otherwise) */ bool omap_mux_get_wakeupenable(struct omap_mux *m) { diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h index 87bf022..e631b5e 100644 --- a/arch/arm/mach-omap2/mux.h +++ b/arch/arm/mach-omap2/mux.h @@ -286,6 +286,11 @@ int omap_mux_clear_wakeupenable(struct omap_mux *m); */ bool omap_mux_get_wakeupenable(struct omap_mux *m); +/** omap_mux_get_wakeupevent() - get the wakeupevent bit from a mux struct + * @m: mux struct + */ +bool omap_mux_get_wakeupevent(struct omap_mux *m); + /** * omap_mux_set_gpio() - set mux register value based on GPIO number * @val: New mux register value diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 6a9bca6..561cb4f 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1398,6 +1398,8 @@ static int omap_gpio_pm_runtime_resume(struct device *dev) struct gpio_bank *bank = platform_get_drvdata(pdev); u32 l = 0, gen, gen0, gen1; int j; + unsigned long pad_wakeup; + int i; for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++) clk_enable(bank->dbck); @@ -1421,6 +1423,11 @@ static int omap_gpio_pm_runtime_resume(struct device *dev) l ^= bank->saved_datain; l &= bank->enabled_non_wakeup_gpios; + pad_wakeup = bank->enabled_non_wakeup_gpios; + for_each_set_bit(i, &pad_wakeup, bank->width) + if (omap_mux_get_wakeupevent(bank->mux[i])) + l |= BIT(i); + /* * No need to generate IRQs for the rising edge for gpio IRQs * configured with falling edge only; and vice versa. |