diff options
author | Dan Willemsen <dwillemsen@nvidia.com> | 2012-05-30 00:36:39 -0700 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2013-09-14 12:09:17 -0700 |
commit | 3e26212eee0c1e3ff763650fbff18f1b3ed83dbc (patch) | |
tree | a9aec37f017820cc07f42fa05242633cbe9e700e /arch/arm/mach-tegra/wakeups-t2.c | |
parent | b43f28d8f3fc7efea4c271e5039e3af38bf45557 (diff) |
ARM: tegra: wakeups: Refactor
TODO: Share code between T2 & T3.
Move irq->wake translation to the driver layer, this lets us split out
the tegra_irq_to_wake gpio searching to a tegra_gpio_to_wake function.
tegra_pm_irq_set_wake: the tegra_*_to_wake() functions can never return
-EALREADY or -ENOTSUPP (even before this change)
This has a side effect of removing usage of TEGRA_GPIO_TO_IRQ, which is
deprecated.
Change-Id: I07c00952997db9f1597fd0a1caadbf4dfe1b5045
Signed-off-by: Dan Willemsen <dwillemsen@nvidia.com>
Reviewed-on: http://git-master/r/106365
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Varun Wadekar <vwadekar@nvidia.com>
Tested-by: Varun Wadekar <vwadekar@nvidia.com>
Rebase-Id: R0161f34fd215e8ec4763c33d9f2f96b6f88dc8f8
Diffstat (limited to 'arch/arm/mach-tegra/wakeups-t2.c')
-rw-r--r-- | arch/arm/mach-tegra/wakeups-t2.c | 68 |
1 files changed, 44 insertions, 24 deletions
diff --git a/arch/arm/mach-tegra/wakeups-t2.c b/arch/arm/mach-tegra/wakeups-t2.c index 5ffb1c71d0be..13b7b0858747 100644 --- a/arch/arm/mach-tegra/wakeups-t2.c +++ b/arch/arm/mach-tegra/wakeups-t2.c @@ -93,37 +93,54 @@ static int tegra_wake_event_irq[] = { [30] = -EAGAIN, }; -int tegra_irq_to_wake(int irq) +static int last_gpio = -1; + +int tegra_gpio_to_wake(int gpio) { int i; - static int last_wake = -1; - for (i = 0; i < ARRAY_SIZE(tegra_wake_event_irq); i++) - if (tegra_wake_event_irq[i] == irq) - goto out; + for (i = 0; i < ARRAY_SIZE(tegra_gpio_wakes); i++) { + if (tegra_gpio_wakes[i] == gpio) { + pr_info("gpio wake%d for gpio=%d\n", i, gpio); + last_gpio = i; + return i; + } + } - for (i = 0; i < ARRAY_SIZE(tegra_gpio_wakes); i++) - if (gpio_to_irq(tegra_gpio_wakes[i]) == irq) - goto out; + return -EINVAL; +} - /* Two level wake irq search for gpio based wakeups - - * 1. check for GPIO irq(based on tegra_wake_event_irq table) - * e.g. for a board, wake7 based on GPIO PU6 and irq==358 done first - * 2. check for gpio bank irq assuming search for GPIO irq - * preceded this search. - * e.g. in this step check for gpio bank irq GPIO6 irq==119 - */ - if (last_wake < 0 || last_wake >= ARRAY_SIZE(tegra_gpio_wakes)) - return -EINVAL; +int tegra_irq_to_wake(int irq) +{ + int i; + int ret = -EINVAL; - if (tegra_gpio_get_bank_int_nr(tegra_gpio_wakes[last_wake]) == irq) - return last_wake; + for (i = 0; i < ARRAY_SIZE(tegra_wake_event_irq); i++) { + if (tegra_wake_event_irq[i] == irq) { + pr_info("Wake %d for irq=%d\n", i, irq); + ret = i; + goto out; + } + } + + /* The gpio set_wake code bubbles the set_wake call up to the irq + * set_wake code. This insures that the nested irq set_wake call + * succeeds, even though it doesn't have to do any pm setup for the + * bank. + * + * This is very fragile - there's no locking, so two callers could + * cause issues with this. + */ + if (last_gpio < 0) + goto out; - return -EINVAL; + if (tegra_gpio_get_bank_int_nr(tegra_gpio_wakes[last_gpio]) == irq) { + pr_info("gpio bank wake found: wake %d for irq=%d\n", i, irq); + ret = last_gpio; + } out: - last_wake = i; - return i; + return ret; } int tegra_wake_to_irq(int wake) @@ -137,8 +154,11 @@ int tegra_wake_to_irq(int wake) return -EINVAL; ret = tegra_wake_event_irq[wake]; - if (ret == -EAGAIN) - ret = gpio_to_irq(tegra_gpio_wakes[wake]); + if (ret == -EAGAIN) { + ret = tegra_gpio_wakes[wake]; + if (ret != -EINVAL) + ret = gpio_to_irq(ret); + } return ret; } |