summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Tashakkor <w36098@motorola.com>2014-07-09 15:42:22 -0500
committerERIC TASHAKKOR <w36098@motorola.com>2014-07-10 13:20:41 +0000
commit2f02ffa1a9d46c192d19fed48190beceb9b6ec21 (patch)
tree5726951fcc89a14602cf5982e78cfb5cc8d26ef1
parente1dfac029c58558d572d68b18d4d2a89470de088 (diff)
downloadolio-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.c6
-rw-r--r--drivers/misc/m4sensorhub_fusion.c5
-rw-r--r--drivers/misc/m4sensorhub_heartrate.c6
-rw-r--r--drivers/misc/m4sensorhub_mpu9150.c77
-rw-r--r--drivers/misc/m4sensorhub_passive.c4
-rw-r--r--drivers/misc/m4sensorhub_pedometer.c6
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)