summaryrefslogtreecommitdiff
path: root/recipes-kernel
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel')
-rw-r--r--recipes-kernel/linux/linux-at91-4.9/linux-4.9-at91_gpio_set_single_ended.patch148
-rw-r--r--recipes-kernel/linux/linux-at91_4.9.bb4
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"