drivers: nvshm: staging: take wake_lock in all DL processing
Martin Chabot [Fri, 15 Feb 2013 21:57:16 +0000 (13:57 -0800)]
change to wake_lock to be consistent with other tegra drivers
take wake_lock nvshm in all DL processing to avoid
blocking BBC bootrom when cleanup interface

Bug 1237415

Change-Id: I3ec48241da01fef05b465986ef8e56cce43518ad
Signed-off-by: Martin Chabot <mchabot@nvidia.com>
Reviewed-on: http://git-master/r/205511
Reviewed-by: Vinayak Pane <vpane@nvidia.com>
Reviewed-by: Jean-Marc Guiraudet <jguiraudet@nvidia.com>
Reviewed-by: Bo Yan <byan@nvidia.com>

drivers/staging/nvshm/nvshm_init.c
drivers/staging/nvshm/nvshm_ipc.c
drivers/staging/nvshm/nvshm_priv.h
drivers/staging/nvshm/nvshm_queue.c

index f001e49..0052854 100644 (file)
@@ -49,6 +49,9 @@ static int nvshm_probe(struct platform_device *pdev)
        spin_lock_init(&handle->lock);
        spin_lock_init(&handle->qlock);
 
+       wake_lock_init(&handle->ul_lock, WAKE_LOCK_SUSPEND, "SHM-UL");
+       wake_lock_init(&handle->dl_lock, WAKE_LOCK_SUSPEND, "SHM-DL");
+
        handle->ipc_base_virt = pdata->ipc_base_virt;
        handle->ipc_size = pdata->ipc_size;
 
@@ -120,6 +123,8 @@ static void __exit nvshm_exit(void)
        pr_debug("%s\n", __func__);
        nvshm_tty_cleanup();
        nvshm_unregister_ipc(handle);
+       wake_lock_destroy(&handle->dl_lock);
+       wake_lock_destroy(&handle->ul_lock);
        kfree(handle);
        platform_driver_unregister(&nvshm_driver);
 }
index 8e500f2..6a9af0e 100644 (file)
@@ -21,7 +21,6 @@
 #include "nvshm_queue.h"
 
 #include <linux/interrupt.h>
-#include <linux/pm_wakeup.h>
 #include <asm/mach/map.h>
 #include <mach/tegra_bb.h>
 #include <asm/cacheflush.h>
@@ -196,6 +195,8 @@ static void ipc_work(struct work_struct *work)
        int new_state;
        int cmd;
 
+       if (!wake_lock_active(&handle->dl_lock))
+               wake_lock(&handle->dl_lock);
        new_state = *((int *)handle->mb_base_virt);
        cmd = new_state & 0xFFFF;
        if (((~new_state >> 16) ^ (cmd)) & 0xFFFF) {
@@ -206,6 +207,7 @@ static void ipc_work(struct work_struct *work)
                        cleanup_interfaces(handle);
                }
                enable_irq(handle->bb_irq);
+               wake_unlock(&handle->dl_lock);
                return;
        }
        switch (cmd) {
@@ -222,12 +224,14 @@ static void ipc_work(struct work_struct *work)
                }
                handle->old_status = cmd;
                enable_irq(handle->bb_irq);
+               wake_unlock(&handle->dl_lock);
                return;
        case NVSHM_IPC_BOOT_FW_REQ:
        case NVSHM_IPC_BOOT_RESTART_FW_REQ:
                if (handle->configured) {
                        nvshm_abort_queue(handle);
                        cleanup_interfaces(handle);
+                       pr_debug("%s: cleanup done\n", __func__);
                }
                break;
        case NVSHM_IPC_BOOT_ERROR_BT2_HDR:
@@ -254,6 +258,7 @@ static void ipc_work(struct work_struct *work)
        }
        handle->old_status = cmd;
        enable_irq(handle->bb_irq);
+       wake_unlock(&handle->dl_lock);
 }
 
 static void nvshm_ipc_handler(void *data)
@@ -271,13 +276,13 @@ static enum hrtimer_restart nvshm_ipc_timer_func(struct hrtimer *timer)
 
        if (tegra_bb_check_ipc(handle->tegra_bb) == 1) {
                pr_debug("%s AP2BB is cleared\n", __func__);
-               pm_relax(handle->dev);
+               wake_unlock(&handle->ul_lock);
                return HRTIMER_NORESTART;
        }
-       if (handle->timeout > NVSHM_WAKE_MAX_COUNT) {
+       if (handle->timeout++ > NVSHM_WAKE_MAX_COUNT) {
                pr_warn("%s AP2BB not cleared in 1s - aborting\n", __func__);
                tegra_bb_abort_ipc(handle->tegra_bb);
-               pm_relax(handle->dev);
+               wake_unlock(&handle->ul_lock);
                return HRTIMER_NORESTART;
        }
        pr_debug("%s AP2BB is still set\n", __func__);
@@ -317,8 +322,11 @@ int nvshm_unregister_ipc(struct nvshm_handle *handle)
 int nvshm_generate_ipc(struct nvshm_handle *handle)
 {
        int ret;
+
        /* take wake lock until BB ack our irq */
-       pm_stay_awake(handle->dev);
+       if (!wake_lock_active(&handle->ul_lock))
+               wake_lock(&handle->ul_lock);
+
        if (!hrtimer_active(&handle->wake_timer)) {
                handle->timeout = 0;
                ret = hrtimer_start(&handle->wake_timer,
index f6a0c82..7d830b9 100644 (file)
 #include <linux/hrtimer.h>
 #include <linux/module.h>
 #include <linux/mm.h>
+#include <linux/wakelock.h>
 #include <asm/memory.h>
 #include <asm/cacheflush.h>
 #include <asm/outercache.h>
-
 /*
  * Test stub is used to implement nvshm on private memory for testing purpose.
  * Data are allocated into this private memory but queues loop on themselves
@@ -60,6 +60,8 @@
 struct nvshm_handle {
        spinlock_t lock;
        spinlock_t qlock;
+       struct wake_lock ul_lock;
+       struct wake_lock dl_lock;
        int instance;
        int old_status;
        int configured;
index 353f4b0..de2d6a9 100644 (file)
@@ -20,7 +20,6 @@
 #include "nvshm_iobuf.h"
 
 #include <mach/tegra_bb.h>
-#include <linux/pm_wakeup.h>
 
 /* Flush cache lines associated with iobuf list */
 static void flush_iob_list(struct nvshm_handle *handle, struct nvshm_iobuf *iob)
@@ -189,8 +188,6 @@ void nvshm_process_queue(struct nvshm_handle *handle)
        int chan;
 
        spin_lock_bh(&handle->lock);
-       pr_debug("%s: awake\n", __func__);
-       pm_stay_awake(handle->dev);
        iob = nvshm_queue_get(handle);
        while (iob) {
                pr_debug("%s %p/%d/%d/%d->%p\n", __func__,
@@ -212,8 +209,6 @@ void nvshm_process_queue(struct nvshm_handle *handle)
                }
                iob = nvshm_queue_get(handle);
        }
-       pm_relax(handle->dev);
-       pr_debug("%s: relax\n", __func__);
        spin_unlock_bh(&handle->lock);
 }