diff options
author | Shawn Guo <shawn.guo@linaro.org> | 2011-06-07 04:25:37 -0400 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2011-06-07 10:49:20 -0400 |
commit | e4ea933363d39b5858f55682550314b4ea1285cc (patch) | |
tree | 13de170922bfde627f67c6165955a41da5b9613e /drivers/gpio/gpio-mxc.c | |
parent | c103de240439dfee24ac50eb99c8be3a30d13323 (diff) |
gpio/mxc: convert gpio-mxc to use generic irq chip
The patch converts gpio-mxc driver to use generic irq chip.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/gpio/gpio-mxc.c')
-rw-r--r-- | drivers/gpio/gpio-mxc.c | 90 |
1 files changed, 29 insertions, 61 deletions
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index b351952893bb..950e53a636fa 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c | |||
@@ -65,46 +65,11 @@ static LIST_HEAD(mxc_gpio_ports); | |||
65 | 65 | ||
66 | /* Note: This driver assumes 32 GPIOs are handled in one register */ | 66 | /* Note: This driver assumes 32 GPIOs are handled in one register */ |
67 | 67 | ||
68 | static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index) | ||
69 | { | ||
70 | writel(1 << index, port->base + GPIO_ISR); | ||
71 | } | ||
72 | |||
73 | static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index, | ||
74 | int enable) | ||
75 | { | ||
76 | u32 l; | ||
77 | |||
78 | l = readl(port->base + GPIO_IMR); | ||
79 | l = (l & (~(1 << index))) | (!!enable << index); | ||
80 | writel(l, port->base + GPIO_IMR); | ||
81 | } | ||
82 | |||
83 | static void gpio_ack_irq(struct irq_data *d) | ||
84 | { | ||
85 | struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d); | ||
86 | u32 gpio = irq_to_gpio(d->irq); | ||
87 | _clear_gpio_irqstatus(port, gpio & 0x1f); | ||
88 | } | ||
89 | |||
90 | static void gpio_mask_irq(struct irq_data *d) | ||
91 | { | ||
92 | struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d); | ||
93 | u32 gpio = irq_to_gpio(d->irq); | ||
94 | _set_gpio_irqenable(port, gpio & 0x1f, 0); | ||
95 | } | ||
96 | |||
97 | static void gpio_unmask_irq(struct irq_data *d) | ||
98 | { | ||
99 | struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d); | ||
100 | u32 gpio = irq_to_gpio(d->irq); | ||
101 | _set_gpio_irqenable(port, gpio & 0x1f, 1); | ||
102 | } | ||
103 | |||
104 | static int gpio_set_irq_type(struct irq_data *d, u32 type) | 68 | static int gpio_set_irq_type(struct irq_data *d, u32 type) |
105 | { | 69 | { |
106 | u32 gpio = irq_to_gpio(d->irq); | 70 | u32 gpio = irq_to_gpio(d->irq); |
107 | struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d); | 71 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
72 | struct mxc_gpio_port *port = gc->private; | ||
108 | u32 bit, val; | 73 | u32 bit, val; |
109 | int edge; | 74 | int edge; |
110 | void __iomem *reg = port->base; | 75 | void __iomem *reg = port->base; |
@@ -142,7 +107,7 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type) | |||
142 | bit = gpio & 0xf; | 107 | bit = gpio & 0xf; |
143 | val = readl(reg) & ~(0x3 << (bit << 1)); | 108 | val = readl(reg) & ~(0x3 << (bit << 1)); |
144 | writel(val | (edge << (bit << 1)), reg); | 109 | writel(val | (edge << (bit << 1)), reg); |
145 | _clear_gpio_irqstatus(port, gpio & 0x1f); | 110 | writel(1 << (gpio & 0x1f), port->base + GPIO_ISR); |
146 | 111 | ||
147 | return 0; | 112 | return 0; |
148 | } | 113 | } |
@@ -231,7 +196,8 @@ static int gpio_set_wake_irq(struct irq_data *d, u32 enable) | |||
231 | { | 196 | { |
232 | u32 gpio = irq_to_gpio(d->irq); | 197 | u32 gpio = irq_to_gpio(d->irq); |
233 | u32 gpio_idx = gpio & 0x1F; | 198 | u32 gpio_idx = gpio & 0x1F; |
234 | struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d); | 199 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
200 | struct mxc_gpio_port *port = gc->private; | ||
235 | 201 | ||
236 | if (enable) { | 202 | if (enable) { |
237 | if (port->irq_high && (gpio_idx >= 16)) | 203 | if (port->irq_high && (gpio_idx >= 16)) |
@@ -248,26 +214,33 @@ static int gpio_set_wake_irq(struct irq_data *d, u32 enable) | |||
248 | return 0; | 214 | return 0; |
249 | } | 215 | } |
250 | 216 | ||
251 | static struct irq_chip gpio_irq_chip = { | 217 | static void __init mxc_gpio_init_gc(struct mxc_gpio_port *port) |
252 | .name = "GPIO", | 218 | { |
253 | .irq_ack = gpio_ack_irq, | 219 | struct irq_chip_generic *gc; |
254 | .irq_mask = gpio_mask_irq, | 220 | struct irq_chip_type *ct; |
255 | .irq_unmask = gpio_unmask_irq, | 221 | |
256 | .irq_set_type = gpio_set_irq_type, | 222 | gc = irq_alloc_generic_chip("gpio-mxc", 1, port->virtual_irq_start, |
257 | .irq_set_wake = gpio_set_wake_irq, | 223 | port->base, handle_level_irq); |
258 | }; | 224 | gc->private = port; |
259 | 225 | ||
260 | /* | 226 | ct = gc->chip_types; |
261 | * This lock class tells lockdep that GPIO irqs are in a different | 227 | ct->chip.irq_ack = irq_gc_ack, |
262 | * category than their parents, so it won't report false recursion. | 228 | ct->chip.irq_mask = irq_gc_mask_clr_bit; |
263 | */ | 229 | ct->chip.irq_unmask = irq_gc_mask_set_bit; |
264 | static struct lock_class_key gpio_lock_class; | 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 | } | ||
265 | 238 | ||
266 | static int __devinit mxc_gpio_probe(struct platform_device *pdev) | 239 | static int __devinit mxc_gpio_probe(struct platform_device *pdev) |
267 | { | 240 | { |
268 | struct mxc_gpio_port *port; | 241 | struct mxc_gpio_port *port; |
269 | struct resource *iores; | 242 | struct resource *iores; |
270 | int err, i; | 243 | int err; |
271 | 244 | ||
272 | port = kzalloc(sizeof(struct mxc_gpio_port), GFP_KERNEL); | 245 | port = kzalloc(sizeof(struct mxc_gpio_port), GFP_KERNEL); |
273 | if (!port) | 246 | if (!port) |
@@ -304,13 +277,8 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev) | |||
304 | writel(0, port->base + GPIO_IMR); | 277 | writel(0, port->base + GPIO_IMR); |
305 | writel(~0, port->base + GPIO_ISR); | 278 | writel(~0, port->base + GPIO_ISR); |
306 | 279 | ||
307 | for (i = port->virtual_irq_start; | 280 | /* gpio-mxc can be a generic irq chip */ |
308 | i < port->virtual_irq_start + 32; i++) { | 281 | mxc_gpio_init_gc(port); |
309 | irq_set_lockdep_class(i, &gpio_lock_class); | ||
310 | irq_set_chip_and_handler(i, &gpio_irq_chip, handle_level_irq); | ||
311 | set_irq_flags(i, IRQF_VALID); | ||
312 | irq_set_chip_data(i, port); | ||
313 | } | ||
314 | 282 | ||
315 | if (cpu_is_mx2()) { | 283 | if (cpu_is_mx2()) { |
316 | /* setup one handler for all GPIO interrupts */ | 284 | /* setup one handler for all GPIO interrupts */ |