diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-09-22 01:17:57 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-09-22 01:27:49 -0400 |
commit | 44ca397bcfda83a2b1c3e778c547c05678d7ec69 (patch) | |
tree | 08b9fd3234e46209ddaae657d76661e075216a24 /drivers/input | |
parent | 0baf81ba157cb2b89448f0b73fcd9a4f191be8c6 (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')
-rw-r--r-- | drivers/input/keyboard/max7359_keypad.c | 48 |
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 | ||
69 | static int max7359_write_reg(struct i2c_client *client, u8 reg, u8 val) | 65 | static 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 | ||
109 | static void max7359_worker(struct work_struct *work) | 105 | /* runs in an IRQ thread -- can (and will!) sleep */ |
106 | static 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 | |||
133 | static 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 | ||
270 | failed_free_irq: | 253 | failed_free_irq: |
271 | free_irq(keypad->irq, keypad); | 254 | free_irq(client->irq, keypad); |
272 | failed_free_mem: | 255 | failed_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 |
292 | static int max7359_suspend(struct i2c_client *client, pm_message_t mesg) | 274 | static 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 | ||
304 | static int max7359_resume(struct i2c_client *client) | 284 | static 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); |