summaryrefslogtreecommitdiff
path: root/drivers/input/misc/rotary_encoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/misc/rotary_encoder.c')
-rw-r--r--drivers/input/misc/rotary_encoder.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c
index ebbadf3f0579..aeeaaea69610 100644
--- a/drivers/input/misc/rotary_encoder.c
+++ b/drivers/input/misc/rotary_encoder.c
@@ -33,6 +33,7 @@
struct rotary_encoder {
struct input_dev *input;
const struct rotary_encoder_platform_data *pdata;
+ struct mutex access_mutex;
unsigned int axis;
unsigned int pos;
@@ -48,8 +49,8 @@ struct rotary_encoder {
static int rotary_encoder_get_state(const struct rotary_encoder_platform_data *pdata)
{
- int a = !!gpio_get_value(pdata->gpio_a);
- int b = !!gpio_get_value(pdata->gpio_b);
+ int a = !!gpio_get_value_cansleep(pdata->gpio_a);
+ int b = !!gpio_get_value_cansleep(pdata->gpio_b);
a ^= pdata->inverted_a;
b ^= pdata->inverted_b;
@@ -94,6 +95,8 @@ static irqreturn_t rotary_encoder_irq(int irq, void *dev_id)
struct rotary_encoder *encoder = dev_id;
int state;
+ mutex_lock(&encoder->access_mutex);
+
state = rotary_encoder_get_state(encoder->pdata);
switch (state) {
@@ -115,6 +118,8 @@ static irqreturn_t rotary_encoder_irq(int irq, void *dev_id)
break;
}
+ mutex_unlock(&encoder->access_mutex);
+
return IRQ_HANDLED;
}
@@ -123,6 +128,8 @@ static irqreturn_t rotary_encoder_half_period_irq(int irq, void *dev_id)
struct rotary_encoder *encoder = dev_id;
int state;
+ mutex_lock(&encoder->access_mutex);
+
state = rotary_encoder_get_state(encoder->pdata);
switch (state) {
@@ -140,6 +147,8 @@ static irqreturn_t rotary_encoder_half_period_irq(int irq, void *dev_id)
break;
}
+ mutex_unlock(&encoder->access_mutex);
+
return IRQ_HANDLED;
}
@@ -149,6 +158,8 @@ static irqreturn_t rotary_encoder_quarter_period_irq(int irq, void *dev_id)
unsigned char sum;
int state;
+ mutex_lock(&encoder->access_mutex);
+
state = rotary_encoder_get_state(encoder->pdata);
/*
@@ -189,6 +200,8 @@ static irqreturn_t rotary_encoder_quarter_period_irq(int irq, void *dev_id)
out:
encoder->last_stable = state;
+ mutex_unlock(&encoder->access_mutex);
+
return IRQ_HANDLED;
}
@@ -285,6 +298,8 @@ static int rotary_encoder_probe(struct platform_device *pdev)
if (!input)
return -ENOMEM;
+ mutex_init(&encoder->access_mutex);
+
encoder->input = input;
encoder->pdata = pdata;
@@ -337,17 +352,19 @@ static int rotary_encoder_probe(struct platform_device *pdev)
return -EINVAL;
}
- err = devm_request_irq(dev, encoder->irq_a, handler,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- DRV_NAME, encoder);
+ err = devm_request_threaded_irq(dev, encoder->irq_a, NULL, handler,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
+ IRQF_ONESHOT,
+ DRV_NAME, encoder);
if (err) {
dev_err(dev, "unable to request IRQ %d\n", encoder->irq_a);
return err;
}
- err = devm_request_irq(dev, encoder->irq_b, handler,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- DRV_NAME, encoder);
+ err = devm_request_threaded_irq(dev, encoder->irq_b, NULL, handler,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
+ IRQF_ONESHOT,
+ DRV_NAME, encoder);
if (err) {
dev_err(dev, "unable to request IRQ %d\n", encoder->irq_b);
return err;