Commit 8937cb60 authored by Shawn Guo's avatar Shawn Guo Committed by Grant Likely

gpio/mxc: add device tree probe support

The patch adds device tree probe support for gpio-mxc driver.
Signed-off-by: default avatarShawn Guo <shawn.guo@linaro.org>
Signed-off-by: default avatarGrant Likely <grant.likely@secretlab.ca>
parent 14305e68
* Freescale i.MX/MXC GPIO controller
Required properties:
- compatible : Should be "fsl,<soc>-gpio"
- reg : Address and length of the register set for the device
- interrupts : Should be the port interrupt shared by all 32 pins, if
one number. If two numbers, the first one is the interrupt shared
by low 16 pins and the second one is for high 16 pins.
- gpio-controller : Marks the device node as a gpio controller.
- #gpio-cells : Should be two. The first cell is the pin number and
the second cell is used to specify optional parameters (currently
unused).
Example:
gpio0: gpio@73f84000 {
compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
reg = <0x73f84000 0x4000>;
interrupts = <50 51>;
gpio-controller;
#gpio-cells = <2>;
};
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/basic_mmio_gpio.h> #include <linux/basic_mmio_gpio.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <asm-generic/bug.h> #include <asm-generic/bug.h>
enum mxc_gpio_hwtype { enum mxc_gpio_hwtype {
...@@ -120,6 +122,13 @@ static struct platform_device_id mxc_gpio_devtype[] = { ...@@ -120,6 +122,13 @@ static struct platform_device_id mxc_gpio_devtype[] = {
} }
}; };
static const struct of_device_id mxc_gpio_dt_ids[] = {
{ .compatible = "fsl,imx1-gpio", .data = &mxc_gpio_devtype[IMX1_GPIO], },
{ .compatible = "fsl,imx21-gpio", .data = &mxc_gpio_devtype[IMX21_GPIO], },
{ .compatible = "fsl,imx31-gpio", .data = &mxc_gpio_devtype[IMX31_GPIO], },
{ /* sentinel */ }
};
/* /*
* MX2 has one interrupt *for all* gpio ports. The list is used * MX2 has one interrupt *for all* gpio ports. The list is used
* to save the references to all ports, so that mx2_gpio_irq_handler * 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,7 +311,13 @@ static void __init mxc_gpio_init_gc(struct mxc_gpio_port *port)
static void __devinit mxc_gpio_get_hw(struct platform_device *pdev) static void __devinit mxc_gpio_get_hw(struct platform_device *pdev)
{ {
enum mxc_gpio_hwtype hwtype = pdev->id_entry->driver_data; const struct of_device_id *of_id =
of_match_device(mxc_gpio_dt_ids, &pdev->dev);
enum mxc_gpio_hwtype hwtype;
if (of_id)
pdev->id_entry = of_id->data;
hwtype = pdev->id_entry->driver_data;
if (mxc_gpio_hwtype) { if (mxc_gpio_hwtype) {
/* /*
...@@ -324,6 +339,7 @@ static void __devinit mxc_gpio_get_hw(struct platform_device *pdev) ...@@ -324,6 +339,7 @@ static void __devinit mxc_gpio_get_hw(struct platform_device *pdev)
static int __devinit mxc_gpio_probe(struct platform_device *pdev) static int __devinit mxc_gpio_probe(struct platform_device *pdev)
{ {
struct device_node *np = pdev->dev.of_node;
struct mxc_gpio_port *port; struct mxc_gpio_port *port;
struct resource *iores; struct resource *iores;
int err; int err;
...@@ -334,8 +350,6 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev) ...@@ -334,8 +350,6 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev)
if (!port) if (!port)
return -ENOMEM; return -ENOMEM;
port->virtual_irq_start = MXC_GPIO_IRQ_START + pdev->id * 32;
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!iores) { if (!iores) {
err = -ENODEV; err = -ENODEV;
...@@ -365,9 +379,6 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev) ...@@ -365,9 +379,6 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev)
writel(0, port->base + GPIO_IMR); writel(0, port->base + GPIO_IMR);
writel(~0, port->base + GPIO_ISR); writel(~0, port->base + GPIO_ISR);
/* gpio-mxc can be a generic irq chip */
mxc_gpio_init_gc(port);
if (mxc_gpio_hwtype == IMX21_GPIO) { if (mxc_gpio_hwtype == IMX21_GPIO) {
/* setup one handler for all GPIO interrupts */ /* setup one handler for all GPIO interrupts */
if (pdev->id == 0) if (pdev->id == 0)
...@@ -400,6 +411,16 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev) ...@@ -400,6 +411,16 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev)
if (err) if (err)
goto out_bgpio_remove; goto out_bgpio_remove;
/*
* In dt case, we use gpio number range dynamically
* allocated by gpio core.
*/
port->virtual_irq_start = MXC_GPIO_IRQ_START + (np ? port->bgc.gc.base :
pdev->id * 32);
/* gpio-mxc can be a generic irq chip */
mxc_gpio_init_gc(port);
list_add_tail(&port->node, &mxc_gpio_ports); list_add_tail(&port->node, &mxc_gpio_ports);
return 0; return 0;
...@@ -420,6 +441,7 @@ static struct platform_driver mxc_gpio_driver = { ...@@ -420,6 +441,7 @@ static struct platform_driver mxc_gpio_driver = {
.driver = { .driver = {
.name = "gpio-mxc", .name = "gpio-mxc",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = mxc_gpio_dt_ids,
}, },
.probe = mxc_gpio_probe, .probe = mxc_gpio_probe,
.id_table = mxc_gpio_devtype, .id_table = mxc_gpio_devtype,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment