diff options
| author | Viditha Hanumanthareddy <ngjq36@motorola.com> | 2014-08-07 14:20:40 -0500 |
|---|---|---|
| committer | Viditha Hanumanthareddy <ngjq36@motorola.com> | 2014-08-08 15:28:25 -0500 |
| commit | a5547c59d1127884c88948f769e80db33a9cb3d5 (patch) | |
| tree | 8d40cf792c198feb0a821338086cf1ae0620a876 /drivers/misc/m4sensorhub_fusion.c | |
| parent | 43d49c02672e9ea8ac5d2b85ae215166c195f967 (diff) | |
| download | olio-linux-3.10-a5547c59d1127884c88948f769e80db33a9cb3d5.tar.xz olio-linux-3.10-a5547c59d1127884c88948f769e80db33a9cb3d5.zip | |
IKXCLOCK-3320: Poll for non wakable sensors
Bug : 16656953
All sensors were interrupt based, m4 would interrupt omap
when the delay timeout occurs, but to be able mask
non wakable sensor interrupts on suspend and resume, we
r now moving non wakable sensors to be poll based, the
kernel starts a timer for each sensor and reads data from m4
on timer expiry.
Change-Id: I39f1a94563f3c4c65b586b63018e9e1afebd0d28
Diffstat (limited to 'drivers/misc/m4sensorhub_fusion.c')
| -rw-r--r-- | drivers/misc/m4sensorhub_fusion.c | 71 |
1 files changed, 26 insertions, 45 deletions
diff --git a/drivers/misc/m4sensorhub_fusion.c b/drivers/misc/m4sensorhub_fusion.c index c8d579fe4fe..f1ce277f2fe 100644 --- a/drivers/misc/m4sensorhub_fusion.c +++ b/drivers/misc/m4sensorhub_fusion.c @@ -45,17 +45,20 @@ struct m4fus_driver_data { struct mutex mutex; /* controls driver entry points */ struct m4sensorhub_fusion_iio_data iiodat[M4FUS_NUM_FUSION_BUFFERS]; + struct delayed_work m4fus_work; int16_t samplerate; int16_t latest_samplerate; + int16_t fastest_rate; uint16_t status; }; - -static void m4fus_isr(enum m4sensorhub_irqs int_event, void *handle) +static void m4fus_work_func(struct work_struct *work) { int err = 0; - struct iio_dev *iio = handle; - struct m4fus_driver_data *dd = iio_priv(iio); + struct m4fus_driver_data *dd = container_of(work, + struct m4fus_driver_data, + m4fus_work.work); + struct iio_dev *iio = platform_get_drvdata(dd->pdev); int size = 0; mutex_lock(&(dd->mutex)); @@ -129,6 +132,9 @@ static void m4fus_isr(enum m4sensorhub_irqs int_event, void *handle) * in this one call (see the M4 passive driver). */ iio_push_to_buffers(iio, (unsigned char *)&(dd->iiodat[0])); + if (dd->samplerate > 0) + schedule_delayed_work(&(dd->m4fus_work), + msecs_to_jiffies(dd->samplerate)); m4fus_isr_fail: if (err < 0) @@ -145,9 +151,13 @@ static int m4fus_set_samplerate(struct iio_dev *iio, int16_t rate) struct m4fus_driver_data *dd = iio_priv(iio); int size = 0; + if ((rate >= 0) && (rate <= dd->fastest_rate)) + rate = dd->fastest_rate; + dd->latest_samplerate = rate; + if (rate == dd->samplerate) - goto m4fus_set_samplerate_irq_check; + goto m4fus_set_samplerate_fail; size = m4sensorhub_reg_getsize(dd->m4, M4SH_REG_FUSION_SAMPLERATE); err = m4sensorhub_reg_write(dd->m4, M4SH_REG_FUSION_SAMPLERATE, @@ -162,33 +172,10 @@ static int m4fus_set_samplerate(struct iio_dev *iio, int16_t rate) goto m4fus_set_samplerate_fail; } dd->samplerate = rate; - -m4fus_set_samplerate_irq_check: - if (rate >= 0) { - /* Enable the IRQ if necessary */ - if (!(dd->status & (1 << M4FUS_IRQ_ENABLED_BIT))) { - err = m4sensorhub_irq_enable(dd->m4, - M4SH_IRQ_FUSION_DATA_READY); - if (err < 0) { - m4fus_err("%s: Failed to enable irq.\n", - __func__); - goto m4fus_set_samplerate_fail; - } - dd->status = dd->status | (1 << M4FUS_IRQ_ENABLED_BIT); - } - } else { - /* Disable the IRQ if necessary */ - if (dd->status & (1 << M4FUS_IRQ_ENABLED_BIT)) { - err = m4sensorhub_irq_disable(dd->m4, - M4SH_IRQ_FUSION_DATA_READY); - if (err < 0) { - m4fus_err("%s: Failed to disable irq.\n", - __func__); - goto m4fus_set_samplerate_fail; - } - dd->status = dd->status & ~(1 << M4FUS_IRQ_ENABLED_BIT); - } - } + cancel_delayed_work(&(dd->m4fus_work)); + if (dd->samplerate > 0) + schedule_delayed_work(&(dd->m4fus_work), + msecs_to_jiffies(rate)); m4fus_set_samplerate_fail: return err; @@ -383,6 +370,10 @@ static void m4fus_panic_restore(struct m4sensorhub_data *m4sensorhub, __func__, err, size); } + cancel_delayed_work(&(dd->m4fus_work)); + if (dd->samplerate > 0) + schedule_delayed_work(&(dd->m4fus_work), + msecs_to_jiffies(dd->samplerate)); mutex_unlock(&(dd->mutex)); } @@ -401,12 +392,7 @@ static int m4fus_driver_init(struct init_calldata *p_arg) goto m4fus_driver_init_fail; } - err = m4sensorhub_irq_register(dd->m4, - 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; - } + INIT_DELAYED_WORK(&(dd->m4fus_work), m4fus_work_func); err = m4sensorhub_panic_register(dd->m4, PANICHDL_FUSION_RESTORE, m4fus_panic_restore, dd); @@ -441,6 +427,7 @@ static int m4fus_probe(struct platform_device *pdev) platform_set_drvdata(pdev, iio); dd->samplerate = -1; /* We always start disabled */ dd->latest_samplerate = dd->samplerate; + dd->fastest_rate = 40; err = m4fus_create_iiodev(iio); /* iio and dd are freed on fail */ if (err < 0) { @@ -476,11 +463,7 @@ static int __exit m4fus_remove(struct platform_device *pdev) goto m4fus_remove_exit; mutex_lock(&(dd->mutex)); - if (dd->status & (1 << M4FUS_IRQ_ENABLED_BIT)) { - m4sensorhub_irq_disable(dd->m4, M4SH_IRQ_FUSION_DATA_READY); - dd->status = dd->status & ~(1 << M4FUS_IRQ_ENABLED_BIT); - } - m4sensorhub_irq_unregister(dd->m4, M4SH_IRQ_FUSION_DATA_READY); + cancel_delayed_work(&(dd->m4fus_work)); m4sensorhub_unregister_initcall(m4fus_driver_init); m4fus_remove_iiodev(iio); /* dd is freed here */ @@ -492,10 +475,8 @@ static int m4fus_suspend(struct platform_device *pdev, pm_message_t state) { struct iio_dev *iio = platform_get_drvdata(pdev); struct m4fus_driver_data *dd = iio_priv(iio); - mutex_lock(&(dd->mutex)); if (m4fus_set_samplerate(iio, dd->latest_samplerate) < 0) m4fus_err("%s: setrate retry failed\n", __func__); - mutex_unlock(&(dd->mutex)); return 0; } |