diff options
Diffstat (limited to 'drivers/input/keyboard/gpio_keys.c')
-rw-r--r-- | drivers/input/keyboard/gpio_keys.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index bef317ff7352..29093657f2ef 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -96,7 +96,7 @@ struct gpio_keys_drvdata { * Return value of this function can be used to allocate bitmap * large enough to hold all bits for given type. */ -static inline int get_n_events_by_type(int type) +static int get_n_events_by_type(int type) { BUG_ON(type != EV_SW && type != EV_KEY); @@ -104,6 +104,22 @@ static inline int get_n_events_by_type(int type) } /** + * get_bm_events_by_type() - returns bitmap of supported events per @type + * @input: input device from which bitmap is retrieved + * @type: type of button (%EV_KEY, %EV_SW) + * + * Return value of this function can be used to allocate bitmap + * large enough to hold all bits for given type. + */ +static const unsigned long *get_bm_events_by_type(struct input_dev *dev, + int type) +{ + BUG_ON(type != EV_SW && type != EV_KEY); + + return (type == EV_KEY) ? dev->keybit : dev->swbit; +} + +/** * gpio_keys_disable_button() - disables given GPIO button * @bdata: button data for button to be disabled * @@ -213,6 +229,7 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, const char *buf, unsigned int type) { int n_events = get_n_events_by_type(type); + const unsigned long *bitmap = get_bm_events_by_type(ddata->input, type); unsigned long *bits; ssize_t error; int i; @@ -226,6 +243,11 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, goto out; /* First validate */ + if (!bitmap_subset(bits, bitmap, n_events)) { + error = -EINVAL; + goto out; + } + for (i = 0; i < ddata->pdata->nbuttons; i++) { struct gpio_button_data *bdata = &ddata->data[i]; @@ -239,11 +261,6 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, } } - if (i == ddata->pdata->nbuttons) { - error = -EINVAL; - goto out; - } - mutex_lock(&ddata->disable_lock); for (i = 0; i < ddata->pdata->nbuttons; i++) { @@ -613,7 +630,7 @@ gpio_keys_get_devtree_pdata(struct device *dev) if (!node) return ERR_PTR(-ENODEV); - nbuttons = of_get_child_count(node); + nbuttons = of_get_available_child_count(node); if (nbuttons == 0) return ERR_PTR(-ENODEV); @@ -628,8 +645,10 @@ gpio_keys_get_devtree_pdata(struct device *dev) pdata->rep = !!of_get_property(node, "autorepeat", NULL); + of_property_read_string(node, "label", &pdata->name); + i = 0; - for_each_child_of_node(node, pp) { + for_each_available_child_of_node(node, pp) { enum of_gpio_flags flags; button = &pdata->buttons[i++]; |