Add device tree support for gpio-mxs
Subsystems (5)
cover Add device tree support for gpio-mxs
This patch series cleans up gpio-mxs a bit, and then adds device tree support for the driver. Currently, the irqdomain for gpio is still added in platform code, and should be moved into driver later with the help from the generic-irq-chip irqdomain support.
It's based on mxs device tree branch, and might be easier to go via arm-soc tree.
Shawn Guo (4):
gpio/mxs: use devm_* helpers to make error handling simple gpio/mxs: get rid of the use of cpu_is_xxx gpio/mxs: add device tree probe
ARM: mxs: add gpio support for device tree boot
.../devicetree/bindings/gpio/gpio-mxs.txt | 87 +++++++++++ arch/arm/boot/dts/imx23.dtsi | 35 +++++- arch/arm/boot/dts/imx28.dtsi | 55 +++++++- arch/arm/mach-mxs/devices/platform-gpio-mxs.c | 24 +--- arch/arm/mach-mxs/include/mach/common.h | 5 +- arch/arm/mach-mxs/mach-mxs.c | 12 ++ arch/arm/mach-mxs/mm.c | 10 ++ drivers/gpio/gpio-mxs.c | 156 ++++++++++++-------- 8 files changed, 296 insertions(+), 88 deletions(-) create mode 100644 Documentation/devicetree/bindings/gpio/gpio-mxs.txt
Signature · 1 line
1.7.5.4
PATCH 1/4 gpio/mxs: use devm_* helpers to make error handling simple
It uses devm_* helpers to make the error handling of probe clean and simple.
--- drivers/gpio/gpio-mxs.c | 52 +++++++++++----------------------------------- 1 files changed, 13 insertions(+), 39 deletions(-)
drivers/gpio/gpio-mxs.c +13 -39
@@ -186,44 +186,29 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)struct resource *iores =NULL ;int err; - port =kzalloc (sizeof (struct mxs_gpio_port ),GFP_KERNEL ); + port =devm_kzalloc (&pdev->dev,sizeof (*port),GFP_KERNEL );if (!port)return -ENOMEM ; port->id = pdev->id; port->virtual_irq_start =MXS_GPIO_IRQ_START + port->id *32 ; + port->irq =platform_get_irq (pdev,0 ); +if (port->irq <0 ) +return port->irq; +/* * map memory region only once, as all the gpio ports * share the same one */ if (!base) { iores =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); -if (!iores) { - err = -ENODEV ; - goto out_kfree; - } - -if (!request_mem_region (iores->start,resource_size (iores), - pdev->name)) { - err = -EBUSY ; - goto out_kfree; - } - - base =ioremap (iores->start,resource_size (iores)); -if (!base) { - err = -ENOMEM ; - goto out_release_mem; - } + base =devm_request_and_ioremap (&pdev->dev, iores); +if (!base) +return -EADDRNOTAVAIL ; } port->base = base; - port->irq =platform_get_irq (pdev,0 ); -if (port->irq <0 ) { - err = -EINVAL ; - goto out_iounmap; - } -/* * select the pin interrupt functionality but initially * disable the interrupts
@@ -246,29 +231,18 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev) port->base +PINCTRL_DOUT (port->id),NULL , port->base + PINCTRL_DOE(port->id), NULL, false);if (err) - goto out_iounmap; +return err; port->bgc.gc.to_irq = mxs_gpio_to_irq; port->bgc.gc.base = port->id *32 ; err =gpiochip_add (&port->bgc.gc); -if (err) - goto out_bgpio_remove; +if (err) { +bgpio_remove (&port->bgc); +return err; + }return 0 ; - -out_bgpio_remove: -bgpio_remove (&port->bgc); -out_iounmap: -if (iores) -iounmap (port->base); -out_release_mem: -if (iores) -release_mem_region (iores->start,resource_size (iores)); -out_kfree: -kfree (port); -dev_info (&pdev->dev,"%s failed with errno %d\n" , __func__, err); -return err; }static struct platform_driver mxs_gpio_driver = {
Signature · 1 line
1.7.5.4
PATCH 2/4 gpio/mxs: get rid of the use of cpu_is_xxx
In reply to Shawn GuoIt removes the use of cpu_is_xxx from gpio-mxs driver and instead use platform_device_id to identify the device. Accordingly, mxs platform code is changed to register gpio device with different names, and the registeration are done in soc specific initialization functions now, so postcore_initcall(mxs_add_mxs_gpio) gets removed.
--- arch/arm/mach-mxs/devices/platform-gpio-mxs.c | 24 +------- arch/arm/mach-mxs/include/mach/common.h | 5 +- arch/arm/mach-mxs/mm.c | 10 +++ drivers/gpio/gpio-mxs.c | 74 +++++++++++++++++------- 4 files changed, 67 insertions(+), 46 deletions(-)
arch/arm/mach-mxs/devices/platform-gpio-mxs.c +2 -22
@@ -14,7 +14,7 @@#include <mach/devices-common.h> struct platform_device *__init mxs_add_gpio ( -int id,resource_size_t iobase,int irq) +char *name,int id,resource_size_t iobase,int irq) {struct resource res[] = { {
@@ -29,25 +29,5 @@ struct platform_device *__init mxs_add_gpio( };return platform_device_register_resndata (&mxs_apbh_bus, -"gpio-mxs" , id, res,ARRAY_SIZE (res),NULL ,0 ); + name, id, res,ARRAY_SIZE (res),NULL ,0 ); } - -static int __init mxs_add_mxs_gpio (void ) -{ -if (cpu_is_mx23 ()) { -mxs_add_gpio (0 ,MX23_PINCTRL_BASE_ADDR ,MX23_INT_GPIO0 ); -mxs_add_gpio (1 ,MX23_PINCTRL_BASE_ADDR ,MX23_INT_GPIO1 ); -mxs_add_gpio (2 ,MX23_PINCTRL_BASE_ADDR ,MX23_INT_GPIO2 ); - } - -if (cpu_is_mx28 ()) { -mxs_add_gpio (0 ,MX28_PINCTRL_BASE_ADDR ,MX28_INT_GPIO0 ); -mxs_add_gpio (1 ,MX28_PINCTRL_BASE_ADDR ,MX28_INT_GPIO1 ); -mxs_add_gpio (2 ,MX28_PINCTRL_BASE_ADDR ,MX28_INT_GPIO2 ); -mxs_add_gpio (3 ,MX28_PINCTRL_BASE_ADDR ,MX28_INT_GPIO3 ); -mxs_add_gpio (4 ,MX28_PINCTRL_BASE_ADDR ,MX28_INT_GPIO4 ); - } - -return 0 ; -} -postcore_initcall (mxs_add_mxs_gpio);
arch/arm/mach-mxs/include/mach/common.h +3 -2
@@ -20,13 +20,11 @@ extern void mxs_restart(char, const char *);extern int mxs_saif_clkmux_select (unsigned int clkmux);extern void mx23_soc_init (void ); -extern int mx23_register_gpios (void );extern int mx23_clocks_init (void );extern void mx23_map_io (void );extern void mx23_init_irq (void );extern void mx28_soc_init (void ); -extern int mx28_register_gpios (void );extern int mx28_clocks_init (void );extern void mx28_map_io (void );extern void mx28_init_irq (void );
@@ -37,4 +35,7 @@ extern int mxs_clkctrl_timeout(unsigned int reg_offset, unsigned int mask);extern struct platform_device *mxs_add_dma (const char *devid,resource_size_t base); +extern struct platform_device *mxs_add_gpio (char *name,int id, +resource_size_t iobase,int irq); +#endif /* __MACH_MXS_COMMON_H__ */
arch/arm/mach-mxs/mm.c +10 -0
@@ -66,10 +66,20 @@ void __init mx23_soc_init(void) {mxs_add_dma ("imx23-dma-apbh" ,MX23_APBH_DMA_BASE_ADDR );mxs_add_dma ("imx23-dma-apbx" ,MX23_APBX_DMA_BASE_ADDR ); + +mxs_add_gpio ("imx23-gpio" ,0 ,MX23_PINCTRL_BASE_ADDR ,MX23_INT_GPIO0 ); +mxs_add_gpio ("imx23-gpio" ,1 ,MX23_PINCTRL_BASE_ADDR ,MX23_INT_GPIO1 ); +mxs_add_gpio ("imx23-gpio" ,2 ,MX23_PINCTRL_BASE_ADDR ,MX23_INT_GPIO2 ); }void __init mx28_soc_init (void ) {mxs_add_dma ("imx28-dma-apbh" ,MX23_APBH_DMA_BASE_ADDR );mxs_add_dma ("imx28-dma-apbx" ,MX23_APBX_DMA_BASE_ADDR ); + +mxs_add_gpio ("imx28-gpio" ,0 ,MX28_PINCTRL_BASE_ADDR ,MX28_INT_GPIO0 ); +mxs_add_gpio ("imx28-gpio" ,1 ,MX28_PINCTRL_BASE_ADDR ,MX28_INT_GPIO1 ); +mxs_add_gpio ("imx28-gpio" ,2 ,MX28_PINCTRL_BASE_ADDR ,MX28_INT_GPIO2 ); +mxs_add_gpio ("imx28-gpio" ,3 ,MX28_PINCTRL_BASE_ADDR ,MX28_INT_GPIO3 ); +mxs_add_gpio ("imx28-gpio" ,4 ,MX28_PINCTRL_BASE_ADDR ,MX28_INT_GPIO4 ); }
drivers/gpio/gpio-mxs.c +52 -22
160 lines not on this page · raw message
Signature · 1 line
1.7.5.4
PATCH 3/4 gpio/mxs: add device tree probe
In reply to Shawn GuoIt adds device tree probe for gpio-mxs driver.
--- .../devicetree/bindings/gpio/gpio-mxs.txt | 87 ++++++++++++++++++++ drivers/gpio/gpio-mxs.c | 36 +++++++- 2 files changed, 119 insertions(+), 4 deletions(-) create mode 100644 Documentation/devicetree/bindings/gpio/gpio-mxs.txt
Documentation/devicetree/bindings/gpio/gpio-mxs.txt new file +87 -0
@@ -0,0 +1,87 @@ +* Freescale MXS GPIO controller + +The Freescale MXS GPIO controller is part of MXS PIN controller. The +GPIOs are organized in port/bank. Each port consists of 32 GPIOs. + +As the GPIO controller is embedded in the PIN controller and all the +GPIO ports share the same IO space with PIN controller, the GPIO node +will be represented as sub-nodes of MXS pinctrl node. + +Required properties for GPIO node: +- compatible : Should be "fsl,<soc>-gpio". The supported SoCs include + imx23 and imx28. +- interrupts : Should be the port interrupt shared by all 32 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). +- interrupt-controller: Marks the device node as an interrupt controller. +- #interrupt-cells : Should be 2. The first cell is the GPIO number. + The second cell bits[3:0] is used to specify trigger type and level flags: + 1 = low-to-high edge triggered. + 2 = high-to-low edge triggered. + 4 = active high level-sensitive. + 8 = active low level-sensitive. + +Note: Each GPIO port should have an alias correctly numbered in "aliases" +node. + +Examples: + +aliases { + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + gpio3 = &gpio3; + gpio4 = &gpio4; +}; + +pinctrl at 80018000 { + compatible = "fsl,imx28-pinctrl", "simple-bus"; + reg = <0x80018000 2000>; + + gpio0: gpio at 0 { + compatible = "fsl,imx28-gpio"; + interrupts = <127>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio1: gpio at 1 { + compatible = "fsl,imx28-gpio"; + interrupts = <126>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio2: gpio at 2 { + compatible = "fsl,imx28-gpio"; + interrupts = <125>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio3: gpio at 3 { + compatible = "fsl,imx28-gpio"; + interrupts = <124>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio4: gpio at 4 { + compatible = "fsl,imx28-gpio"; + interrupts = <123>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; +};
drivers/gpio/gpio-mxs.c +32 -4
@@ -25,6 +25,9 @@#include <linux/io.h> #include <linux/irq.h> #include <linux/gpio.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/basic_mmio_gpio.h>
@@ -207,8 +210,19 @@ static struct platform_device_id mxs_gpio_ids[] = { };MODULE_DEVICE_TABLE (platform, mxs_gpio_ids); +static const struct of_device_id mxs_gpio_dt_ids[] = { + { .compatible ="fsl,imx23-gpio" , .data = (void *)IMX23_GPIO , }, + { .compatible ="fsl,imx28-gpio" , .data = (void *)IMX28_GPIO , }, + {/* sentinel */ } +}; +MODULE_DEVICE_TABLE (of, mxs_gpio_dt_ids); +static int __devinit mxs_gpio_probe (struct platform_device *pdev) { +const struct of_device_id *of_id = +of_match_device (mxs_gpio_dt_ids, &pdev->dev); +struct device_node *np = pdev->dev.of_node; +struct device_node *parent;static void __iomem *base;struct mxs_gpio_port *port;struct resource *iores =NULL ;
@@ -218,8 +232,15 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)if (!port)return -ENOMEM ; - port->id = pdev->id; - port->devid = pdev->id_entry->driver_data; +if (np) { + port->id =of_alias_get_id (np,"gpio" ); +if (port->id <0 ) +return port->id; + port->devid = (enum mxs_gpio_id ) of_id->data; + }else { + port->id = pdev->id; + port->devid = pdev->id_entry->driver_data; + } port->virtual_irq_start =MXS_GPIO_IRQ_START + port->id *32 ; port->irq =platform_get_irq (pdev,0 );
@@ -231,8 +252,14 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)* share the same one */ if (!base) { - iores =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); - base =devm_request_and_ioremap (&pdev->dev, iores); +if (np) { + parent =of_get_parent (np); + base =of_iomap (parent,0 ); +of_node_put (parent); + }else { + iores =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); + base =devm_request_and_ioremap (&pdev->dev, iores); + }if (!base)return -EADDRNOTAVAIL ; }
@@ -278,6 +305,7 @@ static struct platform_driver mxs_gpio_driver = { .driver = { .name = "gpio-mxs", .owner = THIS_MODULE, + .of_match_table = mxs_gpio_dt_ids, }, .probe = mxs_gpio_probe, .id_table = mxs_gpio_ids,
Signature · 1 line
1.7.5.4
PATCH 4/4 ARM: mxs: add gpio support for device tree boot
In reply to Shawn GuoIt adds gpio support for device tree boot.
--- arch/arm/boot/dts/imx23.dtsi | 35 ++++++++++++++++++++++++++- arch/arm/boot/dts/imx28.dtsi | 55 +++++++++++++++++++++++++++++++++++++++++- arch/arm/mach-mxs/mach-mxs.c | 12 +++++++++ 3 files changed, 100 insertions(+), 2 deletions(-)
arch/arm/boot/dts/imx23.dtsi +34 -1
@@ -14,6 +14,12 @@ / { interrupt-parent = <&icoll>; + aliases { + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + }; + cpus { cpu at 0 { compatible = "arm,arm926ejs";
@@ -72,8 +78,35 @@ }; pinctrl at 80018000 { + compatible = "fsl,imx23-pinctrl", "simple-bus"; reg = <0x80018000 2000>; - status = "disabled"; + + gpio0: gpio at 0 { + compatible = "fsl,imx23-gpio", "fsl,mxs-gpio"; + interrupts = <16>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio1: gpio at 1 { + compatible = "fsl,imx23-gpio", "fsl,mxs-gpio"; + interrupts = <17>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio2: gpio at 2 { + compatible = "fsl,imx23-gpio", "fsl,mxs-gpio"; + interrupts = <18>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; }; digctl at 8001c000 {
arch/arm/boot/dts/imx28.dtsi +54 -1
68 lines not on this page · raw message
arch/arm/mach-mxs/mach-mxs.c +12 -0
@@ -26,8 +26,20 @@ static int __init mxs_icoll_add_irq_domain(struct device_node *np,return 0 ; } +static int __init mxs_gpio_add_irq_domain (struct device_node *np, +struct device_node *interrupt_parent) +{ +static int gpio_irq_base =MXS_GPIO_IRQ_START ; + +irq_domain_add_legacy (np,32 , gpio_irq_base,0 , &irq_domain_simple_ops,NULL ); + gpio_irq_base +=32 ; + +return 0 ; +} +static const struct of_device_id mxs_irq_match[]__initconst = { { .compatible ="fsl,mxs-icoll" , .data = mxs_icoll_add_irq_domain, }, + { .compatible ="fsl,mxs-gpio" , .data = mxs_gpio_add_irq_domain, }, {/* sentinel */ } };
Signature · 1 line
1.7.5.4
cover Add device tree support for gpio-mxs
In reply to Shawn GuoQuoted 7 lines · Shawn Guo
This patch series cleans up gpio-mxs a bit, and then adds device tree support for the driver. ?Currently, the irqdomain for gpio is still added in platform code, and should be moved into driver later with the help from the generic-irq-chip irqdomain support.
It's based on mxs device tree branch, and might be easier to go via arm-soc tree.
This all looks good to me.
Yours,
Linus Walleij
cover Add device tree support for gpio-mxs
Quoted 7 lines · Linus Walleij
Quoted 5 lines · Shawn Guo
This patch series cleans up gpio-mxs a bit, and then adds device tree support for the driver. ??Currently, the irqdomain for gpio is still added in platform code, and should be moved into driver later with the help from the generic-irq-chip irqdomain support.
Quoted 5 lines
Quoted 2 lines
It's based on mxs device tree branch, and might be easier to go via arm-soc tree.
This all looks good to me.
Acked-by Linus Walleij <[email protected]>
Same here.
For all 4 patches and for the pinmux one you posted later. Feel free to merge them via arm-soc.
g.