diff options
| author | Viditha Hanumanthareddy <ngjq36@motorola.com> | 2014-05-14 07:17:14 -0500 |
|---|---|---|
| committer | Viditha H <ngjq36@motorola.com> | 2014-05-14 16:53:22 +0000 |
| commit | 281ee14b6350aa2cd341507816a28fc067b3578a (patch) | |
| tree | 9d9298d0a463c2ca896a71828c7ffb9a06c8bac6 | |
| parent | 65fcccea0ee3987f0fef3047adde958e7cd62103 (diff) | |
| download | olio-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
| -rw-r--r-- | drivers/mfd/m4sensorhub-irq.c | 24 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_als.c | 2 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_audio.c | 2 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_download.c | 2 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_fusion.c | 2 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_gesture.c | 2 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_heartrate.c | 2 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_mpu9150.c | 6 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_passive.c | 2 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_pedometer.c | 4 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_stillmode.c | 13 | ||||
| -rw-r--r-- | drivers/rtc/rtc-sensorhub.c | 2 | ||||
| -rw-r--r-- | include/linux/m4sensorhub.h | 2 |
13 files changed, 36 insertions, 29 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); diff --git a/drivers/misc/m4sensorhub_als.c b/drivers/misc/m4sensorhub_als.c index 1835efab2c0..fbb7c110672 100644 --- a/drivers/misc/m4sensorhub_als.c +++ b/drivers/misc/m4sensorhub_als.c @@ -288,7 +288,7 @@ static int m4als_driver_init(struct init_calldata *p_arg) } err = m4sensorhub_irq_register(dd->m4, M4SH_IRQ_LIGHTSENSOR_DATA_READY, - m4als_isr, dd); + m4als_isr, dd, 0); if (err < 0) { m4als_err("%s: Failed to register M4 IRQ.\n", __func__); goto m4als_driver_init_irq_fail; diff --git a/drivers/misc/m4sensorhub_audio.c b/drivers/misc/m4sensorhub_audio.c index 86d737230f7..7f6c3d313a4 100644 --- a/drivers/misc/m4sensorhub_audio.c +++ b/drivers/misc/m4sensorhub_audio.c @@ -355,7 +355,7 @@ static int audio_driver_init(struct init_calldata *p_arg) struct m4sensorhub_data *m4sensorhub = p_arg->p_m4sensorhub_data; ret = m4sensorhub_irq_register(m4sensorhub, M4SH_IRQ_MIC_DATA_READY, - m4_handle_audio_irq, audio_data); + m4_handle_audio_irq, audio_data, 0); if (ret < 0) { KDEBUG(M4SH_ERROR, "Error registering int %d (%d)\n", M4SH_IRQ_MIC_DATA_READY, ret); diff --git a/drivers/misc/m4sensorhub_download.c b/drivers/misc/m4sensorhub_download.c index 85206e228f9..bdd75c33677 100644 --- a/drivers/misc/m4sensorhub_download.c +++ b/drivers/misc/m4sensorhub_download.c @@ -317,7 +317,7 @@ static int download_driver_init(struct init_calldata *p_arg) struct m4sensorhub_data *m4sensorhub = p_arg->p_m4sensorhub_data; ret = m4sensorhub_irq_register(m4sensorhub, M4SH_IRQ_DLCMD_RESP_READY, m4_handle_download_irq, - misc_download_data); + misc_download_data, 0); if (ret < 0) { KDEBUG(M4SH_ERROR, "Error registering int %d (%d)\n", M4SH_IRQ_DLCMD_RESP_READY, ret); diff --git a/drivers/misc/m4sensorhub_fusion.c b/drivers/misc/m4sensorhub_fusion.c index bd3d426fd78..e426efe9021 100644 --- a/drivers/misc/m4sensorhub_fusion.c +++ b/drivers/misc/m4sensorhub_fusion.c @@ -324,7 +324,7 @@ static int m4fus_driver_init(struct init_calldata *p_arg) } err = m4sensorhub_irq_register(dd->m4, - M4SH_IRQ_FUSION_DATA_READY, m4fus_isr, iio); + M4SH_IRQ_FUSION_DATA_READY, m4fus_isr, iio, 0); if (err < 0) { m4fus_err("%s: Failed to register M4 IRQ.\n", __func__); goto m4fus_driver_init_fail; diff --git a/drivers/misc/m4sensorhub_gesture.c b/drivers/misc/m4sensorhub_gesture.c index 22a972f3dd9..d311758b08c 100644 --- a/drivers/misc/m4sensorhub_gesture.c +++ b/drivers/misc/m4sensorhub_gesture.c @@ -332,7 +332,7 @@ static int m4ges_driver_init(struct init_calldata *p_arg) } err = m4sensorhub_irq_register(dd->m4, - M4SH_IRQ_GESTURE_DETECTED, m4ges_isr, iio); + M4SH_IRQ_GESTURE_DETECTED, m4ges_isr, iio, 1); if (err < 0) { m4ges_err("%s: Failed to register M4 IRQ.\n", __func__); goto m4ges_driver_init_fail; diff --git a/drivers/misc/m4sensorhub_heartrate.c b/drivers/misc/m4sensorhub_heartrate.c index 9d785ab4b06..f92eae8284a 100644 --- a/drivers/misc/m4sensorhub_heartrate.c +++ b/drivers/misc/m4sensorhub_heartrate.c @@ -482,7 +482,7 @@ static int m4hrt_driver_init(struct init_calldata *p_arg) } err = m4sensorhub_irq_register(dd->m4, - M4SH_IRQ_HEARTRATE_DATA_READY, m4hrt_isr, iio); + M4SH_IRQ_HEARTRATE_DATA_READY, m4hrt_isr, iio, 0); if (err < 0) { m4hrt_err("%s: Failed to register M4 IRQ.\n", __func__); goto m4hrt_driver_init_fail; diff --git a/drivers/misc/m4sensorhub_mpu9150.c b/drivers/misc/m4sensorhub_mpu9150.c index c1785faaea9..8185273f31a 100644 --- a/drivers/misc/m4sensorhub_mpu9150.c +++ b/drivers/misc/m4sensorhub_mpu9150.c @@ -531,7 +531,7 @@ static int mpu9150_irq_init(struct mpu9150_client *mpu9150_client_data) ret = m4sensorhub_irq_register(mpu9150_client_data->m4sensorhub, M4SH_IRQ_GYRO_DATA_READY, m4_handle_mpu9150_gyro_irq, - mpu9150_client_data); + mpu9150_client_data, 0); if (ret < 0) { KDEBUG(M4SH_ERROR, "Error registering int %d (%d)\n", M4SH_IRQ_GYRO_DATA_READY, ret); @@ -540,7 +540,7 @@ static int mpu9150_irq_init(struct mpu9150_client *mpu9150_client_data) ret = m4sensorhub_irq_register(mpu9150_client_data->m4sensorhub, M4SH_IRQ_ACCEL_DATA_READY, m4_handle_mpu9150_accel_irq, - mpu9150_client_data); + mpu9150_client_data, 0); if (ret < 0) { KDEBUG(M4SH_ERROR, "Error registering int %d (%d)\n", M4SH_IRQ_ACCEL_DATA_READY, ret); @@ -549,7 +549,7 @@ static int mpu9150_irq_init(struct mpu9150_client *mpu9150_client_data) ret = m4sensorhub_irq_register(mpu9150_client_data->m4sensorhub, M4SH_IRQ_COMPASS_DATA_READY, m4_handle_mpu9150_compass_irq, - mpu9150_client_data); + mpu9150_client_data, 0); if (ret < 0) { KDEBUG(M4SH_ERROR, "Error registering int %d (%d)\n", M4SH_IRQ_COMPASS_DATA_READY, ret); diff --git a/drivers/misc/m4sensorhub_passive.c b/drivers/misc/m4sensorhub_passive.c index d94ba4381ac..6c0de12aa33 100644 --- a/drivers/misc/m4sensorhub_passive.c +++ b/drivers/misc/m4sensorhub_passive.c @@ -403,7 +403,7 @@ static int m4pas_driver_init(struct init_calldata *p_arg) } err = m4sensorhub_irq_register(dd->m4, - M4SH_IRQ_PASSIVE_BUFFER_FULL, m4pas_isr, iio); + M4SH_IRQ_PASSIVE_BUFFER_FULL, m4pas_isr, iio, 1); if (err < 0) { m4pas_err("%s: Failed to register M4 IRQ.\n", __func__); goto m4pas_driver_init_fail; diff --git a/drivers/misc/m4sensorhub_pedometer.c b/drivers/misc/m4sensorhub_pedometer.c index 87fd15be3f3..4f80122c7e1 100644 --- a/drivers/misc/m4sensorhub_pedometer.c +++ b/drivers/misc/m4sensorhub_pedometer.c @@ -546,14 +546,14 @@ static int m4ped_driver_init(struct init_calldata *p_arg) } err = m4sensorhub_irq_register(dd->m4, - M4SH_IRQ_PEDOMETER_DATA_READY, m4ped_isr, iio); + M4SH_IRQ_PEDOMETER_DATA_READY, m4ped_isr, iio, 0); if (err < 0) { m4ped_err("%s: Failed to register M4 PED IRQ.\n", __func__); goto m4ped_driver_init_fail; } err = m4sensorhub_irq_register(dd->m4, - M4SH_IRQ_ACTIVITY_CHANGE, m4ped_isr, iio); + M4SH_IRQ_ACTIVITY_CHANGE, m4ped_isr, iio, 0); if (err < 0) { m4ped_err("%s: Failed to register M4 ACT IRQ.\n", __func__); goto m4ped_driver_init_irq_act_fail; diff --git a/drivers/misc/m4sensorhub_stillmode.c b/drivers/misc/m4sensorhub_stillmode.c index 20ced175c6c..f0f95ae47c4 100644 --- a/drivers/misc/m4sensorhub_stillmode.c +++ b/drivers/misc/m4sensorhub_stillmode.c @@ -44,7 +44,6 @@ struct stillmode_client { struct m4sensorhub_data *m4sensorhub; struct input_dev *input_dev; enum m4_stillmode_type state; - struct wake_lock wakelock; struct work_struct queued_work; u16 timeout; }; @@ -82,9 +81,6 @@ static void stillmode_set_state(struct stillmode_client *stillmode_client_data, stillmode_client_data->state = state; mutex_unlock(&state_access); - /* Hold a 500ms wakelock to let data get to KineticManager */ - wake_lock_timeout(&stillmode_client_data->wakelock, 0.5 * HZ); - input_report_switch(stillmode_client_data->input_dev, SW_STILL_MODE, (stillmode_client_data->state == STILL)); @@ -231,7 +227,7 @@ static int stillmode_driver_init(struct init_calldata *p_arg) ret = m4sensorhub_irq_register(m4sensorhub, M4SH_IRQ_STILL_DETECTED, m4_handle_stillmode_irq, - g_stillmode_data); + g_stillmode_data, 1); if (ret < 0) { KDEBUG(M4SH_ERROR, "Error registering still mode IRQ: %d\n", @@ -248,7 +244,7 @@ static int stillmode_driver_init(struct init_calldata *p_arg) ret = m4sensorhub_irq_register(m4sensorhub, M4SH_IRQ_MOTION_DETECTED, m4_handle_stillmode_irq, - g_stillmode_data); + g_stillmode_data, 1); if (ret < 0) { KDEBUG(M4SH_ERROR, "Error registering moving mode IRQ: %d\n", @@ -315,9 +311,6 @@ static int stillmode_client_probe(struct platform_device *pdev) goto free_memory; } - wake_lock_init(&stillmode_client_data->wakelock, WAKE_LOCK_SUSPEND, - STILLMODE_CLIENT_DRIVER_NAME); - INIT_WORK(&stillmode_client_data->queued_work, m4sensorhub_stillmode_work); @@ -351,7 +344,6 @@ remove_stillmode_sysfs: unregister_initcall: m4sensorhub_unregister_initcall(stillmode_driver_init); destroy_wakelock: - wake_lock_destroy(&stillmode_client_data->wakelock); input_unregister_device(stillmode_client_data->input_dev); free_memory: platform_set_drvdata(pdev, NULL); @@ -377,7 +369,6 @@ static int __exit stillmode_client_remove(struct platform_device *pdev) m4sensorhub_irq_disable(m4sensorhub, M4SH_IRQ_STILL_DETECTED); m4sensorhub_irq_unregister(m4sensorhub, M4SH_IRQ_STILL_DETECTED); m4sensorhub_unregister_initcall(stillmode_driver_init); - wake_lock_destroy(&stillmode_client_data->wakelock); input_unregister_device(stillmode_client_data->input_dev); platform_set_drvdata(pdev, NULL); m4sensorhub->pdev->stillmode_exit = NULL; diff --git a/drivers/rtc/rtc-sensorhub.c b/drivers/rtc/rtc-sensorhub.c index 92e19700c3b..4939ff8874f 100644 --- a/drivers/rtc/rtc-sensorhub.c +++ b/drivers/rtc/rtc-sensorhub.c @@ -263,7 +263,7 @@ static int rtc_sensorhub_init(struct init_calldata *p_arg) err = m4sensorhub_irq_register(p_priv_data->p_m4sensorhub_data, M4SH_IRQ_AP_ALARM_EXPIRED, rtc_handle_sensorhub_irq, - p_priv_data); + p_priv_data, 1); if (err < 0) pr_err("%s: irq register failed\n", DRIVER_NAME); diff --git a/include/linux/m4sensorhub.h b/include/linux/m4sensorhub.h index deb6bd0d45a..4b0cdd62eb8 100644 --- a/include/linux/m4sensorhub.h +++ b/include/linux/m4sensorhub.h @@ -191,7 +191,7 @@ void m4sensorhub_irq_shutdown(struct m4sensorhub_data *m4sensorhub); 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); int m4sensorhub_irq_unregister(struct m4sensorhub_data *m4sensorhub, enum m4sensorhub_irqs irq); int m4sensorhub_irq_disable(struct m4sensorhub_data *m4sensorhub, |