diff options
| author | Simon Wilson <simonwilson@google.com> | 2014-07-29 12:46:03 -0700 |
|---|---|---|
| committer | Douglas Zobel <dzobel1@motorola.com> | 2014-08-07 02:10:45 +0000 |
| commit | 767129434361fd64e64f975b5c559cf0e3a1d58f (patch) | |
| tree | 2e188b5758b8f374906ffe16ac6dc11488cbad5c | |
| parent | 275fa5a308cf364128a137c056fc55149f3a0896 (diff) | |
| download | olio-linux-3.10-767129434361fd64e64f975b5c559cf0e3a1d58f.tar.xz olio-linux-3.10-767129434361fd64e64f975b5c559cf0e3a1d58f.zip | |
mfd: sensorhub: convert to threaded IRQ handler
Change-Id: Id1c895ffdae01b085b79adc3934c5a2438a12157
Signed-off-by: Simon Wilson <simonwilson@google.com>
| -rw-r--r-- | drivers/mfd/m4sensorhub-irq.c | 47 | ||||
| -rw-r--r-- | include/linux/m4sensorhub.h | 1 |
2 files changed, 10 insertions, 38 deletions
diff --git a/drivers/mfd/m4sensorhub-irq.c b/drivers/mfd/m4sensorhub-irq.c index 139359cc73e..41c8378c142 100644 --- a/drivers/mfd/m4sensorhub-irq.c +++ b/drivers/mfd/m4sensorhub-irq.c @@ -20,7 +20,6 @@ #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/mutex.h> -#include <linux/workqueue.h> #include <linux/wakelock.h> #include <linux/i2c.h> #include <linux/slab.h> @@ -47,7 +46,7 @@ /* ------------ Local Function Prototypes ----------- */ static unsigned short get_enable_reg(enum m4sensorhub_irqs event); -static void irq_work_func(struct work_struct *work); +static irqreturn_t event_threaded(int irq, void *devid); #ifdef CONFIG_DEBUG_FS static int m4sensorhub_dbg_irq_open(struct inode *inode, struct file *file); #endif @@ -95,8 +94,6 @@ struct m4sensorhub_irq_info { struct m4sensorhub_irqdata { struct mutex lock; /* lock event handlers and data */ - struct work_struct work; - struct workqueue_struct *workqueue; struct m4sensorhub_data *m4sensorhub; struct m4sensorhub_event_handler event_handler[M4SH_IRQ__NUM]; struct m4sensorhub_irq_info irq_info[M4SH_IRQ__NUM]; @@ -126,21 +123,11 @@ static const struct { static irqreturn_t event_isr(int irq, void *data) { - /* Interrupts are left enabled; if multiple interrupts arrive, there - * will be multiple jobs in the workqueue. In this case, the first - * job in the workqueue may service multple interrupts and - * susbsequent jobs will have no interrupts left to service. - */ struct m4sensorhub_irqdata *irq_data = data; - disable_irq_nosync(irq_data->m4sensorhub->i2c_client->irq); - wake_lock(&irq_data->wake_lock); - - if (irq_data->m4sensorhub->irq_dbg.suspend == 1) - irq_data->m4sensorhub->irq_dbg.print_irqs = 1; - queue_work(irq_data->workqueue, &irq_data->work); + wake_lock(&irq_data->wake_lock); - return IRQ_HANDLED; + return IRQ_WAKE_THREAD; } #ifdef CONFIG_DEBUG_FS @@ -201,20 +188,12 @@ int m4sensorhub_irq_init(struct m4sensorhub_data *m4sensorhub) goto err_free; } - data->workqueue = create_workqueue("m4sensorhub_irq"); - if (data->workqueue == NULL) { - KDEBUG(M4SH_ERROR, "%s: IRQ Workqueue init failure\n", - __func__); - retval = -ENOMEM; - goto err_free; - } - INIT_WORK(&data->work, irq_work_func); - wake_lock_init(&data->wake_lock, WAKE_LOCK_SUSPEND, "m4sensorhub-irq"); wake_lock_init(&data->tm_wake_lock, WAKE_LOCK_SUSPEND, "m4sensorhub-timed-irq"); - retval = request_irq(i2c->irq, event_isr, IRQF_TRIGGER_HIGH, + retval = request_threaded_irq(i2c->irq, event_isr, event_threaded, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "m4sensorhub-irq", data); if (retval) { KDEBUG(M4SH_ERROR, "%s: Failed requesting irq.\n", __func__); @@ -252,7 +231,6 @@ err_free_irq: err_destroy_wq: wake_lock_destroy(&data->wake_lock); wake_lock_destroy(&data->tm_wake_lock); - destroy_workqueue(data->workqueue); err_free: mutex_destroy(&data->lock); m4sensorhub->irqdata = NULL; @@ -315,9 +293,6 @@ void m4sensorhub_irq_shutdown(struct m4sensorhub_data *m4sensorhub) mutex_unlock(&data->lock); mutex_destroy(&data->lock); - cancel_work_sync(&data->work); - destroy_workqueue(data->workqueue); - kfree(data); } EXPORT_SYMBOL_GPL(m4sensorhub_irq_shutdown); @@ -731,16 +706,15 @@ error: return; } -static void irq_work_func(struct work_struct *work) +static irqreturn_t event_threaded(int irq, void *devid) { unsigned short en_ints[NUM_INT_REGS] = { 0 }; int i; - struct m4sensorhub_irqdata *data; + struct m4sensorhub_irqdata *data = devid; struct m4sensorhub_data *m4sensorhub; struct i2c_client *i2c; unsigned char value, is_irq_set = 0; - data = container_of(work, struct m4sensorhub_irqdata, work); m4sensorhub = data->m4sensorhub; i2c = m4sensorhub->i2c_client; @@ -762,10 +736,8 @@ static void irq_work_func(struct work_struct *work) goto error; } - if (m4sensorhub->irq_dbg.print_irqs == 1) { + if (m4sensorhub->irq_dbg.suspend == 1) m4sensorhub_print_irq_sources(en_ints); - m4sensorhub->irq_dbg.print_irqs = 0; - } for (i = 0; i < NUM_INT_REGS; ++i) { unsigned char index; @@ -810,7 +782,8 @@ static void irq_work_func(struct work_struct *work) } error: wake_unlock(&data->wake_lock); - enable_irq(m4sensorhub->i2c_client->irq); + + return IRQ_HANDLED; } #ifdef CONFIG_DEBUG_FS diff --git a/include/linux/m4sensorhub.h b/include/linux/m4sensorhub.h index ae3645d5d99..5bc54f0885b 100644 --- a/include/linux/m4sensorhub.h +++ b/include/linux/m4sensorhub.h @@ -95,7 +95,6 @@ struct m4sensorhub_hwconfig { struct m4sensorhub_irq_dbg { unsigned char suspend; /* 1 - Suspended, 0 - Normal */ - unsigned char print_irqs; /* 1 - IRQs to print, 0 - None */ }; struct m4sensorhub_data { |