Commit 0df883df authored by Linus Walleij's avatar Linus Walleij Committed by Samuel Ortiz

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: default avatarLinus Walleij <linus.walleij@stericsson.com>
Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
parent 38f6ce45
...@@ -365,10 +365,13 @@ int ab3100_event_registers_startup_state_get(struct ab3100 *ab3100, ...@@ -365,10 +365,13 @@ int ab3100_event_registers_startup_state_get(struct ab3100 *ab3100,
} }
EXPORT_SYMBOL(ab3100_event_registers_startup_state_get); 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]; u8 event_regs[3];
u32 fatevent; u32 fatevent;
int err; int err;
...@@ -376,7 +379,7 @@ static void ab3100_work(struct work_struct *work) ...@@ -376,7 +379,7 @@ static void ab3100_work(struct work_struct *work)
err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1, err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1,
event_regs, 3); event_regs, 3);
if (err) if (err)
goto err_event_wq; goto err_event;
fatevent = (event_regs[0] << 16) | fatevent = (event_regs[0] << 16) |
(event_regs[1] << 8) | (event_regs[1] << 8) |
...@@ -398,29 +401,11 @@ static void ab3100_work(struct work_struct *work) ...@@ -398,29 +401,11 @@ static void ab3100_work(struct work_struct *work)
dev_dbg(ab3100->dev, dev_dbg(ab3100->dev,
"IRQ Event: 0x%08x\n", fatevent); "IRQ Event: 0x%08x\n", fatevent);
/* By now the IRQ should be acked and deasserted so enable it again */ return IRQ_HANDLED;
enable_irq(ab3100->i2c_client->irq);
return;
err_event_wq: err_event:
dev_dbg(ab3100->dev, dev_dbg(ab3100->dev,
"error in event workqueue\n"); "error reading event status\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);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -904,12 +889,10 @@ static int __init ab3100_probe(struct i2c_client *client, ...@@ -904,12 +889,10 @@ static int __init ab3100_probe(struct i2c_client *client,
if (err) if (err)
goto exit_no_setup; goto exit_no_setup;
INIT_WORK(&ab3100->work, ab3100_work);
/* This real unpredictable IRQ is of course sampled for entropy */ /* This real unpredictable IRQ is of course sampled for entropy */
err = request_irq(client->irq, ab3100_irq_handler, err = request_threaded_irq(client->irq, NULL, ab3100_irq_handler,
IRQF_DISABLED | IRQF_SAMPLE_RANDOM, IRQF_ONESHOT,
"AB3100 IRQ", ab3100); "ab3100-core", ab3100);
if (err) if (err)
goto exit_no_irq; goto exit_no_irq;
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
*/ */
#include <linux/device.h> #include <linux/device.h>
#include <linux/workqueue.h>
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
#ifndef MFD_AB3100_H #ifndef MFD_AB3100_H
...@@ -74,7 +73,6 @@ ...@@ -74,7 +73,6 @@
* @testreg_client: secondary client for test registers * @testreg_client: secondary client for test registers
* @chip_name: name of this chip variant * @chip_name: name of this chip variant
* @chip_id: 8 bit chip ID for 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 * @event_subscribers: event subscribers are listed here
* @startup_events: a copy of the first reading of the event registers * @startup_events: a copy of the first reading of the event registers
* @startup_events_read: whether the first events have been read * @startup_events_read: whether the first events have been read
...@@ -90,7 +88,6 @@ struct ab3100 { ...@@ -90,7 +88,6 @@ struct ab3100 {
struct i2c_client *testreg_client; struct i2c_client *testreg_client;
char chip_name[32]; char chip_name[32];
u8 chip_id; u8 chip_id;
struct work_struct work;
struct blocking_notifier_head event_subscribers; struct blocking_notifier_head event_subscribers;
u32 startup_events; u32 startup_events;
bool startup_events_read; bool startup_events_read;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment