diff options
| -rw-r--r-- | Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt | 22 | ||||
| -rw-r--r-- | drivers/gpio/gpio-mxc.c | 34 |
2 files changed, 50 insertions, 6 deletions
diff --git a/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt b/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt new file mode 100644 index 000000000000..4363ae4b3c14 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | * Freescale i.MX/MXC GPIO controller | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible : Should be "fsl,<soc>-gpio" | ||
| 5 | - reg : Address and length of the register set for the device | ||
| 6 | - interrupts : Should be the port interrupt shared by all 32 pins, if | ||
| 7 | one number. If two numbers, the first one is the interrupt shared | ||
| 8 | by low 16 pins and the second one is for high 16 pins. | ||
| 9 | - gpio-controller : Marks the device node as a gpio controller. | ||
| 10 | - #gpio-cells : Should be two. The first cell is the pin number and | ||
| 11 | the second cell is used to specify optional parameters (currently | ||
| 12 | unused). | ||
| 13 | |||
| 14 | Example: | ||
| 15 | |||
| 16 | gpio0: gpio@73f84000 { | ||
| 17 | compatible = "fsl,imx51-gpio", "fsl,imx31-gpio"; | ||
| 18 | reg = <0x73f84000 0x4000>; | ||
| 19 | interrupts = <50 51>; | ||
| 20 | gpio-controller; | ||
| 21 | #gpio-cells = <2>; | ||
| 22 | }; | ||
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, |
