dm:gpio:mxc get configuration from dtb
Subsystems (2)
PATCH 1/1 dm:gpio:mxc get configuration from dtb
This patch supports getting gpios' configuration from dtb. CONFIG_OF_CONTROL is used to indicated which part is for device tree, and which is not.
This patch is already tested on mx6sxsabresd board. Since device tree has not been upstreamed, if want to test this patch. The followings need to be done.
+ pieces of code does not gpio_request when using gpio_direction_xxx and etc, need to request gpio.
+ move the gpio settings from board_early_init_f to board_init
+ define CONFIG_DM ,CONFIG_DM_GPIO and CONFIG_OF_CONTROL
+ Add device tree file and do related configuration in
make ARCH=arm menuconfig
--- drivers/gpio/mxc_gpio.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+)
drivers/gpio/mxc_gpio.c +76 -0
@@ -14,6 +14,10 @@#include <asm/arch/imx-regs.h> #include <asm/gpio.h> #include <asm/io.h> +#ifdef CONFIG_OF_CONTROL +#include <fdtdec.h> +DECLARE_GLOBAL_DATA_PTR ; +#endif enum mxc_gpio_direction {MXC_GPIO_DIRECTION_IN ,
@@ -258,6 +262,7 @@ static const struct dm_gpio_ops gpio_mxc_ops = { .get_function = mxc_gpio_get_function, }; +#ifndef CONFIG_OF_CONTROL static const struct mxc_gpio_plat mxc_plat[] = { { (struct gpio_regs *)GPIO1_BASE_ADDR }, { (struct gpio_regs *)GPIO2_BASE_ADDR },
@@ -274,6 +279,7 @@ static const struct mxc_gpio_plat mxc_plat[] = { { (struct gpio_regs *)GPIO7_BASE_ADDR },#endif }; +#endif static int mxc_gpio_probe (struct udevice *dev) {
@@ -283,7 +289,19 @@ static int mxc_gpio_probe(struct udevice *dev)int banknum;char name[18 ], *str; +#ifdef CONFIG_OF_CONTROL +/* +* In dts file add: +* aliases { +* gpio0 = &gpio1; +* gpio1 = &gpio2; +* ..... +* }; +* Then set banknum accoring dev's seq number. */ + banknum = dev->seq; +#else banknum = plat - mxc_plat; +#endif sprintf (name,"GPIO%d_" , banknum +1 ); str =strdup (name);if (!str)
@@ -295,14 +313,71 @@ static int mxc_gpio_probe(struct udevice *dev)return 0 ; } +#ifdef CONFIG_OF_CONTROL +static int mxc_gpio_bind (struct udevice *device) +{ +struct mxc_gpio_plat *plat = device->platdata; +struct gpio_regs *ctrl; + +if (plat) +return 0 ; +/* +* In the dts file, gpiox bank are as following: +* gpio1: gpio at 0209c000 { +* compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; +* reg = <0x0209c000 0x4000>; +* interrupts = <0 66 0x04 0 67 0x04>; +* gpio-controller; +* #gpio-cells = <2>; +* interrupt-controller; +* #interrupt-cells = <2>; +* }; +* +* gpio2: gpio at 020a0000 { +* compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; +* reg = <0x020a0000 0x4000>; +* interrupts = <0 68 0x04 0 69 0x04>; +* gpio-controller; +* #gpio-cells = <2>; +* interrupt-controller; +* #interrupt-cells = <2>; +* }; +* +* gpio1 is the 1st bank, gpio2 is the 2nd bank and gpio3 .... +*/ + + ctrl = (struct gpio_regs *)fdtdec_get_addr (gd->fdt_blob, + device->of_offset,"reg" ); + plat =calloc (1 ,sizeof (*plat)); +if (!plat) +return -ENOMEM ; + + plat->regs = ctrl; + + device->platdata = plat; + +return 0 ; +} + +static const struct udevice_id mxc_gpio_ids[] = { + { .compatible ="fsl,imx35-gpio" }, + { } +}; +#endif +U_BOOT_DRIVER (gpio_mxc) = { .name ="gpio_mxc" , .id =UCLASS_GPIO , .ops = &gpio_mxc_ops, .probe = mxc_gpio_probe, .priv_auto_alloc_size =sizeof (struct mxc_bank_info ), +#ifdef CONFIG_OF_CONTROL + .of_match = mxc_gpio_ids, + .bind = mxc_gpio_bind, +#endif }; +#ifndef CONFIG_OF_CONTROL U_BOOT_DEVICES (mxc_gpios) = { {"gpio_mxc" , &mxc_plat[0 ] }, { "gpio_mxc", &mxc_plat[1] },
@@ -320,3 +395,4 @@ U_BOOT_DEVICES(mxc_gpios) = {#endif };#endif +#endif
Signature · 1 line
1.8.4
PATCH 1/1 dm:gpio:mxc get configuration from dtb
Hi Peng Fan,
Quoted 3 lines · Peng Fan
This patch supports getting gpios' configuration from dtb.
CONFIG_OF_CONTROLis used to indicated which part is for device tree, and which is not.
Can we please avoid the DT #ifdeffery in the drivers? and just implement the needed API stubs?
Quoted 21 lines
This patch is already tested on mx6sxsabresd board. Since device tree has not been upstreamed, if want to test this patch. The followings need to be done.
+ pieces of code does notgpio_requestwhen usinggpio_direction_xxxand etc, need to request gpio.
+ move the gpio settings fromboard_early_init_ftoboard_init
+ defineCONFIG_DM,CONFIG_DM_GPIO andCONFIG_OF_CONTROL
+ Add device tree file and do related configuration in
make ARCH=arm menuconfigSigned-off-by Peng Fan <[email protected]>--- drivers/gpio/mxc_gpio.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+)drivers/gpio/mxc_gpio.c +0
-0
drivers/gpio/mxc_gpio.c line 20
Quoted 7 lines
drivers/gpio/mxc_gpio.c +4
-0@@ -14,6 +14,10 @@#include <asm/arch/imx-regs.h> #include <asm/gpio.h> #include <asm/io.h> +#ifdef CONFIG_OF_CONTROL +#include <fdtdec.h> +DECLARE_GLOBAL_DATA_PTR ; +#endif
Is there a problem to include fdtdec.h with no CONFIG_OF_CONTROL?
Quoted 12 lines
drivers/gpio/mxc_gpio.c +1
-0enum mxc_gpio_direction {MXC_GPIO_DIRECTION_IN ,@@ -258,6 +262,7 @@ static const struct dm_gpio_ops gpio_mxc_ops = { .get_function = mxc_gpio_get_function, }; +#ifndef CONFIG_OF_CONTROL static const struct mxc_gpio_plat mxc_plat[] = { { (struct gpio_regs *)GPIO1_BASE_ADDR }, { (struct gpio_regs *)GPIO2_BASE_ADDR },
drivers/gpio/mxc_gpio.c static const struct mxc_gpio_plat mxc_plat[] = { · line 282
Quoted 4 lines
drivers/gpio/mxc_gpio.c +1
-0@@ -274,6 +279,7 @@ static const struct mxc_gpio_plat mxc_plat[] = { { (struct gpio_regs *)GPIO7_BASE_ADDR },#endif }; +#endif
I think instead of compiling this out, you should reuse it.
Quoted 10 lines
drivers/gpio/mxc_gpio.c +3
-0static int mxc_gpio_probe (struct udevice *dev) {@@ -283,7 +289,19 @@ static int mxc_gpio_probe(struct udevice *dev)int banknum;char name[18 ], *str; +#ifdef CONFIG_OF_CONTROL +/* +* In dts file add:
drivers/gpio/mxc_gpio.c static int mxc_gpio_probe(struct udevice *dev) · line 304
Quoted 10 lines
drivers/gpio/mxc_gpio.c +9
-0+* aliases { +* gpio0 = &gpio1; +* gpio1 = &gpio2; +* ..... +* }; +* Then set banknum accoring dev's seq number. */ + banknum = dev->seq; +#else banknum = plat - mxc_plat; +#endif
Well, I never liked too much that plat - mxc-plat logic, but still I think, you should be able to have one implementation for both cases? There is a good example in doc/driver-model/spi-howto.txt.
Quoted 29 lines
drivers/gpio/mxc_gpio.c +22
-0sprintf (name,"GPIO%d_" , banknum +1 ); str =strdup (name);if (!str)@@ -295,14 +313,71 @@ static int mxc_gpio_probe(struct udevice *dev)return 0 ; } +#ifdef CONFIG_OF_CONTROL +static int mxc_gpio_bind (struct udevice *device) +{ +struct mxc_gpio_plat *plat = device->platdata; +struct gpio_regs *ctrl; + +if (plat) +return 0 ; +/* +* In the dts file, gpiox bank are as following: +* gpio1: gpio at 0209c000 { +* compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; +* reg = <0x0209c000 0x4000>; +* interrupts = <0 66 0x04 0 67 0x04>; +* gpio-controller; +* #gpio-cells = <2>; +* interrupt-controller; +* #interrupt-cells = <2>; +* }; +* +* gpio2: gpio at 020a0000 { +* compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
drivers/gpio/mxc_gpio.c static int mxc_gpio_probe(struct udevice *dev) · line 347
Quoted 10 lines
drivers/gpio/mxc_gpio.c +10
-0+* reg = <0x020a0000 0x4000>; +* interrupts = <0 68 0x04 0 69 0x04>; +* gpio-controller; +* #gpio-cells = <2>; +* interrupt-controller; +* #interrupt-cells = <2>; +* }; +* +* gpio1 is the 1st bank, gpio2 is the 2nd bank and gpio3 .... +*/
The above comment looks not belonging here... but in documentation/dts itself?
drivers/gpio/mxc_gpio.c static int mxc_gpio_probe(struct udevice *dev) · line 350
Quoted 3 lines
drivers/gpio/mxc_gpio.c +3
-0+ + ctrl = (struct gpio_regs *)fdtdec_get_addr (gd->fdt_blob, + device->of_offset,"reg" );
How about implementing a stub for this returning NULL?
Quoted 39 lines
drivers/gpio/mxc_gpio.c +23
-0+ plat =calloc (1 ,sizeof (*plat)); +if (!plat) +return -ENOMEM ; + + plat->regs = ctrl; + + device->platdata = plat; + +return 0 ; +} + +static const struct udevice_id mxc_gpio_ids[] = { + { .compatible ="fsl,imx35-gpio" }, + { } +}; +#endif +U_BOOT_DRIVER (gpio_mxc) = { .name ="gpio_mxc" , .id =UCLASS_GPIO , .ops = &gpio_mxc_ops, .probe = mxc_gpio_probe, .priv_auto_alloc_size =sizeof (struct mxc_bank_info ), +#ifdef CONFIG_OF_CONTROL + .of_match = mxc_gpio_ids, + .bind = mxc_gpio_bind, +#endif }; +#ifndef CONFIG_OF_CONTROL U_BOOT_DEVICES (mxc_gpios) = { {"gpio_mxc" , &mxc_plat[0 ] }, { "gpio_mxc", &mxc_plat[1] },@@ -320,3 +395,4 @@ U_BOOT_DEVICES(mxc_gpios) = {#endif };#endif +#endif
Signature · 2 lines
Regards, Igor.
PATCH 1/1 dm:gpio:mxc get configuration from dtb
In reply to Peng FanHi Peng.
Quoted 4 lines · Peng Fan
This patch supports getting gpios' configuration from dtb.
CONFIG_OF_CONTROLis used to indicated which part is for device tree, and which is not.
Quoted 10 lines
This patch is already tested on mx6sxsabresd board. Since device tree has not been upstreamed, if want to test this patch. The followings need to be done.
+ pieces of code does notgpio_requestwhen usinggpio_direction_xxxand etc, need to request gpio.
+ move the gpio settings fromboard_early_init_ftoboard_init
+ defineCONFIG_DM,CONFIG_DM_GPIO andCONFIG_OF_CONTROL
+ Add device tree file and do related configuration in
make ARCH=arm menuconfig
Sorry I am going to repeat some of Igor's comments...
Quoted 10 lines
Signed-off-by Peng Fan <[email protected]>--- drivers/gpio/mxc_gpio.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+)drivers/gpio/mxc_gpio.c +0
-0
drivers/gpio/mxc_gpio.c line 20
Quoted 7 lines
drivers/gpio/mxc_gpio.c +4
-0@@ -14,6 +14,10 @@#include <asm/arch/imx-regs.h> #include <asm/gpio.h> #include <asm/io.h> +#ifdef CONFIG_OF_CONTROL +#include <fdtdec.h> +DECLARE_GLOBAL_DATA_PTR ; +#endif
Hopefully #ifdef not needed.
Quoted 12 lines
drivers/gpio/mxc_gpio.c +1
-0enum mxc_gpio_direction {MXC_GPIO_DIRECTION_IN ,@@ -258,6 +262,7 @@ static const struct dm_gpio_ops gpio_mxc_ops = { .get_function = mxc_gpio_get_function, }; +#ifndef CONFIG_OF_CONTROL static const struct mxc_gpio_plat mxc_plat[] = { { (struct gpio_regs *)GPIO1_BASE_ADDR }, { (struct gpio_regs *)GPIO2_BASE_ADDR },
drivers/gpio/mxc_gpio.c static const struct mxc_gpio_plat mxc_plat[] = { · line 280
Quoted 2 lines
drivers/gpio/mxc_gpio.c +0
-0@@ -274,6 +279,7 @@ static const struct mxc_gpio_plat mxc_plat[] = { { (struct gpio_regs *)GPIO7_BASE_ADDR }, #endif
Same here.
Quoted 98 lines
drivers/gpio/mxc_gpio.c +70
-0}; +#endif static int mxc_gpio_probe (struct udevice *dev) {@@ -283,7 +289,19 @@ static int mxc_gpio_probe(struct udevice *dev)int banknum;char name[18 ], *str; +#ifdef CONFIG_OF_CONTROL +/* +* In dts file add: +* aliases { +* gpio0 = &gpio1; +* gpio1 = &gpio2; +* ..... +* }; +* Then set banknum accoring dev's seq number. */ + banknum = dev->seq; +#else banknum = plat - mxc_plat; +#endif sprintf (name,"GPIO%d_" , banknum +1 ); str =strdup (name);if (!str)@@ -295,14 +313,71 @@ static int mxc_gpio_probe(struct udevice *dev)return 0 ; } +#ifdef CONFIG_OF_CONTROL +static int mxc_gpio_bind (struct udevice *device) +{ +struct mxc_gpio_plat *plat = device->platdata; +struct gpio_regs *ctrl; + +if (plat) +return 0 ; +/* +* In the dts file, gpiox bank are as following: +* gpio1: gpio at 0209c000 { +* compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; +* reg = <0x0209c000 0x4000>; +* interrupts = <0 66 0x04 0 67 0x04>; +* gpio-controller; +* #gpio-cells = <2>; +* interrupt-controller; +* #interrupt-cells = <2>; +* }; +* +* gpio2: gpio at 020a0000 { +* compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; +* reg = <0x020a0000 0x4000>; +* interrupts = <0 68 0x04 0 69 0x04>; +* gpio-controller; +* #gpio-cells = <2>; +* interrupt-controller; +* #interrupt-cells = <2>; +* }; +* +* gpio1 is the 1st bank, gpio2 is the 2nd bank and gpio3 .... +*/ + + ctrl = (struct gpio_regs *)fdtdec_get_addr (gd->fdt_blob, + device->of_offset,"reg" ); + plat =calloc (1 ,sizeof (*plat)); +if (!plat) +return -ENOMEM ; + + plat->regs = ctrl; + + device->platdata = plat; + +return 0 ; +} + +static const struct udevice_id mxc_gpio_ids[] = { + { .compatible ="fsl,imx35-gpio" }, + { } +}; +#endif +U_BOOT_DRIVER (gpio_mxc) = { .name ="gpio_mxc" , .id =UCLASS_GPIO , .ops = &gpio_mxc_ops, .probe = mxc_gpio_probe, .priv_auto_alloc_size =sizeof (struct mxc_bank_info ), +#ifdef CONFIG_OF_CONTROL + .of_match = mxc_gpio_ids, + .bind = mxc_gpio_bind, +#endif }; +#ifndef CONFIG_OF_CONTROL U_BOOT_DEVICES (mxc_gpios) = { {"gpio_mxc" , &mxc_plat[0 ] }, { "gpio_mxc", &mxc_plat[1] },
drivers/gpio/mxc_gpio.c U_BOOT_DEVICES(mxc_gpios) = { · line 398
Quoted 4 lines
drivers/gpio/mxc_gpio.c +1
-0@@ -320,3 +395,4 @@ U_BOOT_DEVICES(mxc_gpios) = {#endif };#endif +#endif
Overall I wonder why you don't just convert the boards to device tree? It might be more work, but it would be a lot cleaner.
Regards,
Simon
PATCH 1/1 dm:gpio:mxc get configuration from dtb
Hi Simon,
Quoted 17 lines · Simon Glass
Hi Peng.
Quoted 4 lines · Peng Fan
This patch supports getting gpios' configuration from dtb.
CONFIG_OF_CONTROLis used to indicated which part is for device tree, and which is not.Quoted 10 lines
This patch is already tested on mx6sxsabresd board. Since device tree has not been upstreamed, if want to test this patch. The followings need to be done.
+ pieces of code does notgpio_requestwhen usinggpio_direction_xxxand etc, need to request gpio.
+ move the gpio settings fromboard_early_init_ftoboard_init
+ defineCONFIG_DM,CONFIG_DM_GPIO andCONFIG_OF_CONTROL
+ Add device tree file and do related configuration in
make ARCH=arm menuconfig
Quoted 1 line
Sorry I am going to repeat some of Igor's comments...
I've seen Igor's comments.I'll address them.
Quoted 6 lines
Quoted 6 lines
Signed-off-by Peng Fan <[email protected]>--- drivers/gpio/mxc_gpio.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+)
Quoted 13 lines
drivers/gpio/mxc_gpio.c line 20
Quoted 12 lines
drivers/gpio/mxc_gpio.c +4
-0@@ -14,6 +14,10 @@#include <asm/arch/imx-regs.h> #include <asm/gpio.h> #include <asm/io.h> +#ifdef CONFIG_OF_CONTROL +#include <fdtdec.h> +DECLARE_GLOBAL_DATA_PTR ; +#endif Hopefully #ifdef not needed.
Ok. I'll try to remove them in v2 patch.
Quoted 109 lines
Quoted 12 lines
drivers/gpio/mxc_gpio.c +1
-0enum mxc_gpio_direction {MXC_GPIO_DIRECTION_IN ,@@ -258,6 +262,7 @@ static const struct dm_gpio_ops gpio_mxc_ops = { .get_function = mxc_gpio_get_function, }; +#ifndef CONFIG_OF_CONTROL static const struct mxc_gpio_plat mxc_plat[] = { { (struct gpio_regs *)GPIO1_BASE_ADDR }, { (struct gpio_regs *)GPIO2_BASE_ADDR },drivers/gpio/mxc_gpio.c static const struct mxc_gpio_plat mxc_plat[] = { · line 280
Quoted 2 lines
drivers/gpio/mxc_gpio.c +0
-0@@ -274,6 +279,7 @@ static const struct mxc_gpio_plat mxc_plat[] = { { (struct gpio_regs *)GPIO7_BASE_ADDR }, #endifSame here.
Quoted 93 lines
drivers/gpio/mxc_gpio.c +69
-0}; +#endif static int mxc_gpio_probe (struct udevice *dev) {@@ -283,7 +289,19 @@ static int mxc_gpio_probe(struct udevice *dev)int banknum;char name[18 ], *str; +#ifdef CONFIG_OF_CONTROL +/* +* In dts file add: +* aliases { +* gpio0 = &gpio1; +* gpio1 = &gpio2; +* ..... +* }; +* Then set banknum accoring dev's seq number. */ + banknum = dev->seq; +#else banknum = plat - mxc_plat; +#endif sprintf (name,"GPIO%d_" , banknum +1 ); str =strdup (name);if (!str)@@ -295,14 +313,71 @@ static int mxc_gpio_probe(struct udevice *dev)return 0 ; } +#ifdef CONFIG_OF_CONTROL +static int mxc_gpio_bind (struct udevice *device) +{ +struct mxc_gpio_plat *plat = device->platdata; +struct gpio_regs *ctrl; + +if (plat) +return 0 ; +/* +* In the dts file, gpiox bank are as following: +* gpio1: gpio at 0209c000 { +* compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; +* reg = <0x0209c000 0x4000>; +* interrupts = <0 66 0x04 0 67 0x04>; +* gpio-controller; +* #gpio-cells = <2>; +* interrupt-controller; +* #interrupt-cells = <2>; +* }; +* +* gpio2: gpio at 020a0000 { +* compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio"; +* reg = <0x020a0000 0x4000>; +* interrupts = <0 68 0x04 0 69 0x04>; +* gpio-controller; +* #gpio-cells = <2>; +* interrupt-controller; +* #interrupt-cells = <2>; +* }; +* +* gpio1 is the 1st bank, gpio2 is the 2nd bank and gpio3 .... +*/ + + ctrl = (struct gpio_regs *)fdtdec_get_addr (gd->fdt_blob, + device->of_offset,"reg" ); + plat =calloc (1 ,sizeof (*plat)); +if (!plat) +return -ENOMEM ; + + plat->regs = ctrl; + + device->platdata = plat; + +return 0 ; +} + +static const struct udevice_id mxc_gpio_ids[] = { + { .compatible ="fsl,imx35-gpio" }, + { } +}; +#endif +U_BOOT_DRIVER (gpio_mxc) = { .name ="gpio_mxc" , .id =UCLASS_GPIO , .ops = &gpio_mxc_ops, .probe = mxc_gpio_probe, .priv_auto_alloc_size =sizeof (struct mxc_bank_info ), +#ifdef CONFIG_OF_CONTROL + .of_match = mxc_gpio_ids, + .bind = mxc_gpio_bind, +#endif };
Quoted 11 lines
drivers/gpio/mxc_gpio.c U_BOOT_DEVICES(mxc_gpios) = { · line 398
Quoted 9 lines
drivers/gpio/mxc_gpio.c +2
-0+#ifndef CONFIG_OF_CONTROL U_BOOT_DEVICES (mxc_gpios) = { {"gpio_mxc" , &mxc_plat[0 ] }, { "gpio_mxc", &mxc_plat[1] },@@ -320,3 +395,4 @@ U_BOOT_DEVICES(mxc_gpios) = {#endif };#endif +#endif Overall I wonder why you don't just convert the boards to device tree? It might be more work, but it would be a lot cleaner.
Yeah. Agree. Converting the boards to device tree may require lots of change, I am just hacking this in my side for personal interests.
Anyway, I'll try to address you all comments to make it better.
Quoted 3 lines
Regards,
Simon
Regards,
Peng.