summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnshul Jain <anshulj@nvidia.com>2013-06-21 14:44:53 -0700
committerAnshul Jain (SW) <anshulj@nvidia.com>2013-06-21 15:13:55 -0700
commit8e7a3713364aed4a0e70fb3046de8a3a91d0df62 (patch)
tree4157d116948f5200f7af7bd1ca316b0563590509
parentb9e37740c8614acd8e65210773133a4f0029705f (diff)
drivers:misc:issp: Hold wakelock while recovery
This change takes a wakelock before stating the recovery mechanism of JS Bug 1306389 Change-Id: I0109455647988248f1e37d5a000e1e34654e40e5 Signed-off-by: Anshul Jain <anshulj@nvidia.com> Reviewed-on: http://git-master/r/241103
-rw-r--r--drivers/misc/issp/issp.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/drivers/misc/issp/issp.c b/drivers/misc/issp/issp.c
index b1fb71d19bbd..f77fca7a62cc 100644
--- a/drivers/misc/issp/issp.c
+++ b/drivers/misc/issp/issp.c
@@ -23,12 +23,15 @@
#include <linux/platform_device.h>
#include <linux/ihex.h>
#include <linux/gpio.h>
+#include <linux/wakelock.h>
+#include <linux/delay.h>
#include "issp_priv.h"
#define DRIVER_NAME "issp"
struct issp_host *g_issp_host;
+struct wake_lock *g_issp_wake_lock;
static int issp_check_fw(struct issp_host *host)
{
@@ -139,20 +142,28 @@ extern void roth_usb_reload(void);
struct workqueue_struct *issp_workqueue;
struct delayed_work issp_recovery_work;
-static void issp_recovery_work_func(struct delayed_work *dwork)
+static void issp_recovery_work_func(struct work_struct *work)
{
int i;
extern void roth_usb_unload(void);
extern void roth_usb_reload(void);
pr_info("%s\n", __func__);
+ if (!g_issp_wake_lock) {
+ pr_err("%s: wake_lock null!!\n", __func__);
+ return;
+ }
for (i = 0; i < 1; i++) {
pr_info("%s: recovery attempt #%d\n", __func__, i);
roth_usb_unload();
issp_uc_reset();
roth_usb_reload();
+ msleep(500);
}
+
+ /*Done resetting JS, lets release the Wakelock*/
+ wake_unlock(g_issp_wake_lock);
}
void issp_start_recovery_work(void)
@@ -162,6 +173,9 @@ void issp_start_recovery_work(void)
pr_err("%s: no workqueue!\n", __func__);
return;
}
+
+ /*Hold wakelock, so we can be sure that JS resets!*/
+ wake_lock(g_issp_wake_lock);
queue_delayed_work(issp_workqueue, &issp_recovery_work,
msecs_to_jiffies(ISSP_RECOVERY_DELAY));
@@ -235,11 +249,21 @@ static int __init issp_probe(struct platform_device *pdev)
dev_err(dev, "Firmware update failed!\n");
}
+ g_issp_wake_lock = devm_kzalloc(dev, sizeof(struct wake_lock),
+ GFP_KERNEL);
+ if (!g_issp_wake_lock)
+ goto err;
+
+ /*Wake lock to prevent suspend when USB is deregistered! and recovery
+ of JS is happening!*/
+ wake_lock_init(g_issp_wake_lock, WAKE_LOCK_SUSPEND,
+ "issp-js-recovery");
+
/* create workqueue to recover from failed usb resume */
issp_workqueue = create_workqueue("issp_recovery_wq");
if (!issp_workqueue) {
dev_err(&pdev->dev, "can't create work queue\n");
- goto err;
+ goto err_work;
}
INIT_DELAYED_WORK(&issp_recovery_work, issp_recovery_work_func);
@@ -250,13 +274,14 @@ err_id:
release_firmware(host->fw);
return 0;
+err_work:
+ devm_kfree(dev, g_issp_wake_lock);
err:
gpio_direction_input(pdata->data_gpio);
gpio_direction_input(pdata->clk_gpio);
release_firmware(host->fw);
devm_kfree(dev, host);
-
- return 0;
+ return -ENOMEM;
}
static int __exit issp_remove(struct platform_device *pdev)
@@ -269,6 +294,9 @@ static int __exit issp_remove(struct platform_device *pdev)
issp_workqueue = NULL;
}
+ if (g_issp_wake_lock != NULL)
+ wake_lock_destroy(g_issp_wake_lock);
+
return 0;
}