diff options
author | Linus Walleij <linus.walleij@stericsson.com> | 2010-01-08 04:44:16 -0500 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2010-03-07 16:17:00 -0500 |
commit | 0df883df8e8aea79b501f6262b595e66dec175dc (patch) | |
tree | 4b63d615304b2c7c00f2ca3433b83cb9d28d6bfc | |
parent | 38f6ce45f0bca04ac653c57cacd375c469995321 (diff) |
mfd: Convert AB3100 driver to threaded IRQ
This converts the AB3100 core MFD driver to use a threaded
interrupt handler instead of the explicit top/bottom-half
construction with a workqueue. This saves some code and make it
more similar to other modern MFD drivers.
Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r-- | drivers/mfd/ab3100-core.c | 43 | ||||
-rw-r--r-- | include/linux/mfd/ab3100.h | 3 |
2 files changed, 13 insertions, 33 deletions
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c index fd42a80e7bf9..aa3824a1b4f2 100644 --- a/drivers/mfd/ab3100-core.c +++ b/drivers/mfd/ab3100-core.c | |||
@@ -365,10 +365,13 @@ int ab3100_event_registers_startup_state_get(struct ab3100 *ab3100, | |||
365 | } | 365 | } |
366 | EXPORT_SYMBOL(ab3100_event_registers_startup_state_get); | 366 | EXPORT_SYMBOL(ab3100_event_registers_startup_state_get); |
367 | 367 | ||
368 | /* Interrupt handling worker */ | 368 | /* |
369 | static void ab3100_work(struct work_struct *work) | 369 | * This is a threaded interrupt handler so we can make some |
370 | * I2C calls etc. | ||
371 | */ | ||
372 | static irqreturn_t ab3100_irq_handler(int irq, void *data) | ||
370 | { | 373 | { |
371 | struct ab3100 *ab3100 = container_of(work, struct ab3100, work); | 374 | struct ab3100 *ab3100 = data; |
372 | u8 event_regs[3]; | 375 | u8 event_regs[3]; |
373 | u32 fatevent; | 376 | u32 fatevent; |
374 | int err; | 377 | int err; |
@@ -376,7 +379,7 @@ static void ab3100_work(struct work_struct *work) | |||
376 | err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1, | 379 | err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1, |
377 | event_regs, 3); | 380 | event_regs, 3); |
378 | if (err) | 381 | if (err) |
379 | goto err_event_wq; | 382 | goto err_event; |
380 | 383 | ||
381 | fatevent = (event_regs[0] << 16) | | 384 | fatevent = (event_regs[0] << 16) | |
382 | (event_regs[1] << 8) | | 385 | (event_regs[1] << 8) | |
@@ -398,29 +401,11 @@ static void ab3100_work(struct work_struct *work) | |||
398 | dev_dbg(ab3100->dev, | 401 | dev_dbg(ab3100->dev, |
399 | "IRQ Event: 0x%08x\n", fatevent); | 402 | "IRQ Event: 0x%08x\n", fatevent); |
400 | 403 | ||
401 | /* By now the IRQ should be acked and deasserted so enable it again */ | 404 | return IRQ_HANDLED; |
402 | enable_irq(ab3100->i2c_client->irq); | ||
403 | return; | ||
404 | 405 | ||
405 | err_event_wq: | 406 | err_event: |
406 | dev_dbg(ab3100->dev, | 407 | dev_dbg(ab3100->dev, |
407 | "error in event workqueue\n"); | 408 | "error reading event status\n"); |
408 | /* Enable the IRQ anyway, what choice do we have? */ | ||
409 | enable_irq(ab3100->i2c_client->irq); | ||
410 | return; | ||
411 | } | ||
412 | |||
413 | static irqreturn_t ab3100_irq_handler(int irq, void *data) | ||
414 | { | ||
415 | struct ab3100 *ab3100 = data; | ||
416 | /* | ||
417 | * Disable the IRQ and dispatch a worker to handle the | ||
418 | * event. Since the chip resides on I2C this is slow | ||
419 | * stuff and we will re-enable the interrupts once th | ||
420 | * worker has finished. | ||
421 | */ | ||
422 | disable_irq_nosync(irq); | ||
423 | schedule_work(&ab3100->work); | ||
424 | return IRQ_HANDLED; | 409 | return IRQ_HANDLED; |
425 | } | 410 | } |
426 | 411 | ||
@@ -904,12 +889,10 @@ static int __init ab3100_probe(struct i2c_client *client, | |||
904 | if (err) | 889 | if (err) |
905 | goto exit_no_setup; | 890 | goto exit_no_setup; |
906 | 891 | ||
907 | INIT_WORK(&ab3100->work, ab3100_work); | ||
908 | |||
909 | /* This real unpredictable IRQ is of course sampled for entropy */ | 892 | /* This real unpredictable IRQ is of course sampled for entropy */ |
910 | err = request_irq(client->irq, ab3100_irq_handler, | 893 | err = request_threaded_irq(client->irq, NULL, ab3100_irq_handler, |
911 | IRQF_DISABLED | IRQF_SAMPLE_RANDOM, | 894 | IRQF_ONESHOT, |
912 | "AB3100 IRQ", ab3100); | 895 | "ab3100-core", ab3100); |
913 | if (err) | 896 | if (err) |
914 | goto exit_no_irq; | 897 | goto exit_no_irq; |
915 | 898 | ||
diff --git a/include/linux/mfd/ab3100.h b/include/linux/mfd/ab3100.h index e9aa4c9d749d..9a881c305a50 100644 --- a/include/linux/mfd/ab3100.h +++ b/include/linux/mfd/ab3100.h | |||
@@ -6,7 +6,6 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <linux/device.h> | 8 | #include <linux/device.h> |
9 | #include <linux/workqueue.h> | ||
10 | #include <linux/regulator/machine.h> | 9 | #include <linux/regulator/machine.h> |
11 | 10 | ||
12 | #ifndef MFD_AB3100_H | 11 | #ifndef MFD_AB3100_H |
@@ -74,7 +73,6 @@ | |||
74 | * @testreg_client: secondary client for test registers | 73 | * @testreg_client: secondary client for test registers |
75 | * @chip_name: name of this chip variant | 74 | * @chip_name: name of this chip variant |
76 | * @chip_id: 8 bit chip ID for this chip variant | 75 | * @chip_id: 8 bit chip ID for this chip variant |
77 | * @work: an event handling worker | ||
78 | * @event_subscribers: event subscribers are listed here | 76 | * @event_subscribers: event subscribers are listed here |
79 | * @startup_events: a copy of the first reading of the event registers | 77 | * @startup_events: a copy of the first reading of the event registers |
80 | * @startup_events_read: whether the first events have been read | 78 | * @startup_events_read: whether the first events have been read |
@@ -90,7 +88,6 @@ struct ab3100 { | |||
90 | struct i2c_client *testreg_client; | 88 | struct i2c_client *testreg_client; |
91 | char chip_name[32]; | 89 | char chip_name[32]; |
92 | u8 chip_id; | 90 | u8 chip_id; |
93 | struct work_struct work; | ||
94 | struct blocking_notifier_head event_subscribers; | 91 | struct blocking_notifier_head event_subscribers; |
95 | u32 startup_events; | 92 | u32 startup_events; |
96 | bool startup_events_read; | 93 | bool startup_events_read; |