diff options
| author | Viditha Hanumanthareddy <ngjq36@motorola.com> | 2014-07-07 15:15:01 -0500 |
|---|---|---|
| committer | Viditha H <ngjq36@motorola.com> | 2014-07-08 20:27:16 +0000 |
| commit | 859956ec4ef635c2b7fd42b53ee880aa502aa724 (patch) | |
| tree | bf84ed2e6d140a7bacc644c0c38bac8838ad6998 | |
| parent | 649585cbe0bc50b36291576e79e90ba3072aa88d (diff) | |
| download | olio-linux-3.10-859956ec4ef635c2b7fd42b53ee880aa502aa724.tar.xz olio-linux-3.10-859956ec4ef635c2b7fd42b53ee880aa502aa724.zip | |
IKXCLOCK-2713: Retry setrate's
If i2c communication fails while doing a set sample rate for a sensor
retry the same during suspend. It is seems that sometimes omap->M4
i2c bus dies for a brief period and then recovers. But during the failure
period if an app tries to turn off a sensor and this turn off fails,
it could lead to wakeups after omap suspend, and so this fix
retries setting the sample rate on suspend only if it had failed earlier.
Change-Id: I5874738a78ed900b1b039160f852031321dd2e30
| -rw-r--r-- | drivers/misc/m4sensorhub_als.c | 21 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_fusion.c | 16 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_gesture.c | 21 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_heartrate.c | 17 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_mpu9150.c | 25 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_passive.c | 21 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_pedometer.c | 42 |
7 files changed, 142 insertions, 21 deletions
diff --git a/drivers/misc/m4sensorhub_als.c b/drivers/misc/m4sensorhub_als.c index d0d9ab7425a..02e7ec8b31b 100644 --- a/drivers/misc/m4sensorhub_als.c +++ b/drivers/misc/m4sensorhub_als.c @@ -43,7 +43,7 @@ struct m4als_driver_data { uint16_t luminosity; int16_t samplerate; - + int16_t latest_samplerate; uint16_t status; }; @@ -95,6 +95,10 @@ static int m4als_set_samplerate(struct m4als_driver_data *dd, int16_t rate) int err = 0; int size = 0; + /* This variabled is to be always updated ireespective of the + transaction status */ + dd->latest_samplerate = rate; + if (rate == dd->samplerate) goto m4als_change_interrupt_bit; @@ -351,6 +355,7 @@ static int m4als_probe(struct platform_device *pdev) mutex_init(&(dd->mutex)); platform_set_drvdata(pdev, dd); dd->samplerate = -1; /* We always start disabled */ + dd->latest_samplerate = dd->samplerate; dd->m4 = m4sensorhub_client_get_drvdata(); if (dd->m4 == NULL) { @@ -396,6 +401,16 @@ static int __exit m4als_remove(struct platform_device *pdev) return 0; } +static int m4als_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct m4als_driver_data *dd = platform_get_drvdata(pdev); + mutex_lock(&(dd->mutex)); + if (m4als_set_samplerate(dd, dd->latest_samplerate) < 0) + m4als_err("%s: setrate retry failed\n", __func__); + mutex_unlock(&(dd->mutex)); + return 0; +} + static struct of_device_id m4als_match_tbl[] = { { .compatible = "mot,m4als" }, {}, @@ -405,8 +420,8 @@ static struct platform_driver m4als_driver = { .probe = m4als_probe, .remove = __exit_p(m4als_remove), .shutdown = NULL, - .suspend = NULL, - .resume = NULL, + .suspend = m4als_suspend, + .resume = NULL, .driver = { .name = M4ALS_DRIVER_NAME, .owner = THIS_MODULE, diff --git a/drivers/misc/m4sensorhub_fusion.c b/drivers/misc/m4sensorhub_fusion.c index 9a6649c2a88..6984ce8f4cd 100644 --- a/drivers/misc/m4sensorhub_fusion.c +++ b/drivers/misc/m4sensorhub_fusion.c @@ -46,6 +46,7 @@ struct m4fus_driver_data { struct m4sensorhub_fusion_iio_data iiodat[M4FUS_NUM_FUSION_BUFFERS]; int16_t samplerate; + int16_t latest_samplerate; uint16_t status; }; @@ -144,6 +145,7 @@ static int m4fus_set_samplerate(struct iio_dev *iio, int16_t rate) struct m4fus_driver_data *dd = iio_priv(iio); int size = 0; + dd->latest_samplerate = rate; if (rate == dd->samplerate) goto m4fus_set_samplerate_irq_check; @@ -436,6 +438,7 @@ static int m4fus_probe(struct platform_device *pdev) mutex_init(&(dd->mutex)); platform_set_drvdata(pdev, iio); dd->samplerate = -1; /* We always start disabled */ + dd->latest_samplerate = dd->samplerate; err = m4fus_create_iiodev(iio); /* iio and dd are freed on fail */ if (err < 0) { @@ -483,6 +486,17 @@ m4fus_remove_exit: return 0; } +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; +} + static struct of_device_id m4fusion_match_tbl[] = { { .compatible = "mot,m4fusion" }, {}, @@ -492,7 +506,7 @@ static struct platform_driver m4fus_driver = { .probe = m4fus_probe, .remove = __exit_p(m4fus_remove), .shutdown = NULL, - .suspend = NULL, + .suspend = m4fus_suspend, .resume = NULL, .driver = { .name = M4FUS_DRIVER_NAME, diff --git a/drivers/misc/m4sensorhub_gesture.c b/drivers/misc/m4sensorhub_gesture.c index d311758b08c..c954bf97f5a 100644 --- a/drivers/misc/m4sensorhub_gesture.c +++ b/drivers/misc/m4sensorhub_gesture.c @@ -46,6 +46,7 @@ struct m4ges_driver_data { struct m4sensorhub_gesture_iio_data iiodat; int16_t samplerate; + int16_t latest_samplerate; uint16_t status; }; @@ -120,7 +121,9 @@ static int m4ges_set_samplerate(struct iio_dev *iio, int16_t rate) * Currently, there is no concept of setting a sample rate for this * sensor, so this function only enables/disables interrupt reporting. */ - dd->samplerate = rate; + dd->latest_samplerate = rate; + if (rate == dd->samplerate) + goto m4ges_set_samplerate_fail; if (rate >= 0) { /* Enable the IRQ if necessary */ @@ -133,6 +136,7 @@ static int m4ges_set_samplerate(struct iio_dev *iio, int16_t rate) goto m4ges_set_samplerate_fail; } dd->status = dd->status | (1 << M4GES_IRQ_ENABLED_BIT); + dd->samplerate = rate; } } else { /* Disable the IRQ if necessary */ @@ -145,6 +149,7 @@ static int m4ges_set_samplerate(struct iio_dev *iio, int16_t rate) goto m4ges_set_samplerate_fail; } dd->status = dd->status & ~(1 << M4GES_IRQ_ENABLED_BIT); + dd->samplerate = rate; } } @@ -365,6 +370,7 @@ static int m4ges_probe(struct platform_device *pdev) mutex_init(&(dd->mutex)); platform_set_drvdata(pdev, iio); dd->samplerate = -1; /* We always start disabled */ + dd->latest_samplerate = dd->samplerate; err = m4ges_create_iiodev(iio); /* iio and dd are freed on fail */ if (err < 0) { @@ -414,6 +420,17 @@ m4ges_remove_exit: return 0; } +static int m4ges_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct iio_dev *iio = platform_get_drvdata(pdev); + struct m4ges_driver_data *dd = iio_priv(iio); + mutex_lock(&(dd->mutex)); + if (m4ges_set_samplerate(iio, dd->latest_samplerate) < 0) + m4ges_err("%s: setrate retry failed\n", __func__); + mutex_unlock(&(dd->mutex)); + return 0; +} + static struct of_device_id m4gesture_match_tbl[] = { { .compatible = "mot,m4gesture" }, {}, @@ -423,7 +440,7 @@ static struct platform_driver m4ges_driver = { .probe = m4ges_probe, .remove = __exit_p(m4ges_remove), .shutdown = NULL, - .suspend = NULL, + .suspend = m4ges_suspend, .resume = NULL, .driver = { .name = M4GES_DRIVER_NAME, diff --git a/drivers/misc/m4sensorhub_heartrate.c b/drivers/misc/m4sensorhub_heartrate.c index ebe59128595..6e45b134bba 100644 --- a/drivers/misc/m4sensorhub_heartrate.c +++ b/drivers/misc/m4sensorhub_heartrate.c @@ -47,6 +47,7 @@ struct m4hrt_driver_data { struct m4sensorhub_heartrate_iio_data iiodat; int32_t samplerate; + int32_t latest_samplerate; uint16_t status; uint8_t dbg_addr; @@ -106,6 +107,8 @@ static int m4hrt_set_samplerate(struct iio_dev *iio, int32_t rate) struct m4hrt_driver_data *dd = iio_priv(iio); int size = 0; + dd->latest_samplerate = rate; + if (rate == dd->samplerate) goto m4hrt_set_samplerate_irq_check; @@ -558,6 +561,7 @@ static int m4hrt_probe(struct platform_device *pdev) mutex_init(&(dd->mutex)); platform_set_drvdata(pdev, iio); dd->samplerate = -1; /* We always start disabled */ + dd->latest_samplerate = dd->samplerate; err = m4hrt_create_iiodev(iio); /* iio and dd are freed on fail */ if (err < 0) { @@ -607,6 +611,17 @@ m4hrt_remove_exit: return 0; } +static int m4hrt_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct iio_dev *iio = platform_get_drvdata(pdev); + struct m4hrt_driver_data *dd = iio_priv(iio); + mutex_lock(&(dd->mutex)); + if (m4hrt_set_samplerate(iio, dd->latest_samplerate) < 0) + m4hrt_err("%s: setrate retry failed\n", __func__); + mutex_unlock(&(dd->mutex)); + return 0; +} + static struct of_device_id m4heartrate_match_tbl[] = { { .compatible = "mot,m4heartrate" }, {}, @@ -616,7 +631,7 @@ static struct platform_driver m4hrt_driver = { .probe = m4hrt_probe, .remove = __exit_p(m4hrt_remove), .shutdown = NULL, - .suspend = NULL, + .suspend = m4hrt_suspend, .resume = NULL, .driver = { .name = M4HRT_DRIVER_NAME, diff --git a/drivers/misc/m4sensorhub_mpu9150.c b/drivers/misc/m4sensorhub_mpu9150.c index bd27a9da3d5..2c6d6c12808 100644 --- a/drivers/misc/m4sensorhub_mpu9150.c +++ b/drivers/misc/m4sensorhub_mpu9150.c @@ -72,6 +72,7 @@ struct mpu9150_client { struct m4sensorhub_data *m4sensorhub; struct input_dev *input_dev; signed short samplerate[NUM_TYPES]; + signed short latest_samplerate[NUM_TYPES]; struct mpu9150_accel_data accel_data; struct mpu9150_gyro_data gyro_data; struct mpu9150_compass_data compass_data; @@ -145,6 +146,8 @@ static void m4_report_mpu9150_inputevent( static void m4_set_mpu9150_delay(struct mpu9150_client *mpu9150_client_data, int delay, enum mpu9150_sensor type) { + mpu9150_client_data->latest_samplerate[type] = delay; + if (delay != mpu9150_client_data->samplerate[type]) { switch (type) { case TYPE_GYRO: @@ -698,6 +701,15 @@ static int mpu9150_client_probe(struct platform_device *pdev) mpu9150_client_data->m4sensorhub = m4sensorhub; platform_set_drvdata(pdev, mpu9150_client_data); + mpu9150_client_data->samplerate[TYPE_ACCEL] = -1; + mpu9150_client_data->samplerate[TYPE_GYRO] = -1; + mpu9150_client_data->samplerate[TYPE_COMPASS] = -1; + mpu9150_client_data->latest_samplerate[TYPE_ACCEL] = + mpu9150_client_data->samplerate[TYPE_ACCEL]; + mpu9150_client_data->latest_samplerate[TYPE_GYRO] = + mpu9150_client_data->samplerate[TYPE_GYRO]; + mpu9150_client_data->latest_samplerate[TYPE_COMPASS] = + mpu9150_client_data->samplerate[TYPE_COMPASS]; mpu9150_client_data->input_dev = input_allocate_device(); if (!mpu9150_client_data->input_dev) { @@ -795,6 +807,17 @@ static int __exit mpu9150_client_remove(struct platform_device *pdev) return 0; } +static int mpu9150_client_suspend(struct platform_device *pdev, + pm_message_t state) +{ + struct mpu9150_client *dd = platform_get_drvdata(pdev); + m4_set_mpu9150_delay(dd, dd->latest_samplerate[TYPE_ACCEL], TYPE_ACCEL); + m4_set_mpu9150_delay(dd, dd->latest_samplerate[TYPE_GYRO], TYPE_GYRO); + m4_set_mpu9150_delay(dd, dd->latest_samplerate[TYPE_COMPASS], + TYPE_COMPASS); + return 0; +} + static struct of_device_id m4mpu9150_match_tbl[] = { { .compatible = "mot,m4mpu9150" }, {}, @@ -804,7 +827,7 @@ static struct platform_driver mpu9150_client_driver = { .probe = mpu9150_client_probe, .remove = __exit_p(mpu9150_client_remove), .shutdown = NULL, - .suspend = NULL, + .suspend = mpu9150_client_suspend, .resume = NULL, .driver = { .name = MPU9150_CLIENT_DRIVER_NAME, diff --git a/drivers/misc/m4sensorhub_passive.c b/drivers/misc/m4sensorhub_passive.c index 692a70ae69f..70c77692573 100644 --- a/drivers/misc/m4sensorhub_passive.c +++ b/drivers/misc/m4sensorhub_passive.c @@ -46,6 +46,7 @@ struct m4pas_driver_data { struct m4sensorhub_passive_iio_data iiodat[M4PAS_NUM_PASSIVE_BUFFERS]; int16_t samplerate; + int16_t latest_samplerate; uint16_t status; }; @@ -183,7 +184,9 @@ static int m4pas_set_samplerate(struct iio_dev *iio, int16_t rate) * Currently, there is no concept of setting a sample rate for this * sensor, so this function only enables/disables interrupt reporting. */ - dd->samplerate = rate; + dd->latest_samplerate = rate; + if (dd->samplerate == rate) + goto m4pas_set_samplerate_fail; if (rate >= 0) { /* Enable passive mode feature */ @@ -205,6 +208,7 @@ static int m4pas_set_samplerate(struct iio_dev *iio, int16_t rate) goto m4pas_set_samplerate_fail; } dd->status = dd->status | (1 << M4PAS_IRQ_ENABLED_BIT); + dd->samplerate = rate; } } else { /* Disable passive mode feature */ @@ -226,6 +230,7 @@ static int m4pas_set_samplerate(struct iio_dev *iio, int16_t rate) goto m4pas_set_samplerate_fail; } dd->status = dd->status & ~(1 << M4PAS_IRQ_ENABLED_BIT); + dd->samplerate = rate; } } @@ -479,6 +484,7 @@ static int m4pas_probe(struct platform_device *pdev) mutex_init(&(dd->mutex)); platform_set_drvdata(pdev, iio); dd->samplerate = -1; /* We always start disabled */ + dd->latest_samplerate = dd->samplerate; err = m4pas_create_iiodev(iio); /* iio and dd are freed on fail */ if (err < 0) { @@ -528,6 +534,17 @@ m4pas_remove_exit: return 0; } +static int m4pas_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct iio_dev *iio = platform_get_drvdata(pdev); + struct m4pas_driver_data *dd = iio_priv(iio); + mutex_lock(&(dd->mutex)); + if (m4pas_set_samplerate(iio, dd->latest_samplerate) < 0) + m4pas_err("%s: setrate retry failed\n", __func__); + mutex_unlock(&(dd->mutex)); + return 0; +} + static struct of_device_id m4passive_match_tbl[] = { { .compatible = "mot,m4passive" }, {}, @@ -537,7 +554,7 @@ static struct platform_driver m4pas_driver = { .probe = m4pas_probe, .remove = __exit_p(m4pas_remove), .shutdown = NULL, - .suspend = NULL, + .suspend = m4pas_suspend, .resume = NULL, .driver = { .name = M4PAS_DRIVER_NAME, diff --git a/drivers/misc/m4sensorhub_pedometer.c b/drivers/misc/m4sensorhub_pedometer.c index e53d62dee15..de8564bc317 100644 --- a/drivers/misc/m4sensorhub_pedometer.c +++ b/drivers/misc/m4sensorhub_pedometer.c @@ -46,6 +46,8 @@ struct m4ped_driver_data { struct m4sensorhub_pedometer_iio_data iiodat; int16_t samplerate; + int16_t latest_samplerate; + uint16_t status; struct m4sensorhub_pedometer_iio_data base_dat; @@ -182,7 +184,9 @@ static int m4ped_set_samplerate(struct iio_dev *iio, int16_t rate) * Currently, there is no concept of setting a sample rate for this * sensor, so this function only enables/disables interrupt reporting. */ - dd->samplerate = rate; + dd->latest_samplerate = rate; + if (rate == dd->samplerate) + goto m4ped_set_samplerate_fail; if (rate >= 0) { /* Enable the IRQ if necessary */ @@ -204,15 +208,7 @@ static int m4ped_set_samplerate(struct iio_dev *iio, int16_t rate) } dd->status = dd->status | (1 << M4PED_IRQ_ENABLED_BIT); - } - /* When an app registers, there is no data reported - unless the user starts walking. But the application - would like to have atleast one set of data sent - immediately following the register */ - err = m4ped_read_report_data(iio, dd); - if (err < 0) { - m4ped_err("%s:Failed to report pedo data\n", __func__); - goto m4ped_set_samplerate_fail; + dd->samplerate = rate; } } else { /* Disable the IRQ if necessary */ @@ -234,6 +230,7 @@ static int m4ped_set_samplerate(struct iio_dev *iio, int16_t rate) } dd->status = dd->status & ~(1 << M4PED_IRQ_ENABLED_BIT); + dd->samplerate = rate; } } @@ -283,6 +280,17 @@ static ssize_t m4ped_setrate_store(struct device *dev, m4ped_err("%s: Failed to set sample rate.\n", __func__); goto m4ped_enable_store_exit; } + if (value >= 0) { + /* When an app registers, there is no data reported + unless the user starts walking. But the application + would like to have atleast one set of data sent + immediately following the register */ + err = m4ped_read_report_data(iio, dd); + if (err < 0) { + m4ped_err("%s:Failed to report pedo data\n", __func__); + goto m4ped_enable_store_exit; + } + } m4ped_enable_store_exit: if (err < 0) { @@ -618,6 +626,7 @@ static int m4ped_probe(struct platform_device *pdev) mutex_init(&(dd->mutex)); platform_set_drvdata(pdev, iio); dd->samplerate = -1; /* We always start disabled */ + dd->latest_samplerate = dd->samplerate; err = m4ped_create_iiodev(iio); /* iio and dd are freed on fail */ if (err < 0) { @@ -671,6 +680,17 @@ m4ped_remove_exit: return 0; } +static int m4ped_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct iio_dev *iio = platform_get_drvdata(pdev); + struct m4ped_driver_data *dd = iio_priv(iio); + mutex_lock(&(dd->mutex)); + if (m4ped_set_samplerate(iio, dd->latest_samplerate) < 0) + m4ped_err("%s: setrate retry failed\n", __func__); + mutex_unlock(&(dd->mutex)); + return 0; +} + static struct of_device_id m4pedometer_match_tbl[] = { { .compatible = "mot,m4pedometer" }, {}, @@ -680,7 +700,7 @@ static struct platform_driver m4ped_driver = { .probe = m4ped_probe, .remove = __exit_p(m4ped_remove), .shutdown = NULL, - .suspend = NULL, + .suspend = m4ped_suspend, .resume = NULL, .driver = { .name = M4PED_DRIVER_NAME, |