aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2016-01-06 17:20:07 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2016-01-10 12:51:56 -0500
commit8679ee4204cfd5cf78b996508ccadc1ec6130f1a (patch)
treeba1cabafbfacc1fca1797636546d0ca5a0b943d1 /drivers/input
parent35f8679f577ae5673a778598bcbe7b45cbec8923 (diff)
Input: gpio-keys - fix check for disabling unsupported keys
Commit 4ea14a53d8f881034fa9e186653821c4e3d9a8fb ("Input: gpio-keys - report error when disabling unsupported key") tried let user know that they attempted to disable an unsupported key, unfortunately the check is wrong as it believes that all codes are invalid. Fix it by ensuring that keys that we try to disable are subset of keys (or switches) that device reports. Fixes: 4ea14a53d8f8 ("Input: gpio-keys - report error when disabling unsupported key") Reported-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com> Tested-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/keyboard/gpio_keys.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index bef317ff7352..b9f01bd1b7ef 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -96,7 +96,7 @@ struct gpio_keys_drvdata {
96 * Return value of this function can be used to allocate bitmap 96 * Return value of this function can be used to allocate bitmap
97 * large enough to hold all bits for given type. 97 * large enough to hold all bits for given type.
98 */ 98 */
99static inline int get_n_events_by_type(int type) 99static int get_n_events_by_type(int type)
100{ 100{
101 BUG_ON(type != EV_SW && type != EV_KEY); 101 BUG_ON(type != EV_SW && type != EV_KEY);
102 102
@@ -104,6 +104,22 @@ static inline int get_n_events_by_type(int type)
104} 104}
105 105
106/** 106/**
107 * get_bm_events_by_type() - returns bitmap of supported events per @type
108 * @input: input device from which bitmap is retrieved
109 * @type: type of button (%EV_KEY, %EV_SW)
110 *
111 * Return value of this function can be used to allocate bitmap
112 * large enough to hold all bits for given type.
113 */
114static const unsigned long *get_bm_events_by_type(struct input_dev *dev,
115 int type)
116{
117 BUG_ON(type != EV_SW && type != EV_KEY);
118
119 return (type == EV_KEY) ? dev->keybit : dev->swbit;
120}
121
122/**
107 * gpio_keys_disable_button() - disables given GPIO button 123 * gpio_keys_disable_button() - disables given GPIO button
108 * @bdata: button data for button to be disabled 124 * @bdata: button data for button to be disabled
109 * 125 *
@@ -213,6 +229,7 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata,
213 const char *buf, unsigned int type) 229 const char *buf, unsigned int type)
214{ 230{
215 int n_events = get_n_events_by_type(type); 231 int n_events = get_n_events_by_type(type);
232 const unsigned long *bitmap = get_bm_events_by_type(ddata->input, type);
216 unsigned long *bits; 233 unsigned long *bits;
217 ssize_t error; 234 ssize_t error;
218 int i; 235 int i;
@@ -226,6 +243,11 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata,
226 goto out; 243 goto out;
227 244
228 /* First validate */ 245 /* First validate */
246 if (!bitmap_subset(bits, bitmap, n_events)) {
247 error = -EINVAL;
248 goto out;
249 }
250
229 for (i = 0; i < ddata->pdata->nbuttons; i++) { 251 for (i = 0; i < ddata->pdata->nbuttons; i++) {
230 struct gpio_button_data *bdata = &ddata->data[i]; 252 struct gpio_button_data *bdata = &ddata->data[i];
231 253
@@ -239,11 +261,6 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata,
239 } 261 }
240 } 262 }
241 263
242 if (i == ddata->pdata->nbuttons) {
243 error = -EINVAL;
244 goto out;
245 }
246
247 mutex_lock(&ddata->disable_lock); 264 mutex_lock(&ddata->disable_lock);
248 265
249 for (i = 0; i < ddata->pdata->nbuttons; i++) { 266 for (i = 0; i < ddata->pdata->nbuttons; i++) {