This is a fix for pm code with regard to the DSP.
In the current code we have a problem that DSP won't
re-enabled after suspend if DSP is just turned on
(with idle request) from McBSP  driver but not used
by DSP Gateway.
I moved DSP related code from pm.c to dsp_common.c.
With this patch DSP will be resumed to the original state
after suspend, whichever state (reset / idling for
McBSP / running with DSP Gateway) DSP was in.
Signed-off-by: Toshihiro Kobayashi <Toshihiro.Kobayashi@nokia.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
 #include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/mm.h>
+#include <asm/io.h>
 #include <asm/tlbflush.h>
 #include <asm/irq.h>
 #include <asm/arch/dsp.h>
                dsp_idle();
 }
 
+static unsigned short save_dsp_idlect2;
+
+/*
+ * note: if we are in pm_suspend / pm_resume function,
+ * we are out of clk_use() management.
+ */
+void omap_dsp_pm_suspend(void)
+{
+       unsigned short save_arm_idlect2;
+
+       /* Reset DSP */
+       __dsp_reset();
+
+       clk_disable(dsp_ck_handle);
+
+       /* Stop any DSP domain clocks */
+       save_arm_idlect2 = omap_readw(ARM_IDLECT2); // api_ck is in ARM_IDLECT2
+       clk_enable(api_ck_handle);
+       save_dsp_idlect2 = __raw_readw(DSP_IDLECT2);
+       __raw_writew(0, DSP_IDLECT2);
+       omap_writew(save_arm_idlect2, ARM_IDLECT2);
+}
+
+void omap_dsp_pm_resume(void)
+{
+       unsigned short save_arm_idlect2;
+
+       /* Restore DSP domain clocks */
+       save_arm_idlect2 = omap_readw(ARM_IDLECT2); // api_ck is in ARM_IDLECT2
+       clk_enable(api_ck_handle);
+       __raw_writew(save_dsp_idlect2, DSP_IDLECT2);
+       omap_writew(save_arm_idlect2, ARM_IDLECT2);
+
+       /* Run DSP, if it was running */
+       if (dsp_runstat != RUNSTAT_RESET)
+               __dsp_run();
+}
 static int init_done;
 
 static int __init omap_dsp_init(void)
 
 arch_initcall(omap_dsp_init);
 
+EXPORT_SYMBOL(omap_dsp_pm_suspend);
+EXPORT_SYMBOL(omap_dsp_pm_resume);
 EXPORT_SYMBOL(omap_dsp_request_idle);
 
 #ifdef CONFIG_OMAP_DSP_MODULE
 
                return -ERESTARTSYS;
 
        if (!dsp_is_ready()) {
-               printk(KERN_WARNING
-                      "omapdsp: DSP is not ready. suspend failed.\n");
                ret = -EINVAL;
                goto up_out;
        }
        }
 
        udelay(100);
-       dsp_reset();
        cfgstat = CFG_SUSPEND;
 up_out:
        up(&ioctl_sem);
                return 0;
 
        cfgstat = CFG_READY;
-       dsp_run();
        return 0;
 }
 
                break;
 
        case OMAP_DSP_IOCTL_SUSPEND:
-               ret = dsp_suspend();
+               if ((ret = dsp_suspend()) < 0)
+                       break;
+               dsp_reset();
                break;
 
        case OMAP_DSP_IOCTL_RESUME:
-               ret = dsp_resume();
+               if ((ret = dsp_resume()) < 0)
+                       break;
+               dsp_run();
                break;
 
        case OMAP_DSP_IOCTL_REGMEMR:
 
 #include <asm/arch/pm.h>
 #include <asm/arch/mux.h>
 #include <asm/arch/tps65010.h>
+#include <asm/arch/dsp_common.h>
 
 #include "clock.h"
 
 {
        unsigned long arg0 = 0, arg1 = 0;
        int (*func_ptr)(unsigned short, unsigned short) = NULL;
-       unsigned short save_dsp_idlect2;
 
        printk("PM: OMAP%x is trying to enter deep sleep...\n", system_rev);
 
         * Step 4: OMAP DSP Shutdown
         */
 
-       /* Set DSP_RST = 1 and DSP_EN = 0, put DSP block into reset */
-       omap_writel((omap_readl(ARM_RSTCT1) | DSP_RST) & ~DSP_ENABLE,
-                   ARM_RSTCT1);
-
-       /* Set DSP boot mode to DSP-IDLE, DSP_BOOT_MODE = 0x2 */
-        omap_writel(DSP_IDLE_MODE, MPUI_DSP_BOOT_CONFIG);
-
-       /* Set EN_DSPCK = 0, stop DSP block clock */
-       omap_writel(omap_readl(ARM_CKCTL) & ~DSP_CLOCK_ENABLE, ARM_CKCTL);
-
-       /* Stop any DSP domain clocks */
-       omap_writel(omap_readl(ARM_IDLECT2) | (1<<EN_APICK), ARM_IDLECT2);
-       save_dsp_idlect2 = __raw_readw(DSP_IDLECT2);
-       __raw_writew(0, DSP_IDLECT2);
+       omap_dsp_pm_suspend();
 
        /*
         * Step 5: Wakeup Event Setup
         */
 
        /* Restore DSP clocks */
-       omap_writel(omap_readl(ARM_IDLECT2) | (1<<EN_APICK), ARM_IDLECT2);
-       __raw_writew(save_dsp_idlect2, DSP_IDLECT2);
-       ARM_RESTORE(ARM_IDLECT2);
+       omap_dsp_pm_resume();
 
        /*
         * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did
 
 #ifndef ASM_ARCH_DSP_COMMON_H
 #define ASM_ARCH_DSP_COMMON_H
 
+void omap_dsp_pm_suspend(void);
+void omap_dsp_pm_resume(void);
 void omap_dsp_request_idle(void);
 
 #endif /* ASM_ARCH_DSP_COMMON_H */