ARM: tegra: suspend: add LP0 wakeup sources
Colin Cross [Mon, 4 Apr 2011 20:07:37 +0000 (13:07 -0700)]
LP0 suspend can only wake up from 31 sources, mostly gpios spread
randomly across all the gpio banks, but also a few internal irqs.

Change-Id: Ic707d1da6b8d7ddb45dc511ed3739f31066aceaf
Signed-off-by: Colin Cross <ccross@android.com>

arch/arm/mach-tegra/Makefile
arch/arm/mach-tegra/wakeups-t2.c [new file with mode: 0644]
arch/arm/mach-tegra/wakeups-t2.h [new file with mode: 0644]

index f11b910..e6fc2cd 100644 (file)
@@ -10,6 +10,7 @@ obj-y                                 += fuse.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += clock.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += tegra2_clocks.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += tegra2_emc.o
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += wakeups-t2.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += pinmux-t2-tables.o
 obj-$(CONFIG_SMP)                       += platsmp.o localtimer.o headsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)               += hotplug.o
diff --git a/arch/arm/mach-tegra/wakeups-t2.c b/arch/arm/mach-tegra/wakeups-t2.c
new file mode 100644 (file)
index 0000000..667fea7
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2011, Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <mach/iomap.h>
+#include <mach/irqs.h>
+
+#include "gpio-names.h"
+
+#define NUM_WAKE_EVENTS 31
+
+static int tegra_wake_event_irq[] = {
+       [0]  = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PO5),
+       [1]  = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV3),
+       [2]  = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PL1),
+       [3]  = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PB6),
+       [4]  = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PN7),
+       [5]  = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PA0),
+       [6]  = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU5),
+       [7]  = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU6),
+       [8]  = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PC7),
+       [9]  = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS2),
+       [10] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PAA1),
+       [11] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PW3),
+       [12] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PW2),
+       [13] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PY6),
+       [14] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV6),
+       [15] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PJ7),
+       [16] = INT_RTC,
+       [17] = INT_KBC,
+       [18] = INT_EXTERNAL_PMU,
+       [19] = -EINVAL,  /* TEGRA_USB1_VBUS, */
+       [20] = -EINVAL, /* TEGRA_USB3_VBUS, */
+       [21] = -EINVAL, /* TEGRA_USB1_ID, */
+       [22] = -EINVAL, /* TEGRA_USB3_ID, */
+       [23] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PI5),
+       [24] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV2),
+       [25] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS4),
+       [26] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS5),
+       [27] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS0),
+       [28] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PQ6),
+       [29] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PQ7),
+       [30] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PN2),
+       [31] = -EINVAL,
+       /*
+        * The gpio bank irqs aren't actually wake sources, but they don't
+        * prevent lp0 because the gpio chained irq is requested directly
+        */
+       [32] = INT_GPIO1,
+       [33] = INT_GPIO2,
+       [34] = INT_GPIO3,
+       [35] = INT_GPIO4,
+       [36] = INT_GPIO5,
+       [37] = INT_GPIO6,
+       [38] = INT_GPIO7,
+};
+
+int tegra_irq_to_wake(int irq)
+{
+       int i;
+       for (i = 0; i < ARRAY_SIZE(tegra_wake_event_irq); i++)
+               if (tegra_wake_event_irq[i] == irq)
+                       break;
+
+       if (i == ARRAY_SIZE(tegra_wake_event_irq))
+               return -ENOTSUPP;
+
+       if (i > NUM_WAKE_EVENTS)
+               return -EALREADY;
+
+       return i;
+}
+
+int tegra_wake_to_irq(int wake)
+{
+       if (wake < 0)
+               return -EINVAL;
+
+       if (wake >= NUM_WAKE_EVENTS)
+               return -EINVAL;
+
+       return tegra_wake_event_irq[wake];
+}
diff --git a/arch/arm/mach-tegra/wakeups-t2.h b/arch/arm/mach-tegra/wakeups-t2.h
new file mode 100644 (file)
index 0000000..0cd6e0f
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * arch/arm/mach-tegra/wakeups-t2.h
+ *
+ * Declarations of Tegra 2 LP0 wakeup sources
+ *
+ * Copyright (c) 2010, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef __MACH_TEGRA_WAKEUPS_T2_H
+#define __MACH_TEGRA_WAKEUPS_T2_H
+
+int tegra_irq_to_wake(int irq);
+int tegra_wake_to_irq(int wake);
+
+#define TEGRA_WAKE_GPIO_PO5    (1 << 0)
+#define TEGRA_WAKE_GPIO_PV3    (1 << 1)
+#define TEGRA_WAKE_GPIO_PL1    (1 << 2)
+#define TEGRA_WAKE_GPIO_PB6    (1 << 3)
+#define TEGRA_WAKE_GPIO_PN7    (1 << 4)
+#define TEGRA_WAKE_GPIO_PA0    (1 << 5)
+#define TEGRA_WAKE_GPIO_PU5    (1 << 6)
+#define TEGRA_WAKE_GPIO_PU6    (1 << 7)
+#define TEGRA_WAKE_GPIO_PC7    (1 << 8)
+#define TEGRA_WAKE_GPIO_PS2    (1 << 9)
+#define TEGRA_WAKE_GPIO_PAA1   (1 << 10)
+#define TEGRA_WAKE_GPIO_PW3    (1 << 11)
+#define TEGRA_WAKE_GPIO_PW2    (1 << 12)
+#define TEGRA_WAKE_GPIO_PY6    (1 << 13)
+#define TEGRA_WAKE_GPIO_PV6    (1 << 14)
+#define TEGRA_WAKE_GPIO_PJ7    (1 << 15)
+#define TEGRA_WAKE_RTC_ALARM   (1 << 16)
+#define TEGRA_WAKE_KBC_EVENT   (1 << 17)
+#define TEGRA_WAKE_PWR_INT     (1 << 18)
+#define TEGRA_WAKE_USB1_VBUS   (1 << 19)
+#define TEGRA_WAKE_USB3_VBUS   (1 << 20)
+#define TEGRA_WAKE_USB1_ID     (1 << 21)
+#define TEGRA_WAKE_USB3_ID     (1 << 22)
+#define TEGRA_WAKE_GPIO_PI5    (1 << 23)
+#define TEGRA_WAKE_GPIO_PV2    (1 << 24)
+#define TEGRA_WAKE_GPIO_PS4    (1 << 25)
+#define TEGRA_WAKE_GPIO_PS5    (1 << 26)
+#define TEGRA_WAKE_GPIO_PS0    (1 << 27)
+#define TEGRA_WAKE_GPIO_PQ6    (1 << 28)
+#define TEGRA_WAKE_GPIO_PQ7    (1 << 29)
+#define TEGRA_WAKE_GPIO_PN2    (1 << 30)
+
+#endif