diff options
author | Shawn Guo <shawn.guo@linaro.org> | 2011-07-06 12:37:43 -0400 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2011-07-08 14:38:18 -0400 |
commit | 8937cb602bea120248cef64961fc46836a394c8a (patch) | |
tree | dff8c06485812bf1316a7da37c3f690f313b4508 /drivers/gpio/gpio-mxc.c | |
parent | 14305e685dff531583e95c5076f633f2fe2b141c (diff) |
gpio/mxc: add device tree probe support
The patch adds device tree probe support for gpio-mxc driver.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
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 | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index 3775dccef4ad..89fda58db90d 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/basic_mmio_gpio.h> | 29 | #include <linux/basic_mmio_gpio.h> |
30 | #include <linux/of.h> | ||
31 | #include <linux/of_device.h> | ||
30 | #include <asm-generic/bug.h> | 32 | #include <asm-generic/bug.h> |
31 | 33 | ||
32 | enum mxc_gpio_hwtype { | 34 | enum mxc_gpio_hwtype { |
@@ -120,6 +122,13 @@ static struct platform_device_id mxc_gpio_devtype[] = { | |||
120 | } | 122 | } |
121 | }; | 123 | }; |
122 | 124 | ||
125 | static const struct of_device_id mxc_gpio_dt_ids[] = { | ||
126 | { .compatible = "fsl,imx1-gpio", .data = &mxc_gpio_devtype[IMX1_GPIO], }, | ||
127 | { .compatible = "fsl,imx21-gpio", .data = &mxc_gpio_devtype[IMX21_GPIO], }, | ||
128 | { .compatible = "fsl,imx31-gpio", .data = &mxc_gpio_devtype[IMX31_GPIO], }, | ||
129 | { /* sentinel */ } | ||
130 | }; | ||
131 | |||
123 | /* | 132 | /* |
124 | * MX2 has one interrupt *for all* gpio ports. The list is used | 133 | * MX2 has one interrupt *for all* gpio ports. The list is used |
125 | * to save the references to all ports, so that mx2_gpio_irq_handler | 134 | * to save the references to all ports, so that mx2_gpio_irq_handler |
@@ -302,7 +311,13 @@ static void __init mxc_gpio_init_gc(struct mxc_gpio_port *port) | |||
302 | 311 | ||
303 | static void __devinit mxc_gpio_get_hw(struct platform_device *pdev) | 312 | static void __devinit mxc_gpio_get_hw(struct platform_device *pdev) |
304 | { | 313 | { |
305 | enum mxc_gpio_hwtype hwtype = pdev->id_entry->driver_data; | 314 | const struct of_device_id *of_id = |
315 | of_match_device(mxc_gpio_dt_ids, &pdev->dev); | ||
316 | enum mxc_gpio_hwtype hwtype; | ||
317 | |||
318 | if (of_id) | ||
319 | pdev->id_entry = of_id->data; | ||
320 | hwtype = pdev->id_entry->driver_data; | ||
306 | 321 | ||
307 | if (mxc_gpio_hwtype) { | 322 | if (mxc_gpio_hwtype) { |
308 | /* | 323 | /* |
@@ -324,6 +339,7 @@ static void __devinit mxc_gpio_get_hw(struct platform_device *pdev) | |||
324 | 339 | ||
325 | static int __devinit mxc_gpio_probe(struct platform_device *pdev) | 340 | static int __devinit mxc_gpio_probe(struct platform_device *pdev) |
326 | { | 341 | { |
342 | struct device_node *np = pdev->dev.of_node; | ||
327 | struct mxc_gpio_port *port; | 343 | struct mxc_gpio_port *port; |
328 | struct resource *iores; | 344 | struct resource *iores; |
329 | int err; | 345 | int err; |
@@ -334,8 +350,6 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev) | |||
334 | if (!port) | 350 | if (!port) |
335 | return -ENOMEM; | 351 | return -ENOMEM; |
336 | 352 | ||
337 | port->virtual_irq_start = MXC_GPIO_IRQ_START + pdev->id * 32; | ||
338 | |||
339 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 353 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
340 | if (!iores) { | 354 | if (!iores) { |
341 | err = -ENODEV; | 355 | err = -ENODEV; |
@@ -365,9 +379,6 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev) | |||
365 | writel(0, port->base + GPIO_IMR); | 379 | writel(0, port->base + GPIO_IMR); |
366 | writel(~0, port->base + GPIO_ISR); | 380 | writel(~0, port->base + GPIO_ISR); |
367 | 381 | ||
368 | /* gpio-mxc can be a generic irq chip */ | ||
369 | mxc_gpio_init_gc(port); | ||
370 | |||
371 | if (mxc_gpio_hwtype == IMX21_GPIO) { | 382 | if (mxc_gpio_hwtype == IMX21_GPIO) { |
372 | /* setup one handler for all GPIO interrupts */ | 383 | /* setup one handler for all GPIO interrupts */ |
373 | if (pdev->id == 0) | 384 | if (pdev->id == 0) |
@@ -400,6 +411,16 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev) | |||
400 | if (err) | 411 | if (err) |
401 | goto out_bgpio_remove; | 412 | goto out_bgpio_remove; |
402 | 413 | ||
414 | /* | ||
415 | * In dt case, we use gpio number range dynamically | ||
416 | * allocated by gpio core. | ||
417 | */ | ||
418 | port->virtual_irq_start = MXC_GPIO_IRQ_START + (np ? port->bgc.gc.base : | ||
419 | pdev->id * 32); | ||
420 | |||
421 | /* gpio-mxc can be a generic irq chip */ | ||
422 | mxc_gpio_init_gc(port); | ||
423 | |||
403 | list_add_tail(&port->node, &mxc_gpio_ports); | 424 | list_add_tail(&port->node, &mxc_gpio_ports); |
404 | 425 | ||
405 | return 0; | 426 | return 0; |
@@ -420,6 +441,7 @@ static struct platform_driver mxc_gpio_driver = { | |||
420 | .driver = { | 441 | .driver = { |
421 | .name = "gpio-mxc", | 442 | .name = "gpio-mxc", |
422 | .owner = THIS_MODULE, | 443 | .owner = THIS_MODULE, |
444 | .of_match_table = mxc_gpio_dt_ids, | ||
423 | }, | 445 | }, |
424 | .probe = mxc_gpio_probe, | 446 | .probe = mxc_gpio_probe, |
425 | .id_table = mxc_gpio_devtype, | 447 | .id_table = mxc_gpio_devtype, |