diff options
| author | Miguel Vadillo <vadillo@ti.com> | 2011-01-07 20:48:03 -0500 |
|---|---|---|
| committer | Paolo Pisati <paolo.pisati@canonical.com> | 2012-08-17 04:19:11 -0400 |
| commit | f63da2ac11b26c81aab5e3c964024596b750e103 (patch) | |
| tree | 7338576e07e37e3d3ffde65cefa4dba7f482801e /drivers/dsp | |
| parent | d15bd422aea2047e026563c4a684b16b657a3467 (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.c | 37 | ||||
| -rw-r--r-- | drivers/dsp/syslink/ipu_pm/ipu_pm.h | 1 |
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 | ||
