summaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-mxc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/gpio-mxc.c')
-rw-r--r--drivers/gpio/gpio-mxc.c136
1 files changed, 94 insertions, 42 deletions
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index c337143b18f8..80f44bb64a87 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -23,6 +23,7 @@
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/io.h> 24#include <linux/io.h>
25#include <linux/irq.h> 25#include <linux/irq.h>
26#include <linux/irqdomain.h>
26#include <linux/gpio.h> 27#include <linux/gpio.h>
27#include <linux/platform_device.h> 28#include <linux/platform_device.h>
28#include <linux/slab.h> 29#include <linux/slab.h>
@@ -33,12 +34,11 @@
33#include <asm-generic/bug.h> 34#include <asm-generic/bug.h>
34#include <asm/mach/irq.h> 35#include <asm/mach/irq.h>
35 36
36#define irq_to_gpio(irq) ((irq) - MXC_GPIO_IRQ_START)
37
38enum mxc_gpio_hwtype { 37enum mxc_gpio_hwtype {
39 IMX1_GPIO, /* runs on i.mx1 */ 38 IMX1_GPIO, /* runs on i.mx1 */
40 IMX21_GPIO, /* runs on i.mx21 and i.mx27 */ 39 IMX21_GPIO, /* runs on i.mx21 and i.mx27 */
41 IMX31_GPIO, /* runs on all other i.mx */ 40 IMX31_GPIO, /* runs on i.mx31 */
41 IMX35_GPIO, /* runs on all other i.mx */
42}; 42};
43 43
44/* device type dependent stuff */ 44/* device type dependent stuff */
@@ -50,6 +50,7 @@ struct mxc_gpio_hwdata {
50 unsigned icr2_reg; 50 unsigned icr2_reg;
51 unsigned imr_reg; 51 unsigned imr_reg;
52 unsigned isr_reg; 52 unsigned isr_reg;
53 int edge_sel_reg;
53 unsigned low_level; 54 unsigned low_level;
54 unsigned high_level; 55 unsigned high_level;
55 unsigned rise_edge; 56 unsigned rise_edge;
@@ -61,7 +62,7 @@ struct mxc_gpio_port {
61 void __iomem *base; 62 void __iomem *base;
62 int irq; 63 int irq;
63 int irq_high; 64 int irq_high;
64 int virtual_irq_start; 65 struct irq_domain *domain;
65 struct bgpio_chip bgc; 66 struct bgpio_chip bgc;
66 u32 both_edges; 67 u32 both_edges;
67}; 68};
@@ -74,6 +75,7 @@ static struct mxc_gpio_hwdata imx1_imx21_gpio_hwdata = {
74 .icr2_reg = 0x2c, 75 .icr2_reg = 0x2c,
75 .imr_reg = 0x30, 76 .imr_reg = 0x30,
76 .isr_reg = 0x34, 77 .isr_reg = 0x34,
78 .edge_sel_reg = -EINVAL,
77 .low_level = 0x03, 79 .low_level = 0x03,
78 .high_level = 0x02, 80 .high_level = 0x02,
79 .rise_edge = 0x00, 81 .rise_edge = 0x00,
@@ -88,6 +90,22 @@ static struct mxc_gpio_hwdata imx31_gpio_hwdata = {
88 .icr2_reg = 0x10, 90 .icr2_reg = 0x10,
89 .imr_reg = 0x14, 91 .imr_reg = 0x14,
90 .isr_reg = 0x18, 92 .isr_reg = 0x18,
93 .edge_sel_reg = -EINVAL,
94 .low_level = 0x00,
95 .high_level = 0x01,
96 .rise_edge = 0x02,
97 .fall_edge = 0x03,
98};
99
100static struct mxc_gpio_hwdata imx35_gpio_hwdata = {
101 .dr_reg = 0x00,
102 .gdir_reg = 0x04,
103 .psr_reg = 0x08,
104 .icr1_reg = 0x0c,
105 .icr2_reg = 0x10,
106 .imr_reg = 0x14,
107 .isr_reg = 0x18,
108 .edge_sel_reg = 0x1c,
91 .low_level = 0x00, 109 .low_level = 0x00,
92 .high_level = 0x01, 110 .high_level = 0x01,
93 .rise_edge = 0x02, 111 .rise_edge = 0x02,
@@ -104,12 +122,13 @@ static struct mxc_gpio_hwdata *mxc_gpio_hwdata;
104#define GPIO_ICR2 (mxc_gpio_hwdata->icr2_reg) 122#define GPIO_ICR2 (mxc_gpio_hwdata->icr2_reg)
105#define GPIO_IMR (mxc_gpio_hwdata->imr_reg) 123#define GPIO_IMR (mxc_gpio_hwdata->imr_reg)
106#define GPIO_ISR (mxc_gpio_hwdata->isr_reg) 124#define GPIO_ISR (mxc_gpio_hwdata->isr_reg)
125#define GPIO_EDGE_SEL (mxc_gpio_hwdata->edge_sel_reg)
107 126
108#define GPIO_INT_LOW_LEV (mxc_gpio_hwdata->low_level) 127#define GPIO_INT_LOW_LEV (mxc_gpio_hwdata->low_level)
109#define GPIO_INT_HIGH_LEV (mxc_gpio_hwdata->high_level) 128#define GPIO_INT_HIGH_LEV (mxc_gpio_hwdata->high_level)
110#define GPIO_INT_RISE_EDGE (mxc_gpio_hwdata->rise_edge) 129#define GPIO_INT_RISE_EDGE (mxc_gpio_hwdata->rise_edge)
111#define GPIO_INT_FALL_EDGE (mxc_gpio_hwdata->fall_edge) 130#define GPIO_INT_FALL_EDGE (mxc_gpio_hwdata->fall_edge)
112#define GPIO_INT_NONE 0x4 131#define GPIO_INT_BOTH_EDGES 0x4
113 132
114static struct platform_device_id mxc_gpio_devtype[] = { 133static struct platform_device_id mxc_gpio_devtype[] = {
115 { 134 {
@@ -122,6 +141,9 @@ static struct platform_device_id mxc_gpio_devtype[] = {
122 .name = "imx31-gpio", 141 .name = "imx31-gpio",
123 .driver_data = IMX31_GPIO, 142 .driver_data = IMX31_GPIO,
124 }, { 143 }, {
144 .name = "imx35-gpio",
145 .driver_data = IMX35_GPIO,
146 }, {
125 /* sentinel */ 147 /* sentinel */
126 } 148 }
127}; 149};
@@ -130,6 +152,7 @@ static const struct of_device_id mxc_gpio_dt_ids[] = {
130 { .compatible = "fsl,imx1-gpio", .data = &mxc_gpio_devtype[IMX1_GPIO], }, 152 { .compatible = "fsl,imx1-gpio", .data = &mxc_gpio_devtype[IMX1_GPIO], },
131 { .compatible = "fsl,imx21-gpio", .data = &mxc_gpio_devtype[IMX21_GPIO], }, 153 { .compatible = "fsl,imx21-gpio", .data = &mxc_gpio_devtype[IMX21_GPIO], },
132 { .compatible = "fsl,imx31-gpio", .data = &mxc_gpio_devtype[IMX31_GPIO], }, 154 { .compatible = "fsl,imx31-gpio", .data = &mxc_gpio_devtype[IMX31_GPIO], },
155 { .compatible = "fsl,imx35-gpio", .data = &mxc_gpio_devtype[IMX35_GPIO], },
133 { /* sentinel */ } 156 { /* sentinel */ }
134}; 157};
135 158
@@ -144,14 +167,15 @@ static LIST_HEAD(mxc_gpio_ports);
144 167
145static int gpio_set_irq_type(struct irq_data *d, u32 type) 168static int gpio_set_irq_type(struct irq_data *d, u32 type)
146{ 169{
147 u32 gpio = irq_to_gpio(d->irq);
148 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 170 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
149 struct mxc_gpio_port *port = gc->private; 171 struct mxc_gpio_port *port = gc->private;
150 u32 bit, val; 172 u32 bit, val;
173 u32 gpio_idx = d->hwirq;
174 u32 gpio = port->bgc.gc.base + gpio_idx;
151 int edge; 175 int edge;
152 void __iomem *reg = port->base; 176 void __iomem *reg = port->base;
153 177
154 port->both_edges &= ~(1 << (gpio & 31)); 178 port->both_edges &= ~(1 << gpio_idx);
155 switch (type) { 179 switch (type) {
156 case IRQ_TYPE_EDGE_RISING: 180 case IRQ_TYPE_EDGE_RISING:
157 edge = GPIO_INT_RISE_EDGE; 181 edge = GPIO_INT_RISE_EDGE;
@@ -160,15 +184,19 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
160 edge = GPIO_INT_FALL_EDGE; 184 edge = GPIO_INT_FALL_EDGE;
161 break; 185 break;
162 case IRQ_TYPE_EDGE_BOTH: 186 case IRQ_TYPE_EDGE_BOTH:
163 val = gpio_get_value(gpio); 187 if (GPIO_EDGE_SEL >= 0) {
164 if (val) { 188 edge = GPIO_INT_BOTH_EDGES;
165 edge = GPIO_INT_LOW_LEV;
166 pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
167 } else { 189 } else {
168 edge = GPIO_INT_HIGH_LEV; 190 val = gpio_get_value(gpio);
169 pr_debug("mxc: set GPIO %d to high trigger\n", gpio); 191 if (val) {
192 edge = GPIO_INT_LOW_LEV;
193 pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
194 } else {
195 edge = GPIO_INT_HIGH_LEV;
196 pr_debug("mxc: set GPIO %d to high trigger\n", gpio);
197 }
198 port->both_edges |= 1 << gpio_idx;
170 } 199 }
171 port->both_edges |= 1 << (gpio & 31);
172 break; 200 break;
173 case IRQ_TYPE_LEVEL_LOW: 201 case IRQ_TYPE_LEVEL_LOW:
174 edge = GPIO_INT_LOW_LEV; 202 edge = GPIO_INT_LOW_LEV;
@@ -180,11 +208,24 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
180 return -EINVAL; 208 return -EINVAL;
181 } 209 }
182 210
183 reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ 211 if (GPIO_EDGE_SEL >= 0) {
184 bit = gpio & 0xf; 212 val = readl(port->base + GPIO_EDGE_SEL);
185 val = readl(reg) & ~(0x3 << (bit << 1)); 213 if (edge == GPIO_INT_BOTH_EDGES)
186 writel(val | (edge << (bit << 1)), reg); 214 writel(val | (1 << gpio_idx),
187 writel(1 << (gpio & 0x1f), port->base + GPIO_ISR); 215 port->base + GPIO_EDGE_SEL);
216 else
217 writel(val & ~(1 << gpio_idx),
218 port->base + GPIO_EDGE_SEL);
219 }
220
221 if (edge != GPIO_INT_BOTH_EDGES) {
222 reg += GPIO_ICR1 + ((gpio_idx & 0x10) >> 2); /* lower or upper register */
223 bit = gpio_idx & 0xf;
224 val = readl(reg) & ~(0x3 << (bit << 1));
225 writel(val | (edge << (bit << 1)), reg);
226 }
227
228 writel(1 << gpio_idx, port->base + GPIO_ISR);
188 229
189 return 0; 230 return 0;
190} 231}
@@ -217,15 +258,13 @@ static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
217/* handle 32 interrupts in one status register */ 258/* handle 32 interrupts in one status register */
218static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat) 259static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat)
219{ 260{
220 u32 gpio_irq_no_base = port->virtual_irq_start;
221
222 while (irq_stat != 0) { 261 while (irq_stat != 0) {
223 int irqoffset = fls(irq_stat) - 1; 262 int irqoffset = fls(irq_stat) - 1;
224 263
225 if (port->both_edges & (1 << irqoffset)) 264 if (port->both_edges & (1 << irqoffset))
226 mxc_flip_edge(port, irqoffset); 265 mxc_flip_edge(port, irqoffset);
227 266
228 generic_handle_irq(gpio_irq_no_base + irqoffset); 267 generic_handle_irq(irq_find_mapping(port->domain, irqoffset));
229 268
230 irq_stat &= ~(1 << irqoffset); 269 irq_stat &= ~(1 << irqoffset);
231 } 270 }
@@ -276,10 +315,9 @@ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
276 */ 315 */
277static int gpio_set_wake_irq(struct irq_data *d, u32 enable) 316static int gpio_set_wake_irq(struct irq_data *d, u32 enable)
278{ 317{
279 u32 gpio = irq_to_gpio(d->irq);
280 u32 gpio_idx = gpio & 0x1F;
281 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 318 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
282 struct mxc_gpio_port *port = gc->private; 319 struct mxc_gpio_port *port = gc->private;
320 u32 gpio_idx = d->hwirq;
283 321
284 if (enable) { 322 if (enable) {
285 if (port->irq_high && (gpio_idx >= 16)) 323 if (port->irq_high && (gpio_idx >= 16))
@@ -296,12 +334,12 @@ static int gpio_set_wake_irq(struct irq_data *d, u32 enable)
296 return 0; 334 return 0;
297} 335}
298 336
299static void __init mxc_gpio_init_gc(struct mxc_gpio_port *port) 337static void __init mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base)
300{ 338{
301 struct irq_chip_generic *gc; 339 struct irq_chip_generic *gc;
302 struct irq_chip_type *ct; 340 struct irq_chip_type *ct;
303 341
304 gc = irq_alloc_generic_chip("gpio-mxc", 1, port->virtual_irq_start, 342 gc = irq_alloc_generic_chip("gpio-mxc", 1, irq_base,
305 port->base, handle_level_irq); 343 port->base, handle_level_irq);
306 gc->private = port; 344 gc->private = port;
307 345
@@ -338,7 +376,9 @@ static void __devinit mxc_gpio_get_hw(struct platform_device *pdev)
338 return; 376 return;
339 } 377 }
340 378
341 if (hwtype == IMX31_GPIO) 379 if (hwtype == IMX35_GPIO)
380 mxc_gpio_hwdata = &imx35_gpio_hwdata;
381 else if (hwtype == IMX31_GPIO)
342 mxc_gpio_hwdata = &imx31_gpio_hwdata; 382 mxc_gpio_hwdata = &imx31_gpio_hwdata;
343 else 383 else
344 mxc_gpio_hwdata = &imx1_imx21_gpio_hwdata; 384 mxc_gpio_hwdata = &imx1_imx21_gpio_hwdata;
@@ -352,7 +392,7 @@ static int mxc_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
352 struct mxc_gpio_port *port = 392 struct mxc_gpio_port *port =
353 container_of(bgc, struct mxc_gpio_port, bgc); 393 container_of(bgc, struct mxc_gpio_port, bgc);
354 394
355 return port->virtual_irq_start + offset; 395 return irq_find_mapping(port->domain, offset);
356} 396}
357 397
358static int __devinit mxc_gpio_probe(struct platform_device *pdev) 398static int __devinit mxc_gpio_probe(struct platform_device *pdev)
@@ -360,6 +400,7 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev)
360 struct device_node *np = pdev->dev.of_node; 400 struct device_node *np = pdev->dev.of_node;
361 struct mxc_gpio_port *port; 401 struct mxc_gpio_port *port;
362 struct resource *iores; 402 struct resource *iores;
403 int irq_base;
363 int err; 404 int err;
364 405
365 mxc_gpio_get_hw(pdev); 406 mxc_gpio_get_hw(pdev);
@@ -398,10 +439,12 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev)
398 writel(~0, port->base + GPIO_ISR); 439 writel(~0, port->base + GPIO_ISR);
399 440
400 if (mxc_gpio_hwtype == IMX21_GPIO) { 441 if (mxc_gpio_hwtype == IMX21_GPIO) {
401 /* setup one handler for all GPIO interrupts */ 442 /*
402 if (pdev->id == 0) 443 * Setup one handler for all GPIO interrupts. Actually setting
403 irq_set_chained_handler(port->irq, 444 * the handler is needed only once, but doing it for every port
404 mx2_gpio_irq_handler); 445 * is more robust and easier.
446 */
447 irq_set_chained_handler(port->irq, mx2_gpio_irq_handler);
405 } else { 448 } else {
406 /* setup one handler for each entry */ 449 /* setup one handler for each entry */
407 irq_set_chained_handler(port->irq, mx3_gpio_irq_handler); 450 irq_set_chained_handler(port->irq, mx3_gpio_irq_handler);
@@ -422,28 +465,37 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev)
422 goto out_iounmap; 465 goto out_iounmap;
423 466
424 port->bgc.gc.to_irq = mxc_gpio_to_irq; 467 port->bgc.gc.to_irq = mxc_gpio_to_irq;
425 port->bgc.gc.base = pdev->id * 32; 468 port->bgc.gc.base = (pdev->id < 0) ? of_alias_get_id(np, "gpio") * 32 :
426 port->bgc.dir = port->bgc.read_reg(port->bgc.reg_dir); 469 pdev->id * 32;
427 port->bgc.data = port->bgc.read_reg(port->bgc.reg_set);
428 470
429 err = gpiochip_add(&port->bgc.gc); 471 err = gpiochip_add(&port->bgc.gc);
430 if (err) 472 if (err)
431 goto out_bgpio_remove; 473 goto out_bgpio_remove;
432 474
433 /* 475 irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id());
434 * In dt case, we use gpio number range dynamically 476 if (irq_base < 0) {
435 * allocated by gpio core. 477 err = irq_base;
436 */ 478 goto out_gpiochip_remove;
437 port->virtual_irq_start = MXC_GPIO_IRQ_START + (np ? port->bgc.gc.base : 479 }
438 pdev->id * 32); 480
481 port->domain = irq_domain_add_legacy(np, 32, irq_base, 0,
482 &irq_domain_simple_ops, NULL);
483 if (!port->domain) {
484 err = -ENODEV;
485 goto out_irqdesc_free;
486 }
439 487
440 /* gpio-mxc can be a generic irq chip */ 488 /* gpio-mxc can be a generic irq chip */
441 mxc_gpio_init_gc(port); 489 mxc_gpio_init_gc(port, irq_base);
442 490
443 list_add_tail(&port->node, &mxc_gpio_ports); 491 list_add_tail(&port->node, &mxc_gpio_ports);
444 492
445 return 0; 493 return 0;
446 494
495out_irqdesc_free:
496 irq_free_descs(irq_base, 32);
497out_gpiochip_remove:
498 WARN_ON(gpiochip_remove(&port->bgc.gc) < 0);
447out_bgpio_remove: 499out_bgpio_remove:
448 bgpio_remove(&port->bgc); 500 bgpio_remove(&port->bgc);
449out_iounmap: 501out_iounmap: