Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+20 −22
Original line number Diff line number Diff line
@@ -23,30 +23,16 @@
 * pressed, or its autorepeat kicks in, an event is sent.  This driver
 * 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.
 *
 * This driver was tested with firmware revision A4.
 */
struct dm355evm_keys {
	struct work_struct	work;
	struct input_dev	*input;
	struct device		*dev;
	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(). */
static struct {
	u16	event;
@@ -110,13 +96,12 @@ static struct {
	{ 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;

	keys = container_of(work, struct dm355evm_keys, work);

	/* For simplicity we ignore INPUT_COUNT and just read
	 * events until we get the "queue empty" indicator.
	 * Reading INPUT_LOW decrements the count.
@@ -183,6 +168,19 @@ static void dm355evm_keys_work(struct work_struct *work)
		input_report_key(keys->input, keycode, 0);
		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)
@@ -233,7 +231,6 @@ static int __devinit dm355evm_keys_probe(struct platform_device *pdev)

	keys->dev = &pdev->dev;
	keys->input = input;
	INIT_WORK(&keys->work, dm355evm_keys_work);

	/* set up "threaded IRQ handler" */
	status = platform_get_irq(pdev, 0);
@@ -260,7 +257,8 @@ static int __devinit dm355evm_keys_probe(struct platform_device *pdev)

	/* REVISIT:  flush the event queue? */

	status = request_irq(keys->irq, dm355evm_keys_irq,
	status = request_threaded_irq(keys->irq,
			dm355evm_keys_hardirq, dm355evm_keys_irq,
			IRQF_TRIGGER_FALLING,
			dev_name(&pdev->dev), keys);
	if (status < 0)