diff options
Diffstat (limited to 'arch/arm/mach-tegra/wakeups-t2.c')
-rw-r--r-- | arch/arm/mach-tegra/wakeups-t2.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/wakeups-t2.c b/arch/arm/mach-tegra/wakeups-t2.c new file mode 100644 index 00000000000..7c5d12ac60d --- /dev/null +++ b/arch/arm/mach-tegra/wakeups-t2.c | |||
@@ -0,0 +1,111 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011, Google, Inc. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/gpio.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/io.h> | ||
19 | |||
20 | #include <mach/iomap.h> | ||
21 | #include <mach/irqs.h> | ||
22 | #include <mach/gpio.h> | ||
23 | |||
24 | #include "gpio-names.h" | ||
25 | |||
26 | static int tegra_wake_event_irq[] = { | ||
27 | [0] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PO5), | ||
28 | [1] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV3), | ||
29 | [2] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PL1), | ||
30 | [3] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PB6), | ||
31 | [4] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PN7), | ||
32 | [5] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PA0), | ||
33 | [6] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU5), | ||
34 | [7] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU6), | ||
35 | [8] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PC7), | ||
36 | [9] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS2), | ||
37 | [10] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PAA1), | ||
38 | [11] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PW3), | ||
39 | [12] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PW2), | ||
40 | [13] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PY6), | ||
41 | [14] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV6), | ||
42 | [15] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PJ7), | ||
43 | [16] = INT_RTC, | ||
44 | [17] = INT_KBC, | ||
45 | [18] = INT_EXTERNAL_PMU, | ||
46 | [19] = -EINVAL, /* TEGRA_USB1_VBUS, */ | ||
47 | [20] = -EINVAL, /* TEGRA_USB3_VBUS, */ | ||
48 | [21] = -EINVAL, /* TEGRA_USB1_ID, */ | ||
49 | [22] = -EINVAL, /* TEGRA_USB3_ID, */ | ||
50 | [23] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PI5), | ||
51 | [24] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PV2), | ||
52 | [25] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS4), | ||
53 | [26] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS5), | ||
54 | [27] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS0), | ||
55 | [28] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PQ6), | ||
56 | [29] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PQ7), | ||
57 | [30] = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PN2), | ||
58 | }; | ||
59 | |||
60 | int tegra_irq_to_wake(int irq) | ||
61 | { | ||
62 | int i; | ||
63 | int wake_irq; | ||
64 | int search_gpio; | ||
65 | static int last_wake = -1; | ||
66 | |||
67 | /* Two level wake irq search for gpio based wakeups - | ||
68 | * 1. check for GPIO irq(based on tegra_wake_event_irq table) | ||
69 | * e.g. for a board, wake7 based on GPIO PU6 and irq==358 done first | ||
70 | * 2. check for gpio bank irq assuming search for GPIO irq | ||
71 | * preceded this search. | ||
72 | * e.g. in this step check for gpio bank irq GPIO6 irq==119 | ||
73 | */ | ||
74 | for (i = 0; i < ARRAY_SIZE(tegra_wake_event_irq); i++) { | ||
75 | /* return if step 1 matches */ | ||
76 | if (tegra_wake_event_irq[i] == irq) { | ||
77 | pr_info("Wake%d for irq=%d\n", i, irq); | ||
78 | last_wake = i; | ||
79 | return i; | ||
80 | } | ||
81 | |||
82 | /* step 2 below uses saved last_wake from step 1 | ||
83 | * in previous call */ | ||
84 | search_gpio = irq_to_gpio( | ||
85 | tegra_wake_event_irq[i]); | ||
86 | if (search_gpio < 0) | ||
87 | continue; | ||
88 | wake_irq = tegra_gpio_get_bank_int_nr(search_gpio); | ||
89 | if (wake_irq < 0) | ||
90 | continue; | ||
91 | if ((last_wake == i) && | ||
92 | (wake_irq == irq)) { | ||
93 | pr_info("gpio bank wake found: wake%d for irq=%d\n", | ||
94 | i, irq); | ||
95 | return i; | ||
96 | } | ||
97 | } | ||
98 | |||
99 | return -EINVAL; | ||
100 | } | ||
101 | |||
102 | int tegra_wake_to_irq(int wake) | ||
103 | { | ||
104 | if (wake < 0) | ||
105 | return -EINVAL; | ||
106 | |||
107 | if (wake >= ARRAY_SIZE(tegra_wake_event_irq)) | ||
108 | return -EINVAL; | ||
109 | |||
110 | return tegra_wake_event_irq[wake]; | ||
111 | } | ||