From 7bd19dbe99b18c5dfd85a004595df6061e8df8f6 Mon Sep 17 00:00:00 2001 From: DENG Qingfang Date: Tue, 17 Mar 2020 20:54:34 +0800 Subject: ramips: mt7621: backport GPIO driver fix Backport 2 patches from linux-next to fix mt7621 GPIO driver Signed-off-by: DENG Qingfang --- ...pio-mmio-introduce-BGPIOF_NO_SET_ON_INPUT.patch | 85 ++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 target/linux/ramips/patches-5.4/111-gpio-mmio-introduce-BGPIOF_NO_SET_ON_INPUT.patch (limited to 'target/linux/ramips/patches-5.4/111-gpio-mmio-introduce-BGPIOF_NO_SET_ON_INPUT.patch') diff --git a/target/linux/ramips/patches-5.4/111-gpio-mmio-introduce-BGPIOF_NO_SET_ON_INPUT.patch b/target/linux/ramips/patches-5.4/111-gpio-mmio-introduce-BGPIOF_NO_SET_ON_INPUT.patch new file mode 100644 index 0000000000..fdb89d0902 --- /dev/null +++ b/target/linux/ramips/patches-5.4/111-gpio-mmio-introduce-BGPIOF_NO_SET_ON_INPUT.patch @@ -0,0 +1,85 @@ +From 5d7b644aad721ecca20bd8976b38fb243fdc84f9 Mon Sep 17 00:00:00 2001 +From: Chuanhong Guo +Date: Sun, 15 Mar 2020 20:13:37 +0800 +Subject: [PATCH] gpio: mmio: introduce BGPIOF_NO_SET_ON_INPUT +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Some gpio controllers ignores pin value writing when that pin is +configured as input mode. As a result, bgpio_dir_out should set +pin to output before configuring pin values or gpio pin values +can't be set up properly. +Introduce two variants of bgpio_dir_out: bgpio_dir_out_val_first +and bgpio_dir_out_dir_first, and assign direction_output according +to a new flag: BGPIOF_NO_SET_ON_INPUT. + +Signed-off-by: Chuanhong Guo +Tested-by: René van Dorst +Reviewed-by: Sergio Paracuellos +Signed-off-by: Bartosz Golaszewski +--- + drivers/gpio/gpio-mmio.c | 23 +++++++++++++++++++---- + include/linux/gpio/driver.h | 1 + + 2 files changed, 20 insertions(+), 4 deletions(-) + +--- a/drivers/gpio/gpio-mmio.c ++++ b/drivers/gpio/gpio-mmio.c +@@ -381,12 +381,10 @@ static int bgpio_get_dir(struct gpio_chi + return 1; + } + +-static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) ++static void bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) + { + unsigned long flags; + +- gc->set(gc, gpio, val); +- + spin_lock_irqsave(&gc->bgpio_lock, flags); + + gc->bgpio_dir |= bgpio_line2mask(gc, gpio); +@@ -397,7 +395,21 @@ static int bgpio_dir_out(struct gpio_chi + gc->write_reg(gc->reg_dir_out, gc->bgpio_dir); + + spin_unlock_irqrestore(&gc->bgpio_lock, flags); ++} + ++static int bgpio_dir_out_dir_first(struct gpio_chip *gc, unsigned int gpio, ++ int val) ++{ ++ bgpio_dir_out(gc, gpio, val); ++ gc->set(gc, gpio, val); ++ return 0; ++} ++ ++static int bgpio_dir_out_val_first(struct gpio_chip *gc, unsigned int gpio, ++ int val) ++{ ++ gc->set(gc, gpio, val); ++ bgpio_dir_out(gc, gpio, val); + return 0; + } + +@@ -530,7 +542,10 @@ static int bgpio_setup_direction(struct + if (dirout || dirin) { + gc->reg_dir_out = dirout; + gc->reg_dir_in = dirin; +- gc->direction_output = bgpio_dir_out; ++ if (flags & BGPIOF_NO_SET_ON_INPUT) ++ gc->direction_output = bgpio_dir_out_dir_first; ++ else ++ gc->direction_output = bgpio_dir_out_val_first; + gc->direction_input = bgpio_dir_in; + gc->get_direction = bgpio_get_dir; + } else { +--- a/include/linux/gpio/driver.h ++++ b/include/linux/gpio/driver.h +@@ -567,6 +567,7 @@ int bgpio_init(struct gpio_chip *gc, str + #define BGPIOF_BIG_ENDIAN_BYTE_ORDER BIT(3) + #define BGPIOF_READ_OUTPUT_REG_SET BIT(4) /* reg_set stores output value */ + #define BGPIOF_NO_OUTPUT BIT(5) /* only input */ ++#define BGPIOF_NO_SET_ON_INPUT BIT(6) + + int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hwirq); -- cgit v1.2.3