Skip to content

Commit

Permalink
mfd: Convert AB3100 driver to threaded IRQ
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Linus Walleij authored and Samuel Ortiz committed Mar 7, 2010
1 parent 38f6ce4 commit 0df883d
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 33 deletions.
43 changes: 13 additions & 30 deletions drivers/mfd/ab3100-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,18 +365,21 @@ int ab3100_event_registers_startup_state_get(struct ab3100 *ab3100,
}
EXPORT_SYMBOL(ab3100_event_registers_startup_state_get);

/* Interrupt handling worker */
static void ab3100_work(struct work_struct *work)
/*
* This is a threaded interrupt handler so we can make some
* I2C calls etc.
*/
static irqreturn_t ab3100_irq_handler(int irq, void *data)
{
struct ab3100 *ab3100 = container_of(work, struct ab3100, work);
struct ab3100 *ab3100 = data;
u8 event_regs[3];
u32 fatevent;
int err;

err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1,
event_regs, 3);
if (err)
goto err_event_wq;
goto err_event;

fatevent = (event_regs[0] << 16) |
(event_regs[1] << 8) |
Expand All @@ -398,29 +401,11 @@ static void ab3100_work(struct work_struct *work)
dev_dbg(ab3100->dev,
"IRQ Event: 0x%08x\n", fatevent);

/* By now the IRQ should be acked and deasserted so enable it again */
enable_irq(ab3100->i2c_client->irq);
return;
return IRQ_HANDLED;

err_event_wq:
err_event:
dev_dbg(ab3100->dev,
"error in event workqueue\n");
/* Enable the IRQ anyway, what choice do we have? */
enable_irq(ab3100->i2c_client->irq);
return;
}

static irqreturn_t ab3100_irq_handler(int irq, void *data)
{
struct ab3100 *ab3100 = data;
/*
* Disable the IRQ and dispatch a worker to handle the
* event. Since the chip resides on I2C this is slow
* stuff and we will re-enable the interrupts once th
* worker has finished.
*/
disable_irq_nosync(irq);
schedule_work(&ab3100->work);
"error reading event status\n");
return IRQ_HANDLED;
}

Expand Down Expand Up @@ -904,12 +889,10 @@ static int __init ab3100_probe(struct i2c_client *client,
if (err)
goto exit_no_setup;

INIT_WORK(&ab3100->work, ab3100_work);

/* This real unpredictable IRQ is of course sampled for entropy */
err = request_irq(client->irq, ab3100_irq_handler,
IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
"AB3100 IRQ", ab3100);
err = request_threaded_irq(client->irq, NULL, ab3100_irq_handler,
IRQF_ONESHOT,
"ab3100-core", ab3100);
if (err)
goto exit_no_irq;

Expand Down
3 changes: 0 additions & 3 deletions include/linux/mfd/ab3100.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
*/

#include <linux/device.h>
#include <linux/workqueue.h>
#include <linux/regulator/machine.h>

#ifndef MFD_AB3100_H
Expand Down Expand Up @@ -74,7 +73,6 @@
* @testreg_client: secondary client for test registers
* @chip_name: name of this chip variant
* @chip_id: 8 bit chip ID for this chip variant
* @work: an event handling worker
* @event_subscribers: event subscribers are listed here
* @startup_events: a copy of the first reading of the event registers
* @startup_events_read: whether the first events have been read
Expand All @@ -90,7 +88,6 @@ struct ab3100 {
struct i2c_client *testreg_client;
char chip_name[32];
u8 chip_id;
struct work_struct work;
struct blocking_notifier_head event_subscribers;
u32 startup_events;
bool startup_events_read;
Expand Down

0 comments on commit 0df883d

Please sign in to comment.