Commit 43a365ab authored by Dmitry Torokhov's avatar Dmitry Torokhov

Input: gpio-keys - switch to using cleanup functions

Start using __free() and guard() primitives to simplify the code
and error handling. This makes the code more compact and error
handling more robust by ensuring that locks are released in all
code paths when control leaves critical section and all allocated
memory is freed.
Reviewed-by: default avatarHans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20240825051627.2848495-6-dmitry.torokhov@gmail.comSigned-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 934976f6
...@@ -245,23 +245,20 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, ...@@ -245,23 +245,20 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata,
{ {
int n_events = get_n_events_by_type(type); int n_events = get_n_events_by_type(type);
const unsigned long *bitmap = get_bm_events_by_type(ddata->input, type); const unsigned long *bitmap = get_bm_events_by_type(ddata->input, type);
unsigned long *bits;
ssize_t error; ssize_t error;
int i; int i;
bits = bitmap_alloc(n_events, GFP_KERNEL); unsigned long *bits __free(bitmap) = bitmap_alloc(n_events, GFP_KERNEL);
if (!bits) if (!bits)
return -ENOMEM; return -ENOMEM;
error = bitmap_parselist(buf, bits, n_events); error = bitmap_parselist(buf, bits, n_events);
if (error) if (error)
goto out; return error;
/* First validate */ /* First validate */
if (!bitmap_subset(bits, bitmap, n_events)) { if (!bitmap_subset(bits, bitmap, n_events))
error = -EINVAL; return -EINVAL;
goto out;
}
for (i = 0; i < ddata->pdata->nbuttons; i++) { for (i = 0; i < ddata->pdata->nbuttons; i++) {
struct gpio_button_data *bdata = &ddata->data[i]; struct gpio_button_data *bdata = &ddata->data[i];
...@@ -271,12 +268,11 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, ...@@ -271,12 +268,11 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata,
if (test_bit(*bdata->code, bits) && if (test_bit(*bdata->code, bits) &&
!bdata->button->can_disable) { !bdata->button->can_disable) {
error = -EINVAL; return -EINVAL;
goto out;
} }
} }
mutex_lock(&ddata->disable_lock); guard(mutex)(&ddata->disable_lock);
for (i = 0; i < ddata->pdata->nbuttons; i++) { for (i = 0; i < ddata->pdata->nbuttons; i++) {
struct gpio_button_data *bdata = &ddata->data[i]; struct gpio_button_data *bdata = &ddata->data[i];
...@@ -290,11 +286,7 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, ...@@ -290,11 +286,7 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata,
gpio_keys_enable_button(bdata); gpio_keys_enable_button(bdata);
} }
mutex_unlock(&ddata->disable_lock); return 0;
out:
bitmap_free(bits);
return error;
} }
#define ATTR_SHOW_FN(name, type, only_disabled) \ #define ATTR_SHOW_FN(name, type, only_disabled) \
...@@ -470,11 +462,10 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id) ...@@ -470,11 +462,10 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id)
{ {
struct gpio_button_data *bdata = dev_id; struct gpio_button_data *bdata = dev_id;
struct input_dev *input = bdata->input; struct input_dev *input = bdata->input;
unsigned long flags;
BUG_ON(irq != bdata->irq); BUG_ON(irq != bdata->irq);
spin_lock_irqsave(&bdata->lock, flags); guard(spinlock_irqsave)(&bdata->lock);
if (!bdata->key_pressed) { if (!bdata->key_pressed) {
if (bdata->button->wakeup) if (bdata->button->wakeup)
...@@ -497,7 +488,6 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id) ...@@ -497,7 +488,6 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id)
ms_to_ktime(bdata->release_delay), ms_to_ktime(bdata->release_delay),
HRTIMER_MODE_REL_HARD); HRTIMER_MODE_REL_HARD);
out: out:
spin_unlock_irqrestore(&bdata->lock, flags);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -1062,10 +1052,10 @@ static int gpio_keys_suspend(struct device *dev) ...@@ -1062,10 +1052,10 @@ static int gpio_keys_suspend(struct device *dev)
if (error) if (error)
return error; return error;
} else { } else {
mutex_lock(&input->mutex); guard(mutex)(&input->mutex);
if (input_device_enabled(input)) if (input_device_enabled(input))
gpio_keys_close(input); gpio_keys_close(input);
mutex_unlock(&input->mutex);
} }
return 0; return 0;
...@@ -1075,19 +1065,19 @@ static int gpio_keys_resume(struct device *dev) ...@@ -1075,19 +1065,19 @@ static int gpio_keys_resume(struct device *dev)
{ {
struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev); struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev);
struct input_dev *input = ddata->input; struct input_dev *input = ddata->input;
int error = 0; int error;
if (device_may_wakeup(dev)) { if (device_may_wakeup(dev)) {
gpio_keys_disable_wakeup(ddata); gpio_keys_disable_wakeup(ddata);
} else { } else {
mutex_lock(&input->mutex); guard(mutex)(&input->mutex);
if (input_device_enabled(input))
error = gpio_keys_open(input);
mutex_unlock(&input->mutex);
}
if (input_device_enabled(input)) {
error = gpio_keys_open(input);
if (error) if (error)
return error; return error;
}
}
gpio_keys_report_state(ddata); gpio_keys_report_state(ddata);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment