aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Guo <shawn.guo@linaro.org>2012-08-20 04:43:32 -0400
committerShawn Guo <shawn.guo@linaro.org>2012-09-02 21:31:44 -0400
commit0b76c5412146c1c9e8aef495d2926f31351bc3c0 (patch)
treee99af001689a62706776681577c1bcafa9d85b5f
parentd9875690d9b89a866022ff49e3fcea892345ad92 (diff)
gpio/mxs: adopt irq_domain support for mxs gpio driver
Remove irq_domain_add_legacy call from mach-mxs.c and have the gpio driver adopt irqdomain support, so that we can have the mapping between gpio and irq number available without using virtual_irq_start and MXS_GPIO_IRQ_START. Signed-off-by: Shawn Guo <shawn.guo@linaro.org> Acked-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--arch/arm/mach-mxs/mach-mxs.c12
-rw-r--r--drivers/gpio/gpio-mxs.c48
2 files changed, 30 insertions, 30 deletions
diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c
index 8dabfe81d07c..78bf07a8cd3c 100644
--- a/arch/arm/mach-mxs/mach-mxs.c
+++ b/arch/arm/mach-mxs/mach-mxs.c
@@ -113,20 +113,8 @@ static int __init mxs_icoll_add_irq_domain(struct device_node *np,
113 return 0; 113 return 0;
114} 114}
115 115
116static int __init mxs_gpio_add_irq_domain(struct device_node *np,
117 struct device_node *interrupt_parent)
118{
119 static int gpio_irq_base = MXS_GPIO_IRQ_START;
120
121 irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, NULL);
122 gpio_irq_base += 32;
123
124 return 0;
125}
126
127static const struct of_device_id mxs_irq_match[] __initconst = { 116static const struct of_device_id mxs_irq_match[] __initconst = {
128 { .compatible = "fsl,mxs-icoll", .data = mxs_icoll_add_irq_domain, }, 117 { .compatible = "fsl,mxs-icoll", .data = mxs_icoll_add_irq_domain, },
129 { .compatible = "fsl,mxs-gpio", .data = mxs_gpio_add_irq_domain, },
130 { /* sentinel */ } 118 { /* sentinel */ }
131}; 119};
132 120
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c
index 39e495669961..796fb13e4815 100644
--- a/drivers/gpio/gpio-mxs.c
+++ b/drivers/gpio/gpio-mxs.c
@@ -24,6 +24,7 @@
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/irq.h> 26#include <linux/irq.h>
27#include <linux/irqdomain.h>
27#include <linux/gpio.h> 28#include <linux/gpio.h>
28#include <linux/of.h> 29#include <linux/of.h>
29#include <linux/of_address.h> 30#include <linux/of_address.h>
@@ -52,8 +53,6 @@
52#define GPIO_INT_LEV_MASK (1 << 0) 53#define GPIO_INT_LEV_MASK (1 << 0)
53#define GPIO_INT_POL_MASK (1 << 1) 54#define GPIO_INT_POL_MASK (1 << 1)
54 55
55#define irq_to_gpio(irq) ((irq) - MXS_GPIO_IRQ_START)
56
57enum mxs_gpio_id { 56enum mxs_gpio_id {
58 IMX23_GPIO, 57 IMX23_GPIO,
59 IMX28_GPIO, 58 IMX28_GPIO,
@@ -63,7 +62,7 @@ struct mxs_gpio_port {
63 void __iomem *base; 62 void __iomem *base;
64 int id; 63 int id;
65 int irq; 64 int irq;
66 int virtual_irq_start; 65 struct irq_domain *domain;
67 struct bgpio_chip bgc; 66 struct bgpio_chip bgc;
68 enum mxs_gpio_id devid; 67 enum mxs_gpio_id devid;
69}; 68};
@@ -82,8 +81,7 @@ static inline int is_imx28_gpio(struct mxs_gpio_port *port)
82 81
83static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type) 82static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
84{ 83{
85 u32 gpio = irq_to_gpio(d->irq); 84 u32 pin_mask = 1 << d->hwirq;
86 u32 pin_mask = 1 << (gpio & 31);
87 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 85 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
88 struct mxs_gpio_port *port = gc->private; 86 struct mxs_gpio_port *port = gc->private;
89 void __iomem *pin_addr; 87 void __iomem *pin_addr;
@@ -120,7 +118,7 @@ static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
120 else 118 else
121 writel(pin_mask, pin_addr + MXS_CLR); 119 writel(pin_mask, pin_addr + MXS_CLR);
122 120
123 writel(1 << (gpio & 0x1f), 121 writel(pin_mask,
124 port->base + PINCTRL_IRQSTAT(port) + MXS_CLR); 122 port->base + PINCTRL_IRQSTAT(port) + MXS_CLR);
125 123
126 return 0; 124 return 0;
@@ -131,7 +129,6 @@ static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
131{ 129{
132 u32 irq_stat; 130 u32 irq_stat;
133 struct mxs_gpio_port *port = irq_get_handler_data(irq); 131 struct mxs_gpio_port *port = irq_get_handler_data(irq);
134 u32 gpio_irq_no_base = port->virtual_irq_start;
135 132
136 desc->irq_data.chip->irq_ack(&desc->irq_data); 133 desc->irq_data.chip->irq_ack(&desc->irq_data);
137 134
@@ -140,7 +137,7 @@ static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
140 137
141 while (irq_stat != 0) { 138 while (irq_stat != 0) {
142 int irqoffset = fls(irq_stat) - 1; 139 int irqoffset = fls(irq_stat) - 1;
143 generic_handle_irq(gpio_irq_no_base + irqoffset); 140 generic_handle_irq(irq_find_mapping(port->domain, irqoffset));
144 irq_stat &= ~(1 << irqoffset); 141 irq_stat &= ~(1 << irqoffset);
145 } 142 }
146} 143}
@@ -167,12 +164,12 @@ static int mxs_gpio_set_wake_irq(struct irq_data *d, unsigned int enable)
167 return 0; 164 return 0;
168} 165}
169 166
170static void __init mxs_gpio_init_gc(struct mxs_gpio_port *port) 167static void __init mxs_gpio_init_gc(struct mxs_gpio_port *port, int irq_base)
171{ 168{
172 struct irq_chip_generic *gc; 169 struct irq_chip_generic *gc;
173 struct irq_chip_type *ct; 170 struct irq_chip_type *ct;
174 171
175 gc = irq_alloc_generic_chip("gpio-mxs", 1, port->virtual_irq_start, 172 gc = irq_alloc_generic_chip("gpio-mxs", 1, irq_base,
176 port->base, handle_level_irq); 173 port->base, handle_level_irq);
177 gc->private = port; 174 gc->private = port;
178 175
@@ -194,7 +191,7 @@ static int mxs_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
194 struct mxs_gpio_port *port = 191 struct mxs_gpio_port *port =
195 container_of(bgc, struct mxs_gpio_port, bgc); 192 container_of(bgc, struct mxs_gpio_port, bgc);
196 193
197 return port->virtual_irq_start + offset; 194 return irq_find_mapping(port->domain, offset);
198} 195}
199 196
200static struct platform_device_id mxs_gpio_ids[] = { 197static struct platform_device_id mxs_gpio_ids[] = {
@@ -226,6 +223,7 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)
226 static void __iomem *base; 223 static void __iomem *base;
227 struct mxs_gpio_port *port; 224 struct mxs_gpio_port *port;
228 struct resource *iores = NULL; 225 struct resource *iores = NULL;
226 int irq_base;
229 int err; 227 int err;
230 228
231 port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL); 229 port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL);
@@ -241,7 +239,6 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)
241 port->id = pdev->id; 239 port->id = pdev->id;
242 port->devid = pdev->id_entry->driver_data; 240 port->devid = pdev->id_entry->driver_data;
243 } 241 }
244 port->virtual_irq_start = MXS_GPIO_IRQ_START + port->id * 32;
245 242
246 port->irq = platform_get_irq(pdev, 0); 243 port->irq = platform_get_irq(pdev, 0);
247 if (port->irq < 0) 244 if (port->irq < 0)
@@ -275,8 +272,19 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)
275 /* clear address has to be used to clear IRQSTAT bits */ 272 /* clear address has to be used to clear IRQSTAT bits */
276 writel(~0U, port->base + PINCTRL_IRQSTAT(port) + MXS_CLR); 273 writel(~0U, port->base + PINCTRL_IRQSTAT(port) + MXS_CLR);
277 274
275 irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id());
276 if (irq_base < 0)
277 return irq_base;
278
279 port->domain = irq_domain_add_legacy(np, 32, irq_base, 0,
280 &irq_domain_simple_ops, NULL);
281 if (!port->domain) {
282 err = -ENODEV;
283 goto out_irqdesc_free;
284 }
285
278 /* gpio-mxs can be a generic irq chip */ 286 /* gpio-mxs can be a generic irq chip */
279 mxs_gpio_init_gc(port); 287 mxs_gpio_init_gc(port, irq_base);
280 288
281 /* setup one handler for each entry */ 289 /* setup one handler for each entry */
282 irq_set_chained_handler(port->irq, mxs_gpio_irq_handler); 290 irq_set_chained_handler(port->irq, mxs_gpio_irq_handler);
@@ -287,18 +295,22 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)
287 port->base + PINCTRL_DOUT(port), NULL, 295 port->base + PINCTRL_DOUT(port), NULL,
288 port->base + PINCTRL_DOE(port), NULL, 0); 296 port->base + PINCTRL_DOE(port), NULL, 0);
289 if (err) 297 if (err)
290 return err; 298 goto out_irqdesc_free;
291 299
292 port->bgc.gc.to_irq = mxs_gpio_to_irq; 300 port->bgc.gc.to_irq = mxs_gpio_to_irq;
293 port->bgc.gc.base = port->id * 32; 301 port->bgc.gc.base = port->id * 32;
294 302
295 err = gpiochip_add(&port->bgc.gc); 303 err = gpiochip_add(&port->bgc.gc);
296 if (err) { 304 if (err)
297 bgpio_remove(&port->bgc); 305 goto out_bgpio_remove;
298 return err;
299 }
300 306
301 return 0; 307 return 0;
308
309out_bgpio_remove:
310 bgpio_remove(&port->bgc);
311out_irqdesc_free:
312 irq_free_descs(irq_base, 32);
313 return err;
302} 314}
303 315
304static struct platform_driver mxs_gpio_driver = { 316static struct platform_driver mxs_gpio_driver = {