diff options
| author | Eric Tashakkor <w36098@motorola.com> | 2014-07-09 15:42:22 -0500 |
|---|---|---|
| committer | ERIC TASHAKKOR <w36098@motorola.com> | 2014-07-10 13:20:41 +0000 |
| commit | 2f02ffa1a9d46c192d19fed48190beceb9b6ec21 (patch) | |
| tree | 5726951fcc89a14602cf5982e78cfb5cc8d26ef1 | |
| parent | e1dfac029c58558d572d68b18d4d2a89470de088 (diff) | |
| download | olio-linux-3.10-2f02ffa1a9d46c192d19fed48190beceb9b6ec21.tar.xz olio-linux-3.10-2f02ffa1a9d46c192d19fed48190beceb9b6ec21.zip | |
IKXCLOCK-2819 Add Mutex Protection to M4 Panic Handlers
Added mutex locking in panic restore handlers for all drivers to prevent
losing data when restoring after an M4 panic.
Added a mutex to the mpu9150 driver to prevent concurrent access issues
and loss of data during normal operation.
Change-Id: I9ad5595c632518093ad1aec86afc7a51d3cbbee3
Signed-off-by: Eric Tashakkor <w36098@motorola.com>
| -rw-r--r-- | drivers/misc/m4sensorhub_als.c | 6 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_fusion.c | 5 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_heartrate.c | 6 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_mpu9150.c | 77 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_passive.c | 4 | ||||
| -rw-r--r-- | drivers/misc/m4sensorhub_pedometer.c | 6 |
6 files changed, 93 insertions, 11 deletions
diff --git a/drivers/misc/m4sensorhub_als.c b/drivers/misc/m4sensorhub_als.c index 02e7ec8b31b..b5f90fd72a3 100644 --- a/drivers/misc/m4sensorhub_als.c +++ b/drivers/misc/m4sensorhub_als.c @@ -277,13 +277,15 @@ static void m4als_panic_restore(struct m4sensorhub_data *m4sensorhub, { int size, err; struct m4als_driver_data *dd = (struct m4als_driver_data *)data; - + if (dd == NULL) { m4als_err("%s: Driver data is null, unable to restore\n", __func__); return; } + mutex_lock(&(dd->mutex)); + size = m4sensorhub_reg_getsize(dd->m4, M4SH_REG_LIGHTSENSOR_SAMPLERATE); err = m4sensorhub_reg_write(dd->m4, M4SH_REG_LIGHTSENSOR_SAMPLERATE, @@ -294,6 +296,8 @@ static void m4als_panic_restore(struct m4sensorhub_data *m4sensorhub, m4als_err("%s: Wrote %d bytes instead of %d.\n", __func__, err, size); } + + mutex_unlock(&(dd->mutex)); } static int m4als_driver_init(struct init_calldata *p_arg) diff --git a/drivers/misc/m4sensorhub_fusion.c b/drivers/misc/m4sensorhub_fusion.c index 6984ce8f4cd..c1debaf2780 100644 --- a/drivers/misc/m4sensorhub_fusion.c +++ b/drivers/misc/m4sensorhub_fusion.c @@ -373,6 +373,9 @@ static void m4fus_panic_restore(struct m4sensorhub_data *m4sensorhub, __func__); return; } + + mutex_lock(&(dd->mutex)); + size = m4sensorhub_reg_getsize(dd->m4, M4SH_REG_FUSION_SAMPLERATE); err = m4sensorhub_reg_write(dd->m4, M4SH_REG_FUSION_SAMPLERATE, (char *)&dd->samplerate, m4sh_no_mask); @@ -382,6 +385,8 @@ static void m4fus_panic_restore(struct m4sensorhub_data *m4sensorhub, m4fus_err("%s: Wrote %d bytes instead of %d.\n", __func__, err, size); } + + mutex_unlock(&(dd->mutex)); } static int m4fus_driver_init(struct init_calldata *p_arg) diff --git a/drivers/misc/m4sensorhub_heartrate.c b/drivers/misc/m4sensorhub_heartrate.c index 6e45b134bba..f2876ce9cda 100644 --- a/drivers/misc/m4sensorhub_heartrate.c +++ b/drivers/misc/m4sensorhub_heartrate.c @@ -494,9 +494,11 @@ static void m4hrt_panic_restore(struct m4sensorhub_data *m4sensorhub, __func__); return; } + + mutex_lock(&(dd->mutex)); + size = m4sensorhub_reg_getsize(dd->m4, M4SH_REG_HEARTRATE_APSAMPLERATE); - err = m4sensorhub_reg_write(dd->m4, M4SH_REG_HEARTRATE_APSAMPLERATE, (char *)&dd->samplerate, m4sh_no_mask); if (err < 0) { @@ -505,6 +507,8 @@ static void m4hrt_panic_restore(struct m4sensorhub_data *m4sensorhub, m4hrt_err("%s: Wrote %d bytes instead of %d.\n", __func__, err, size); } + + mutex_unlock(&(dd->mutex)); } static int m4hrt_driver_init(struct init_calldata *p_arg) diff --git a/drivers/misc/m4sensorhub_mpu9150.c b/drivers/misc/m4sensorhub_mpu9150.c index 2c6d6c12808..0d852d4bdd4 100644 --- a/drivers/misc/m4sensorhub_mpu9150.c +++ b/drivers/misc/m4sensorhub_mpu9150.c @@ -76,6 +76,7 @@ struct mpu9150_client { struct mpu9150_accel_data accel_data; struct mpu9150_gyro_data gyro_data; struct mpu9150_compass_data compass_data; + struct mutex mutex; /* prevent concurrent thread access */ }; struct mpu9150_client *misc_mpu9150_data; @@ -140,9 +141,6 @@ static void m4_report_mpu9150_inputevent( } } -/* TO DO -***** implement the delay functionality when M4 changes will be ready -*/ static void m4_set_mpu9150_delay(struct mpu9150_client *mpu9150_client_data, int delay, enum mpu9150_sensor type) { @@ -228,12 +226,18 @@ static void m4_read_mpu9150_data(struct mpu9150_client *mpu9150_client_data, } } + static void m4_handle_mpu9150_gyro_irq(enum m4sensorhub_irqs int_event, void *mpu9150_data) { struct mpu9150_client *mpu9150_client_data = mpu9150_data; + + mutex_lock(&(mpu9150_client_data->mutex)); + m4_read_mpu9150_data(mpu9150_client_data, TYPE_GYRO); m4_report_mpu9150_inputevent(mpu9150_client_data, TYPE_GYRO); + + mutex_unlock(&(mpu9150_client_data->mutex)); } static void m4_handle_mpu9150_accel_irq(enum m4sensorhub_irqs int_event, @@ -241,8 +245,12 @@ static void m4_handle_mpu9150_accel_irq(enum m4sensorhub_irqs int_event, { struct mpu9150_client *mpu9150_client_data = mpu9150_data; + mutex_lock(&(mpu9150_client_data->mutex)); + m4_read_mpu9150_data(mpu9150_client_data, TYPE_ACCEL); m4_report_mpu9150_inputevent(mpu9150_client_data, TYPE_ACCEL); + + mutex_unlock(&(mpu9150_client_data->mutex)); } static void m4_handle_mpu9150_compass_irq(enum m4sensorhub_irqs int_event, @@ -250,8 +258,12 @@ static void m4_handle_mpu9150_compass_irq(enum m4sensorhub_irqs int_event, { struct mpu9150_client *mpu9150_client_data = mpu9150_data; + mutex_lock(&(mpu9150_client_data->mutex)); + m4_read_mpu9150_data(mpu9150_client_data, TYPE_COMPASS); m4_report_mpu9150_inputevent(mpu9150_client_data, TYPE_COMPASS); + + mutex_unlock(&(mpu9150_client_data->mutex)); } static ssize_t m4_mpu9150_write_accel_setdelay(struct device *dev, @@ -273,6 +285,9 @@ static ssize_t m4_mpu9150_write_accel_setdelay(struct device *dev, ); return -EINVAL; } + + mutex_lock(&(misc_mpu9150_data->mutex)); + m4_set_mpu9150_delay(misc_mpu9150_data, scanresult, TYPE_ACCEL); if (scanresult == -1) { @@ -287,10 +302,11 @@ static ssize_t m4_mpu9150_write_accel_setdelay(struct device *dev, ); } + mutex_unlock(&(misc_mpu9150_data->mutex)); + return count; } - -static DEVICE_ATTR(accel_setdelay, S_IRUSR | S_IWUSR, NULL, +static DEVICE_ATTR(accel_setdelay, S_IWUSR, NULL, m4_mpu9150_write_accel_setdelay); static ssize_t m4_mpu9150_write_gyro_setdelay(struct device *dev, @@ -312,6 +328,9 @@ static ssize_t m4_mpu9150_write_gyro_setdelay(struct device *dev, ); return -EINVAL; } + + mutex_lock(&(misc_mpu9150_data->mutex)); + m4_set_mpu9150_delay(misc_mpu9150_data, scanresult, TYPE_GYRO); if (scanresult == -1) { mpu9150_irq_enable_disable( @@ -324,10 +343,12 @@ static ssize_t m4_mpu9150_write_gyro_setdelay(struct device *dev, SENSOR_IRQ_ENABLE ); } + + mutex_unlock(&(misc_mpu9150_data->mutex)); + return count; } - -static DEVICE_ATTR(gyro_setdelay, S_IRUSR | S_IWUSR, NULL, +static DEVICE_ATTR(gyro_setdelay, S_IWUSR, NULL, m4_mpu9150_write_gyro_setdelay); static ssize_t m4_mpu9150_write_compass_setdelay(struct device *dev, @@ -349,6 +370,9 @@ static ssize_t m4_mpu9150_write_compass_setdelay(struct device *dev, ); return -EINVAL; } + + mutex_lock(&(misc_mpu9150_data->mutex)); + m4_set_mpu9150_delay(misc_mpu9150_data, scanresult, TYPE_COMPASS); if (scanresult == -1) { mpu9150_irq_enable_disable( @@ -361,10 +385,14 @@ static ssize_t m4_mpu9150_write_compass_setdelay(struct device *dev, SENSOR_IRQ_ENABLE ); } + + mutex_unlock(&(misc_mpu9150_data->mutex)); + return count; } -static DEVICE_ATTR(compass_setdelay, S_IRUSR | S_IWUSR, NULL, +static DEVICE_ATTR(compass_setdelay, S_IWUSR, NULL, m4_mpu9150_write_compass_setdelay); + static struct attribute *mpu9150_control_attributes[] = { &dev_attr_accel_setdelay.attr, &dev_attr_gyro_setdelay.attr, @@ -372,7 +400,6 @@ static struct attribute *mpu9150_control_attributes[] = { NULL }; - static const struct attribute_group mpu9150_control_group = { .attrs = mpu9150_control_attributes, }; @@ -659,15 +686,23 @@ static void mpu9150_panic_restore(struct m4sensorhub_data *m4sensorhub, __func__); return; } + + mutex_lock(&(dd->mutex)); + KDEBUG(M4SH_INFO, "Executing mpu9150 panic restore\n"); m4_set_mpu9150_delay(dd, dd->samplerate[TYPE_ACCEL], TYPE_ACCEL); m4_set_mpu9150_delay(dd, dd->samplerate[TYPE_GYRO], TYPE_GYRO); m4_set_mpu9150_delay(dd, dd->samplerate[TYPE_COMPASS], TYPE_COMPASS); + + mutex_unlock(&(dd->mutex)); } static int mpu9150_driver_init(struct init_calldata *p_arg) { int ret; + + mutex_lock(&(misc_mpu9150_data->mutex)); + ret = mpu9150_irq_init(misc_mpu9150_data); if (ret < 0) { KDEBUG(M4SH_ERROR, "mpu9150 irq init failed\n"); @@ -682,6 +717,7 @@ static int mpu9150_driver_init(struct init_calldata *p_arg) KDEBUG(M4SH_ERROR, "HR panic callback register failed\n"); driver_init_exit: + mutex_unlock(&(misc_mpu9150_data->mutex)); return ret; } @@ -748,7 +784,10 @@ static int mpu9150_client_probe(struct platform_device *pdev) KDEBUG(M4SH_ERROR, "Error registering %s driver\n", __func__); goto unregister_input_device; } + misc_mpu9150_data = mpu9150_client_data; + mutex_init(&(misc_mpu9150_data->mutex)); + ret = m4sensorhub_register_initcall(mpu9150_driver_init, mpu9150_client_data); if (ret < 0) { @@ -765,6 +804,7 @@ static int mpu9150_client_probe(struct platform_device *pdev) if (ret) goto unregister_control_group; #endif + KDEBUG(M4SH_INFO, "Initialized %s driver\n", __func__); return 0; @@ -775,6 +815,7 @@ unregister_control_group: unregister_initcall: m4sensorhub_unregister_initcall(mpu9150_driver_init); unregister_misc_device: + mutex_destroy(&(misc_mpu9150_data->mutex)); misc_mpu9150_data = NULL; misc_deregister(&mpu9150_client_miscdrv); unregister_input_device: @@ -791,6 +832,11 @@ static int __exit mpu9150_client_remove(struct platform_device *pdev) { struct mpu9150_client *mpu9150_client_data = platform_get_drvdata(pdev); + + if (mpu9150_client_data == NULL) + return 0; + + mutex_lock(&(mpu9150_client_data->mutex)); sysfs_remove_group(&pdev->dev.kobj, &mpu9150_control_group); #ifdef MPU9150_DEBUG sysfs_remove_group(&pdev->dev.kobj, &mpu9150_group); @@ -802,6 +848,7 @@ static int __exit mpu9150_client_remove(struct platform_device *pdev) input_unregister_device(mpu9150_client_data->input_dev); platform_set_drvdata(pdev, NULL); mpu9150_client_data->m4sensorhub = NULL; + mutex_destroy(&(mpu9150_client_data->mutex)); kfree(mpu9150_client_data); mpu9150_client_data = NULL; return 0; @@ -811,10 +858,22 @@ static int mpu9150_client_suspend(struct platform_device *pdev, pm_message_t state) { struct mpu9150_client *dd = platform_get_drvdata(pdev); + + if (dd == NULL) { + KDEBUG(M4SH_ERROR, "%s: Driver data is NULL--%s.\n", + __func__, "cannot suspend"); + return 0; + } + + mutex_lock(&(dd->mutex)); + 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); + + mutex_unlock(&(dd->mutex)); + return 0; } diff --git a/drivers/misc/m4sensorhub_passive.c b/drivers/misc/m4sensorhub_passive.c index 70c77692573..e8c18335141 100644 --- a/drivers/misc/m4sensorhub_passive.c +++ b/drivers/misc/m4sensorhub_passive.c @@ -423,12 +423,16 @@ static void m4pas_panic_restore(struct m4sensorhub_data *m4sensorhub, return; } + mutex_lock(&(dd->mutex)); + en = (dd->samplerate >= 0) ? 1 : 0; err = m4sensorhub_reg_write_1byte(dd->m4, M4SH_REG_PASSIVE_ENABLE, en, 0xFF); if (err != 1) m4pas_err("%s: Failed to enable with %d.\n", __func__, err); + + mutex_unlock(&(dd->mutex)); } static int m4pas_driver_init(struct init_calldata *p_arg) diff --git a/drivers/misc/m4sensorhub_pedometer.c b/drivers/misc/m4sensorhub_pedometer.c index de8564bc317..fee4c92c81a 100644 --- a/drivers/misc/m4sensorhub_pedometer.c +++ b/drivers/misc/m4sensorhub_pedometer.c @@ -549,11 +549,15 @@ static void m4ped_panic_restore(struct m4sensorhub_data *m4sensorhub, void *data) { struct m4ped_driver_data *dd = (struct m4ped_driver_data *)data; + if (dd == NULL) { m4ped_err("%s: Driver data is null, unable to restore\n", __func__); return; } + + mutex_lock(&(dd->mutex)); + dd->base_dat.total_distance = dd->iiodat.total_distance; dd->base_dat.total_steps = dd->iiodat.total_steps; dd->base_dat.healthy_minutes = dd->iiodat.healthy_minutes; @@ -561,6 +565,8 @@ static void m4ped_panic_restore(struct m4sensorhub_data *m4sensorhub, m4ped_err("%s: Pedometer bases after panic = %d %d %d %d", __func__, dd->base_dat.total_distance, dd->base_dat.total_steps, dd->base_dat.healthy_minutes, dd->base_dat.calories); + + mutex_unlock(&(dd->mutex)); } static int m4ped_driver_init(struct init_calldata *p_arg) |