diff options
Diffstat (limited to 'recipes-kernel')
-rw-r--r-- | recipes-kernel/linux/linux-at91-4.9/linux-4.9-at91_gpio_set_single_ended.patch | 148 | ||||
-rw-r--r-- | recipes-kernel/linux/linux-at91_4.9.bb | 4 |
2 files changed, 151 insertions, 1 deletions
diff --git a/recipes-kernel/linux/linux-at91-4.9/linux-4.9-at91_gpio_set_single_ended.patch b/recipes-kernel/linux/linux-at91-4.9/linux-4.9-at91_gpio_set_single_ended.patch new file mode 100644 index 0000000..25da603 --- /dev/null +++ b/recipes-kernel/linux/linux-at91-4.9/linux-4.9-at91_gpio_set_single_ended.patch @@ -0,0 +1,148 @@ +diff -Naru linux-4.9.orig/drivers/gpio/gpiolib.c linux-4.9/drivers/gpio/gpiolib.c +--- linux-4.9.orig/drivers/gpio/gpiolib.c 2018-12-11 10:11:06.000000000 -0600 ++++ linux-4.9/drivers/gpio/gpiolib.c 2018-12-12 10:20:01.690638477 -0600 +@@ -478,6 +478,8 @@ + set_bit(FLAG_OPEN_DRAIN, &desc->flags); + if (lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE) + set_bit(FLAG_OPEN_SOURCE, &desc->flags); ++ if (lflags & GPIOHANDLE_REQUEST_PULLUP) ++ set_bit(FLAG_PULLUP, &desc->flags); + + /* + * Lines have to be requested explicitly for input +@@ -804,6 +806,8 @@ + set_bit(FLAG_OPEN_DRAIN, &desc->flags); + if (lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE) + set_bit(FLAG_OPEN_SOURCE, &desc->flags); ++ if (lflags & GPIOHANDLE_REQUEST_PULLUP) ++ set_bit(FLAG_PULLUP, &desc->flags); + + ret = gpiod_direction_input(desc); + if (ret) +@@ -953,6 +957,8 @@ + lineinfo.flags |= GPIOLINE_FLAG_OPEN_DRAIN; + if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) + lineinfo.flags |= GPIOLINE_FLAG_OPEN_SOURCE; ++ if (test_bit(FLAG_PULLUP, &desc->flags)) ++ lineinfo.flags |= GPIOLINE_FLAG_PULLUP; + + if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) + return -EFAULT; +@@ -2090,6 +2096,7 @@ + clear_bit(FLAG_REQUESTED, &desc->flags); + clear_bit(FLAG_OPEN_DRAIN, &desc->flags); + clear_bit(FLAG_OPEN_SOURCE, &desc->flags); ++ clear_bit(FLAG_PULLUP, &desc->flags); + clear_bit(FLAG_IS_HOGGED, &desc->flags); + ret = true; + } +@@ -2256,6 +2263,17 @@ + if (!ret) + goto set_output_value; + } ++ /* Emulate open source by not actively driving the line low */ ++ if (!value) ++ return gpiod_direction_input(desc); ++ } ++ else if (test_bit(FLAG_PULLUP, &desc->flags)) { ++ if (gc->set_single_ended) { ++ ret = gc->set_single_ended(gc, gpio_chip_hwgpio(desc), ++ LINE_MODE_PULLUP); ++ if (!ret) ++ goto set_output_value; ++ } + /* Emulate open source by not actively driving the line low */ + if (!value) + return gpiod_direction_input(desc); +diff -Naru linux-4.9.orig/drivers/gpio/gpiolib.h linux-4.9/drivers/gpio/gpiolib.h +--- linux-4.9.orig/drivers/gpio/gpiolib.h 2018-12-11 12:10:06.937000782 -0600 ++++ linux-4.9/drivers/gpio/gpiolib.h 2018-12-11 12:11:30.324998313 -0600 +@@ -189,6 +189,7 @@ + #define FLAG_OPEN_SOURCE 8 /* Gpio is open source type */ + #define FLAG_USED_AS_IRQ 9 /* GPIO is connected to an IRQ */ + #define FLAG_IS_HOGGED 11 /* GPIO is hogged */ ++#define FLAG_PULLUP 12 /* GPIO is pulled up */ + + /* Connection label */ + const char *label; +diff -Naru linux-4.9.orig/drivers/pinctrl/pinctrl-at91.c linux-4.9/drivers/pinctrl/pinctrl-at91.c +--- linux-4.9.orig/drivers/pinctrl/pinctrl-at91.c 2018-12-11 10:11:15.000000000 -0600 ++++ linux-4.9/drivers/pinctrl/pinctrl-at91.c 2018-12-12 10:25:46.154628279 -0600 +@@ -1671,6 +1671,33 @@ + return -EINVAL; + } + ++static int at91_gpio_set_single_ended(struct gpio_chip *chip, unsigned offset, enum single_ended_mode mode) ++{ ++ struct at91_gpio_chip *at91_gpio = gpiochip_get_data(chip); ++ void __iomem *pio = at91_gpio->regbase; ++ unsigned mask = 1 << offset; ++ ++ /* Other possibilities: ++ * PIO_IFSCDR, PIO_IFSCER (Input Filter Slow Clock disable/enable register) ++ * PIO_SCDR (Slow Clock Divider Debouncing register) ++ */ ++ switch(mode) { ++ case LINE_MODE_PULLUP: ++ at91_mux_set_pullup(pio, mask, true); ++ return 0; ++ case LINE_MODE_OPEN_DRAIN: ++ /* Open Drain is Multi Drive */ ++ at91_mux_set_multidrive(pio, mask, true); ++ return 0; ++ case LINE_MODE_PUSH_PULL: ++ /* Not pull up or open drain */ ++ at91_mux_set_pullup(pio, mask, false); ++ at91_mux_set_multidrive(pio, mask, false); ++ return 0; ++ default: return -EINVAL; ++ } ++} ++ + /* This structure is replicated for each GPIO block allocated at probe time */ + static const struct gpio_chip at91_gpio_template = { + .request = gpiochip_generic_request, +@@ -1681,6 +1708,7 @@ + .direction_output = at91_gpio_direction_output, + .set = at91_gpio_set, + .set_multiple = at91_gpio_set_multiple, ++ .set_single_ended = at91_gpio_set_single_ended, + .dbg_show = at91_gpio_dbg_show, + .can_sleep = false, + .ngpio = MAX_NB_GPIO_PER_BANK, +diff -Naru linux-4.9.orig/include/linux/gpio/driver.h linux-4.9/include/linux/gpio/driver.h +--- linux-4.9.orig/include/linux/gpio/driver.h 2018-12-11 10:11:20.000000000 -0600 ++++ linux-4.9/include/linux/gpio/driver.h 2018-12-11 17:47:56.188400715 -0600 +@@ -23,11 +23,13 @@ + * @LINE_MODE_PUSH_PULL: normal mode for a GPIO line, drive actively high/low + * @LINE_MODE_OPEN_DRAIN: set line to be open drain + * @LINE_MODE_OPEN_SOURCE: set line to be open source ++ * @LINE_MODE_PULLUP: set line to be pullup + */ + enum single_ended_mode { + LINE_MODE_PUSH_PULL, + LINE_MODE_OPEN_DRAIN, + LINE_MODE_OPEN_SOURCE, ++ LINE_MODE_PULLUP, + }; + + /** +diff -Naru linux-4.9.orig/include/uapi/linux/gpio.h linux-4.9/include/uapi/linux/gpio.h +--- linux-4.9.orig/include/uapi/linux/gpio.h 2018-12-11 10:11:21.000000000 -0600 ++++ linux-4.9/include/uapi/linux/gpio.h 2018-12-11 12:21:03.884981333 -0600 +@@ -32,6 +32,7 @@ + #define GPIOLINE_FLAG_ACTIVE_LOW (1UL << 2) + #define GPIOLINE_FLAG_OPEN_DRAIN (1UL << 3) + #define GPIOLINE_FLAG_OPEN_SOURCE (1UL << 4) ++#define GPIOLINE_FLAG_PULLUP (1UL << 5) + + /** + * struct gpioline_info - Information about a certain GPIO line +@@ -61,6 +62,7 @@ + #define GPIOHANDLE_REQUEST_ACTIVE_LOW (1UL << 2) + #define GPIOHANDLE_REQUEST_OPEN_DRAIN (1UL << 3) + #define GPIOHANDLE_REQUEST_OPEN_SOURCE (1UL << 4) ++#define GPIOHANDLE_REQUEST_PULLUP (1UL << 5) + + /** + * struct gpiohandle_request - Information about a GPIO handle request diff --git a/recipes-kernel/linux/linux-at91_4.9.bb b/recipes-kernel/linux/linux-at91_4.9.bb index fe728ba..243bdd0 100644 --- a/recipes-kernel/linux/linux-at91_4.9.bb +++ b/recipes-kernel/linux/linux-at91_4.9.bb @@ -25,13 +25,15 @@ SRC_URI += "file://defconfig" COMMON_PATCHES = "file://linux-4.9-pps-gpio.patch" +# file://at91pinctrl_reprobe.patch + SRC_URI_append_mtcdt = "\ ${COMMON_PATCHES} \ file://defconfig \ file://linux-4.9-mtcdt-device-tree.patch \ file://linux-4.9-add-num_accessory_ports-config-option.patch \ file://950-0090-OF-DT-Overlay-configfs-interface.patch \ - file://at91pinctrl_reprobe.patch \ + file://linux-4.9-at91_gpio_set_single_ended.patch \ " DTB_APPEND_mtcdt = "mtcdt" |