vf610: Add GPIO support
Subsystems (4)
v3 cover vf610: Add GPIO support
This 3rd version of the GPIO support for Vybrid now also includes the wakeup support which was part of the suspend/resume patchset I sent earlier this week.
Changes in v3:
- Configure the pin completely on imx_pmx_gpio_request_enable
- Drop the GPIO_CONTROL flag in favor of using the existing SHARE_MUX_CONF_REG flag
- Extend GPIO driver to also include wakeup support
- Cleanup includes in GPIO driver file
- Add brackets in PORT_PCR define
- Use platform_get_irq in favor of irq_of_parse_and_map
- Use device_initcall instead of subsys_initicall
Changes in v2:
- Use bit operations in GPIO driver
- Use VF610_ prefix for GPIOS_PER_PORT define
- Drop irq in drivers struct
- Use arch/subsys_initicall for GPIO/pinctrl driver
- Fix log message title
- Add documentation for GPIO/PORT module bindings
- Extended GPIO device tree bindings for Colibri VF61
Stefan Agner (5):
pinctrl: imx: detect uninitialized pins
pinctrl: imx: add gpio pinmux support for vf610
gpio: vf610: add gpiolib/IRQ chip driver for Vybrid
ARM: dts: vf610: use new GPIO support
Documentation: dts: add bindings for Vybrid GPIO/PORT module
.../devicetree/bindings/gpio/gpio-vf610.txt | 56 ++++ arch/arm/boot/dts/vf610-colibri.dtsi | 9 + arch/arm/boot/dts/vf610-twr.dts | 1 + arch/arm/boot/dts/vf610.dtsi | 1 + drivers/gpio/Kconfig | 7 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-vf610.c | 295 +++++++++++++++++++++ drivers/pinctrl/pinctrl-imx.c | 81 +++++- drivers/pinctrl/pinctrl-imx.h | 7 +- drivers/pinctrl/pinctrl-vf610.c | 2 +- 10 files changed, 451 insertions(+), 9 deletions(-) create mode 100644 Documentation/devicetree/bindings/gpio/gpio-vf610.txt create mode 100644 drivers/gpio/gpio-vf610.c
Signature · 1 line
2.1.0
PATCH v3 1/5 pinctrl: imx: detect uninitialized pins
The pinctrl driver initialized the register offsets for the pins with 0. On Vybrid an offset of 0 is a valid offset for the pinctrl mux register. So far, this was solved using the ZERO_OFFSET_VALID flag which allowed offsets of 0. However, this does not allow to verify whether a pins struct imx_pmx_func was initialized or not.
Use signed offset values for register offsets and initialize those with -1 in order to detect uninitialized offset values reliable.
--- drivers/pinctrl/pinctrl-imx.c | 9 +++++---- drivers/pinctrl/pinctrl-imx.h | 7 +++---- drivers/pinctrl/pinctrl-vf610.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-)
drivers/pinctrl/pinctrl-imx.c +5 -4
@@ -204,7 +204,7 @@ static int imx_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector, pin_id = pin->pin; pin_reg = &info->pin_regs[pin_id]; -if (!(info->flags &ZERO_OFFSET_VALID ) && !pin_reg->mux_reg) { +if (pin_reg->mux_reg ==-1 ) {dev_err (ipctl->dev,"Pin(%s) does not support mux function\n" , info->pins[pin_id].name);return -EINVAL ;
@@ -308,7 +308,7 @@ static int imx_pinconf_get(struct pinctrl_dev *pctldev,const struct imx_pinctrl_soc_info *info = ipctl->info;const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id]; -if (!(info->flags &ZERO_OFFSET_VALID ) && !pin_reg->conf_reg) { +if (pin_reg->conf_reg ==-1 ) {dev_err (info->dev,"Pin(%s) does not support config function\n" , info->pins[pin_id].name);return -EINVAL ;
@@ -331,7 +331,7 @@ static int imx_pinconf_set(struct pinctrl_dev *pctldev,const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id];int i; -if (!(info->flags &ZERO_OFFSET_VALID ) && !pin_reg->conf_reg) { +if (pin_reg->conf_reg ==-1 ) {dev_err (info->dev,"Pin(%s) does not support config function\n" , info->pins[pin_id].name);return -EINVAL ;
@@ -586,10 +586,11 @@ int imx_pinctrl_probe(struct platform_device *pdev,if (!ipctl)return -ENOMEM ; - info->pin_regs =devm_kzalloc (&pdev->dev,sizeof (*info->pin_regs) * + info->pin_regs =devm_kmalloc (&pdev->dev,sizeof (*info->pin_regs) * info->npins,GFP_KERNEL );if (!info->pin_regs)return -ENOMEM ; +memset (info->pin_regs,0xff ,sizeof (*info->pin_regs) * info->npins); res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); ipctl->base =devm_ioremap_resource (&pdev->dev, res);
drivers/pinctrl/pinctrl-imx.h +3 -4
@@ -67,8 +67,8 @@ struct imx_pmx_func {* @conf_reg: config register offset */ struct imx_pin_reg { -u16 mux_reg; -u16 conf_reg; +s16 mux_reg; +s16 conf_reg; };struct imx_pinctrl_soc_info {
@@ -83,8 +83,7 @@ struct imx_pinctrl_soc_info {unsigned int flags; }; -#define ZERO_OFFSET_VALID 0x1 -#define SHARE_MUX_CONF_REG 0x2 +#define SHARE_MUX_CONF_REG 0x1#define NO_MUX 0x0#define NO_PAD 0x0
drivers/pinctrl/pinctrl-vf610.c +1 -1
@@ -299,7 +299,7 @@ static const struct pinctrl_pin_desc vf610_pinctrl_pads[] = {static struct imx_pinctrl_soc_info vf610_pinctrl_info = { .pins = vf610_pinctrl_pads, .npins =ARRAY_SIZE (vf610_pinctrl_pads), - .flags =ZERO_OFFSET_VALID |SHARE_MUX_CONF_REG , + .flags =SHARE_MUX_CONF_REG , };static struct of_device_id vf610_pinctrl_of_match[] = {
Signature · 1 line
2.1.0
PATCH v3 2/5 pinctrl: imx: add gpio pinmux support for vf610
In reply to Stefan AgnerAdd pinmux support for GPIO for Vybrid (vf610) IOMUX controller. This is needed since direction configuration is not part of the GPIO module in Vybrid.
--- drivers/pinctrl/pinctrl-imx.c | 72 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+)
drivers/pinctrl/pinctrl-imx.c +72 -0
@@ -294,10 +294,82 @@ static int imx_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector,return 0 ; } +static int imx_pmx_gpio_request_enable (struct pinctrl_dev *pctldev, +struct pinctrl_gpio_range *range,unsigned offset) +{ +struct imx_pinctrl *ipctl =pinctrl_dev_get_drvdata (pctldev); +const struct imx_pinctrl_soc_info *info = ipctl->info; +const struct imx_pin_reg *pin_reg; +struct imx_pin_group *grp; +struct imx_pin *imx_pin; +unsigned int pin, group; +u32 reg; + +/* Currently implementation only for shared mux/conf register */ +if (!(info->flags &SHARE_MUX_CONF_REG )) +return -EINVAL ; + + pin_reg = &info->pin_regs[offset]; +if (pin_reg->mux_reg ==-1 ) +return -EINVAL ; + +/* Find the pinctrl config with GPIO mux mode for the requested pin */ +for (group =0 ; group < info->ngroups; group++) { + grp = &info->groups[group]; +for (pin =0 ; pin < grp->npins; pin++) { + imx_pin = &grp->pins[pin]; +if (imx_pin->pin == offset && !imx_pin->mux_mode) + goto mux_pin; + } + } + +return -EINVAL ; + +mux_pin: + reg =readl (ipctl->base + pin_reg->mux_reg); + reg &= ~(0x7 <<20 ); + reg |= imx_pin->config; +writel (reg, ipctl->base + pin_reg->mux_reg); + +return 0 ; +} + +static int imx_pmx_gpio_set_direction (struct pinctrl_dev *pctldev, +struct pinctrl_gpio_range *range,unsigned offset,bool input) +{ +struct imx_pinctrl *ipctl =pinctrl_dev_get_drvdata (pctldev); +const struct imx_pinctrl_soc_info *info = ipctl->info; +const struct imx_pin_reg *pin_reg; +u32 reg; + +/* +* Only Vybrid has the input/output buffer enable flags (IBE/OBE) +* They are part of the shared mux/conf register. +*/ +if (!(info->flags &SHARE_MUX_CONF_REG )) +return -EINVAL ; + + pin_reg = &info->pin_regs[offset]; +if (pin_reg->mux_reg ==-1 ) +return -EINVAL ; + +/* IBE always enabled allows us to read the value "on the wire" */ + reg =readl (ipctl->base + pin_reg->mux_reg); +if (input) + reg &= ~0x2 ; +else + reg |=0x2 ; +writel (reg, ipctl->base + pin_reg->mux_reg); + +return 0 ; +} +static const struct pinmux_ops imx_pmx_ops = { .get_functions_count = imx_pmx_get_funcs_count, .get_function_name = imx_pmx_get_func_name, .get_function_groups = imx_pmx_get_groups, + .gpio_request_enable = imx_pmx_gpio_request_enable, + .gpio_set_direction = imx_pmx_gpio_set_direction, .enable = imx_pmx_enable, };
Signature · 1 line
2.1.0
PATCH v3 3/5 gpio: vf610: add gpiolib/IRQ chip driver for Vybrid
In reply to Stefan AgnerAdd a gpiolib and IRQ chip driver for Vybrid ARM SoC using the Vybrid's GPIO and PORT module. The driver is instanced once per each GPIO/PORT module pair and handles 32 GPIO's.
--- drivers/gpio/Kconfig | 7 ++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-vf610.c | 295 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 303 insertions(+) create mode 100644 drivers/gpio/gpio-vf610.c
drivers/gpio/Kconfig +7 -0
@@ -334,6 +334,13 @@ config GPIO_TZ1090_PDC help Say yes here to support Toumaz Xenif TZ1090 PDC GPIOs. +config GPIO_VF610 + def_bool y + depends on ARCH_MXC && SOC_VF610 + select GPIOLIB_IRQCHIP + help + Say yes here to support Vybrid vf610 GPIOs. + config GPIO_XILINX bool "Xilinx GPIO support" depends on PPC_OF || MICROBLAZE || ARCH_ZYNQ
drivers/gpio/Makefile +1 -0
@@ -95,6 +95,7 @@ obj-$(CONFIG_GPIO_TWL6040) += gpio-twl6040.o obj-$(CONFIG_GPIO_TZ1090) += gpio-tz1090.o obj-$(CONFIG_GPIO_TZ1090_PDC) += gpio-tz1090-pdc.o obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o +obj-$(CONFIG_GPIO_VF610) += gpio-vf610.o obj-$(CONFIG_GPIO_VIPERBOARD) += gpio-viperboard.o obj-$(CONFIG_GPIO_VR41XX) += gpio-vr41xx.o obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o
drivers/gpio/gpio-vf610.c new file +295 -0
295 lines not on this page · raw message
Signature · 1 line
2.1.0
PATCH v3 4/5 ARM: dts: vf610: use new GPIO support
In reply to Stefan AgnerUse GPIO support by adding SD card detection configuration and GPIO pinmux for Colibri's standard GPIO pins. Attach the GPIO pins to the iomuxc node to get the GPIO pin settings applied.
--- arch/arm/boot/dts/vf610-colibri.dtsi | 9 +++++++++ arch/arm/boot/dts/vf610-twr.dts | 1 + arch/arm/boot/dts/vf610.dtsi | 1 + 3 files changed, 11 insertions(+)
arch/arm/boot/dts/vf610-colibri.dtsi +9 -0
@@ -31,6 +31,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_esdhc1>; bus-width = <4>; + cd-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>; }; &fec1 {
@@ -71,6 +72,14 @@ &iomuxc { vf610-colibri { + pinctrl_gpio_ext: gpio_ext { + fsl,pins = < + VF610_PAD_PTD10__GPIO_89 0x22ed /* EXT_IO_0 */ + VF610_PAD_PTD9__GPIO_88 0x22ed /* EXT_IO_1 */ + VF610_PAD_PTD26__GPIO_68 0x22ed /* EXT_IO_2 */ + >; + }; + pinctrl_esdhc1: esdhc1grp { fsl,pins = < VF610_PAD_PTA24__ESDHC1_CLK 0x31ef
arch/arm/boot/dts/vf610-twr.dts +1 -0
@@ -116,6 +116,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_esdhc1>; bus-width = <4>; + cd-gpios = <&gpio5 6 GPIO_ACTIVE_LOW>; status = "okay"; };
arch/arm/boot/dts/vf610.dtsi +1 -0
@@ -11,6 +11,7 @@ #include "vf610-pinfunc.h" #include <dt-bindings/clock/vf610-clock.h> #include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/gpio/gpio.h> / { aliases {
Signature · 1 line
2.1.0
Re: [PATCH v3 4/5] ARM: dts: vf610: use new GPIO support
Quoted 25 lines · Stefan Agner
Use GPIO support by adding SD card detection configuration and GPIO pinmux for Colibri's standard GPIO pins. Attach the GPIO pins to the iomuxc node to get the GPIO pin settings applied.
Signed-off-by Stefan Agner <[email protected]>--- arch/arm/boot/dts/vf610-colibri.dtsi | 9 +++++++++ arch/arm/boot/dts/vf610-twr.dts | 1 + arch/arm/boot/dts/vf610.dtsi | 1 + 3 files changed, 11 insertions(+)arch/arm/boot/dts/vf610-colibri.dtsi +1
-0@@ -31,6 +31,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_esdhc1>; bus-width = <4>; + cd-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>; }; &fec1 {@@ -71,6 +72,14 @@
arch/arm/boot/dts/vf610-colibri.dtsi line 82
Quoted 10 lines
arch/arm/boot/dts/vf610-colibri.dtsi +8
-0&iomuxc { vf610-colibri { + pinctrl_gpio_ext: gpio_ext { + fsl,pins = < + VF610_PAD_PTD10__GPIO_89 0x22ed /* EXT_IO_0 */ + VF610_PAD_PTD9__GPIO_88 0x22ed /* EXT_IO_1 */ + VF610_PAD_PTD26__GPIO_68 0x22ed /* EXT_IO_2 */ + >; + }; +
I'm not sure these GPIOs will be set up at anywhere. To set them up, you need to either have pinctrl_gpio_ext referenced by some client device in its pinctrl-* property or put these pins into hog group (see example in arch/arm/boot/dts/vf610-twr.dts).
Shawn
Quoted 30 lines
arch/arm/boot/dts/vf610-colibri.dtsi +0
-0pinctrl_esdhc1: esdhc1grp { fsl,pins = < VF610_PAD_PTA24__ESDHC1_CLK 0x31efarch/arm/boot/dts/vf610-twr.dts +1
-0@@ -116,6 +116,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_esdhc1>; bus-width = <4>; + cd-gpios = <&gpio5 6 GPIO_ACTIVE_LOW>; status = "okay"; };arch/arm/boot/dts/vf610.dtsi +1
-0@@ -11,6 +11,7 @@ #include "vf610-pinfunc.h" #include <dt-bindings/clock/vf610-clock.h> #include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/gpio/gpio.h> / { aliases {Signature · 1 line
2.1.0
Re: [PATCH v3 4/5] ARM: dts: vf610: use new GPIO support
Am 2014-09-26 03:21, schrieb Shawn Guo:
Quoted 42 lines · Stefan Agner
Quoted 25 lines
Use GPIO support by adding SD card detection configuration and GPIO pinmux for Colibri's standard GPIO pins. Attach the GPIO pins to the iomuxc node to get the GPIO pin settings applied.
Signed-off-by Stefan Agner <[email protected]>--- arch/arm/boot/dts/vf610-colibri.dtsi | 9 +++++++++ arch/arm/boot/dts/vf610-twr.dts | 1 + arch/arm/boot/dts/vf610.dtsi | 1 + 3 files changed, 11 insertions(+)arch/arm/boot/dts/vf610-colibri.dtsi +1
-0@@ -31,6 +31,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_esdhc1>; bus-width = <4>; + cd-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>; }; &fec1 {@@ -71,6 +72,14 @@arch/arm/boot/dts/vf610-colibri.dtsi line 82
Quoted 10 lines
arch/arm/boot/dts/vf610-colibri.dtsi +8
-0&iomuxc { vf610-colibri { + pinctrl_gpio_ext: gpio_ext { + fsl,pins = < + VF610_PAD_PTD10__GPIO_89 0x22ed /* EXT_IO_0 */ + VF610_PAD_PTD9__GPIO_88 0x22ed /* EXT_IO_1 */ + VF610_PAD_PTD26__GPIO_68 0x22ed /* EXT_IO_2 */ + >; + }; +I'm not sure these GPIOs will be set up at anywhere. To set them up, you need to either have
pinctrl_gpio_extreferenced by some client device in its pinctrl-* property or put these pins into hog group (see example inarch/arm/boot/dts/vf610-twr.dts).
Quoted 2 lines
Shawn
This GPIO's are meant to be used from user space by default. The latest implementation of imx_pmx_gpio_request_enable not only takes care of the muxing, but also applies the whole pad settings. Hence we do not need the pinctrl subsystem to apply it (through pinctrl-* dt properties).
I changed this now in v3, in v2 I had still to use the pinctrl-* properties. I like that 3rd version much more, this way the pin only really gets muxed when the user uses it (e.g. we save power because the pad is disabled when the GPIO is not in use). If the pin needs to be in a defined state, then we would have to explicitly configure/enable it through a pinctrl-* properties, but this is not the case for these external GPIO's.
--
Stefan
Quoted 30 lines
Quoted 30 lines
arch/arm/boot/dts/vf610-colibri.dtsi +0
-0pinctrl_esdhc1: esdhc1grp { fsl,pins = < VF610_PAD_PTA24__ESDHC1_CLK 0x31efarch/arm/boot/dts/vf610-twr.dts +1
-0@@ -116,6 +116,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_esdhc1>; bus-width = <4>; + cd-gpios = <&gpio5 6 GPIO_ACTIVE_LOW>; status = "okay"; };arch/arm/boot/dts/vf610.dtsi +1
-1@@ -11,6 +11,7 @@ #include "vf610-pinfunc.h" #include <dt-bindings/clock/vf610-clock.h> #include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/gpio/gpio.h> / { aliases { --2.1.0
Re: [PATCH v3 4/5] ARM: dts: vf610: use new GPIO support
Quoted 5 lines · Stefan Agner
This GPIO's are meant to be used from user space by default. The latest implementation of
imx_pmx_gpio_request_enablenot only takes care of the muxing, but also applies the whole pad settings. Hence we do not need the pinctrl subsystem to apply it (through pinctrl-* dt properties).
Quoted 7 lines
I changed this now in v3, in v2 I had still to use the pinctrl-* properties. I like that 3rd version much more, this way the pin only really gets muxed when the user uses it (e.g. we save power because the pad is disabled when the GPIO is not in use). If the pin needs to be in a defined state, then we would have to explicitly configure/enable it through a pinctrl-* properties, but this is not the case for these external GPIO's.
Ah, yes, you're right. I was still thinking about the way how it worked before your patch.
Patch applied, thanks.
PATCH v3 5/5 Documentation: dts: add bindings for Vybrid GPIO/PORT module
In reply to Stefan AgnerThe Vybrid SoC device tree (vf610.dtsi) used this bindings since its initial commit in May 2013. However, a proper gpiolib driver was missing so far. With the addition of the gpiolib driver, the bindings proved to be useful and complete, hence a good time to add the documentation.
--- .../devicetree/bindings/gpio/gpio-vf610.txt | 56 ++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpio/gpio-vf610.txt
Documentation/devicetree/bindings/gpio/gpio-vf610.txt new file +56 -0
@@ -0,0 +1,56 @@ +* Freescale VF610 PORT/GPIO module + +The Freescale PORT/GPIO modules are two adjacent modules providing GPIO +functionality. Each pair serves 32 GPIOs. The VF610 has 5 instances of +each, and each PORT module has its own interrupt. + +Required properties for GPIO node: +- compatible : Should be "fsl,<soc>-gpio", currently "fsl,vf610-gpio" +- reg : The first reg tuple represents the PORT module, the second tuple + the GPIO module. +- 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 the gpio polarity: + 0 = active high + 1 = active low +- 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 = &gpio1; + gpio1 = &gpio2; +}; + +gpio1: gpio at 40049000 { + compatible = "fsl,vf610-gpio"; + reg = <0x40049000 0x1000 0x400ff000 0x40>; + interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&iomuxc 0 0 32>; +}; + +gpio2: gpio at 4004a000 { + compatible = "fsl,vf610-gpio"; + reg = <0x4004a000 0x1000 0x400ff040 0x40>; + interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&iomuxc 0 32 32>; +}; +
Signature · 1 line
2.1.0
Quoted 6 lines · Stefan Agner
Stefan Agner (5):
pinctrl: imx: detect uninitialized pins
pinctrl: imx: add gpio pinmux support for vf610
gpio: vf610: add gpiolib/IRQ chip driver for Vybrid
ARM: dts: vf610: use new GPIO support
Documentation: dts: add bindings for Vybrid GPIO/PORT module
For patch #1, #2, #3 and #5:
Quoted 5 lines · Stefan Agner
This 3rd version of the GPIO support for Vybrid now also includes the wakeup support which was part of the suspend/resume patchset I sent earlier this week.
Changes in v3:
I've already applied patch 1/5.
However I had to fix conflicts against the development branch and from patch 2/5 and onward there are even more conflicts, the most obvious is that the driver is moved to drivers/pinctrl/freescale, but there are other conflicts as well.
Can you please rebase patches 2-5 onto my "devel" branch from the pin control tree and resend, also collect ACKs.
https://git.kernel.org/cgit/linux/kernel/git/linusw/linux-pinctrl.git/log/?h=devel
I saw there was still discussion on 2/5 as well, but I'm ready to merge anything ACKed by Shawn.
Yours,
Linus Walleij