Commit 666cbe34 authored by David Brownell's avatar David Brownell Committed by Dmitry Torokhov

Input: dm355evm_keys - use threaded IRQs

Convert the dm355evm keys driver to use IRQ threading instead of
a private workqueue.  IRQ threads were added to Linux after this
driver was written, and in this case fit what the driver needs.
(Although the non-shared thread costs more runtime memory.)
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent eef3e4ca
...@@ -23,30 +23,16 @@ ...@@ -23,30 +23,16 @@
* pressed, or its autorepeat kicks in, an event is sent. This driver * pressed, or its autorepeat kicks in, an event is sent. This driver
* read those events from the small (32 event) queue and reports them. * read those events from the small (32 event) queue and reports them.
* *
* Because we communicate with the MSP430 using I2C, and all I2C calls
* in Linux sleep, we need to cons up a kind of threaded IRQ handler
* using a work_struct. The IRQ is active low, but we use it through
* the GPIO controller so we can trigger on falling edges.
*
* Note that physically there can only be one of these devices. * Note that physically there can only be one of these devices.
* *
* This driver was tested with firmware revision A4. * This driver was tested with firmware revision A4.
*/ */
struct dm355evm_keys { struct dm355evm_keys {
struct work_struct work;
struct input_dev *input; struct input_dev *input;
struct device *dev; struct device *dev;
int irq; int irq;
}; };
static irqreturn_t dm355evm_keys_irq(int irq, void *_keys)
{
struct dm355evm_keys *keys = _keys;
schedule_work(&keys->work);
return IRQ_HANDLED;
}
/* These initial keycodes can be remapped by dm355evm_setkeycode(). */ /* These initial keycodes can be remapped by dm355evm_setkeycode(). */
static struct { static struct {
u16 event; u16 event;
...@@ -110,13 +96,12 @@ static struct { ...@@ -110,13 +96,12 @@ static struct {
{ 0x3169, KEY_PAUSE, }, { 0x3169, KEY_PAUSE, },
}; };
static void dm355evm_keys_work(struct work_struct *work) /* runs in an IRQ thread -- can (and will!) sleep */
static irqreturn_t dm355evm_keys_irq(int irq, void *_keys)
{ {
struct dm355evm_keys *keys; struct dm355evm_keys *keys = _keys;
int status; int status;
keys = container_of(work, struct dm355evm_keys, work);
/* For simplicity we ignore INPUT_COUNT and just read /* For simplicity we ignore INPUT_COUNT and just read
* events until we get the "queue empty" indicator. * events until we get the "queue empty" indicator.
* Reading INPUT_LOW decrements the count. * Reading INPUT_LOW decrements the count.
...@@ -183,6 +168,19 @@ static void dm355evm_keys_work(struct work_struct *work) ...@@ -183,6 +168,19 @@ static void dm355evm_keys_work(struct work_struct *work)
input_report_key(keys->input, keycode, 0); input_report_key(keys->input, keycode, 0);
input_sync(keys->input); input_sync(keys->input);
} }
return IRQ_HANDLED;
}
/*
* Because we communicate with the MSP430 using I2C, and all I2C calls
* in Linux sleep, we use a threaded IRQ handler. The IRQ itself is
* active low, but we go through the GPIO controller so we can trigger
* on falling edges and not worry about enabling/disabling the IRQ in
* the keypress handling path.
*/
static irqreturn_t dm355evm_keys_hardirq(int irq, void *_keys)
{
return IRQ_WAKE_THREAD;
} }
static int dm355evm_setkeycode(struct input_dev *dev, int index, int keycode) static int dm355evm_setkeycode(struct input_dev *dev, int index, int keycode)
...@@ -233,7 +231,6 @@ static int __devinit dm355evm_keys_probe(struct platform_device *pdev) ...@@ -233,7 +231,6 @@ static int __devinit dm355evm_keys_probe(struct platform_device *pdev)
keys->dev = &pdev->dev; keys->dev = &pdev->dev;
keys->input = input; keys->input = input;
INIT_WORK(&keys->work, dm355evm_keys_work);
/* set up "threaded IRQ handler" */ /* set up "threaded IRQ handler" */
status = platform_get_irq(pdev, 0); status = platform_get_irq(pdev, 0);
...@@ -260,9 +257,10 @@ static int __devinit dm355evm_keys_probe(struct platform_device *pdev) ...@@ -260,9 +257,10 @@ static int __devinit dm355evm_keys_probe(struct platform_device *pdev)
/* REVISIT: flush the event queue? */ /* REVISIT: flush the event queue? */
status = request_irq(keys->irq, dm355evm_keys_irq, status = request_threaded_irq(keys->irq,
IRQF_TRIGGER_FALLING, dm355evm_keys_hardirq, dm355evm_keys_irq,
dev_name(&pdev->dev), keys); IRQF_TRIGGER_FALLING,
dev_name(&pdev->dev), keys);
if (status < 0) if (status < 0)
goto fail1; goto fail1;
......
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