Merge tag 'ntb-3.13' of git://github.com/jonmason/ntb
[linux-drm-fsl-dcu.git] / arch / arm / mach-omap1 / gpio16xx.c
1 /*
2  * OMAP16xx specific gpio init
3  *
4  * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
5  *
6  * Author:
7  *      Charulatha V <charu@ti.com>
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation version 2.
12  *
13  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
14  * kind, whether express or implied; without even the implied warranty
15  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  */
18
19 #include <linux/gpio.h>
20 #include <linux/platform_data/gpio-omap.h>
21
22 #include <mach/irqs.h>
23
24 #define OMAP1610_GPIO1_BASE             0xfffbe400
25 #define OMAP1610_GPIO2_BASE             0xfffbec00
26 #define OMAP1610_GPIO3_BASE             0xfffbb400
27 #define OMAP1610_GPIO4_BASE             0xfffbbc00
28 #define OMAP1_MPUIO_VBASE               OMAP1_MPUIO_BASE
29
30 /* smart idle, enable wakeup */
31 #define SYSCONFIG_WORD                  0x14
32
33 /* mpu gpio */
34 static struct resource omap16xx_mpu_gpio_resources[] = {
35         {
36                 .start  = OMAP1_MPUIO_VBASE,
37                 .end    = OMAP1_MPUIO_VBASE + SZ_2K - 1,
38                 .flags  = IORESOURCE_MEM,
39         },
40         {
41                 .start  = INT_MPUIO,
42                 .flags  = IORESOURCE_IRQ,
43         },
44 };
45
46 static struct omap_gpio_reg_offs omap16xx_mpuio_regs = {
47         .revision       = USHRT_MAX,
48         .direction      = OMAP_MPUIO_IO_CNTL,
49         .datain         = OMAP_MPUIO_INPUT_LATCH,
50         .dataout        = OMAP_MPUIO_OUTPUT,
51         .irqstatus      = OMAP_MPUIO_GPIO_INT,
52         .irqenable      = OMAP_MPUIO_GPIO_MASKIT,
53         .irqenable_inv  = true,
54         .irqctrl        = OMAP_MPUIO_GPIO_INT_EDGE,
55 };
56
57 static struct omap_gpio_platform_data omap16xx_mpu_gpio_config = {
58         .is_mpuio               = true,
59         .bank_width             = 16,
60         .bank_stride            = 1,
61         .regs                   = &omap16xx_mpuio_regs,
62 };
63
64 static struct platform_device omap16xx_mpu_gpio = {
65         .name           = "omap_gpio",
66         .id             = 0,
67         .dev            = {
68                 .platform_data = &omap16xx_mpu_gpio_config,
69         },
70         .num_resources = ARRAY_SIZE(omap16xx_mpu_gpio_resources),
71         .resource = omap16xx_mpu_gpio_resources,
72 };
73
74 /* gpio1 */
75 static struct resource omap16xx_gpio1_resources[] = {
76         {
77                 .start  = OMAP1610_GPIO1_BASE,
78                 .end    = OMAP1610_GPIO1_BASE + SZ_2K - 1,
79                 .flags  = IORESOURCE_MEM,
80         },
81         {
82                 .start  = INT_GPIO_BANK1,
83                 .flags  = IORESOURCE_IRQ,
84         },
85 };
86
87 static struct omap_gpio_reg_offs omap16xx_gpio_regs = {
88         .revision       = OMAP1610_GPIO_REVISION,
89         .direction      = OMAP1610_GPIO_DIRECTION,
90         .set_dataout    = OMAP1610_GPIO_SET_DATAOUT,
91         .clr_dataout    = OMAP1610_GPIO_CLEAR_DATAOUT,
92         .datain         = OMAP1610_GPIO_DATAIN,
93         .dataout        = OMAP1610_GPIO_DATAOUT,
94         .irqstatus      = OMAP1610_GPIO_IRQSTATUS1,
95         .irqenable      = OMAP1610_GPIO_IRQENABLE1,
96         .set_irqenable  = OMAP1610_GPIO_SET_IRQENABLE1,
97         .clr_irqenable  = OMAP1610_GPIO_CLEAR_IRQENABLE1,
98         .wkup_en        = OMAP1610_GPIO_WAKEUPENABLE,
99         .edgectrl1      = OMAP1610_GPIO_EDGE_CTRL1,
100         .edgectrl2      = OMAP1610_GPIO_EDGE_CTRL2,
101 };
102
103 static struct omap_gpio_platform_data omap16xx_gpio1_config = {
104         .bank_width             = 16,
105         .regs                   = &omap16xx_gpio_regs,
106 };
107
108 static struct platform_device omap16xx_gpio1 = {
109         .name           = "omap_gpio",
110         .id             = 1,
111         .dev            = {
112                 .platform_data = &omap16xx_gpio1_config,
113         },
114         .num_resources = ARRAY_SIZE(omap16xx_gpio1_resources),
115         .resource = omap16xx_gpio1_resources,
116 };
117
118 /* gpio2 */
119 static struct resource omap16xx_gpio2_resources[] = {
120         {
121                 .start  = OMAP1610_GPIO2_BASE,
122                 .end    = OMAP1610_GPIO2_BASE + SZ_2K - 1,
123                 .flags  = IORESOURCE_MEM,
124         },
125         {
126                 .start  = INT_1610_GPIO_BANK2,
127                 .flags  = IORESOURCE_IRQ,
128         },
129 };
130
131 static struct omap_gpio_platform_data omap16xx_gpio2_config = {
132         .bank_width             = 16,
133         .regs                   = &omap16xx_gpio_regs,
134 };
135
136 static struct platform_device omap16xx_gpio2 = {
137         .name           = "omap_gpio",
138         .id             = 2,
139         .dev            = {
140                 .platform_data = &omap16xx_gpio2_config,
141         },
142         .num_resources = ARRAY_SIZE(omap16xx_gpio2_resources),
143         .resource = omap16xx_gpio2_resources,
144 };
145
146 /* gpio3 */
147 static struct resource omap16xx_gpio3_resources[] = {
148         {
149                 .start  = OMAP1610_GPIO3_BASE,
150                 .end    = OMAP1610_GPIO3_BASE + SZ_2K - 1,
151                 .flags  = IORESOURCE_MEM,
152         },
153         {
154                 .start  = INT_1610_GPIO_BANK3,
155                 .flags  = IORESOURCE_IRQ,
156         },
157 };
158
159 static struct omap_gpio_platform_data omap16xx_gpio3_config = {
160         .bank_width             = 16,
161         .regs                   = &omap16xx_gpio_regs,
162 };
163
164 static struct platform_device omap16xx_gpio3 = {
165         .name           = "omap_gpio",
166         .id             = 3,
167         .dev            = {
168                 .platform_data = &omap16xx_gpio3_config,
169         },
170         .num_resources = ARRAY_SIZE(omap16xx_gpio3_resources),
171         .resource = omap16xx_gpio3_resources,
172 };
173
174 /* gpio4 */
175 static struct resource omap16xx_gpio4_resources[] = {
176         {
177                 .start  = OMAP1610_GPIO4_BASE,
178                 .end    = OMAP1610_GPIO4_BASE + SZ_2K - 1,
179                 .flags  = IORESOURCE_MEM,
180         },
181         {
182                 .start  = INT_1610_GPIO_BANK4,
183                 .flags  = IORESOURCE_IRQ,
184         },
185 };
186
187 static struct omap_gpio_platform_data omap16xx_gpio4_config = {
188         .bank_width             = 16,
189         .regs                   = &omap16xx_gpio_regs,
190 };
191
192 static struct platform_device omap16xx_gpio4 = {
193         .name           = "omap_gpio",
194         .id             = 4,
195         .dev            = {
196                 .platform_data = &omap16xx_gpio4_config,
197         },
198         .num_resources = ARRAY_SIZE(omap16xx_gpio4_resources),
199         .resource = omap16xx_gpio4_resources,
200 };
201
202 static struct platform_device *omap16xx_gpio_dev[] __initdata = {
203         &omap16xx_mpu_gpio,
204         &omap16xx_gpio1,
205         &omap16xx_gpio2,
206         &omap16xx_gpio3,
207         &omap16xx_gpio4,
208 };
209
210 /*
211  * omap16xx_gpio_init needs to be done before
212  * machine_init functions access gpio APIs.
213  * Hence omap16xx_gpio_init is a postcore_initcall.
214  */
215 static int __init omap16xx_gpio_init(void)
216 {
217         int i;
218         void __iomem *base;
219         struct resource *res;
220         struct platform_device *pdev;
221         struct omap_gpio_platform_data *pdata;
222
223         if (!cpu_is_omap16xx())
224                 return -EINVAL;
225
226         /*
227          * Enable system clock for GPIO module.
228          * The CAM_CLK_CTRL *is* really the right place.
229          */
230         omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04,
231                                         ULPD_CAM_CLK_CTRL);
232
233         for (i = 0; i < ARRAY_SIZE(omap16xx_gpio_dev); i++) {
234                 pdev = omap16xx_gpio_dev[i];
235                 pdata = pdev->dev.platform_data;
236
237                 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
238                 if (unlikely(!res)) {
239                         dev_err(&pdev->dev, "Invalid mem resource.\n");
240                         return -ENODEV;
241                 }
242
243                 base = ioremap(res->start, resource_size(res));
244                 if (unlikely(!base)) {
245                         dev_err(&pdev->dev, "ioremap failed.\n");
246                         return -ENOMEM;
247                 }
248
249                 __raw_writel(SYSCONFIG_WORD, base + OMAP1610_GPIO_SYSCONFIG);
250                 iounmap(base);
251
252                 platform_device_register(omap16xx_gpio_dev[i]);
253         }
254
255         return 0;
256 }
257 postcore_initcall(omap16xx_gpio_init);