summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/wakeups-t2.c
diff options
context:
space:
mode:
authorDan Willemsen <dwillemsen@nvidia.com>2012-05-30 00:36:39 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2013-09-14 12:09:17 -0700
commit3e26212eee0c1e3ff763650fbff18f1b3ed83dbc (patch)
treea9aec37f017820cc07f42fa05242633cbe9e700e /arch/arm/mach-tegra/wakeups-t2.c
parentb43f28d8f3fc7efea4c271e5039e3af38bf45557 (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.c68
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;
}