]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.9.30/gpio-omap-return-error-if-requested-debounce-time-is-not-possible.patch
Linux 4.14.95
[thirdparty/kernel/stable-queue.git] / releases / 4.9.30 / gpio-omap-return-error-if-requested-debounce-time-is-not-possible.patch
CommitLineData
899c9bca
GKH
1From 83977443938122baeed28dc9f078db3da9855f7c Mon Sep 17 00:00:00 2001
2From: David Rivshin <DRivshin@allworx.com>
3Date: Mon, 24 Apr 2017 18:56:50 -0400
4Subject: gpio: omap: return error if requested debounce time is not possible
5
6From: David Rivshin <DRivshin@allworx.com>
7
8commit 83977443938122baeed28dc9f078db3da9855f7c upstream.
9
10omap_gpio_debounce() does not validate that the requested debounce
11is within a range it can handle. Instead it lets the register value
12wrap silently, and always returns success.
13
14This can lead to all sorts of unexpected behavior, such as gpio_keys
15asking for a too-long debounce, but getting a very short debounce in
16practice.
17
18Fix this by returning -EINVAL if the requested value does not fit into
19the register field. If there is no debounce clock available at all,
20return -ENOTSUPP.
21
22Fixes: e85ec6c3047b ("gpio: omap: fix omap2_set_gpio_debounce")
23Signed-off-by: David Rivshin <drivshin@allworx.com>
24Acked-by: Grygorii Strashko <grygorii.strashko@ti.com>
25Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
26Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
27
28---
29 drivers/gpio/gpio-omap.c | 23 +++++++++++++++++------
30 1 file changed, 17 insertions(+), 6 deletions(-)
31
32--- a/drivers/gpio/gpio-omap.c
33+++ b/drivers/gpio/gpio-omap.c
34@@ -208,9 +208,11 @@ static inline void omap_gpio_dbck_disabl
35 * OMAP's debounce time is in 31us steps
36 * <debounce time> = (GPIO_DEBOUNCINGTIME[7:0].DEBOUNCETIME + 1) x 31
37 * so we need to convert and round up to the closest unit.
38+ *
39+ * Return: 0 on success, negative error otherwise.
40 */
41-static void omap2_set_gpio_debounce(struct gpio_bank *bank, unsigned offset,
42- unsigned debounce)
43+static int omap2_set_gpio_debounce(struct gpio_bank *bank, unsigned offset,
44+ unsigned debounce)
45 {
46 void __iomem *reg;
47 u32 val;
48@@ -218,11 +220,12 @@ static void omap2_set_gpio_debounce(stru
49 bool enable = !!debounce;
50
51 if (!bank->dbck_flag)
52- return;
53+ return -ENOTSUPP;
54
55 if (enable) {
56 debounce = DIV_ROUND_UP(debounce, 31) - 1;
57- debounce &= OMAP4_GPIO_DEBOUNCINGTIME_MASK;
58+ if ((debounce & OMAP4_GPIO_DEBOUNCINGTIME_MASK) != debounce)
59+ return -EINVAL;
60 }
61
62 l = BIT(offset);
63@@ -255,6 +258,8 @@ static void omap2_set_gpio_debounce(stru
64 bank->context.debounce = debounce;
65 bank->context.debounce_en = val;
66 }
67+
68+ return 0;
69 }
70
71 /**
72@@ -964,14 +969,20 @@ static int omap_gpio_debounce(struct gpi
73 {
74 struct gpio_bank *bank;
75 unsigned long flags;
76+ int ret;
77
78 bank = gpiochip_get_data(chip);
79
80 raw_spin_lock_irqsave(&bank->lock, flags);
81- omap2_set_gpio_debounce(bank, offset, debounce);
82+ ret = omap2_set_gpio_debounce(bank, offset, debounce);
83 raw_spin_unlock_irqrestore(&bank->lock, flags);
84
85- return 0;
86+ if (ret)
87+ dev_info(chip->parent,
88+ "Could not set line %u debounce to %u microseconds (%d)",
89+ offset, debounce, ret);
90+
91+ return ret;
92 }
93
94 static void omap_gpio_set(struct gpio_chip *chip, unsigned offset, int value)