aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/keyboard
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2009-09-22 01:17:57 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2009-09-22 01:27:49 -0400
commit44ca397bcfda83a2b1c3e778c547c05678d7ec69 (patch)
tree08b9fd3234e46209ddaae657d76661e075216a24 /drivers/input/keyboard
parent0baf81ba157cb2b89448f0b73fcd9a4f191be8c6 (diff)
Input: max7359 - use threaded IRQs
Convert max7359 driver to use IRQ threading instead of using workqueue. Tested-by: Joonyoung Shim <jy0922.shim@samsung.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r--drivers/input/keyboard/max7359_keypad.c48
1 files changed, 13 insertions, 35 deletions
diff --git a/drivers/input/keyboard/max7359_keypad.c b/drivers/input/keyboard/max7359_keypad.c
index 8b3ee142a6c6..3b5b948eba39 100644
--- a/drivers/input/keyboard/max7359_keypad.c
+++ b/drivers/input/keyboard/max7359_keypad.c
@@ -58,12 +58,8 @@ struct max7359_keypad {
58 /* matrix key code map */ 58 /* matrix key code map */
59 unsigned short keycodes[MAX7359_MAX_KEY_NUM]; 59 unsigned short keycodes[MAX7359_MAX_KEY_NUM];
60 60
61 struct work_struct work;
62
63 struct input_dev *input_dev; 61 struct input_dev *input_dev;
64 struct i2c_client *client; 62 struct i2c_client *client;
65
66 u32 irq;
67}; 63};
68 64
69static int max7359_write_reg(struct i2c_client *client, u8 reg, u8 val) 65static int max7359_write_reg(struct i2c_client *client, u8 reg, u8 val)
@@ -106,10 +102,10 @@ static void max7359_build_keycode(struct max7359_keypad *keypad,
106 __clear_bit(KEY_RESERVED, input_dev->keybit); 102 __clear_bit(KEY_RESERVED, input_dev->keybit);
107} 103}
108 104
109static void max7359_worker(struct work_struct *work) 105/* runs in an IRQ thread -- can (and will!) sleep */
106static irqreturn_t max7359_interrupt(int irq, void *dev_id)
110{ 107{
111 struct max7359_keypad *keypad = 108 struct max7359_keypad *keypad = dev_id;
112 container_of(work, struct max7359_keypad, work);
113 struct input_dev *input_dev = keypad->input_dev; 109 struct input_dev *input_dev = keypad->input_dev;
114 int val, row, col, release, code; 110 int val, row, col, release, code;
115 111
@@ -120,25 +116,13 @@ static void max7359_worker(struct work_struct *work)
120 116
121 code = MATRIX_SCAN_CODE(row, col, MAX7359_ROW_SHIFT); 117 code = MATRIX_SCAN_CODE(row, col, MAX7359_ROW_SHIFT);
122 118
119 dev_dbg(&keypad->client->dev,
120 "key[%d:%d] %s\n", row, col, release ? "release" : "press");
121
123 input_event(input_dev, EV_MSC, MSC_SCAN, code); 122 input_event(input_dev, EV_MSC, MSC_SCAN, code);
124 input_report_key(input_dev, keypad->keycodes[code], !release); 123 input_report_key(input_dev, keypad->keycodes[code], !release);
125 input_sync(input_dev); 124 input_sync(input_dev);
126 125
127 enable_irq(keypad->irq);
128
129 dev_dbg(&keypad->client->dev, "key[%d:%d] %s\n", row, col,
130 (release ? "release" : "press"));
131}
132
133static irqreturn_t max7359_interrupt(int irq, void *dev_id)
134{
135 struct max7359_keypad *keypad = dev_id;
136
137 if (!work_pending(&keypad->work)) {
138 disable_irq_nosync(keypad->irq);
139 schedule_work(&keypad->work);
140 }
141
142 return IRQ_HANDLED; 126 return IRQ_HANDLED;
143} 127}
144 128
@@ -226,8 +210,6 @@ static int __devinit max7359_probe(struct i2c_client *client,
226 210
227 keypad->client = client; 211 keypad->client = client;
228 keypad->input_dev = input_dev; 212 keypad->input_dev = input_dev;
229 keypad->irq = client->irq;
230 INIT_WORK(&keypad->work, max7359_worker);
231 213
232 input_dev->name = client->name; 214 input_dev->name = client->name;
233 input_dev->id.bustype = BUS_I2C; 215 input_dev->id.bustype = BUS_I2C;
@@ -245,8 +227,9 @@ static int __devinit max7359_probe(struct i2c_client *client,
245 227
246 max7359_build_keycode(keypad, keymap_data); 228 max7359_build_keycode(keypad, keymap_data);
247 229
248 error = request_irq(keypad->irq, max7359_interrupt, 230 error = request_threaded_irq(client->irq, NULL, max7359_interrupt,
249 IRQF_TRIGGER_LOW, client->name, keypad); 231 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
232 client->name, keypad);
250 if (error) { 233 if (error) {
251 dev_err(&client->dev, "failed to register interrupt\n"); 234 dev_err(&client->dev, "failed to register interrupt\n");
252 goto failed_free_mem; 235 goto failed_free_mem;
@@ -268,7 +251,7 @@ static int __devinit max7359_probe(struct i2c_client *client,
268 return 0; 251 return 0;
269 252
270failed_free_irq: 253failed_free_irq:
271 free_irq(keypad->irq, keypad); 254 free_irq(client->irq, keypad);
272failed_free_mem: 255failed_free_mem:
273 input_free_device(input_dev); 256 input_free_device(input_dev);
274 kfree(keypad); 257 kfree(keypad);
@@ -279,9 +262,8 @@ static int __devexit max7359_remove(struct i2c_client *client)
279{ 262{
280 struct max7359_keypad *keypad = i2c_get_clientdata(client); 263 struct max7359_keypad *keypad = i2c_get_clientdata(client);
281 264
282 cancel_work_sync(&keypad->work); 265 free_irq(client->irq, keypad);
283 input_unregister_device(keypad->input_dev); 266 input_unregister_device(keypad->input_dev);
284 free_irq(keypad->irq, keypad);
285 i2c_set_clientdata(client, NULL); 267 i2c_set_clientdata(client, NULL);
286 kfree(keypad); 268 kfree(keypad);
287 269
@@ -291,22 +273,18 @@ static int __devexit max7359_remove(struct i2c_client *client)
291#ifdef CONFIG_PM 273#ifdef CONFIG_PM
292static int max7359_suspend(struct i2c_client *client, pm_message_t mesg) 274static int max7359_suspend(struct i2c_client *client, pm_message_t mesg)
293{ 275{
294 struct max7359_keypad *keypad = i2c_get_clientdata(client);
295
296 max7359_fall_deepsleep(client); 276 max7359_fall_deepsleep(client);
297 277
298 if (device_may_wakeup(&client->dev)) 278 if (device_may_wakeup(&client->dev))
299 enable_irq_wake(keypad->irq); 279 enable_irq_wake(client->irq);
300 280
301 return 0; 281 return 0;
302} 282}
303 283
304static int max7359_resume(struct i2c_client *client) 284static int max7359_resume(struct i2c_client *client)
305{ 285{
306 struct max7359_keypad *keypad = i2c_get_clientdata(client);
307
308 if (device_may_wakeup(&client->dev)) 286 if (device_may_wakeup(&client->dev))
309 disable_irq_wake(keypad->irq); 287 disable_irq_wake(client->irq);
310 288
311 /* Restore the default setting */ 289 /* Restore the default setting */
312 max7359_take_catnap(client); 290 max7359_take_catnap(client);