summaryrefslogtreecommitdiff
path: root/drivers/mfd/m4sensorhub-irq.c
diff options
context:
space:
mode:
authorViditha Hanumanthareddy <ngjq36@motorola.com>2014-05-14 07:17:14 -0500
committerViditha H <ngjq36@motorola.com>2014-05-14 16:53:22 +0000
commit281ee14b6350aa2cd341507816a28fc067b3578a (patch)
tree9d9298d0a463c2ca896a71828c7ffb9a06c8bac6 /drivers/mfd/m4sensorhub-irq.c
parent65fcccea0ee3987f0fef3047adde958e7cd62103 (diff)
downloadolio-linux-3.10-281ee14b6350aa2cd341507816a28fc067b3578a.tar.xz
olio-linux-3.10-281ee14b6350aa2cd341507816a28fc067b3578a.zip
IKXCLOCK-1233: Hold a timed wakelock for m4 events
A few m4 interrupts/events like gesture, rtc alarm that can occur when kernel is suspended need enough time to allow the event to reach the higher layer before kernel suspends again. The absence of this was causing gestures & rtc alarm to get missed by the higher layers. Change-Id: Ibf10a1a031bd279ef2a488214498036c648220dc
Diffstat (limited to 'drivers/mfd/m4sensorhub-irq.c')
-rw-r--r--drivers/mfd/m4sensorhub-irq.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/drivers/mfd/m4sensorhub-irq.c b/drivers/mfd/m4sensorhub-irq.c
index b4b046b01d9..090e05b9ef9 100644
--- a/drivers/mfd/m4sensorhub-irq.c
+++ b/drivers/mfd/m4sensorhub-irq.c
@@ -90,6 +90,7 @@ struct m4sensorhub_irq_info {
uint8_t enabled;
uint32_t ena_fired;
uint32_t disa_fired;
+ uint8_t tm_wakelock;
};
struct m4sensorhub_irqdata {
@@ -100,6 +101,7 @@ struct m4sensorhub_irqdata {
struct m4sensorhub_event_handler event_handler[M4SH_IRQ__NUM];
struct m4sensorhub_irq_info irq_info[M4SH_IRQ__NUM];
struct wake_lock wake_lock;
+ struct wake_lock tm_wake_lock; /* timeout wakelock */
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs;
#endif
@@ -197,6 +199,8 @@ int m4sensorhub_irq_init(struct m4sensorhub_data *m4sensorhub)
mutex_init(&data->lock);
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_DISABLED |
IRQF_TRIGGER_RISING, "m4sensorhub-irq", data);
@@ -239,6 +243,7 @@ err_free_irq:
data->m4sensorhub = NULL;
err_destroy_wq:
wake_lock_destroy(&data->wake_lock);
+ wake_lock_destroy(&data->tm_wake_lock);
mutex_destroy(&data->lock);
destroy_workqueue(data->workqueue);
err_free:
@@ -277,6 +282,10 @@ void m4sensorhub_irq_shutdown(struct m4sensorhub_data *m4sensorhub)
wake_unlock(&data->wake_lock);
wake_lock_destroy(&data->wake_lock);
+ if (wake_lock_active(&data->tm_wake_lock))
+ wake_unlock(&data->tm_wake_lock);
+ wake_lock_destroy(&data->tm_wake_lock);
+
if (mutex_is_locked(&data->lock))
mutex_unlock(&data->lock);
mutex_destroy(&data->lock);
@@ -305,7 +314,7 @@ EXPORT_SYMBOL_GPL(m4sensorhub_irq_shutdown);
int m4sensorhub_irq_register(struct m4sensorhub_data *m4sensorhub,
enum m4sensorhub_irqs irq,
void (*cb_func) (enum m4sensorhub_irqs, void *),
- void *data)
+ void *data, uint8_t enable_timed_wakelock)
{
struct m4sensorhub_irqdata *irqdata;
int retval = 0;
@@ -324,6 +333,7 @@ int m4sensorhub_irq_register(struct m4sensorhub_data *m4sensorhub,
if (irqdata->event_handler[irq].func == NULL) {
irqdata->irq_info[irq].registered = 1;
+ irqdata->irq_info[irq].tm_wakelock = enable_timed_wakelock;
irqdata->event_handler[irq].func = cb_func;
irqdata->event_handler[irq].data = data;
KDEBUG(M4SH_NOTICE, "m4sensorhub: %s IRQ registered\n",
@@ -522,7 +532,6 @@ error:
return;
}
EXPORT_SYMBOL_GPL(m4sensorhub_irq_pm_dbg_resume);
-
/* --------------- Local Functions ----------------- */
static unsigned short get_enable_reg(enum m4sensorhub_irqs event)
@@ -617,10 +626,17 @@ static void irq_work_func(struct work_struct *work)
if (data->irq_info[index].enabled) {
event_handler = &data->event_handler[index];
- if (event_handler && event_handler->func)
+ if (event_handler && event_handler->func) {
event_handler->func(index,
event_handler->data);
-
+ if (data->irq_info[index].tm_wakelock) {
+ /* Hold a 500ms wakelock to
+ let data get to apps */
+ wake_lock_timeout(
+ &data->tm_wake_lock,
+ 0.5 * HZ);
+ }
+ }
mutex_lock(&data->lock);
data->irq_info[index].ena_fired++;
mutex_unlock(&data->lock);