ARM: tegra: t12x wake table update
[linux-3.10.git] / arch / arm / mach-tegra / wakeups-t12x.c
1 /*
2  * Copyright (c) 2012, NVIDIA Corporation.
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/irqs.h>
21 #include <mach/gpio-tegra.h>
22
23 #include "gpio-names.h"
24 #include "iomap.h"
25
26 static int tegra_gpio_wakes[] = {
27         TEGRA_GPIO_PO5,                         /* wake0 */
28         TEGRA_GPIO_PV1,                         /* wake1 */
29         -EINVAL,                                /* wake2 */
30         -EINVAL,                                /* wake3 */
31         TEGRA_GPIO_PN7,                         /* wake4 */
32         -EINVAL,                                /* wake5 */
33         TEGRA_GPIO_PU5,                         /* wake6 */
34         TEGRA_GPIO_PU6,                         /* wake7 */
35         TEGRA_GPIO_PC7,                         /* wake8 */
36         -EINVAL,                                /* wake9 */
37         -EINVAL,                                /* wake10 */
38         TEGRA_GPIO_PW3,                         /* wake11 */
39         TEGRA_GPIO_PW2,                         /* wake12 */
40         -EINVAL,                                /* wake13 */
41         -EINVAL,                                /* wake14 */
42         TEGRA_GPIO_PJ2,                         /* wake15 */
43         -EINVAL,                                /* wake16 */
44         -EINVAL,                                /* wake17 */
45         -EINVAL,                                /* wake18 */
46         -EINVAL,                                /* wake19 */
47         -EINVAL,                                /* wake20 */
48         -EINVAL,                                /* wake21 */
49         -EINVAL,                                /* wake22 */
50         TEGRA_GPIO_PI5,                         /* wake23 */
51         TEGRA_GPIO_PV0,                         /* wake24 */
52         TEGRA_GPIO_PS4,                         /* wake25 */
53         TEGRA_GPIO_PS5,                         /* wake26 */
54         TEGRA_GPIO_PS0,                         /* wake27 */
55         TEGRA_GPIO_PS6,                         /* wake28 */
56         -EINVAL,                                /* wake29 */
57         -EINVAL,                                /* wake30 */
58         -EINVAL,                                /* wake31 */
59         -EINVAL,                                /* wake32 */
60         TEGRA_GPIO_PJ0,                         /* wake33 */
61         TEGRA_GPIO_PK2,                         /* wake34 */
62         TEGRA_GPIO_PI6,                         /* wake35 */
63         -EINVAL,                                /* wake36 */
64         -EINVAL,                                /* wake37 */
65         -EINVAL,                                /* wake38 */
66         -EINVAL,                                /* wake39 */
67         -EINVAL,                                /* wake40 */
68         -EINVAL,                                /* wake41 */
69         -EINVAL,                                /* wake42 */
70         -EINVAL,                                /* wake43 */
71         -EINVAL,                                /* wake44 */
72         TEGRA_GPIO_PBB6,                        /* wake45 */
73         -EINVAL,                                /* wake46 */
74         -EINVAL,                                /* wake47 */
75         -EINVAL,                                /* wake48 */
76         TEGRA_GPIO_PR7,                         /* wake49 */
77         TEGRA_GPIO_PR4,                         /* wake50 */
78         TEGRA_GPIO_PQ0,                         /* wake51 */
79         -EINVAL,                                /* wake52 */
80         -EINVAL,                                /* wake53 */
81         TEGRA_GPIO_PQ5,                         /* wake54 */
82         -EINVAL,                                /* wake55 */
83         -EINVAL,                                /* wake56 */
84         TEGRA_GPIO_PK6,                         /* wake57 */
85         -EINVAL,                                /* wake58 */
86         TEGRA_GPIO_PFF2,                        /* wake59 */
87 };
88
89 static int tegra_wake_event_irq[] = {
90         -EAGAIN, /* ULPI DATA4 */               /* wake0 */
91         -EAGAIN,                                /* wake1 */
92         -EAGAIN,                                /* wake2 */
93         INT_SDMMC3, /* SDMMC3 DAT1 */           /* wake3 */
94         INT_HDMI, /* HDMI INT */                /* wake4 */
95         -EAGAIN,                                /* wake5 */
96         -EAGAIN,                                /* wake6 */
97         -EAGAIN,                                /* wake7 */
98         -EAGAIN,                                /* wake8 */
99         INT_UARTC, /* UART3 RXD */              /* wake9 */
100         INT_SDMMC4, /* SDMMC4 DAT1 */           /* wake10 */
101         -EAGAIN,                                /* wake11 */
102         -EAGAIN,                                /* wake12 */
103         INT_SDMMC1, /* SDMMC1 DAT1 */           /* wake13 */
104         INT_PCIE, /* PEX_WAKE_N */              /* wake14 */
105         INT_THERMAL, /* soc_therm_oc4_n:i, PG_OC */     /* wake15 */
106         INT_RTC,                                /* wake16 */
107         INT_KBC,                                /* wake17 */
108         INT_EXTERNAL_PMU,                       /* wake18 */
109         INT_USB,                                /* wake19 */
110         -EINVAL,                                /* wake20 */
111         INT_USB,                                /* wake21 */
112         -EINVAL,                                /* wake22 */
113         -EAGAIN,                                /* wake23 */
114         -EAGAIN,                                /* wake24 */
115         -EAGAIN,                                /* wake25 */
116         -EAGAIN,                                /* wake26 */
117         -EAGAIN,                                /* wake27 */
118         -EAGAIN,                                /* wake28 */
119         INT_THERMAL, /* soc_therm_oc1_n:i, GPU_OC_INT */        /* wake29 */
120         INT_AUDIO_CLUSTER, /* I2S0 SDATA OUT */         /* wake30 */
121         -EINVAL,                                /* wake31 */
122         INT_USB2, /* ULPI DATA3 */              /* wake32 */
123         -EAGAIN,                                /* wake33 */
124         -EAGAIN,                                /* wake34 */
125         -EAGAIN,                                /* wake35 */
126         -EAGAIN,                                /* wake36 */
127         -EINVAL, /* TEGRA_USB3_VBUS, */         /* wake37 */
128         -EINVAL, /* TEGRA_USB3_ID, */           /* wake38 */
129         INT_USB, /* TEGRA_USB1_UTMIP, */        /* wake39 */
130         -EINVAL,                                /* wake40 */
131         INT_USB3, /* TEGRA_USB3_UTMIP, */       /* wake41 */
132         INT_USB, /* USB1 UHSIC PHY */           /* wake42 */
133         INT_USB3, /* USB3 UHSIC PHY */          /* wake43 */
134         INT_I2C, /* I2C1 DAT */         /* wake44 */
135         -EAGAIN,                                /* wake45 */
136         INT_I2C5, /* PWR I2C DAT */             /* wake46 */
137         INT_I2C2, /* I2C2 DAT */                /* wake47 */
138         INT_I2C3, /* I2C3 DAT */                /* wake48 */
139         -EAGAIN,                                /* wake49 */
140         -EAGAIN,                                /* wake50 */
141         INT_KBC, /* KBC11 */                    /* wake51 */
142         INT_HDMI, /* HDMI CEC */                /* wake52 */
143         INT_I2C3, /* I2C3 CLK */                /* wake53 */
144         -EAGAIN,                                /* wake54 */
145         INT_UARTC, /* UART3 CTS */              /* wake55 */
146         INT_SDMMC3, /* SDMMC3 CD */             /* wake56 */
147         -EAGAIN, /* EN_VDD_HDMI, */             /* wake57 */
148         -EAGAIN,                                /* wake58 */
149         -EAGAIN,                                /* wake59 */
150 };
151
152 static int last_gpio = -1;
153
154 int tegra_gpio_to_wake(int gpio)
155 {
156         int i;
157
158         for (i = 0; i < ARRAY_SIZE(tegra_gpio_wakes); i++) {
159                 if (tegra_gpio_wakes[i] == gpio) {
160                         pr_info("gpio wake%d for gpio=%d\n", i, gpio);
161                         last_gpio = i;
162                         return i;
163                 }
164         }
165
166         return -EINVAL;
167 }
168
169 int tegra_irq_to_wake(int irq)
170 {
171         int i;
172         int ret = -EINVAL;
173
174         for (i = 0; i < ARRAY_SIZE(tegra_wake_event_irq); i++) {
175                 if (tegra_wake_event_irq[i] == irq) {
176                         pr_info("Wake%d for irq=%d\n", i, irq);
177                         ret = i;
178                         goto out;
179                 }
180         }
181
182         /* The gpio set_wake code bubbles the set_wake call up to the irq
183          * set_wake code. This insures that the nested irq set_wake call
184          * succeeds, even though it doesn't have to do any pm setup for the
185          * bank.
186          *
187          * This is very fragile - there's no locking, so two callers could
188          * cause issues with this.
189          */
190         if (last_gpio < 0)
191                 goto out;
192
193         if (tegra_gpio_get_bank_int_nr(tegra_gpio_wakes[last_gpio]) == irq) {
194                 pr_info("gpio bank wake found: wake%d for irq=%d\n", i, irq);
195                 ret = last_gpio;
196         }
197
198 out:
199         return ret;
200 }
201
202 int tegra_wake_to_irq(int wake)
203 {
204         int ret;
205
206         if (wake < 0)
207                 return -EINVAL;
208
209         if (wake >= ARRAY_SIZE(tegra_wake_event_irq))
210                 return -EINVAL;
211
212         ret = tegra_wake_event_irq[wake];
213         if (ret == -EAGAIN) {
214                 ret = tegra_gpio_wakes[wake];
215                 if (ret != -EINVAL)
216                         ret = gpio_to_irq(ret);
217         }
218
219         return ret;
220 }
221
222 int tegra_disable_wake_source(int wake)
223 {
224         if (wake >= ARRAY_SIZE(tegra_wake_event_irq))
225                 return -EINVAL;
226
227         tegra_wake_event_irq[wake] = -EINVAL;
228         return 0;
229 }