]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/gpio/gpio-mxc.c
2f6a81b8f12ee89d7ac4e5439497c21f112e5820
[karo-tx-linux.git] / drivers / gpio / gpio-mxc.c
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 <linux/platform_device.h>
28 #include <linux/slab.h>
29 #include <linux/basic_mmio_gpio.h>
30 #include <mach/hardware.h>
31 #include <asm-generic/bug.h>
32
33 struct mxc_gpio_port {
34         struct list_head node;
35         void __iomem *base;
36         int irq;
37         int irq_high;
38         int virtual_irq_start;
39         struct bgpio_chip bgc;
40         u32 both_edges;
41 };
42
43 /*
44  * MX2 has one interrupt *for all* gpio ports. The list is used
45  * to save the references to all ports, so that mx2_gpio_irq_handler
46  * can walk through all interrupt status registers.
47  */
48 static LIST_HEAD(mxc_gpio_ports);
49
50 #define cpu_is_mx1_mx2()        (cpu_is_mx1() || cpu_is_mx2())
51
52 #define GPIO_DR         (cpu_is_mx1_mx2() ? 0x1c : 0x00)
53 #define GPIO_GDIR       (cpu_is_mx1_mx2() ? 0x00 : 0x04)
54 #define GPIO_PSR        (cpu_is_mx1_mx2() ? 0x24 : 0x08)
55 #define GPIO_ICR1       (cpu_is_mx1_mx2() ? 0x28 : 0x0C)
56 #define GPIO_ICR2       (cpu_is_mx1_mx2() ? 0x2C : 0x10)
57 #define GPIO_IMR        (cpu_is_mx1_mx2() ? 0x30 : 0x14)
58 #define GPIO_ISR        (cpu_is_mx1_mx2() ? 0x34 : 0x18)
59
60 #define GPIO_INT_LOW_LEV        (cpu_is_mx1_mx2() ? 0x3 : 0x0)
61 #define GPIO_INT_HIGH_LEV       (cpu_is_mx1_mx2() ? 0x2 : 0x1)
62 #define GPIO_INT_RISE_EDGE      (cpu_is_mx1_mx2() ? 0x0 : 0x2)
63 #define GPIO_INT_FALL_EDGE      (cpu_is_mx1_mx2() ? 0x1 : 0x3)
64 #define GPIO_INT_NONE           0x4
65
66 /* Note: This driver assumes 32 GPIOs are handled in one register */
67
68 static int gpio_set_irq_type(struct irq_data *d, u32 type)
69 {
70         u32 gpio = irq_to_gpio(d->irq);
71         struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
72         struct mxc_gpio_port *port = gc->private;
73         u32 bit, val;
74         int edge;
75         void __iomem *reg = port->base;
76
77         port->both_edges &= ~(1 << (gpio & 31));
78         switch (type) {
79         case IRQ_TYPE_EDGE_RISING:
80                 edge = GPIO_INT_RISE_EDGE;
81                 break;
82         case IRQ_TYPE_EDGE_FALLING:
83                 edge = GPIO_INT_FALL_EDGE;
84                 break;
85         case IRQ_TYPE_EDGE_BOTH:
86                 val = gpio_get_value(gpio);
87                 if (val) {
88                         edge = GPIO_INT_LOW_LEV;
89                         pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
90                 } else {
91                         edge = GPIO_INT_HIGH_LEV;
92                         pr_debug("mxc: set GPIO %d to high trigger\n", gpio);
93                 }
94                 port->both_edges |= 1 << (gpio & 31);
95                 break;
96         case IRQ_TYPE_LEVEL_LOW:
97                 edge = GPIO_INT_LOW_LEV;
98                 break;
99         case IRQ_TYPE_LEVEL_HIGH:
100                 edge = GPIO_INT_HIGH_LEV;
101                 break;
102         default:
103                 return -EINVAL;
104         }
105
106         reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
107         bit = gpio & 0xf;
108         val = readl(reg) & ~(0x3 << (bit << 1));
109         writel(val | (edge << (bit << 1)), reg);
110         writel(1 << (gpio & 0x1f), port->base + GPIO_ISR);
111
112         return 0;
113 }
114
115 static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
116 {
117         void __iomem *reg = port->base;
118         u32 bit, val;
119         int edge;
120
121         reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
122         bit = gpio & 0xf;
123         val = readl(reg);
124         edge = (val >> (bit << 1)) & 3;
125         val &= ~(0x3 << (bit << 1));
126         if (edge == GPIO_INT_HIGH_LEV) {
127                 edge = GPIO_INT_LOW_LEV;
128                 pr_debug("mxc: switch GPIO %d to low trigger\n", gpio);
129         } else if (edge == GPIO_INT_LOW_LEV) {
130                 edge = GPIO_INT_HIGH_LEV;
131                 pr_debug("mxc: switch GPIO %d to high trigger\n", gpio);
132         } else {
133                 pr_err("mxc: invalid configuration for GPIO %d: %x\n",
134                        gpio, edge);
135                 return;
136         }
137         writel(val | (edge << (bit << 1)), reg);
138 }
139
140 /* handle 32 interrupts in one status register */
141 static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat)
142 {
143         u32 gpio_irq_no_base = port->virtual_irq_start;
144
145         while (irq_stat != 0) {
146                 int irqoffset = fls(irq_stat) - 1;
147
148                 if (port->both_edges & (1 << irqoffset))
149                         mxc_flip_edge(port, irqoffset);
150
151                 generic_handle_irq(gpio_irq_no_base + irqoffset);
152
153                 irq_stat &= ~(1 << irqoffset);
154         }
155 }
156
157 /* MX1 and MX3 has one interrupt *per* gpio port */
158 static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
159 {
160         u32 irq_stat;
161         struct mxc_gpio_port *port = irq_get_handler_data(irq);
162
163         irq_stat = readl(port->base + GPIO_ISR) & readl(port->base + GPIO_IMR);
164
165         mxc_gpio_irq_handler(port, irq_stat);
166 }
167
168 /* MX2 has one interrupt *for all* gpio ports */
169 static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
170 {
171         u32 irq_msk, irq_stat;
172         struct mxc_gpio_port *port;
173
174         /* walk through all interrupt status registers */
175         list_for_each_entry(port, &mxc_gpio_ports, node) {
176                 irq_msk = readl(port->base + GPIO_IMR);
177                 if (!irq_msk)
178                         continue;
179
180                 irq_stat = readl(port->base + GPIO_ISR) & irq_msk;
181                 if (irq_stat)
182                         mxc_gpio_irq_handler(port, irq_stat);
183         }
184 }
185
186 /*
187  * Set interrupt number "irq" in the GPIO as a wake-up source.
188  * While system is running, all registered GPIO interrupts need to have
189  * wake-up enabled. When system is suspended, only selected GPIO interrupts
190  * need to have wake-up enabled.
191  * @param  irq          interrupt source number
192  * @param  enable       enable as wake-up if equal to non-zero
193  * @return       This function returns 0 on success.
194  */
195 static int gpio_set_wake_irq(struct irq_data *d, u32 enable)
196 {
197         u32 gpio = irq_to_gpio(d->irq);
198         u32 gpio_idx = gpio & 0x1F;
199         struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
200         struct mxc_gpio_port *port = gc->private;
201
202         if (enable) {
203                 if (port->irq_high && (gpio_idx >= 16))
204                         enable_irq_wake(port->irq_high);
205                 else
206                         enable_irq_wake(port->irq);
207         } else {
208                 if (port->irq_high && (gpio_idx >= 16))
209                         disable_irq_wake(port->irq_high);
210                 else
211                         disable_irq_wake(port->irq);
212         }
213
214         return 0;
215 }
216
217 static void __init mxc_gpio_init_gc(struct mxc_gpio_port *port)
218 {
219         struct irq_chip_generic *gc;
220         struct irq_chip_type *ct;
221
222         gc = irq_alloc_generic_chip("gpio-mxc", 1, port->virtual_irq_start,
223                                     port->base, handle_level_irq);
224         gc->private = port;
225
226         ct = gc->chip_types;
227         ct->chip.irq_ack = irq_gc_ack,
228         ct->chip.irq_mask = irq_gc_mask_clr_bit;
229         ct->chip.irq_unmask = irq_gc_mask_set_bit;
230         ct->chip.irq_set_type = gpio_set_irq_type;
231         ct->chip.irq_set_wake = gpio_set_wake_irq,
232         ct->regs.ack = GPIO_ISR;
233         ct->regs.mask = GPIO_IMR;
234
235         irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_NESTED_LOCK,
236                                IRQ_NOREQUEST, 0);
237 }
238
239 static int __devinit mxc_gpio_probe(struct platform_device *pdev)
240 {
241         struct mxc_gpio_port *port;
242         struct resource *iores;
243         int err;
244
245         port = kzalloc(sizeof(struct mxc_gpio_port), GFP_KERNEL);
246         if (!port)
247                 return -ENOMEM;
248
249         port->virtual_irq_start = MXC_GPIO_IRQ_START + pdev->id * 32;
250
251         iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
252         if (!iores) {
253                 err = -ENODEV;
254                 goto out_kfree;
255         }
256
257         if (!request_mem_region(iores->start, resource_size(iores),
258                                 pdev->name)) {
259                 err = -EBUSY;
260                 goto out_kfree;
261         }
262
263         port->base = ioremap(iores->start, resource_size(iores));
264         if (!port->base) {
265                 err = -ENOMEM;
266                 goto out_release_mem;
267         }
268
269         port->irq_high = platform_get_irq(pdev, 1);
270         port->irq = platform_get_irq(pdev, 0);
271         if (port->irq < 0) {
272                 err = -EINVAL;
273                 goto out_iounmap;
274         }
275
276         /* disable the interrupt and clear the status */
277         writel(0, port->base + GPIO_IMR);
278         writel(~0, port->base + GPIO_ISR);
279
280         /* gpio-mxc can be a generic irq chip */
281         mxc_gpio_init_gc(port);
282
283         if (cpu_is_mx2()) {
284                 /* setup one handler for all GPIO interrupts */
285                 if (pdev->id == 0)
286                         irq_set_chained_handler(port->irq,
287                                                 mx2_gpio_irq_handler);
288         } else {
289                 /* setup one handler for each entry */
290                 irq_set_chained_handler(port->irq, mx3_gpio_irq_handler);
291                 irq_set_handler_data(port->irq, port);
292                 if (port->irq_high > 0) {
293                         /* setup handler for GPIO 16 to 31 */
294                         irq_set_chained_handler(port->irq_high,
295                                                 mx3_gpio_irq_handler);
296                         irq_set_handler_data(port->irq_high, port);
297                 }
298         }
299
300         err = bgpio_init(&port->bgc, &pdev->dev, 4,
301                          port->base + GPIO_PSR,
302                          port->base + GPIO_DR, NULL,
303                          port->base + GPIO_GDIR, NULL, false);
304         if (err)
305                 goto out_iounmap;
306
307         port->bgc.gc.base = pdev->id * 32;
308
309         err = gpiochip_add(&port->bgc.gc);
310         if (err)
311                 goto out_bgpio_remove;
312
313         list_add_tail(&port->node, &mxc_gpio_ports);
314
315         return 0;
316
317 out_bgpio_remove:
318         bgpio_remove(&port->bgc);
319 out_iounmap:
320         iounmap(port->base);
321 out_release_mem:
322         release_mem_region(iores->start, resource_size(iores));
323 out_kfree:
324         kfree(port);
325         dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err);
326         return err;
327 }
328
329 static struct platform_driver mxc_gpio_driver = {
330         .driver         = {
331                 .name   = "gpio-mxc",
332                 .owner  = THIS_MODULE,
333         },
334         .probe          = mxc_gpio_probe,
335 };
336
337 static int __init gpio_mxc_init(void)
338 {
339         return platform_driver_register(&mxc_gpio_driver);
340 }
341 postcore_initcall(gpio_mxc_init);
342
343 MODULE_AUTHOR("Freescale Semiconductor, "
344               "Daniel Mack <danielncaiaq.de>, "
345               "Juergen Beisert <kernel@pengutronix.de>");
346 MODULE_DESCRIPTION("Freescale MXC GPIO");
347 MODULE_LICENSE("GPL");