diff options
author | Jun Yan <juyan@nvidia.com> | 2013-09-30 11:36:45 -0700 |
---|---|---|
committer | Riham Haidar <rhaidar@nvidia.com> | 2013-09-30 18:46:20 -0700 |
commit | 84f2500adc00a29415ac742ff2ccfa5514a03b96 (patch) | |
tree | 5c929584b5098cf09fdd8d8bccf293b5fc59500f | |
parent | aa760d99fb5ebeab8661a6ced8fef7f85e65f411 (diff) |
misc: issp: add lock for usb reset operation
usb reset operation should be in critical region.
Add mutex lock to prevent two WARs resetting the USB
together.
Bug 1364476
Change-Id: I4c17a61a594cad496f5444e919cf101f8098da25
Signed-off-by: Jun Yan <juyan@nvidia.com>
Reviewed-on: http://git-master/r/278072
Reviewed-by: Anshul Jain (SW) <anshulj@nvidia.com>
Tested-by: Anshul Jain (SW) <anshulj@nvidia.com>
Reviewed-on: http://git-master/r/279102
Reviewed-by: Automatic_Commit_Validation_User
-rw-r--r-- | drivers/misc/issp/issp.c | 14 | ||||
-rw-r--r-- | drivers/misc/issp/issp_priv.h | 2 |
2 files changed, 14 insertions, 2 deletions
diff --git a/drivers/misc/issp/issp.c b/drivers/misc/issp/issp.c index daa5b9a37355..dbe5110c890c 100644 --- a/drivers/misc/issp/issp.c +++ b/drivers/misc/issp/issp.c @@ -25,6 +25,7 @@ #include <linux/gpio.h> #include <linux/wakelock.h> #include <linux/delay.h> +#include <linux/mutex.h> #include "issp_priv.h" @@ -158,9 +159,11 @@ static void issp_recovery_work_func(struct work_struct *work) for (i = 0; i < 1; i++) { dev_info(&g_issp_host->pdev->dev, "%s: recovery attempt #%d\n", __func__, i); + mutex_lock(&g_issp_host->issp_lock); roth_usb_unload(); issp_uc_reset(); roth_usb_reload(); + mutex_unlock(&g_issp_host->issp_lock); msleep(500); } @@ -186,22 +189,28 @@ void issp_start_recovery_work(void) static ssize_t issp_reset_set(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - dev_info(dev, "resetting uC\n"); wake_lock(g_issp_wake_lock); + mutex_lock(&g_issp_host->issp_lock); issp_uc_reset(); + mutex_unlock(&g_issp_host->issp_lock); wake_unlock(g_issp_wake_lock); + dev_info(&g_issp_host->pdev->dev, + "issp: toggling reset pin on uC!"); return count; } static ssize_t issp_usbreset_set(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - dev_info(dev, "resetting USB and uC\n"); wake_lock(g_issp_wake_lock); + mutex_lock(&g_issp_host->issp_lock); roth_usb_unload(); issp_uc_reset(); roth_usb_reload(); + mutex_unlock(&g_issp_host->issp_lock); wake_unlock(g_issp_wake_lock); + dev_info(&g_issp_host->pdev->dev, + "issp: reset both usb and uC!"); return count; } @@ -327,6 +336,7 @@ static int __init issp_probe(struct platform_device *pdev) dev_err(dev, "Firmware update failed!\n"); } + mutex_init(&host->issp_lock); ret = device_create_file(dev, &dev_attr_issp_reset); if (ret) dev_err(dev, "ISSP sysfs node create failed\n"); diff --git a/drivers/misc/issp/issp_priv.h b/drivers/misc/issp/issp_priv.h index f1988a429db8..55db7b9c280f 100644 --- a/drivers/misc/issp/issp_priv.h +++ b/drivers/misc/issp/issp_priv.h @@ -22,6 +22,7 @@ #include <linux/kernel.h> #include <linux/issp.h> +#include <linux/mutex.h> struct issp_host { struct platform_device *pdev; @@ -35,6 +36,7 @@ struct issp_host { /* context to get fw data */ const struct ihex_binrec *cur_rec; int cur_idx; + struct mutex issp_lock; }; #define ISSP_FW_SECURITY_ADDR 0x00100000 |