summaryrefslogtreecommitdiff
path: root/recipes-kernel/linux/linux-3.12.70/linux-3.12-gpio-expose-pullups.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/linux/linux-3.12.70/linux-3.12-gpio-expose-pullups.patch')
-rw-r--r--recipes-kernel/linux/linux-3.12.70/linux-3.12-gpio-expose-pullups.patch301
1 files changed, 0 insertions, 301 deletions
diff --git a/recipes-kernel/linux/linux-3.12.70/linux-3.12-gpio-expose-pullups.patch b/recipes-kernel/linux/linux-3.12.70/linux-3.12-gpio-expose-pullups.patch
deleted file mode 100644
index 4e1d482..0000000
--- a/recipes-kernel/linux/linux-3.12.70/linux-3.12-gpio-expose-pullups.patch
+++ /dev/null
@@ -1,301 +0,0 @@
-Index: linux-3.12.13/drivers/gpio/gpiolib.c
-===================================================================
---- linux-3.12.13.orig/drivers/gpio/gpiolib.c 2014-02-22 15:32:50.000000000 -0600
-+++ linux-3.12.13/drivers/gpio/gpiolib.c 2014-04-18 09:25:31.977377592 -0500
-@@ -87,7 +87,9 @@
- static int gpiod_request(struct gpio_desc *desc, const char *label);
- static void gpiod_free(struct gpio_desc *desc);
- static int gpiod_direction_input(struct gpio_desc *desc);
-+static int gpiod_direction_input_pullup(struct gpio_desc *desc, bool pullup);
- static int gpiod_direction_output(struct gpio_desc *desc, int value);
-+static int gpiod_direction_output_pullup(struct gpio_desc *desc, int value, bool pullup);
- static int gpiod_get_direction(const struct gpio_desc *desc);
- static int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce);
- static int gpiod_get_value_cansleep(const struct gpio_desc *desc);
-@@ -1523,11 +1525,19 @@
- if (flags & GPIOF_OPEN_SOURCE)
- set_bit(FLAG_OPEN_SOURCE, &desc->flags);
-
-- if (flags & GPIOF_DIR_IN)
-- err = gpiod_direction_input(desc);
-- else
-- err = gpiod_direction_output(desc,
-- (flags & GPIOF_INIT_HIGH) ? 1 : 0);
-+ if (flags & GPIOF_DIR_IN) {
-+ if (flags & GPIOF_PULLUP)
-+ err = gpiod_direction_input_pullup(desc, (flags & GPIOF_PULLUP) ? true : false);
-+ else
-+ err = gpiod_direction_input(desc);
-+ } else {
-+ if (flags & GPIOF_PULLUP)
-+ err = gpiod_direction_output_pullup(desc,
-+ (flags & GPIOF_INIT_HIGH) ? 1 : 0, (flags & GPIOF_PULLUP) ? true : false);
-+ else
-+ err = gpiod_direction_output(desc,
-+ (flags & GPIOF_INIT_HIGH) ? 1 : 0);
-+ }
-
- if (err)
- goto free_gpio;
-@@ -1613,6 +1623,71 @@
- }
- EXPORT_SYMBOL_GPL(gpiochip_is_requested);
-
-+static int gpiod_direction_input_pullup(struct gpio_desc *desc, bool pullup)
-+{
-+ unsigned long flags;
-+ struct gpio_chip *chip;
-+ int status = -EINVAL;
-+ int offset;
-+
-+ if (!desc || !desc->chip) {
-+ pr_warn("%s: invalid GPIO\n", __func__);
-+ return -EINVAL;
-+ }
-+
-+ chip = desc->chip;
-+ if (!chip->get || !chip->direction_input_pullup) {
-+ pr_warn("%s: missing get() or direction_input_pullup() operations\n",
-+ __func__);
-+ return -EIO;
-+ }
-+
-+ spin_lock_irqsave(&gpio_lock, flags);
-+
-+ status = gpio_ensure_requested(desc);
-+ if (status < 0)
-+ goto fail;
-+
-+ /* now we know the gpio is valid and chip won't vanish */
-+
-+ spin_unlock_irqrestore(&gpio_lock, flags);
-+
-+ might_sleep_if(chip->can_sleep);
-+
-+ offset = gpio_chip_hwgpio(desc);
-+ if (status) {
-+ status = chip->request(chip, offset);
-+ if (status < 0) {
-+ pr_debug("GPIO-%d: chip request fail, %d\n",
-+ desc_to_gpio(desc), status);
-+ /* and it's not available to anyone else ...
-+ * gpio_request() is the fully clean solution.
-+ */
-+ goto lose;
-+ }
-+ }
-+
-+ status = chip->direction_input_pullup(chip, offset, pullup);
-+ if (status == 0)
-+ clear_bit(FLAG_IS_OUT, &desc->flags);
-+
-+ trace_gpio_direction(desc_to_gpio(desc), 1, status);
-+lose:
-+ return status;
-+fail:
-+ spin_unlock_irqrestore(&gpio_lock, flags);
-+ if (status)
-+ pr_debug("%s: gpio-%d status %d\n", __func__,
-+ desc_to_gpio(desc), status);
-+ return status;
-+}
-+
-+int gpio_direction_input_pullup(unsigned gpio, bool pullup)
-+{
-+ return gpiod_direction_input_pullup(gpio_to_desc(gpio), pullup);
-+}
-+EXPORT_SYMBOL_GPL(gpio_direction_input_pullup);
-+
-
- /* Drivers MUST set GPIO direction before making get/set calls. In
- * some cases this is done in early boot, before IRQs are enabled.
-@@ -1688,6 +1763,79 @@
- }
- EXPORT_SYMBOL_GPL(gpio_direction_input);
-
-+static int gpiod_direction_output_pullup(struct gpio_desc *desc, int value, bool pullup)
-+{
-+ unsigned long flags;
-+ struct gpio_chip *chip;
-+ int status = -EINVAL;
-+ int offset;
-+
-+ if (!desc || !desc->chip) {
-+ pr_warn("%s: invalid GPIO\n", __func__);
-+ return -EINVAL;
-+ }
-+
-+ /* Open drain pin should not be driven to 1 */
-+ if (value && test_bit(FLAG_OPEN_DRAIN, &desc->flags))
-+ return gpiod_direction_input(desc);
-+
-+ /* Open source pin should not be driven to 0 */
-+ if (!value && test_bit(FLAG_OPEN_SOURCE, &desc->flags))
-+ return gpiod_direction_input(desc);
-+
-+ chip = desc->chip;
-+ if (!chip->set || !chip->direction_output_pullup) {
-+ pr_warn("%s: missing set() or direction_output_pullup() operations\n",
-+ __func__);
-+ return -EIO;
-+ }
-+
-+ spin_lock_irqsave(&gpio_lock, flags);
-+
-+ status = gpio_ensure_requested(desc);
-+ if (status < 0)
-+ goto fail;
-+
-+ /* now we know the gpio is valid and chip won't vanish */
-+
-+ spin_unlock_irqrestore(&gpio_lock, flags);
-+
-+ might_sleep_if(chip->can_sleep);
-+
-+ offset = gpio_chip_hwgpio(desc);
-+ if (status) {
-+ status = chip->request(chip, offset);
-+ if (status < 0) {
-+ pr_debug("GPIO-%d: chip request fail, %d\n",
-+ desc_to_gpio(desc), status);
-+ /* and it's not available to anyone else ...
-+ * gpio_request() is the fully clean solution.
-+ */
-+ goto lose;
-+ }
-+ }
-+
-+ status = chip->direction_output_pullup(chip, offset, value, pullup);
-+ if (status == 0)
-+ set_bit(FLAG_IS_OUT, &desc->flags);
-+ trace_gpio_value(desc_to_gpio(desc), 0, value);
-+ trace_gpio_direction(desc_to_gpio(desc), 0, status);
-+lose:
-+ return status;
-+fail:
-+ spin_unlock_irqrestore(&gpio_lock, flags);
-+ if (status)
-+ pr_debug("%s: gpio-%d status %d\n", __func__,
-+ desc_to_gpio(desc), status);
-+ return status;
-+}
-+
-+int gpio_direction_output_pullup(unsigned gpio, int value, bool pullup)
-+{
-+ return gpiod_direction_output_pullup(gpio_to_desc(gpio), value, pullup);
-+}
-+EXPORT_SYMBOL_GPL(gpio_direction_output_pullup);
-+
- static int gpiod_direction_output(struct gpio_desc *desc, int value)
- {
- unsigned long flags;
-Index: linux-3.12.13/drivers/pinctrl/pinctrl-at91.c
-===================================================================
---- linux-3.12.13.orig/drivers/pinctrl/pinctrl-at91.c 2014-02-22 15:32:50.000000000 -0600
-+++ linux-3.12.13/drivers/pinctrl/pinctrl-at91.c 2014-04-18 09:25:31.985377595 -0500
-@@ -1112,6 +1112,17 @@
- return 0;
- }
-
-+static int at91_gpio_direction_input_pullup(struct gpio_chip *chip, unsigned offset, bool pullup)
-+{
-+ struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
-+ void __iomem *pio = at91_gpio->regbase;
-+ unsigned mask = 1 << offset;
-+
-+ writel_relaxed(mask, pio + PIO_ODR);
-+ at91_mux_set_pullup(pio, mask, pullup);
-+ return 0;
-+}
-+
- static int at91_gpio_get(struct gpio_chip *chip, unsigned offset)
- {
- struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
-@@ -1146,6 +1157,20 @@
- return 0;
- }
-
-+static int at91_gpio_direction_output_pullup(struct gpio_chip *chip, unsigned offset,
-+ int val, bool pullup)
-+{
-+ struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
-+ void __iomem *pio = at91_gpio->regbase;
-+ unsigned mask = 1 << offset;
-+
-+ writel_relaxed(mask, pio + (val ? PIO_SODR : PIO_CODR));
-+ writel_relaxed(mask, pio + PIO_OER);
-+ at91_mux_set_pullup(pio, mask, pullup);
-+
-+ return 0;
-+}
-+
- static int at91_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
- {
- struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
-@@ -1513,8 +1538,10 @@
- .request = at91_gpio_request,
- .free = at91_gpio_free,
- .direction_input = at91_gpio_direction_input,
-+ .direction_input_pullup = at91_gpio_direction_input_pullup,
- .get = at91_gpio_get,
- .direction_output = at91_gpio_direction_output,
-+ .direction_output_pullup = at91_gpio_direction_output_pullup,
- .set = at91_gpio_set,
- .to_irq = at91_gpio_to_irq,
- .dbg_show = at91_gpio_dbg_show,
-Index: linux-3.12.13/include/linux/gpio.h
-===================================================================
---- linux-3.12.13.orig/include/linux/gpio.h 2014-02-22 15:32:50.000000000 -0600
-+++ linux-3.12.13/include/linux/gpio.h 2014-04-18 09:25:31.957377594 -0500
-@@ -12,7 +12,10 @@
- #define GPIOF_INIT_LOW (0 << 1)
- #define GPIOF_INIT_HIGH (1 << 1)
-
-+#define GPIOF_PULLUP (2 << 0)
-+
- #define GPIOF_IN (GPIOF_DIR_IN)
-+#define GPIOF_IN_PULLUP (GPIOF_DIR_IN | GPIOF_PULLUP)
- #define GPIOF_OUT_INIT_LOW (GPIOF_DIR_OUT | GPIOF_INIT_LOW)
- #define GPIOF_OUT_INIT_HIGH (GPIOF_DIR_OUT | GPIOF_INIT_HIGH)
-
-Index: linux-3.12.13/include/asm-generic/gpio.h
-===================================================================
---- linux-3.12.13.orig/include/asm-generic/gpio.h 2014-02-22 15:32:50.000000000 -0600
-+++ linux-3.12.13/include/asm-generic/gpio.h 2014-04-18 09:26:42.669377408 -0500
-@@ -62,9 +62,11 @@
- * @get_direction: returns direction for signal "offset", 0=out, 1=in,
- * (same as GPIOF_DIR_XXX), or negative error
- * @direction_input: configures signal "offset" as input, or returns error
-+ * @direction_input_pullup: configures signal "offset" as input with pullup enabled, or returns error
- * @get: returns value for signal "offset"; for output signals this
- * returns either the value actually sensed, or zero
- * @direction_output: configures signal "offset" as output, or returns error
-+ * @direction_output_pullup: configures signal "offset" as output with pullup enabled, or returns error
- * @set_debounce: optional hook for setting debounce time for specified gpio in
- * interrupt triggered gpio chips
- * @set: assigns output value for signal "offset"
-@@ -111,10 +113,14 @@
- unsigned offset);
- int (*direction_input)(struct gpio_chip *chip,
- unsigned offset);
-+ int (*direction_input_pullup)(struct gpio_chip *chip,
-+ unsigned offset, bool pullup);
- int (*get)(struct gpio_chip *chip,
- unsigned offset);
- int (*direction_output)(struct gpio_chip *chip,
- unsigned offset, int value);
-+ int (*direction_output_pullup)(struct gpio_chip *chip,
-+ unsigned offset, int value, bool pullup);
- int (*set_debounce)(struct gpio_chip *chip,
- unsigned offset, unsigned debounce);
-
-@@ -173,7 +179,9 @@
- extern void gpio_free(unsigned gpio);
-
- extern int gpio_direction_input(unsigned gpio);
-+extern int gpio_direction_input_pullup(unsigned gpio, bool pullup);
- extern int gpio_direction_output(unsigned gpio, int value);
-+extern int gpio_direction_output_pullup(unsigned gpio, int value, bool pullup);
-
- extern int gpio_set_debounce(unsigned gpio, unsigned debounce);
-