diff options
Diffstat (limited to 'recipes-kernel/linux/linux-3.12.27/linux-3.12-gpio-expose-deglitch.patch')
-rw-r--r-- | recipes-kernel/linux/linux-3.12.27/linux-3.12-gpio-expose-deglitch.patch | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-3.12.27/linux-3.12-gpio-expose-deglitch.patch b/recipes-kernel/linux/linux-3.12.27/linux-3.12-gpio-expose-deglitch.patch new file mode 100644 index 0000000..b868a36 --- /dev/null +++ b/recipes-kernel/linux/linux-3.12.27/linux-3.12-gpio-expose-deglitch.patch @@ -0,0 +1,165 @@ +Index: linux-3.12.13/drivers/gpio/gpiolib.c +=================================================================== +--- linux-3.12.13.orig/drivers/gpio/gpiolib.c 2014-04-18 09:55:28.325372866 -0500 ++++ linux-3.12.13/drivers/gpio/gpiolib.c 2014-04-18 10:01:46.221371869 -0500 +@@ -90,6 +90,7 @@ + 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_deglitch(struct gpio_desc *desc, bool enable); + 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); +@@ -1539,6 +1540,9 @@ + (flags & GPIOF_INIT_HIGH) ? 1 : 0); + } + ++ if (flags & GPIOF_DEGLITCH) ++ err = gpiod_deglitch(desc, (flags & GPIOF_DEGLITCH) ? true : false); ++ + if (err) + goto free_gpio; + +@@ -1909,6 +1913,67 @@ + } + EXPORT_SYMBOL_GPL(gpio_direction_output); + ++static int gpiod_deglitch(struct gpio_desc *desc, bool enable) ++{ ++ 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->deglitch) { ++ pr_warn("%s: missing deglitch() operation\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->deglitch(chip, offset, enable); ++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_deglitch(unsigned gpio, bool enable) ++{ ++ return gpiod_deglitch(gpio_to_desc(gpio), enable); ++} ++EXPORT_SYMBOL_GPL(gpio_deglitch); ++ + /** + * gpio_set_debounce - sets @debounce time for a @gpio + * @gpio: the gpio to set debounce time +Index: linux-3.12.13/drivers/pinctrl/pinctrl-at91.c +=================================================================== +--- linux-3.12.13.orig/drivers/pinctrl/pinctrl-at91.c 2014-04-18 09:55:28.325372866 -0500 ++++ linux-3.12.13/drivers/pinctrl/pinctrl-at91.c 2014-04-18 10:02:45.041371714 -0500 +@@ -1171,6 +1171,17 @@ + return 0; + } + ++static int at91_gpio_set_deglitch(struct gpio_chip *chip, unsigned offset, bool enable) ++{ ++ struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); ++ void __iomem *pio = at91_gpio->regbase; ++ unsigned mask = 1 << offset; ++ ++ at91_mux_pio3_set_deglitch(pio, mask, enable); ++ ++ 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); +@@ -1542,6 +1553,7 @@ + .get = at91_gpio_get, + .direction_output = at91_gpio_direction_output, + .direction_output_pullup = at91_gpio_direction_output_pullup, ++ .deglitch = at91_gpio_set_deglitch, + .set = at91_gpio_set, + .to_irq = at91_gpio_to_irq, + .dbg_show = at91_gpio_dbg_show, +Index: linux-3.12.13/include/asm-generic/gpio.h +=================================================================== +--- linux-3.12.13.orig/include/asm-generic/gpio.h 2014-04-18 09:55:28.325372866 -0500 ++++ linux-3.12.13/include/asm-generic/gpio.h 2014-04-18 09:58:13.081372430 -0500 +@@ -67,6 +67,7 @@ + * 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 ++ * @deglitch: enables deglitch on signal "offset" + * @set_debounce: optional hook for setting debounce time for specified gpio in + * interrupt triggered gpio chips + * @set: assigns output value for signal "offset" +@@ -121,6 +122,8 @@ + unsigned offset, int value); + int (*direction_output_pullup)(struct gpio_chip *chip, + unsigned offset, int value, bool pullup); ++ int (*deglitch)(struct gpio_chip *chip, ++ unsigned offset, bool enable); + int (*set_debounce)(struct gpio_chip *chip, + unsigned offset, unsigned debounce); + +@@ -182,6 +185,7 @@ + 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_deglitch(unsigned gpio, bool enable); + + extern int gpio_set_debounce(unsigned gpio, unsigned debounce); + +Index: linux-3.12.13/include/linux/gpio.h +=================================================================== +--- linux-3.12.13.orig/include/linux/gpio.h 2014-04-18 09:55:28.325372866 -0500 ++++ linux-3.12.13/include/linux/gpio.h 2014-04-18 09:57:56.305372474 -0500 +@@ -13,9 +13,11 @@ + #define GPIOF_INIT_HIGH (1 << 1) + + #define GPIOF_PULLUP (2 << 0) ++#define GPIOF_DEGLITCH (2 << 1) + + #define GPIOF_IN (GPIOF_DIR_IN) + #define GPIOF_IN_PULLUP (GPIOF_DIR_IN | GPIOF_PULLUP) ++#define GPIOF_IN_DEGLITCH (GPIOF_DIR_IN | GPIOF_DEGLITCH) + #define GPIOF_OUT_INIT_LOW (GPIOF_DIR_OUT | GPIOF_INIT_LOW) + #define GPIOF_OUT_INIT_HIGH (GPIOF_DIR_OUT | GPIOF_INIT_HIGH) + |