From: "Timo Teräs" <timo.teras@iki.fi>
To: "linux-input@vger.kernel.org" <linux-input@vger.kernel.org>
Cc: "Timo Teräs" <timo.teras@iki.fi>
Subject: [PATCH 3/3] Input: rotary_encoder - use threaded irqs
Date: Fri, 15 Jan 2016 22:33:50 +0200 [thread overview]
Message-ID: <1452890030-23316-3-git-send-email-timo.teras@iki.fi> (raw)
In-Reply-To: <1452890030-23316-1-git-send-email-timo.teras@iki.fi>
Convert to use threaded IRQs to support GPIOs that can sleep.
Protect the irq handler with mutex as it can be triggered from
two different irq lines accessing the same state.
This allows using GPIO expanders behind I2C or SPI bus.
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
---
drivers/input/misc/rotary_encoder.c | 26 ++++++++++++++++++--------
1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c
index 156f40f..a2d47ce 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,7 @@ 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) {
@@ -114,6 +116,7 @@ static irqreturn_t rotary_encoder_irq(int irq, void *dev_id)
encoder->armed = true;
break;
}
+ mutex_unlock(&encoder->access_mutex);
return IRQ_HANDLED;
}
@@ -123,6 +126,7 @@ 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) {
@@ -139,6 +143,7 @@ static irqreturn_t rotary_encoder_half_period_irq(int irq, void *dev_id)
encoder->dir = (encoder->last_stable + state) & 0x01;
break;
}
+ mutex_unlock(&encoder->access_mutex);
return IRQ_HANDLED;
}
@@ -149,6 +154,7 @@ 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 +195,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;
}
@@ -288,6 +296,8 @@ static int rotary_encoder_probe(struct platform_device *pdev)
if (!encoder || !input)
return -ENOMEM;
+ mutex_init(&encoder->access_mutex);
+
encoder->input = input;
encoder->pdata = pdata;
@@ -338,17 +348,17 @@ 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,
+ 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,
+ DRV_NAME, encoder);
if (err) {
dev_err(dev, "unable to request IRQ %d\n", encoder->irq_b);
return err;
--
2.7.0
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2016-01-15 20:33 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-15 20:33 [PATCH 1/3] Input: rotary_encoder - convert to devm-* api Timo Teräs
2016-01-15 20:33 ` [PATCH 2/3] Input: rotary_encoder - fix device tree error handling Timo Teräs
2016-01-16 19:02 ` Dmitry Torokhov
2016-01-18 14:00 ` Timo Teras
2016-01-15 20:33 ` Timo Teräs [this message]
2016-01-17 4:43 ` [PATCH 1/3] Input: rotary_encoder - convert to devm-* api Dmitry Torokhov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1452890030-23316-3-git-send-email-timo.teras@iki.fi \
--to=timo.teras@iki.fi \
--cc=linux-input@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).