On Mon, Jul 13, 2009 at 02:22:10PM +0530, Trilok Soni wrote: > Hi Dmitry, > > > I don't see this driver picked up yet in your -next branch. We should > target this driver to be mainlined in next merge window. This is very > important driver for some of the embedded systems, including palm pre > :) > I was wondering if somebody could test the patch below and if it still works then I will apply to the next branch. Thanks! -- Dmitry Input: max7359 - use threaded IRQs From: Dmitry Torokhov <dmitry.torokhov@xxxxxxxxx> Convert max7359 driver to use IRQ threading instead of using workqueue. Signed-off-by: Dmitry Torokhov <dtor@xxxxxxx> --- drivers/input/keyboard/max7359_keypad.c | 34 +++++++++++++------------------ 1 files changed, 14 insertions(+), 20 deletions(-) diff --git a/drivers/input/keyboard/max7359_keypad.c b/drivers/input/keyboard/max7359_keypad.c index e359db3..c823c0b 100644 --- a/drivers/input/keyboard/max7359_keypad.c +++ b/drivers/input/keyboard/max7359_keypad.c @@ -57,8 +57,6 @@ struct max7359_keypad { /* matrix key code map */ unsigned short keycodes[MAX7359_MAX_KEY_NUM]; - struct work_struct work; - struct input_dev *input_dev; struct i2c_client *client; @@ -103,10 +101,10 @@ static void max7359_build_keycode(struct max7359_keypad *keypad, __clear_bit(KEY_RESERVED, input_dev->keybit); } -static void max7359_worker(struct work_struct *work) +/* runs in an IRQ thread -- can (and will!) sleep */ +static irqreturn_t max7359_interrupt(int irq, void *dev_id) { - struct max7359_keypad *keypad = - container_of(work, struct max7359_keypad, work); + struct max7359_keypad *keypad = dev_id; struct input_dev *input_dev = keypad->input_dev; int val, row, col, release, code; @@ -116,26 +114,23 @@ static void max7359_worker(struct work_struct *work) release = val & 0x40; code = (row << 3) + col; + dev_dbg(&keypad->client->dev, + "key[%d:%d] %s\n", row, col, release ? "release" : "press"); + input_event(input_dev, EV_MSC, MSC_SCAN, code); input_report_key(input_dev, keypad->keycodes[code], !release); input_sync(input_dev); enable_irq(keypad->irq); - - dev_dbg(&keypad->client->dev, "key[%d:%d] %s\n", row, col, - (release ? "release" : "press")); + return IRQ_HANDLED; } -static irqreturn_t max7359_interrupt(int irq, void *dev_id) +static irqreturn_t max7359_hardirq(int irq, void *dev_id) { struct max7359_keypad *keypad = dev_id; - if (!work_pending(&keypad->work)) { - disable_irq_nosync(keypad->irq); - schedule_work(&keypad->work); - } - - return IRQ_HANDLED; + disable_irq_nosync(keypad->irq); + return IRQ_WAKE_THREAD; } /* @@ -223,7 +218,6 @@ static int __devinit max7359_probe(struct i2c_client *client, keypad->client = client; keypad->input_dev = input_dev; keypad->irq = client->irq; - INIT_WORK(&keypad->work, max7359_worker); input_dev->name = client->name; input_dev->id.bustype = BUS_I2C; @@ -241,8 +235,9 @@ static int __devinit max7359_probe(struct i2c_client *client, max7359_build_keycode(keypad, keymap_data); - error = request_irq(keypad->irq, max7359_interrupt, - IRQF_TRIGGER_LOW, client->name, keypad); + error = request_threaded_irq(keypad->irq, + max7359_hardirq, max7359_interrupt, + IRQF_TRIGGER_LOW, client->name, keypad); if (error) { dev_err(&client->dev, "failed to register interrupt\n"); goto failed_free_mem; @@ -275,9 +270,8 @@ static int __devexit max7359_remove(struct i2c_client *client) { struct max7359_keypad *keypad = i2c_get_clientdata(client); - cancel_work_sync(&keypad->work); - input_unregister_device(keypad->input_dev); free_irq(keypad->irq, keypad); + input_unregister_device(keypad->input_dev); i2c_set_clientdata(client, NULL); kfree(keypad); -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html