diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-22 17:50:57 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-22 17:50:57 -0400 |
commit | c7c8518498e82591d7784452f5674c3aeb4d079c (patch) | |
tree | 790ff7e6b6741daf32ec686b9a302b957b07c0f4 /arch/arm/plat-mxc | |
parent | ece236ce2fad9c27a6fd2530f899289025194bce (diff) | |
parent | 591567a5ea25852f20b7ef2953f6f72020121199 (diff) |
Merge branch 'gpio/next' of git://git.secretlab.ca/git/linux-2.6
* 'gpio/next' of git://git.secretlab.ca/git/linux-2.6: (61 commits)
gpio/mxc/mxs: fix build error introduced by the irq_gc_ack() renaming
mcp23s08: add i2c support
mcp23s08: isolate spi specific parts
mcp23s08: get rid of setup/teardown callbacks
gpio/tegra: dt: add binding for gpio polarity
mcp23s08: remove unused work queue
gpio/da9052: remove a redundant assignment for gpio->da9052
gpio/mxc: add device tree probe support
ARM: mxc: use ARCH_NR_GPIOS to define gpio number
gpio/mxc: get rid of the uses of cpu_is_mx()
gpio/mxc: add missing initialization of basic_mmio_gpio shadow variables
gpio: Move mpc5200 gpio driver to drivers/gpio
GPIO: DA9052 GPIO module v3
gpio/tegra: Use engineering names in DT compatible property
of/gpio: Add new method for getting gpios under different property names
gpio/dt: Refine GPIO device tree binding
gpio/ml-ioh: fix off-by-one for displaying variable i in dev_err
gpio/pca953x: Deprecate meaningless device-tree bindings
gpio/pca953x: Remove dynamic platform data pointer
gpio/pca953x: Fix IRQ support.
...
Diffstat (limited to 'arch/arm/plat-mxc')
-rw-r--r-- | arch/arm/plat-mxc/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/plat-mxc/devices.c | 11 | ||||
-rw-r--r-- | arch/arm/plat-mxc/devices/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/plat-mxc/devices/platform-gpio-mxc.c | 32 | ||||
-rw-r--r-- | arch/arm/plat-mxc/gpio.c | 361 | ||||
-rw-r--r-- | arch/arm/plat-mxc/include/mach/common.h | 12 | ||||
-rw-r--r-- | arch/arm/plat-mxc/include/mach/devices-common.h | 2 | ||||
-rw-r--r-- | arch/arm/plat-mxc/include/mach/gpio.h | 27 | ||||
-rw-r--r-- | arch/arm/plat-mxc/include/mach/irqs.h | 21 |
9 files changed, 61 insertions, 408 deletions
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index a1387875a491..d53c35fe2ea7 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | # Common support | 5 | # Common support |
6 | obj-y := clock.o gpio.o time.o devices.o cpu.o system.o irq-common.o | 6 | obj-y := clock.o time.o devices.o cpu.o system.o irq-common.o |
7 | 7 | ||
8 | # MX51 uses the TZIC interrupt controller, older platforms use AVIC | 8 | # MX51 uses the TZIC interrupt controller, older platforms use AVIC |
9 | obj-$(CONFIG_MXC_TZIC) += tzic.o | 9 | obj-$(CONFIG_MXC_TZIC) += tzic.o |
diff --git a/arch/arm/plat-mxc/devices.c b/arch/arm/plat-mxc/devices.c index eee1b6096a08..fb166b20f60f 100644 --- a/arch/arm/plat-mxc/devices.c +++ b/arch/arm/plat-mxc/devices.c | |||
@@ -89,3 +89,14 @@ err: | |||
89 | 89 | ||
90 | return pdev; | 90 | return pdev; |
91 | } | 91 | } |
92 | |||
93 | struct device mxc_aips_bus = { | ||
94 | .init_name = "mxc_aips", | ||
95 | .parent = &platform_bus, | ||
96 | }; | ||
97 | |||
98 | static int __init mxc_device_init(void) | ||
99 | { | ||
100 | return device_register(&mxc_aips_bus); | ||
101 | } | ||
102 | core_initcall(mxc_device_init); | ||
diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile index ad2922acf480..b41bf972b54b 100644 --- a/arch/arm/plat-mxc/devices/Makefile +++ b/arch/arm/plat-mxc/devices/Makefile | |||
@@ -2,6 +2,7 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o | |||
2 | obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o | 2 | obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o |
3 | obj-$(CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC) += platform-fsl-usb2-udc.o | 3 | obj-$(CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC) += platform-fsl-usb2-udc.o |
4 | obj-$(CONFIG_IMX_HAVE_PLATFORM_GPIO_KEYS) += platform-gpio_keys.o | 4 | obj-$(CONFIG_IMX_HAVE_PLATFORM_GPIO_KEYS) += platform-gpio_keys.o |
5 | obj-y += platform-gpio-mxc.o | ||
5 | obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX21_HCD) += platform-imx21-hcd.o | 6 | obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX21_HCD) += platform-imx21-hcd.o |
6 | obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT) += platform-imx2-wdt.o | 7 | obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT) += platform-imx2-wdt.o |
7 | obj-$(CONFIG_IMX_HAVE_PLATFORM_IMXDI_RTC) += platform-imxdi_rtc.o | 8 | obj-$(CONFIG_IMX_HAVE_PLATFORM_IMXDI_RTC) += platform-imxdi_rtc.o |
diff --git a/arch/arm/plat-mxc/devices/platform-gpio-mxc.c b/arch/arm/plat-mxc/devices/platform-gpio-mxc.c new file mode 100644 index 000000000000..a7919a241032 --- /dev/null +++ b/arch/arm/plat-mxc/devices/platform-gpio-mxc.c | |||
@@ -0,0 +1,32 @@ | |||
1 | /* | ||
2 | * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | * Copyright 2011 Linaro Limited | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it under | ||
6 | * the terms of the GNU General Public License version 2 as published by the | ||
7 | * Free Software Foundation. | ||
8 | */ | ||
9 | #include <mach/devices-common.h> | ||
10 | |||
11 | struct platform_device *__init mxc_register_gpio(char *name, int id, | ||
12 | resource_size_t iobase, resource_size_t iosize, int irq, int irq_high) | ||
13 | { | ||
14 | struct resource res[] = { | ||
15 | { | ||
16 | .start = iobase, | ||
17 | .end = iobase + iosize - 1, | ||
18 | .flags = IORESOURCE_MEM, | ||
19 | }, { | ||
20 | .start = irq, | ||
21 | .end = irq, | ||
22 | .flags = IORESOURCE_IRQ, | ||
23 | }, { | ||
24 | .start = irq_high, | ||
25 | .end = irq_high, | ||
26 | .flags = IORESOURCE_IRQ, | ||
27 | }, | ||
28 | }; | ||
29 | |||
30 | return platform_device_register_resndata(&mxc_aips_bus, | ||
31 | name, id, res, ARRAY_SIZE(res), NULL, 0); | ||
32 | } | ||
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c deleted file mode 100644 index 6cd6d7f686f6..000000000000 --- a/arch/arm/plat-mxc/gpio.c +++ /dev/null | |||
@@ -1,361 +0,0 @@ | |||
1 | /* | ||
2 | * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de> | ||
3 | * Copyright 2008 Juergen Beisert, kernel@pengutronix.de | ||
4 | * | ||
5 | * Based on code from Freescale, | ||
6 | * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version 2 | ||
11 | * of the License, or (at your option) any later version. | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
20 | */ | ||
21 | |||
22 | #include <linux/init.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <linux/irq.h> | ||
26 | #include <linux/gpio.h> | ||
27 | #include <mach/hardware.h> | ||
28 | #include <asm-generic/bug.h> | ||
29 | |||
30 | static struct mxc_gpio_port *mxc_gpio_ports; | ||
31 | static int gpio_table_size; | ||
32 | |||
33 | #define cpu_is_mx1_mx2() (cpu_is_mx1() || cpu_is_mx2()) | ||
34 | |||
35 | #define GPIO_DR (cpu_is_mx1_mx2() ? 0x1c : 0x00) | ||
36 | #define GPIO_GDIR (cpu_is_mx1_mx2() ? 0x00 : 0x04) | ||
37 | #define GPIO_PSR (cpu_is_mx1_mx2() ? 0x24 : 0x08) | ||
38 | #define GPIO_ICR1 (cpu_is_mx1_mx2() ? 0x28 : 0x0C) | ||
39 | #define GPIO_ICR2 (cpu_is_mx1_mx2() ? 0x2C : 0x10) | ||
40 | #define GPIO_IMR (cpu_is_mx1_mx2() ? 0x30 : 0x14) | ||
41 | #define GPIO_ISR (cpu_is_mx1_mx2() ? 0x34 : 0x18) | ||
42 | |||
43 | #define GPIO_INT_LOW_LEV (cpu_is_mx1_mx2() ? 0x3 : 0x0) | ||
44 | #define GPIO_INT_HIGH_LEV (cpu_is_mx1_mx2() ? 0x2 : 0x1) | ||
45 | #define GPIO_INT_RISE_EDGE (cpu_is_mx1_mx2() ? 0x0 : 0x2) | ||
46 | #define GPIO_INT_FALL_EDGE (cpu_is_mx1_mx2() ? 0x1 : 0x3) | ||
47 | #define GPIO_INT_NONE 0x4 | ||
48 | |||
49 | /* Note: This driver assumes 32 GPIOs are handled in one register */ | ||
50 | |||
51 | static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index) | ||
52 | { | ||
53 | __raw_writel(1 << index, port->base + GPIO_ISR); | ||
54 | } | ||
55 | |||
56 | static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index, | ||
57 | int enable) | ||
58 | { | ||
59 | u32 l; | ||
60 | |||
61 | l = __raw_readl(port->base + GPIO_IMR); | ||
62 | l = (l & (~(1 << index))) | (!!enable << index); | ||
63 | __raw_writel(l, port->base + GPIO_IMR); | ||
64 | } | ||
65 | |||
66 | static void gpio_ack_irq(struct irq_data *d) | ||
67 | { | ||
68 | u32 gpio = irq_to_gpio(d->irq); | ||
69 | _clear_gpio_irqstatus(&mxc_gpio_ports[gpio / 32], gpio & 0x1f); | ||
70 | } | ||
71 | |||
72 | static void gpio_mask_irq(struct irq_data *d) | ||
73 | { | ||
74 | u32 gpio = irq_to_gpio(d->irq); | ||
75 | _set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 0); | ||
76 | } | ||
77 | |||
78 | static void gpio_unmask_irq(struct irq_data *d) | ||
79 | { | ||
80 | u32 gpio = irq_to_gpio(d->irq); | ||
81 | _set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 1); | ||
82 | } | ||
83 | |||
84 | static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset); | ||
85 | |||
86 | static int gpio_set_irq_type(struct irq_data *d, u32 type) | ||
87 | { | ||
88 | u32 gpio = irq_to_gpio(d->irq); | ||
89 | struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; | ||
90 | u32 bit, val; | ||
91 | int edge; | ||
92 | void __iomem *reg = port->base; | ||
93 | |||
94 | port->both_edges &= ~(1 << (gpio & 31)); | ||
95 | switch (type) { | ||
96 | case IRQ_TYPE_EDGE_RISING: | ||
97 | edge = GPIO_INT_RISE_EDGE; | ||
98 | break; | ||
99 | case IRQ_TYPE_EDGE_FALLING: | ||
100 | edge = GPIO_INT_FALL_EDGE; | ||
101 | break; | ||
102 | case IRQ_TYPE_EDGE_BOTH: | ||
103 | val = mxc_gpio_get(&port->chip, gpio & 31); | ||
104 | if (val) { | ||
105 | edge = GPIO_INT_LOW_LEV; | ||
106 | pr_debug("mxc: set GPIO %d to low trigger\n", gpio); | ||
107 | } else { | ||
108 | edge = GPIO_INT_HIGH_LEV; | ||
109 | pr_debug("mxc: set GPIO %d to high trigger\n", gpio); | ||
110 | } | ||
111 | port->both_edges |= 1 << (gpio & 31); | ||
112 | break; | ||
113 | case IRQ_TYPE_LEVEL_LOW: | ||
114 | edge = GPIO_INT_LOW_LEV; | ||
115 | break; | ||
116 | case IRQ_TYPE_LEVEL_HIGH: | ||
117 | edge = GPIO_INT_HIGH_LEV; | ||
118 | break; | ||
119 | default: | ||
120 | return -EINVAL; | ||
121 | } | ||
122 | |||
123 | reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ | ||
124 | bit = gpio & 0xf; | ||
125 | val = __raw_readl(reg) & ~(0x3 << (bit << 1)); | ||
126 | __raw_writel(val | (edge << (bit << 1)), reg); | ||
127 | _clear_gpio_irqstatus(port, gpio & 0x1f); | ||
128 | |||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio) | ||
133 | { | ||
134 | void __iomem *reg = port->base; | ||
135 | u32 bit, val; | ||
136 | int edge; | ||
137 | |||
138 | reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ | ||
139 | bit = gpio & 0xf; | ||
140 | val = __raw_readl(reg); | ||
141 | edge = (val >> (bit << 1)) & 3; | ||
142 | val &= ~(0x3 << (bit << 1)); | ||
143 | if (edge == GPIO_INT_HIGH_LEV) { | ||
144 | edge = GPIO_INT_LOW_LEV; | ||
145 | pr_debug("mxc: switch GPIO %d to low trigger\n", gpio); | ||
146 | } else if (edge == GPIO_INT_LOW_LEV) { | ||
147 | edge = GPIO_INT_HIGH_LEV; | ||
148 | pr_debug("mxc: switch GPIO %d to high trigger\n", gpio); | ||
149 | } else { | ||
150 | pr_err("mxc: invalid configuration for GPIO %d: %x\n", | ||
151 | gpio, edge); | ||
152 | return; | ||
153 | } | ||
154 | __raw_writel(val | (edge << (bit << 1)), reg); | ||
155 | } | ||
156 | |||
157 | /* handle 32 interrupts in one status register */ | ||
158 | static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat) | ||
159 | { | ||
160 | u32 gpio_irq_no_base = port->virtual_irq_start; | ||
161 | |||
162 | while (irq_stat != 0) { | ||
163 | int irqoffset = fls(irq_stat) - 1; | ||
164 | |||
165 | if (port->both_edges & (1 << irqoffset)) | ||
166 | mxc_flip_edge(port, irqoffset); | ||
167 | |||
168 | generic_handle_irq(gpio_irq_no_base + irqoffset); | ||
169 | |||
170 | irq_stat &= ~(1 << irqoffset); | ||
171 | } | ||
172 | } | ||
173 | |||
174 | /* MX1 and MX3 has one interrupt *per* gpio port */ | ||
175 | static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc) | ||
176 | { | ||
177 | u32 irq_stat; | ||
178 | struct mxc_gpio_port *port = irq_get_handler_data(irq); | ||
179 | |||
180 | irq_stat = __raw_readl(port->base + GPIO_ISR) & | ||
181 | __raw_readl(port->base + GPIO_IMR); | ||
182 | |||
183 | mxc_gpio_irq_handler(port, irq_stat); | ||
184 | } | ||
185 | |||
186 | /* MX2 has one interrupt *for all* gpio ports */ | ||
187 | static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) | ||
188 | { | ||
189 | int i; | ||
190 | u32 irq_msk, irq_stat; | ||
191 | struct mxc_gpio_port *port = irq_get_handler_data(irq); | ||
192 | |||
193 | /* walk through all interrupt status registers */ | ||
194 | for (i = 0; i < gpio_table_size; i++) { | ||
195 | irq_msk = __raw_readl(port[i].base + GPIO_IMR); | ||
196 | if (!irq_msk) | ||
197 | continue; | ||
198 | |||
199 | irq_stat = __raw_readl(port[i].base + GPIO_ISR) & irq_msk; | ||
200 | if (irq_stat) | ||
201 | mxc_gpio_irq_handler(&port[i], irq_stat); | ||
202 | } | ||
203 | } | ||
204 | |||
205 | /* | ||
206 | * Set interrupt number "irq" in the GPIO as a wake-up source. | ||
207 | * While system is running, all registered GPIO interrupts need to have | ||
208 | * wake-up enabled. When system is suspended, only selected GPIO interrupts | ||
209 | * need to have wake-up enabled. | ||
210 | * @param irq interrupt source number | ||
211 | * @param enable enable as wake-up if equal to non-zero | ||
212 | * @return This function returns 0 on success. | ||
213 | */ | ||
214 | static int gpio_set_wake_irq(struct irq_data *d, u32 enable) | ||
215 | { | ||
216 | u32 gpio = irq_to_gpio(d->irq); | ||
217 | u32 gpio_idx = gpio & 0x1F; | ||
218 | struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; | ||
219 | |||
220 | if (enable) { | ||
221 | if (port->irq_high && (gpio_idx >= 16)) | ||
222 | enable_irq_wake(port->irq_high); | ||
223 | else | ||
224 | enable_irq_wake(port->irq); | ||
225 | } else { | ||
226 | if (port->irq_high && (gpio_idx >= 16)) | ||
227 | disable_irq_wake(port->irq_high); | ||
228 | else | ||
229 | disable_irq_wake(port->irq); | ||
230 | } | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static struct irq_chip gpio_irq_chip = { | ||
236 | .name = "GPIO", | ||
237 | .irq_ack = gpio_ack_irq, | ||
238 | .irq_mask = gpio_mask_irq, | ||
239 | .irq_unmask = gpio_unmask_irq, | ||
240 | .irq_set_type = gpio_set_irq_type, | ||
241 | .irq_set_wake = gpio_set_wake_irq, | ||
242 | }; | ||
243 | |||
244 | static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset, | ||
245 | int dir) | ||
246 | { | ||
247 | struct mxc_gpio_port *port = | ||
248 | container_of(chip, struct mxc_gpio_port, chip); | ||
249 | u32 l; | ||
250 | unsigned long flags; | ||
251 | |||
252 | spin_lock_irqsave(&port->lock, flags); | ||
253 | l = __raw_readl(port->base + GPIO_GDIR); | ||
254 | if (dir) | ||
255 | l |= 1 << offset; | ||
256 | else | ||
257 | l &= ~(1 << offset); | ||
258 | __raw_writel(l, port->base + GPIO_GDIR); | ||
259 | spin_unlock_irqrestore(&port->lock, flags); | ||
260 | } | ||
261 | |||
262 | static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
263 | { | ||
264 | struct mxc_gpio_port *port = | ||
265 | container_of(chip, struct mxc_gpio_port, chip); | ||
266 | void __iomem *reg = port->base + GPIO_DR; | ||
267 | u32 l; | ||
268 | unsigned long flags; | ||
269 | |||
270 | spin_lock_irqsave(&port->lock, flags); | ||
271 | l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset); | ||
272 | __raw_writel(l, reg); | ||
273 | spin_unlock_irqrestore(&port->lock, flags); | ||
274 | } | ||
275 | |||
276 | static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
277 | { | ||
278 | struct mxc_gpio_port *port = | ||
279 | container_of(chip, struct mxc_gpio_port, chip); | ||
280 | |||
281 | return (__raw_readl(port->base + GPIO_PSR) >> offset) & 1; | ||
282 | } | ||
283 | |||
284 | static int mxc_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
285 | { | ||
286 | _set_gpio_direction(chip, offset, 0); | ||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | static int mxc_gpio_direction_output(struct gpio_chip *chip, | ||
291 | unsigned offset, int value) | ||
292 | { | ||
293 | mxc_gpio_set(chip, offset, value); | ||
294 | _set_gpio_direction(chip, offset, 1); | ||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | /* | ||
299 | * This lock class tells lockdep that GPIO irqs are in a different | ||
300 | * category than their parents, so it won't report false recursion. | ||
301 | */ | ||
302 | static struct lock_class_key gpio_lock_class; | ||
303 | |||
304 | int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt) | ||
305 | { | ||
306 | int i, j; | ||
307 | |||
308 | /* save for local usage */ | ||
309 | mxc_gpio_ports = port; | ||
310 | gpio_table_size = cnt; | ||
311 | |||
312 | printk(KERN_INFO "MXC GPIO hardware\n"); | ||
313 | |||
314 | for (i = 0; i < cnt; i++) { | ||
315 | /* disable the interrupt and clear the status */ | ||
316 | __raw_writel(0, port[i].base + GPIO_IMR); | ||
317 | __raw_writel(~0, port[i].base + GPIO_ISR); | ||
318 | for (j = port[i].virtual_irq_start; | ||
319 | j < port[i].virtual_irq_start + 32; j++) { | ||
320 | irq_set_lockdep_class(j, &gpio_lock_class); | ||
321 | irq_set_chip_and_handler(j, &gpio_irq_chip, | ||
322 | handle_level_irq); | ||
323 | set_irq_flags(j, IRQF_VALID); | ||
324 | } | ||
325 | |||
326 | /* register gpio chip */ | ||
327 | port[i].chip.direction_input = mxc_gpio_direction_input; | ||
328 | port[i].chip.direction_output = mxc_gpio_direction_output; | ||
329 | port[i].chip.get = mxc_gpio_get; | ||
330 | port[i].chip.set = mxc_gpio_set; | ||
331 | port[i].chip.base = i * 32; | ||
332 | port[i].chip.ngpio = 32; | ||
333 | |||
334 | spin_lock_init(&port[i].lock); | ||
335 | |||
336 | /* its a serious configuration bug when it fails */ | ||
337 | BUG_ON( gpiochip_add(&port[i].chip) < 0 ); | ||
338 | |||
339 | if (cpu_is_mx1() || cpu_is_mx3() || cpu_is_mx25() || cpu_is_mx51()) { | ||
340 | /* setup one handler for each entry */ | ||
341 | irq_set_chained_handler(port[i].irq, | ||
342 | mx3_gpio_irq_handler); | ||
343 | irq_set_handler_data(port[i].irq, &port[i]); | ||
344 | if (port[i].irq_high) { | ||
345 | /* setup handler for GPIO 16 to 31 */ | ||
346 | irq_set_chained_handler(port[i].irq_high, | ||
347 | mx3_gpio_irq_handler); | ||
348 | irq_set_handler_data(port[i].irq_high, | ||
349 | &port[i]); | ||
350 | } | ||
351 | } | ||
352 | } | ||
353 | |||
354 | if (cpu_is_mx2()) { | ||
355 | /* setup one handler for all GPIO interrupts */ | ||
356 | irq_set_chained_handler(port[0].irq, mx2_gpio_irq_handler); | ||
357 | irq_set_handler_data(port[0].irq, port); | ||
358 | } | ||
359 | |||
360 | return 0; | ||
361 | } | ||
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h index da7991832af6..4e3d97890d69 100644 --- a/arch/arm/plat-mxc/include/mach/common.h +++ b/arch/arm/plat-mxc/include/mach/common.h | |||
@@ -43,6 +43,15 @@ extern void mx35_init_irq(void); | |||
43 | extern void mx50_init_irq(void); | 43 | extern void mx50_init_irq(void); |
44 | extern void mx51_init_irq(void); | 44 | extern void mx51_init_irq(void); |
45 | extern void mx53_init_irq(void); | 45 | extern void mx53_init_irq(void); |
46 | extern void imx1_soc_init(void); | ||
47 | extern void imx21_soc_init(void); | ||
48 | extern void imx25_soc_init(void); | ||
49 | extern void imx27_soc_init(void); | ||
50 | extern void imx31_soc_init(void); | ||
51 | extern void imx35_soc_init(void); | ||
52 | extern void imx50_soc_init(void); | ||
53 | extern void imx51_soc_init(void); | ||
54 | extern void imx53_soc_init(void); | ||
46 | extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq); | 55 | extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq); |
47 | extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int); | 56 | extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int); |
48 | extern int mx1_clocks_init(unsigned long fref); | 57 | extern int mx1_clocks_init(unsigned long fref); |
@@ -55,7 +64,8 @@ extern int mx51_clocks_init(unsigned long ckil, unsigned long osc, | |||
55 | unsigned long ckih1, unsigned long ckih2); | 64 | unsigned long ckih1, unsigned long ckih2); |
56 | extern int mx53_clocks_init(unsigned long ckil, unsigned long osc, | 65 | extern int mx53_clocks_init(unsigned long ckil, unsigned long osc, |
57 | unsigned long ckih1, unsigned long ckih2); | 66 | unsigned long ckih1, unsigned long ckih2); |
58 | extern int mxc_register_gpios(void); | 67 | extern struct platform_device *mxc_register_gpio(char *name, int id, |
68 | resource_size_t iobase, resource_size_t iosize, int irq, int irq_high); | ||
59 | extern int mxc_register_device(struct platform_device *pdev, void *data); | 69 | extern int mxc_register_device(struct platform_device *pdev, void *data); |
60 | extern void mxc_set_cpu_type(unsigned int type); | 70 | extern void mxc_set_cpu_type(unsigned int type); |
61 | extern void mxc_arch_reset_init(void __iomem *); | 71 | extern void mxc_arch_reset_init(void __iomem *); |
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h index fa8477337f91..03f626645374 100644 --- a/arch/arm/plat-mxc/include/mach/devices-common.h +++ b/arch/arm/plat-mxc/include/mach/devices-common.h | |||
@@ -10,6 +10,8 @@ | |||
10 | #include <linux/platform_device.h> | 10 | #include <linux/platform_device.h> |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | 12 | ||
13 | extern struct device mxc_aips_bus; | ||
14 | |||
13 | struct platform_device *imx_add_platform_device_dmamask( | 15 | struct platform_device *imx_add_platform_device_dmamask( |
14 | const char *name, int id, | 16 | const char *name, int id, |
15 | const struct resource *res, unsigned int num_resources, | 17 | const struct resource *res, unsigned int num_resources, |
diff --git a/arch/arm/plat-mxc/include/mach/gpio.h b/arch/arm/plat-mxc/include/mach/gpio.h index a2747f12813e..31c820c1b796 100644 --- a/arch/arm/plat-mxc/include/mach/gpio.h +++ b/arch/arm/plat-mxc/include/mach/gpio.h | |||
@@ -36,31 +36,4 @@ | |||
36 | #define gpio_to_irq(gpio) (MXC_GPIO_IRQ_START + (gpio)) | 36 | #define gpio_to_irq(gpio) (MXC_GPIO_IRQ_START + (gpio)) |
37 | #define irq_to_gpio(irq) ((irq) - MXC_GPIO_IRQ_START) | 37 | #define irq_to_gpio(irq) ((irq) - MXC_GPIO_IRQ_START) |
38 | 38 | ||
39 | struct mxc_gpio_port { | ||
40 | void __iomem *base; | ||
41 | int irq; | ||
42 | int irq_high; | ||
43 | int virtual_irq_start; | ||
44 | struct gpio_chip chip; | ||
45 | u32 both_edges; | ||
46 | spinlock_t lock; | ||
47 | }; | ||
48 | |||
49 | #define DEFINE_IMX_GPIO_PORT_IRQ_HIGH(soc, _id, _hwid, _irq, _irq_high) \ | ||
50 | { \ | ||
51 | .chip.label = "gpio-" #_id, \ | ||
52 | .irq = _irq, \ | ||
53 | .irq_high = _irq_high, \ | ||
54 | .base = soc ## _IO_ADDRESS( \ | ||
55 | soc ## _GPIO ## _hwid ## _BASE_ADDR), \ | ||
56 | .virtual_irq_start = MXC_GPIO_IRQ_START + (_id) * 32, \ | ||
57 | } | ||
58 | |||
59 | #define DEFINE_IMX_GPIO_PORT_IRQ(soc, _id, _hwid, _irq) \ | ||
60 | DEFINE_IMX_GPIO_PORT_IRQ_HIGH(soc, _id, _hwid, _irq, 0) | ||
61 | #define DEFINE_IMX_GPIO_PORT(soc, _id, _hwid) \ | ||
62 | DEFINE_IMX_GPIO_PORT_IRQ(soc, _id, _hwid, 0) | ||
63 | |||
64 | int mxc_gpio_init(struct mxc_gpio_port*, int); | ||
65 | |||
66 | #endif | 39 | #endif |
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h index 35c89bcdf758..00e812bbd81d 100644 --- a/arch/arm/plat-mxc/include/mach/irqs.h +++ b/arch/arm/plat-mxc/include/mach/irqs.h | |||
@@ -11,6 +11,8 @@ | |||
11 | #ifndef __ASM_ARCH_MXC_IRQS_H__ | 11 | #ifndef __ASM_ARCH_MXC_IRQS_H__ |
12 | #define __ASM_ARCH_MXC_IRQS_H__ | 12 | #define __ASM_ARCH_MXC_IRQS_H__ |
13 | 13 | ||
14 | #include <asm-generic/gpio.h> | ||
15 | |||
14 | /* | 16 | /* |
15 | * SoCs with TZIC interrupt controller have 128 IRQs, those with AVIC have 64 | 17 | * SoCs with TZIC interrupt controller have 128 IRQs, those with AVIC have 64 |
16 | */ | 18 | */ |
@@ -22,30 +24,13 @@ | |||
22 | 24 | ||
23 | #define MXC_GPIO_IRQ_START MXC_INTERNAL_IRQS | 25 | #define MXC_GPIO_IRQ_START MXC_INTERNAL_IRQS |
24 | 26 | ||
25 | /* these are ordered by size to support multi-SoC kernels */ | ||
26 | #if defined CONFIG_SOC_IMX53 | ||
27 | #define MXC_GPIO_IRQS (32 * 7) | ||
28 | #elif defined CONFIG_ARCH_MX2 | ||
29 | #define MXC_GPIO_IRQS (32 * 6) | ||
30 | #elif defined CONFIG_SOC_IMX50 | ||
31 | #define MXC_GPIO_IRQS (32 * 6) | ||
32 | #elif defined CONFIG_ARCH_MX1 | ||
33 | #define MXC_GPIO_IRQS (32 * 4) | ||
34 | #elif defined CONFIG_ARCH_MX25 | ||
35 | #define MXC_GPIO_IRQS (32 * 4) | ||
36 | #elif defined CONFIG_SOC_IMX51 | ||
37 | #define MXC_GPIO_IRQS (32 * 4) | ||
38 | #elif defined CONFIG_ARCH_MX3 | ||
39 | #define MXC_GPIO_IRQS (32 * 3) | ||
40 | #endif | ||
41 | |||
42 | /* | 27 | /* |
43 | * The next 16 interrupts are for board specific purposes. Since | 28 | * The next 16 interrupts are for board specific purposes. Since |
44 | * the kernel can only run on one machine at a time, we can re-use | 29 | * the kernel can only run on one machine at a time, we can re-use |
45 | * these. If you need more, increase MXC_BOARD_IRQS, but keep it | 30 | * these. If you need more, increase MXC_BOARD_IRQS, but keep it |
46 | * within sensible limits. | 31 | * within sensible limits. |
47 | */ | 32 | */ |
48 | #define MXC_BOARD_IRQ_START (MXC_INTERNAL_IRQS + MXC_GPIO_IRQS) | 33 | #define MXC_BOARD_IRQ_START (MXC_INTERNAL_IRQS + ARCH_NR_GPIOS) |
49 | 34 | ||
50 | #ifdef CONFIG_MACH_MX31ADS_WM1133_EV1 | 35 | #ifdef CONFIG_MACH_MX31ADS_WM1133_EV1 |
51 | #define MXC_BOARD_IRQS 80 | 36 | #define MXC_BOARD_IRQS 80 |