aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dsp
diff options
context:
space:
mode:
authorMiguel Vadillo <vadillo@ti.com>2011-01-07 20:48:03 -0500
committerPaolo Pisati <paolo.pisati@canonical.com>2012-08-17 04:19:11 -0400
commitf63da2ac11b26c81aab5e3c964024596b750e103 (patch)
tree7338576e07e37e3d3ffde65cefa4dba7f482801e /drivers/dsp
parentd15bd422aea2047e026563c4a684b16b657a3467 (diff)
syslink: ipu_pm: fix wdt and add resource cleanup
wdt notification event was not being sent to the deh because if there are resources in use by IPU the assumption was that it is in a good state (not hanging) and the timer was being reloaded without catching the issue. This fix is avoiding that scenario adding an event PM_ALIVE, sent by ipu, that indicates there are resources in use but ipu wont hibernate, and the timer needs to be reloaded in kernel for hib_time seconds again. Also resources clean up is now done when the wd issue is catched. Change-Id: I34304763ce50ac51595a9a6b7c9305d95174f8f8 Signed-off-by: Miguel Vadillo <vadillo@ti.com> Signed-off-by: Juan Gutierrez <jgutierrez@ti.com>
Diffstat (limited to 'drivers/dsp')
-rw-r--r--drivers/dsp/syslink/ipu_pm/ipu_pm.c37
-rw-r--r--drivers/dsp/syslink/ipu_pm/ipu_pm.h1
2 files changed, 25 insertions, 13 deletions
diff --git a/drivers/dsp/syslink/ipu_pm/ipu_pm.c b/drivers/dsp/syslink/ipu_pm/ipu_pm.c
index 0af1b592ff6..5a727740461 100644
--- a/drivers/dsp/syslink/ipu_pm/ipu_pm.c
+++ b/drivers/dsp/syslink/ipu_pm/ipu_pm.c
@@ -737,14 +737,26 @@ void ipu_pm_notify_callback(u16 proc_id, u16 line_id, u32 event_id,
737 if (!_is_event(event)) 737 if (!_is_event(event))
738 goto error; 738 goto error;
739 if (event == PM_HIBERNATE) { 739 if (event == PM_HIBERNATE) {
740 /* Remote Proc is ready to hibernate 740 /* If any resource in use, no hibernation */
741 * PM_HIBERNATE is a one way notification 741 if (!(handle->rcb_table->state_flag & HIB_REF_MASK)) {
742 * Remote proc to Host proc 742 /* Remote Proc is ready to hibernate
743 * PM_HIBERNATE is a one way notification
744 * Remote proc to Host proc
745 */
746 pr_debug("Remote Proc is ready to hibernate\n");
747
748 retval = ipu_pm_save_ctx(proc_id);
749 if (retval)
750 pr_err("Unable to stop proc %d\n", proc_id);
751 } else
752 pr_err("Hibernation is not allowed if resource in use");
753 } else if (event == PM_ALIVE) {
754 /* If resources are in use ipu will send an event to make
755 * sure it is in a good state but hibernation won't happen
756 * and the timer will be reloaded to hib_time again.
743 */ 757 */
744 pr_debug("Remote Proc is ready to hibernate\n"); 758 pr_debug("Unable to stop proc, Resources in use\n");
745 retval = ipu_pm_save_ctx(proc_id); 759 ipu_pm_timer_state(PM_HIB_TIMER_ON);
746 if (retval)
747 pr_err("Unable to stop proc %d\n", proc_id);
748 } else { 760 } else {
749 pr_debug("Remote Proc received %d event\n", event); 761 pr_debug("Remote Proc received %d event\n", event);
750 handle->pm_event[event].pm_msg = payload; 762 handle->pm_event[event].pm_msg = payload;
@@ -2392,8 +2404,10 @@ int ipu_pm_save_ctx(int proc_id)
2392 PROC_LD_SHIFT; 2404 PROC_LD_SHIFT;
2393 2405
2394 /* If already down don't kill it twice */ 2406 /* If already down don't kill it twice */
2395 if (ipu_pm_get_state(proc_id) & SYS_PROC_DOWN) 2407 if (ipu_pm_get_state(proc_id) & SYS_PROC_DOWN) {
2396 goto exit; 2408 pr_warn("ipu already hibernated, no need to save again");
2409 return 0;
2410 }
2397 2411
2398#ifdef CONFIG_OMAP_PM 2412#ifdef CONFIG_OMAP_PM
2399 retval = omap_pm_set_max_sdma_lat(&pm_qos_handle_2, 2413 retval = omap_pm_set_max_sdma_lat(&pm_qos_handle_2,
@@ -3003,10 +3017,6 @@ static int ipu_pm_timer_state(int event)
3003 switch (event) { 3017 switch (event) {
3004 case PM_HIB_TIMER_EXPIRE: 3018 case PM_HIB_TIMER_EXPIRE:
3005 if (params->hib_timer_state == PM_HIB_TIMER_ON) { 3019 if (params->hib_timer_state == PM_HIB_TIMER_ON) {
3006 /* If any resource in use, no hibernation */
3007 if (handle->rcb_table->state_flag & HIB_REF_MASK)
3008 goto exit;
3009
3010 pr_debug("Starting hibernation, waking up M3 cores"); 3020 pr_debug("Starting hibernation, waking up M3 cores");
3011 handle->rcb_table->state_flag |= (SYS_PROC_HIB | 3021 handle->rcb_table->state_flag |= (SYS_PROC_HIB |
3012 APP_PROC_HIB | ENABLE_IPU_HIB); 3022 APP_PROC_HIB | ENABLE_IPU_HIB);
@@ -3019,6 +3029,7 @@ static int ipu_pm_timer_state(int event)
3019 PM_HIB_TIMER_WDRESET) { 3029 PM_HIB_TIMER_WDRESET) {
3020 /* notify devh to begin error recovery here */ 3030 /* notify devh to begin error recovery here */
3021 pr_debug("Timer ISR: Trigger WD reset + recovery\n"); 3031 pr_debug("Timer ISR: Trigger WD reset + recovery\n");
3032 ipu_pm_recover_schedule();
3022 ipu_pm_notify_event(0, NULL); 3033 ipu_pm_notify_event(0, NULL);
3023 if (sys_rproc->dmtimer != NULL) 3034 if (sys_rproc->dmtimer != NULL)
3024 omap_dm_timer_stop(sys_rproc->dmtimer); 3035 omap_dm_timer_stop(sys_rproc->dmtimer);
diff --git a/drivers/dsp/syslink/ipu_pm/ipu_pm.h b/drivers/dsp/syslink/ipu_pm/ipu_pm.h
index 9b11cc54533..e7efeae9851 100644
--- a/drivers/dsp/syslink/ipu_pm/ipu_pm.h
+++ b/drivers/dsp/syslink/ipu_pm/ipu_pm.h
@@ -337,6 +337,7 @@ enum pm_event_type{
337 PM_RESUME, 337 PM_RESUME,
338 PM_PID_DEATH, 338 PM_PID_DEATH,
339 PM_HIBERNATE, 339 PM_HIBERNATE,
340 PM_ALIVE,
340 PM_LAST_EVENT 341 PM_LAST_EVENT
341}; 342};
342 343