static int s5p6442_pm_enter(suspend_state_t state) { unsigned long regs_save[16]; unsigned int tmp; unsigned int eint_wakeup_mask; /* ensure the debug is initialised (if enabled) */ DBG("s5p6442_pm_enter(%d)\n", state); if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) { printk(KERN_ERR PFX "error: no cpu sleep functions set\n"); return -EINVAL; } /* prepare check area if configured */ s5p6442_pm_check_prepare(); /* store the physical address of the register recovery block */ s5p6442_sleep_save_phys = virt_to_phys(regs_save); printk("s5p6442_sleep_save_phys=0x%08lx\n", s5p6442_sleep_save_phys); DEBUG_WAKEUP("[PM-1] EINT0(0x%08x), EINT1(0x%08x), EINT2(0x%08x), EINT3(0x%08x)\n", __raw_readl(S5P64XX_GPA0_BASE+0xF40), __raw_readl(S5P64XX_GPA0_BASE+0xF44), __raw_readl(S5P64XX_GPA0_BASE+0xF48), __raw_readl(S5P64XX_GPA0_BASE+0xF4C)); /* save all necessary core registers not covered by the drivers */ s5p6442_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save)); s5p6442_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); s5p6442_pm_do_save(core_save, ARRAY_SIZE(core_save)); s5p6442_pm_do_save(sromc_save, ARRAY_SIZE(sromc_save)); // s5p6442_pm_do_save(onenand_save, ARRAY_SIZE(onenand_save)); // s5p6442_pm_do_save(uart_save, ARRAY_SIZE(uart_save)); #ifdef S5P6442_POWER_GATING_IROM //s5p6442_pwrgate_config(S5P6442_IROM_ID, S5P6442_ACTIVE_MODE); tmp = __raw_readl(S5P_NORMAL_CFG); tmp |= (1 << S5P6442_IROM_ID); __raw_writel(tmp, S5P_NORMAL_CFG); #endif /* ensure INF_REG0 has the resume address */ __raw_writel(virt_to_phys(s5p6442_cpu_resume), S5P_INFORM0); // s5p_pwr_clk_gating_reset(); /* set the irq configuration for wake */ // s5p6442_pm_configure_extint(); /* call cpu specific preperation */ pm_cpu_prep(); /* flush cache back to ram */ flush_cache_all(); //s5p6442_pm_check_store(); s5p_config_sleep_gpio(); // for sleep current optimization /* set the irq configuration for wake */ eint_wakeup_mask = s5p6442_pm_configure_extint(); /* USB & OSC Clock pad Disable */ tmp = __raw_readl(S5P_SLEEP_CFG); tmp &= ~((1 << S5P_SLEEP_CFG_OSC_EN) | (1 << S5P_SLEEP_CFG_USBOSC_EN)); if(call_state) { tmp |= ((1 << S5P_SLEEP_CFG_OSC_EN) | (1 << S5P_SLEEP_CFG_USBOSC_EN)); } __raw_writel(tmp , S5P_SLEEP_CFG); /* Power mode Config setting */ tmp = __raw_readl(S5P_PWR_CFG); tmp &= S5P_CFG_WFI_CLEAN; tmp |= S5P_CFG_WFI_SLEEP; __raw_writel(tmp,S5P_PWR_CFG); #if 0 /* Set wakeup mask regsiter */ tmp = 0xFFFF; tmp &= ~(1 << 5); // keypad tmp &= ~(1 << 1); tmp &= ~(1 << 2); __raw_writel(tmp , S5P_WAKEUP_MASK); //Save the normal mode configuration of WAKE_UP sources and make EXT Key as a //wake up source from suspend mode(Praveen) #if 1 eint_wakeup_mask = __raw_readl(S5P_EINT_WAKEUP_MASK); tmp = 0xFFFFFFFF; //tmp &= ~(1 << 10); tmp &= ~(1 << 22); //EINT2_6 //tmp &= ~(1 << 15); __raw_writel(tmp, S5P_EINT_WAKEUP_MASK); #endif #endif //Removed by Praveen(July 12, 2010) //__raw_writel(s3c_irqwake_eintmask,S5P_EINT_WAKEUP_MASK); /* send the cpu to sleep... */ __raw_writel(0xffffffff, S5P64XX_VIC0INTENCLEAR); __raw_writel(0xffffffff, S5P64XX_VIC1INTENCLEAR); __raw_writel(0xffffffff, S5P64XX_VIC2INTENCLEAR); __raw_writel(0xffffffff, S5P64XX_VIC0SOFTINTCLEAR); __raw_writel(0xffffffff, S5P64XX_VIC1SOFTINTCLEAR); __raw_writel(0xffffffff, S5P64XX_VIC2SOFTINTCLEAR); /* EINTPEND CLEAR */ __raw_writel ( 0xFF, S5P64XX_GPA0_BASE + 0xF40 ); __raw_writel ( 0xFF, S5P64XX_GPA0_BASE + 0xF44 ); __raw_writel ( 0xFF, S5P64XX_GPA0_BASE + 0xF48 ); __raw_writel ( 0xFF, S5P64XX_GPA0_BASE + 0xF4C ); #if (CONFIG_BOARD_REVISION == 0x0) // EVT1 doesn't work 'PDNEN' setting. __raw_writel(0x2, S5P64XX_PDNEN); #endif /* SYSC INT Disable */ tmp = __raw_readl(S5P_OTHERS); tmp &= ~(0x3<<8); tmp |= S5P_OTHER_SYSC_INTOFF; if(call_state) { tmp |= (0x3<<8); } __raw_writel(tmp,S5P_OTHERS); tmp = __raw_readl(S5P_WAKEUP_STAT); __raw_writel(tmp, S5P_WAKEUP_STAT); /* s5p6442_cpu_save will also act as our return point from when * we resume as it saves its own register state, so use the return * code to differentiate return from save and return from sleep */ if (s5p6442_cpu_save(regs_save) == 0) { flush_cache_all(); pm_cpu_sleep(); } /* restore the cpu state */ cpu_init(); /* restore the system state */ s5p6442_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save)); s5p6442_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); s5p6442_pm_do_restore_core(core_save, ARRAY_SIZE(core_save)); s5p6442_pm_do_restore(sromc_save, ARRAY_SIZE(sromc_save)); //s5p6442_pm_do_restore(onenand_save, ARRAY_SIZE(onenand_save)); //s5p6442_pm_do_restore(uart_save, ARRAY_SIZE(uart_save)); #if (CONFIG_BOARD_REVISION == 0x0) __raw_writel(0x0, S5P64XX_PDNEN); #endif /*enable gpio, uart, mmc*/ tmp = __raw_readl(S5P_OTHERS); tmp |= (1<<31)|(1<<28)|(1<<29); __raw_writel(tmp, S5P_OTHERS); /* UART INTERRUPT PENDING REG clear */ tmp = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UINTP); __raw_writel(tmp, S3C24XX_VA_UART0 + S3C2410_UINTP); tmp = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UINTP); __raw_writel(tmp, S3C24XX_VA_UART1 + S3C2410_UINTP); tmp = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UINTP); __raw_writel(tmp, S3C24XX_VA_UART2 + S3C2410_UINTP); tmp = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UINTSP); __raw_writel(tmp, S3C24XX_VA_UART0 + S3C2410_UINTSP); tmp = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UINTSP); __raw_writel(tmp, S3C24XX_VA_UART1 + S3C2410_UINTSP); tmp = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UINTSP); __raw_writel(tmp, S3C24XX_VA_UART2 + S3C2410_UINTSP); /* __raw_writel(0xF, S3C24XX_VA_UART0 + S3C2410_UINTSP); __raw_writel(0xF, S3C24XX_VA_UART1 + S3C2410_UINTSP); __raw_writel(0xF, S3C24XX_VA_UART2 + S3C2410_UINTSP); */ /* Enable CLK GATE for UART */ tmp = __raw_readl(S5P_CLKGATE_IP3); tmp |= (S5P_CLKGATE_IP3_UART0 | S5P_CLKGATE_IP3_UART1 | S5P_CLKGATE_IP3_UART2); __raw_writel(tmp, S5P_CLKGATE_IP3); //[sm.kim: remove inconsistant code //tmp = __raw_readl(S5P64XX_EINT2PEND); //__raw_writel(tmp, S5P64XX_EINT2PEND); //] // __raw_writel(__raw_readl(S5P64XX_EINT0MASK)&~(1UL << 1), S5P64XX_EINT0MASK); //unmasking ext. INT tmp = __raw_readl(S5P_WAKEUP_STAT); DEBUG_WAKEUP("[PM] WAKEUP_STAT (0x%08x)\n", tmp); __raw_writel(tmp, S5P_WAKEUP_STAT); if( (__raw_readl(S5P64XX_GPA0_BASE+0xF40) & (1 << 7)) || // AP_PMIC_IRQ (__raw_readl(S5P64XX_GPA0_BASE+0xF48) & (1 << 7)) ) // JACK_nINT charger_wakeup = 1; else charger_wakeup = 0; if (__raw_readl(S5P64XX_GPA0_BASE+0xF48) & 0x01) wakeup_sdslot = 1; if(tmp == 0x00000001) { if((__raw_readl(S5P64XX_GPA0_BASE+0xF48) & 0x40) ||(__raw_readl(S5P64XX_GPA0_BASE+0xF44) & 0x01) ) wakeup_flag_for_key = 249; else if(__raw_readl(S5P64XX_GPA0_BASE+0xF4C) & 0x01) wakeup_flag_for_key = 102; else wakeup_flag_for_key = 0; } DEBUG_WAKEUP("[PM-2] EINT0(0x%08x), EINT1(0x%08x), EINT2(0x%08x), EINT3(0x%08x)\n", __raw_readl(S5P64XX_GPA0_BASE+0xF40), __raw_readl(S5P64XX_GPA0_BASE+0xF44), __raw_readl(S5P64XX_GPA0_BASE+0xF48), __raw_readl(S5P64XX_GPA0_BASE+0xF4C)); #if 1 //Write back the normal mode configuration for WAKE_UP source(Praveen) __raw_writel(eint_wakeup_mask, S5P_EINT_WAKEUP_MASK); #endif // mdelay(10); DBG("post sleep, preparing to return\n"); //s5p6442_pm_check_restore(); /* ok, let's return from sleep */ DBG("S5P6442 PM Resume (post-restore)\n"); return 0; }
static int s5pc11x_pm_enter(suspend_state_t state) { unsigned long regs_save[16]; unsigned int tmp; #ifdef CONFIG_HAS_WAKELOCK //wake_unlock(&pm_wake_lock); #endif /* ensure the debug is initialised (if enabled) */ DBG("s5pc11x_pm_enter(%d)\n", state); if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) { printk(KERN_ERR PFX "error: no cpu sleep functions set\n"); return -EINVAL; } #ifdef CONFIG_CPU_FREQ s5pc110_pm_target(BOOT_ARM_CLK); #endif /* store the physical address of the register recovery block */ s5pc110_sleep_save_phys = virt_to_phys(regs_save); DBG("s5pc11x_sleep_save_phys=0x%08lx\n", s5pc110_sleep_save_phys); s5pc11x_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save)); #ifdef S5PC11X_ALIVEGPIO_STORE s5pc11x_pm_do_save(gpio_save_alive, ARRAY_SIZE(gpio_save_alive)); #endif s5pc11x_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); s5pc11x_pm_do_save(core_save, ARRAY_SIZE(core_save)); s5pc11x_pm_do_save(sromc_save, ARRAY_SIZE(sromc_save)); s5pc11x_pm_do_save(uart_save, ARRAY_SIZE(uart_save)); /* ensure INF_REG0 has the resume address */ __raw_writel(virt_to_phys(s5pc110_cpu_resume), S5P_INFORM0); /* call cpu specific preperation */ pm_cpu_prep(); /* flush cache back to ram */ flush_cache_all(); #if 0 // To preserve 24MHz clock. /* USB & OSC Clock pad Enable */ tmp = __raw_readl(S5P_SLEEP_CFG); //tmp |= (S5P_SLEEP_CFG_OSC_EN | S5P_SLEEP_CFG_USBOSC_EN); tmp &= ~(S5P_SLEEP_CFG_OSC_EN | S5P_SLEEP_CFG_USBOSC_EN); __raw_writel(tmp , S5P_SLEEP_CFG); #endif __raw_writel(0xffffffff , S5P_EINT_WAKEUP_MASK); /* Power mode Config setting */ tmp = __raw_readl(S5P_PWR_CFG); tmp &= S5P_CFG_WFI_CLEAN; tmp |= S5P_CFG_WFI_SLEEP; __raw_writel(tmp,S5P_PWR_CFG); if (!hw_version_check()) { /* Set wakeup mask regsiter */ __raw_writel(0xFFED, S5P_WAKEUP_MASK); } else { __raw_writel(0xFFFD, S5P_WAKEUP_MASK); //0xFFFD:, RTC_ALARM // __raw_writel(0xFFDD, S5P_WAKEUP_MASK); //0xFFDD:key, RTC_ALARM } __raw_writel(0xffffffff, S5PC110_VIC0REG(VIC_INT_ENABLE_CLEAR)); __raw_writel(0xffffffff, S5PC110_VIC1REG(VIC_INT_ENABLE_CLEAR)); __raw_writel(0xffffffff, S5PC110_VIC2REG(VIC_INT_ENABLE_CLEAR)); __raw_writel(0xffffffff, S5PC110_VIC3REG(VIC_INT_ENABLE_CLEAR)); __raw_writel(0xffffffff, S5PC110_VIC0REG(VIC_INT_SOFT_CLEAR)); __raw_writel(0xffffffff, S5PC110_VIC1REG(VIC_INT_SOFT_CLEAR)); __raw_writel(0xffffffff, S5PC110_VIC2REG(VIC_INT_SOFT_CLEAR)); __raw_writel(0xffffffff, S5PC110_VIC3REG(VIC_INT_SOFT_CLEAR)); /* SYSC INT Disable */ tmp = __raw_readl(S5P_OTHERS); tmp |= (S5P_OTHER_SYSC_INTOFF); __raw_writel(tmp,S5P_OTHERS); /* Clear WAKEUP_STAT register for next wakeup */ tmp = __raw_readl(S5P_WAKEUP_STAT); __raw_writel(tmp, S5P_WAKEUP_STAT); /* Wake up source setting */ //s5pc11x_pm_configure_extint(); // key pad direction control for evt0 //s5pc11x_set_keypad_sleep_gpio(); /*Set EINT 22 as wake up source*/ //hojun_kim 100526 [ if(system_rev >= 0x08) { s5pc11x_pm_set_eint(5, 0x4); //Hall SW } //hojun_kim ] s5pc11x_pm_set_eint(11, 0x2); s5pc11x_pm_set_eint(22, 0x2); // s5pc11x_pm_set_eint(21, 0x4); s5pc11x_pm_set_eint(7, 0x02); //PMIC s5pc11x_pm_set_eint(6, 0x4); //det_3.5 s5pc11x_pm_set_eint(30, 0x4); //suik_Fix //short_sendend pin s5pc11x_pm_set_eint(4, 0x4); if(system_rev >= 0x08) //seonha { s5pc11x_pm_set_eint(2, 0x4); //suik_Fix //open_sendend pin } if(gp2a_get_proximity_enable()) { if(system_rev >= 0x0A) //jihyon.82.kim for victory rev 10 { s5pc11x_pm_set_eint(1, 0x4); } } s5pc11x_pm_set_eint(3, 0x3);//WiFi SecFeature.Victory s5pc11x_pm_set_eint(23, 0x2);//microusb.. 20100517_inchul //gpio key // if(HWREV >= 0xB) // { s5pc11x_pm_set_eint(24, 0x4); s5pc11x_pm_set_eint(25, 0x4); // } if (!hw_version_check()) { /*Set keypad as EINT for EVT0 wake up workaround*/ s5pc11x_pm_set_eint(24, 0x2); s5pc11x_pm_set_eint(25, 0x2); s5pc11x_pm_set_eint(26, 0x2); s5pc11x_pm_set_eint(27, 0x2); /*Column pull down enabled*/ tmp = readl(S5PC11X_GPH2PUD); tmp &= ~(0xFF); tmp |= 0x55; writel(tmp, S5PC11X_GPH2PUD); } #if 1 //cky 20100416 WiMAX ext-interrupt if (gpio_get_value(GPIO_WIMAX_EN)) { DBG("WIMAX POWER ON!! Set WIMAX_INT as Ext-Int.\n"); s5pc11x_pm_set_eint(14, 0x0); // WIMAX_INT: GPH1(6); LOW LEVEL DETECT } #endif s3c_config_sleep_gpio(); s3c_gpio_slp_cfgpin(S5PC11X_MP03(3), S3C_GPIO_SLP_OUT0); s3c_gpio_slp_setpull_updown(S5PC11X_MP03(3), S3C_GPIO_SLP_OUT0); #if 0 tmp = __raw_readl(S5P_OTHERS); tmp &= ~(3 << 8); tmp |= (3 << 8); __raw_writel(tmp, S5P_OTHERS); __raw_writel(0,S5P_MIE_CONTROL); __raw_writel(0,S5P_HDMI_CONTROL); __raw_writel(0,S5P_USB_PHY_CONTROL); __raw_writel(0,S5P_DAC_CONTROL); __raw_writel(0,S5P_MIPI_PHY_CONTROL); __raw_writel(0,S5P_ADC_CONTROL); __raw_writel(0,S5P_PSHOLD_CONTROL); #endif #if (!(defined CONFIG_ARIES_VER_B0) && !(defined CONFIG_ARIES_VER_B4) && !(defined CONFIG_ARIES_VER_B5)) // Enable PS_HOLD pin to avoid reset failure */ __raw_writel((0x5 << 12 | 0x1<<9 | 0x1<<8 | 0x1<<0),S5P_PSHOLD_CONTROL); #endif /* s5pc11x_cpu_save will also act as our return point from when * we resume as it saves its own register state, so use the return * code to differentiate return from save and return from sleep */ if (s5pc110_cpu_save(regs_save) == 0) { flush_cache_all(); if (!hw_version_check()) { /* This function for Chip bug on EVT0 */ tmp = __raw_readl(S5P_EINT_WAKEUP_MASK + 4); //PWR_MODE tmp |= (1 << 2); __raw_writel(tmp , S5P_EINT_WAKEUP_MASK + 4); // end mod } pm_cpu_sleep(); } /* restore the cpu state */ cpu_init(); #ifdef __DEBUG_PRINT_EINT_WAKEUP_STATUS int eintcon[4],eintmask[4],eintpend[4]; int eint_wakeup_mask; int i; for(i=0; i<4; i++) { eint_wakeup_mask = readl(S5P_EINT_WAKEUP_MASK); eintcon[i] = __raw_readl(S5PC11X_EINTCON(i)); eintmask[i] = __raw_readl(S5PC11X_EINTMASK(i)); eintpend[i] = __raw_readl(S5PC11X_EINTPEND(i)); } #endif s5pc11x_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save)); #ifdef S5PC11X_ALIVEGPIO_STORE s5pc11x_pm_do_restore_alive(gpio_save_alive, ARRAY_SIZE(gpio_save_alive)); #endif s5pc11x_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); __raw_writel(0x0, S3C24XX_VA_UART2+S3C2410_UCON); __raw_writel(0xf, S3C24XX_VA_UART2+S5P_UINTP); __raw_writel(0xf, S3C24XX_VA_UART2+S5P_UINTSP); __raw_writel(0xf, S3C24XX_VA_UART2+S5P_UINTM); /* Temporary workaround to protect lockup by UART - 20100316 */ __raw_writel(0x0, S3C24XX_VA_UART3+S3C2410_UCON); __raw_writel(0xf, S3C24XX_VA_UART3+S5P_UINTM); __raw_writel(0xf, S3C24XX_VA_UART3+S5P_UINTSP); __raw_writel(0xf, S3C24XX_VA_UART3+S5P_UINTP); __raw_writel(0x0, S3C24XX_VA_UART2+S3C2410_UCON); __raw_writel(0xf, S3C24XX_VA_UART2+S5P_UINTM); __raw_writel(0xf, S3C24XX_VA_UART2+S5P_UINTSP); __raw_writel(0xf, S3C24XX_VA_UART2+S5P_UINTP); __raw_writel(0x0, S3C24XX_VA_UART1+S3C2410_UCON); __raw_writel(0xf, S3C24XX_VA_UART1+S5P_UINTM); __raw_writel(0xf, S3C24XX_VA_UART1+S5P_UINTSP); __raw_writel(0xf, S3C24XX_VA_UART1+S5P_UINTP); __raw_writel(0x0, S3C24XX_VA_UART0+S3C2410_UCON); __raw_writel(0xf, S3C24XX_VA_UART0+S5P_UINTM); __raw_writel(0xf, S3C24XX_VA_UART0+S5P_UINTSP); __raw_writel(0xf, S3C24XX_VA_UART0+S5P_UINTP); s5pc11x_pm_do_restore(uart_save, ARRAY_SIZE(uart_save)); s5pc11x_pm_do_restore(core_save, ARRAY_SIZE(core_save)); s5pc11x_pm_do_restore(sromc_save, ARRAY_SIZE(sromc_save)); /*enable gpio, uart, mmc*/ tmp = __raw_readl(S5P_OTHERS); #if ((defined CONFIG_ARIES_VER_B0) || (defined CONFIG_ARIES_VER_B4) || (defined CONFIG_ARIES_VER_B5)) tmp |= (1<<31) | (1<<28) | (1<<29); #else tmp |= (1<<31) | (0x1<<30) | (1<<28) | (1<<29); #endif __raw_writel(tmp, S5P_OTHERS); /* EINT22 Pending clear */ //s5pc11x_pm_clear_eint(22); //<= do action in s3c-keypad.c // s5pc11x_pm_clear_eint(21); if (!hw_version_check()) { // for evt 0 keypad wakeup workaround s5pc11x_pm_clear_eint(24); s5pc11x_pm_clear_eint(25); s5pc11x_pm_clear_eint(26); s5pc11x_pm_clear_eint(27); s5pc11x_pm_clear_eint(21); s5pc11x_pm_clear_eint(20); } else { /* Clear WAKEUP_STAT register for next wakeup */ tmp = __raw_readl(S5P_WAKEUP_STAT); __raw_writel(tmp, S5P_WAKEUP_STAT); #if 0 /* This is for LCD wakeup if key is pressed */ tmp=(unsigned int)S5PC11X_EINTPEND(3); tmp &= 0x07; printk("wakeup source is 0x%x \n", tmp); if (tmp) key_wakeup_state=1; else key_wakeup_state=0; writel(tmp, S5PC11X_EINTPEND(3)); #else printk("wakeup source is 0x%x \n", tmp); #endif } #ifdef __DEBUG_PRINT_EINT_WAKEUP_STATUS // if woken up by external interrupt print eint registers if(tmp&0x1) { printk("EINT_WAKEUP_MASK(%08X)\n", eint_wakeup_mask); for(i=0; i<4; i++) { printk("EINT%dCON(%08X) EINT%dMASK(%08X) EINT%dPEND(%08X)\n" ,i,eintcon[i] ,i,eintmask[i] ,i,eintpend[i]); } } #endif #if 1 //cky 20100513 ext-int for wimax if (gpio_get_value(GPIO_WIMAX_EN)) { DBG("WIMAX POWER ON!! Set WIMAX_INT: INPUT.\n"); s5pc11x_pm_clear_eint(14); s3c_gpio_cfgpin(GPIO_WIMAX_INT, S3C_GPIO_INPUT); s3c_gpio_setpull(GPIO_WIMAX_INT, S3C_GPIO_PULL_NONE); } #endif DBG("\npost sleep, preparing to return 2\n"); s5pc11x_pm_check_restore(); #ifdef CONFIG_HAS_WAKELOCK //wake_lock_timeout(&pm_wake_lock, 5 * HZ); #endif /* ok, let's return from sleep */ DBG("S5PC110 PM Resume (post-restore)\n"); return 0; }
static int s3c6410_pm_enter(suspend_state_t state) { unsigned long regs_save[16]; unsigned int tmp; unsigned int wakeup_stat = 0x0; unsigned int eint0pend = 0x0; /* ensure the debug is initialised (if enabled) */ DBG("s3c6410_pm_enter(%d)\n", state); if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) { printk(KERN_ERR PFX "error: no cpu sleep functions set\n"); return -EINVAL; } /* prepare check area if configured */ s3c6410_pm_check_prepare(); /* store the physical address of the register recovery block */ s3c6410_sleep_save_phys = virt_to_phys(regs_save); DBG("s3c6410_sleep_save_phys=0x%08lx\n", s3c6410_sleep_save_phys); /* save all necessary core registers not covered by the drivers */ s3c6410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save)); s3c6410_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); s3c6410_pm_do_save(core_save, ARRAY_SIZE(core_save)); s3c6410_pm_do_save(sromc_save, ARRAY_SIZE(sromc_save)); //bss s3c6410_pm_do_save(onenand_save, ARRAY_SIZE(onenand_save)); s3c6410_pm_do_save(uart_save, ARRAY_SIZE(uart_save)); /* ensure INF_REG0 has the resume address */ __raw_writel(0xE240000C, (phys_to_virt(0x50008000))); __raw_writel(0xE5901000, (phys_to_virt(0x50008004))); __raw_writel(0xE1a0f001, (phys_to_virt(0x50008008))); __raw_writel(0xe320f000, (phys_to_virt(0x5000800C))); __raw_writel(0xe320f000, (phys_to_virt(0x50008010))); __raw_writel(0xe320f000, (phys_to_virt(0x50008014))); __raw_writel(virt_to_phys(s3c6410_cpu_resume), S3C_INFORM0); /* set the irq configuration for wake */ s3c6410_pm_configure_extint(); /* call cpu specific preperation */ __raw_writel(0xF, S3C_INFORM3); pm_cpu_prep(); /* flush cache back to ram */ flush_cache_all(); s3c6410_pm_check_store(); s3c_config_sleep_gpio(); tmp = __raw_readl(S3C64XX_SPCONSLP); tmp &= ~(0x3 << 12); __raw_writel(tmp | (0x1 << 12), S3C64XX_SPCONSLP); /* send the cpu to sleep... */ __raw_writel(0xffffffff, S3C64XX_VIC0INTENCLEAR); __raw_writel(0xffffffff, S3C64XX_VIC1INTENCLEAR); __raw_writel(0xffffffff, S3C64XX_VIC0SOFTINTCLEAR); __raw_writel(0xffffffff, S3C64XX_VIC1SOFTINTCLEAR); /* Unmask clock gating and block power turn on */ __raw_writel(0x43E00041, S3C_HCLK_GATE); __raw_writel(0xF2040000, S3C_PCLK_GATE); __raw_writel(0x80000011, S3C_SCLK_GATE); __raw_writel(0x00000000, S3C_MEM0_CLK_GATE); __raw_writel(0x1, S3C_OSC_STABLE); __raw_writel(0x3, S3C_PWR_STABLE); /* Set WFI instruction to SLEEP mode */ tmp = __raw_readl(S3C_PWR_CFG); tmp &= ~(0x3<<5); tmp |= (0x3<<5); __raw_writel(tmp, S3C_PWR_CFG); tmp = __raw_readl(S3C_SLEEP_CFG); tmp &= ~(0x61<<0); __raw_writel(tmp, S3C_SLEEP_CFG); __raw_writel(0x2, S3C64XX_SLPEN); /* Clear WAKEUP_STAT register for next wakeup -jc.lee */ /* If this register do not be cleared, Wakeup will be failed */ __raw_writel(__raw_readl(S3C_WAKEUP_STAT), S3C_WAKEUP_STAT); /* s3c6410_cpu_save will also act as our return point from when * we resume as it saves its own register state, so use the return * code to differentiate return from save and return from sleep */ if (s3c6410_cpu_save(regs_save) == 0) { flush_cache_all(); pm_cpu_sleep(); } /* restore the cpu state */ cpu_init(); __raw_writel(s3c_eint_mask_val, S3C_EINT_MASK); /* restore the system state */ s3c6410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save)); s3c6410_pm_do_restore(sromc_save, ARRAY_SIZE(sromc_save)); s3c6410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save)); s3c6410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); //bss s3c6410_pm_do_restore(onenand_save, ARRAY_SIZE(onenand_save)); s3c6410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save)); __raw_writel(0x0, S3C64XX_SLPEN); wakeup_stat = __raw_readl(S3C_WAKEUP_STAT); eint0pend = __raw_readl(S3C64XX_EINT0PEND); __raw_writel(eint0pend, S3C64XX_EINT0PEND); DBG("post sleep, preparing to return\n"); s3c6410_pm_check_restore(); extra_eint0pend = eint0pend; extra_wakeup_stat = wakeup_stat; pr_info("%s: WAKEUP_STAT(0x%08x), EINT0PEND(0x%08x)\n", __func__, wakeup_stat, eint0pend); s3c_config_wakeup_gpio(); /* ok, let's return from sleep */ DBG("S3C6410 PM Resume (post-restore)\n"); return 0; }
static int s5pc1xx_pm_enter(suspend_state_t state) { unsigned long regs_save[16]; unsigned int tmp; /* ensure the debug is initialised (if enabled) */ DBG("s5pc1xx_pm_enter(%d)\n", state); if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) { printk(KERN_ERR PFX "error: no cpu sleep functions set\n"); return -EINVAL; } /* store the physical address of the register recovery block */ s5pc100_sleep_save_phys = virt_to_phys(regs_save); DBG("s5pc1xx_sleep_save_phys=0x%08lx\n", s5pc100_sleep_save_phys); s5pc1xx_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save)); s5pc1xx_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); s5pc1xx_pm_do_save(core_save, ARRAY_SIZE(core_save)); s5pc1xx_pm_do_save(sromc_save, ARRAY_SIZE(sromc_save)); s5pc1xx_pm_do_save(nand_save, ARRAY_SIZE(nand_save)); s5pc1xx_pm_do_save(uart_save, ARRAY_SIZE(uart_save)); s5pc1xx_pm_do_save(eint_save, ARRAY_SIZE(eint_save)); /* ensure INF_REG0 has the resume address */ __raw_writel(virt_to_phys(s5pc100_cpu_resume), S5P_INFORM0); /* call cpu specific preperation */ pm_cpu_prep(); /* flush cache back to ram */ flush_cache_all(); /* send the cpu to sleep... */ __raw_writel(0xffffffff, S5PC100_VIC0REG(VIC_INT_ENABLE_CLEAR)); __raw_writel(0xffffffff, S5PC100_VIC1REG(VIC_INT_ENABLE_CLEAR)); __raw_writel(0xffffffff, S5PC100_VIC2REG(VIC_INT_ENABLE_CLEAR)); __raw_writel(0xffffffff, S5PC100_VIC0REG(VIC_INT_SOFT_CLEAR)); __raw_writel(0xffffffff, S5PC100_VIC1REG(VIC_INT_SOFT_CLEAR)); __raw_writel(0xffffffff, S5PC100_VIC2REG(VIC_INT_SOFT_CLEAR)); /* Mask all wake up source */ tmp = __raw_readl(S5P_PWR_CFG); tmp &= ~(0x1 << 7); tmp |= (0x7ff << 8); /* unmask alarm wakeup source */ tmp &= ~(0x1 << 10); /* unmask keypad wakeup source */ tmp &= ~(0x1 << 8); __raw_writel(tmp , S5P_PWR_CFG); __raw_writel(0xffffffff , S5P_EINT_WAKEUP_MASK); /* Wake up source setting */ s5pc1xx_pm_configure_extint(); /* : USB Power Control */ /* - USB PHY Disable */ /* - Make USB Tranceiver PAD to Suspend */ tmp = __raw_readl(S5P_OTHERS); tmp &= ~(1<<16); /* USB Signal Mask Clear */ __raw_writel(tmp, S5P_OTHERS); tmp = __raw_readl(S5PC1XX_UHOST); tmp |= (1<<0); __raw_writel(tmp, S5PC1XX_UHOST); #ifdef CONFIG_S5P_DEEP_IDLE_TEST __raw_writel(((0x1 << 0) | (0x1a0 << 16)) ,S5P_CLAMP_STABLE); #endif /* Set WFI instruction to SLEEP mode */ tmp = __raw_readl(S5P_PWR_CFG); tmp &= S5P_CFG_WFI_CLEAN; #ifdef CONFIG_S5P_DEEP_IDLE_TEST tmp &= ~(0x1f << 27); tmp |= S5P_CFG_WFI_DEEPIDLE | (1 << 31) | (0xbff << 7) | (1 << 29); tmp &= ~(1<<17); DBG("Deep Idle mode\n"); #else tmp |= (S5P_CFG_WFI_SLEEP); printk("normal sleep mode\n"); #endif __raw_writel(tmp, S5P_PWR_CFG); /* Clear WAKEUP_STAT register for next wakeup */ tmp = __raw_readl(S5P_WAKEUP_STAT); __raw_writel(tmp, S5P_WAKEUP_STAT); /* Set Power Stable Count */ tmp = __raw_readl(S5P_OTHERS); tmp &=~(1 << S5P_OTHER_STA_TYPE); tmp |= (STA_TYPE_SFR << S5P_OTHER_STA_TYPE); __raw_writel(tmp , S5P_OTHERS); __raw_writel(((S5P_PWR_STABLE_COUNT << S5P_PWR_STA_CNT) | (1 << S5P_PWR_STA_EXP_SCALE)), S5P_PWR_STABLE); /* Set Syscon Interrupt */ tmp = __raw_readl(S5P_OTHERS); tmp |= (1 << S5P_OTHER_SYS_INT); __raw_writel(tmp, S5P_OTHERS); #ifndef CONFIG_S5P_DEEP_IDLE_TEST tmp = __raw_readl(S5P_SLEEP_CFG); tmp &= ~(1 << 0); __raw_writel(tmp, S5P_SLEEP_CFG); #endif /* s5pc1xx_cpu_save will also act as our return point from when * we resume as it saves its own register state, so use the return * code to differentiate return from save and return from sleep */ if (s5pc100_cpu_save(regs_save) == 0) { flush_cache_all(); /* This function for Chip bug on EVT0 */ pm_cpu_sleep(); } /* restore the cpu state */ cpu_init(); /* MTC IO OFF | MTC IO SD-MMC OFF | USB Phy Enable */ tmp = __raw_readl(S5P_OTHERS); tmp |= (1<<31); __raw_writel(tmp, S5P_OTHERS); tmp = __raw_readl(S5P_OTHERS); tmp |= ((1<<22)|(1<<16)); __raw_writel(tmp, S5P_OTHERS); tmp = __raw_readl(S5PC1XX_UHOST); tmp &= ~(1<<0); __raw_writel(tmp, S5PC1XX_UHOST); s5pc1xx_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save)); s5pc1xx_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); s5pc1xx_pm_do_restore(core_save, ARRAY_SIZE(core_save)); s5pc1xx_pm_do_restore(sromc_save, ARRAY_SIZE(sromc_save)); s5pc1xx_pm_do_restore(nand_save, ARRAY_SIZE(nand_save)); s5pc1xx_pm_do_restore(uart_save, ARRAY_SIZE(uart_save)); s5pc1xx_pm_do_restore(eint_save, ARRAY_SIZE(eint_save)); tmp = readl(weint_base + S5P_APM_WEINT1_PEND); writel(tmp , weint_base + S5P_APM_WEINT1_PEND); DBG("post sleep, preparing to return\n"); s5pc1xx_pm_check_restore(); #ifdef CONFIG_S5P_DEEP_IDLE_TEST tmp = __raw_readl(S5P_OTHERS); tmp |= (1<<30); __raw_writel(tmp, S5P_OTHERS); #endif /* ok, let's return from sleep */ DBG("S3C6410 PM Resume (post-restore)\n"); return 0; }
static int s3c2410_pm_enter(suspend_state_t state) { unsigned long regs_save[16]; /* ensure the debug is initialised (if enabled) */ s3c2410_pm_debug_init(); DBG("s3c2410_pm_enter(%d)\n", state); if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) { printk(KERN_ERR PFX "error: no cpu sleep functions set\n"); return -EINVAL; } /* check if we have anything to wake-up with... bad things seem * to happen if you suspend with no wakeup (system will often * require a full power-cycle) */ if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) && !any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) { printk(KERN_ERR PFX "No sources enabled for wake-up!\n"); printk(KERN_ERR PFX "Aborting sleep\n"); return -EINVAL; } /* prepare check area if configured */ s3c2410_pm_check_prepare(); /* store the physical address of the register recovery block */ s3c2410_sleep_save_phys = virt_to_phys(regs_save); DBG("s3c2410_sleep_save_phys=0x%08lx\n", s3c2410_sleep_save_phys); /* save all necessary core registers not covered by the drivers */ s3c2410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save)); s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save)); s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save)); /* set the irq configuration for wake */ s3c2410_pm_configure_extint(); DBG("sleep: irq wakeup masks: %08lx,%08lx\n", s3c_irqwake_intmask, s3c_irqwake_eintmask); __raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK); __raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK); /* ack any outstanding external interrupts before we go to sleep */ __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND); __raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND); __raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND); /* call cpu specific preparation */ pm_cpu_prep(); /* flush cache back to ram */ flush_cache_all(); s3c2410_pm_check_store(); /* send the cpu to sleep... */ __raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */ /* s3c2410_cpu_save will also act as our return point from when * we resume as it saves its own register state, so use the return * code to differentiate return from save and return from sleep */ if (s3c2410_cpu_save(regs_save) == 0) { flush_cache_all(); pm_cpu_sleep(); } /* restore the cpu state */ cpu_init(); /* restore the system state */ s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save)); s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save)); s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save)); s3c2410_pm_debug_init(); /* check what irq (if any) restored the system */ DBG("post sleep: IRQs 0x%08x, 0x%08x\n", __raw_readl(S3C2410_SRCPND), __raw_readl(S3C2410_EINTPEND)); s3c2410_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND), s3c_irqwake_intmask); s3c2410_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND), s3c_irqwake_eintmask); DBG("post sleep, preparing to return\n"); s3c2410_pm_check_restore(); /* ok, let's return from sleep */ DBG("S3C2410 PM Resume (post-restore)\n"); return 0; }
static int s5pc11x_pm_enter(suspend_state_t state) { unsigned long regs_save[16]; unsigned int tmp; #ifdef CONFIG_HAS_WAKELOCK //wake_unlock(&pm_wake_lock); #endif /* ensure the debug is initialised (if enabled) */ DBG("s5pc11x_pm_enter(%d)\n", state); if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) { printk(KERN_ERR PFX "error: no cpu sleep functions set\n"); return -EINVAL; } #ifdef CONFIG_CPU_FREQ s5pc110_pm_target(BOOT_ARM_CLK); #endif /* store the physical address of the register recovery block */ s5pc110_sleep_save_phys = virt_to_phys(regs_save); DBG("s5pc11x_sleep_save_phys=0x%08lx\n", s5pc110_sleep_save_phys); s5pc11x_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save)); #ifdef S5PC11X_ALIVEGPIO_STORE s5pc11x_pm_do_save(gpio_save_alive, ARRAY_SIZE(gpio_save_alive)); #endif s5pc11x_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); s5pc11x_pm_do_save(core_save, ARRAY_SIZE(core_save)); s5pc11x_pm_do_save(sromc_save, ARRAY_SIZE(sromc_save)); s5pc11x_pm_do_save(uart_save, ARRAY_SIZE(uart_save)); /* ensure INF_REG0 has the resume address */ __raw_writel(virt_to_phys(s5pc110_cpu_resume), S5P_INFORM0); /* call cpu specific preperation */ pm_cpu_prep(); /* flush cache back to ram */ flush_cache_all(); #if 0 // To preserve 24MHz clock. /* USB & OSC Clock pad Enable */ tmp = __raw_readl(S5P_SLEEP_CFG); //tmp |= (S5P_SLEEP_CFG_OSC_EN | S5P_SLEEP_CFG_USBOSC_EN); tmp &= ~(S5P_SLEEP_CFG_OSC_EN | S5P_SLEEP_CFG_USBOSC_EN); __raw_writel(tmp , S5P_SLEEP_CFG); #endif __raw_writel(0xffffffff , S5P_EINT_WAKEUP_MASK); /* Power mode Config setting */ tmp = __raw_readl(S5P_PWR_CFG); tmp &= S5P_CFG_WFI_CLEAN; tmp |= S5P_CFG_WFI_SLEEP; __raw_writel(tmp,S5P_PWR_CFG); if (!hw_version_check()) { /* Set wakeup mask regsiter */ __raw_writel(0xFFED, S5P_WAKEUP_MASK); } else { if((is_calling_or_playing & IS_VOICE_CALL_2G) || (is_calling_or_playing & IS_VOICE_CALL_3G) || (is_calling_or_playing & IS_DATA_CALL)){ __raw_writel(0xFFDD, S5P_WAKEUP_MASK); //0xFFDD:key, RTC_ALARM }else{ __raw_writel(0xFFFD, S5P_WAKEUP_MASK); //0xFFDD:key, RTC_ALARM } } __raw_writel(0xffffffff, S5PC110_VIC0REG(VIC_INT_ENABLE_CLEAR)); __raw_writel(0xffffffff, S5PC110_VIC1REG(VIC_INT_ENABLE_CLEAR)); __raw_writel(0xffffffff, S5PC110_VIC2REG(VIC_INT_ENABLE_CLEAR)); __raw_writel(0xffffffff, S5PC110_VIC3REG(VIC_INT_ENABLE_CLEAR)); __raw_writel(0xffffffff, S5PC110_VIC0REG(VIC_INT_SOFT_CLEAR)); __raw_writel(0xffffffff, S5PC110_VIC1REG(VIC_INT_SOFT_CLEAR)); __raw_writel(0xffffffff, S5PC110_VIC2REG(VIC_INT_SOFT_CLEAR)); __raw_writel(0xffffffff, S5PC110_VIC3REG(VIC_INT_SOFT_CLEAR)); /* SYSC INT Disable */ tmp = __raw_readl(S5P_OTHERS); tmp |= (S5P_OTHER_SYSC_INTOFF); __raw_writel(tmp,S5P_OTHERS); /* Clear WAKEUP_STAT register for next wakeup */ tmp = __raw_readl(S5P_WAKEUP_STAT); __raw_writel(tmp, S5P_WAKEUP_STAT); /* Wake up source setting */ //s5pc11x_pm_configure_extint(); // key pad direction control for evt0 //s5pc11x_set_keypad_sleep_gpio(); /*Set EINT 22 as wake up source*/ s5pc11x_pm_set_eint(11, 0x2); s5pc11x_pm_set_eint(22, 0x2); s5pc11x_pm_set_eint(15, 0x4); s5pc11x_pm_set_eint(21, 0x4); s5pc11x_pm_set_eint(7, 0x02); //PMIC s5pc11x_pm_set_eint(6, 0x4); //det_3.5 s5pc11x_pm_set_eint(28, 0x4); // T_FLASH_DETECT //[hdlnc_bp_ytkwon : 20100326 #ifdef CONFIG_KEPLER_AUDIO_A1026 if(HWREV!=0x08) { if(get_headset_status() & SEC_HEADSET_4_POLE_DEVICE) { s5pc11x_pm_set_eint(30, 0x4); //sendend s5pc11x_pm_set_eint(18, 0x4); //sendend 2.5 } else { s5pc11x_pm_clear_eint(30); s5pc11x_pm_clear_eint(18); } } #else if(HWREV==0x0a ||HWREV==0x0c) { if(get_headset_status() & SEC_HEADSET_4_POLE_DEVICE) { s5pc11x_pm_set_eint(30, 0x4); //sendend } else { s5pc11x_pm_clear_eint(30); } } else { if(get_headset_status() & SEC_HEADSET_4_POLE_DEVICE) { s5pc11x_pm_set_eint(30, 0x4); //sendend s5pc11x_pm_set_eint(18, 0x4); //sendend 2.5 } else { s5pc11x_pm_clear_eint(30); s5pc11x_pm_clear_eint(18); } } #endif //]hdlnc_bp_ytkwon : 20100326 if(gp2a_get_proximity_enable()) { s5pc11x_pm_set_eint(2, 0x4);//proximity } s5pc11x_pm_set_eint(20, 0x3);//WiFi s5pc11x_pm_set_eint(23, 0x2);//microusb #if defined CONFIG_T959_VER_B0 s5pc11x_pm_set_eint(29, 0x4); // [[junghyunseok edit for fuel_int interrupt control of fuel_gauge 20100504 #elif defined CONFIG_KEPLER_VER_B0 #elif defined(CONFIG_KEPLER_VER_B2) || defined(CONFIG_T959_VER_B5) s5pc11x_pm_set_eint(27, 0x2); // ]]junghyunseok edit for fuel_int interrupt control of fuel_gauge 20100504 #else //gpio key if(HWREV >= 0xB) { s5pc11x_pm_set_eint(27, 0x4); s5pc11x_pm_set_eint(29, 0x4); } #endif if (!hw_version_check()) { /*Set keypad as EINT for EVT0 wake up workaround*/ s5pc11x_pm_set_eint(24, 0x2); s5pc11x_pm_set_eint(25, 0x2); s5pc11x_pm_set_eint(26, 0x2); s5pc11x_pm_set_eint(27, 0x2); /*Column pull down enabled*/ tmp = readl(S5PC11X_GPH2PUD); tmp &= ~(0xFF); tmp |= 0x55; writel(tmp, S5PC11X_GPH2PUD); } s3c_config_sleep_gpio(); s3c_gpio_slp_cfgpin(S5PC11X_MP03(3), S3C_GPIO_SLP_OUT0); s3c_gpio_slp_setpull_updown(S5PC11X_MP03(3), S3C_GPIO_SLP_OUT0); #if 0 tmp = __raw_readl(S5P_OTHERS); tmp &= ~(3 << 8); tmp |= (3 << 8); __raw_writel(tmp, S5P_OTHERS); __raw_writel(0,S5P_MIE_CONTROL); __raw_writel(0,S5P_HDMI_CONTROL); __raw_writel(0,S5P_USB_PHY_CONTROL); __raw_writel(0,S5P_DAC_CONTROL); __raw_writel(0,S5P_MIPI_PHY_CONTROL); __raw_writel(0,S5P_ADC_CONTROL); __raw_writel(0,S5P_PSHOLD_CONTROL); #endif #if (!(defined CONFIG_ARIES_VER_B0) && !(defined CONFIG_ARIES_VER_B4) && !(defined CONFIG_ARIES_VER_B5)) // Enable PS_HOLD pin to avoid reset failure */ __raw_writel((0x5 << 12 | 0x1<<9 | 0x1<<8 | 0x1<<0),S5P_PSHOLD_CONTROL); #endif /* s5pc11x_cpu_save will also act as our return point from when * we resume as it saves its own register state, so use the return * code to differentiate return from save and return from sleep */ if (s5pc110_cpu_save(regs_save) == 0) { flush_cache_all(); if (!hw_version_check()) { /* This function for Chip bug on EVT0 */ tmp = __raw_readl(S5P_EINT_WAKEUP_MASK + 4); //PWR_MODE tmp |= (1 << 2); __raw_writel(tmp , S5P_EINT_WAKEUP_MASK + 4); // end mod } pm_cpu_sleep(); } /* restore the cpu state */ cpu_init(); s5pc11x_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save)); #ifdef S5PC11X_ALIVEGPIO_STORE s5pc11x_pm_do_restore_alive(gpio_save_alive, ARRAY_SIZE(gpio_save_alive)); #endif s5pc11x_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); __raw_writel(0x0, S3C24XX_VA_UART2+S3C2410_UCON); __raw_writel(0xf, S3C24XX_VA_UART2+S5P_UINTP); __raw_writel(0xf, S3C24XX_VA_UART2+S5P_UINTSP); __raw_writel(0xf, S3C24XX_VA_UART2+S5P_UINTM); /* Temporary workaround to protect lockup by UART - 20100316 */ __raw_writel(0x0, S3C24XX_VA_UART3+S3C2410_UCON); __raw_writel(0xf, S3C24XX_VA_UART3+S5P_UINTM); __raw_writel(0xf, S3C24XX_VA_UART3+S5P_UINTSP); __raw_writel(0xf, S3C24XX_VA_UART3+S5P_UINTP); __raw_writel(0x0, S3C24XX_VA_UART2+S3C2410_UCON); __raw_writel(0xf, S3C24XX_VA_UART2+S5P_UINTM); __raw_writel(0xf, S3C24XX_VA_UART2+S5P_UINTSP); __raw_writel(0xf, S3C24XX_VA_UART2+S5P_UINTP); __raw_writel(0x0, S3C24XX_VA_UART1+S3C2410_UCON); __raw_writel(0xf, S3C24XX_VA_UART1+S5P_UINTM); __raw_writel(0xf, S3C24XX_VA_UART1+S5P_UINTSP); __raw_writel(0xf, S3C24XX_VA_UART1+S5P_UINTP); __raw_writel(0x0, S3C24XX_VA_UART0+S3C2410_UCON); __raw_writel(0xf, S3C24XX_VA_UART0+S5P_UINTM); __raw_writel(0xf, S3C24XX_VA_UART0+S5P_UINTSP); __raw_writel(0xf, S3C24XX_VA_UART0+S5P_UINTP); s5pc11x_pm_do_restore(uart_save, ARRAY_SIZE(uart_save)); s5pc11x_pm_do_restore(core_save, ARRAY_SIZE(core_save)); s5pc11x_pm_do_restore(sromc_save, ARRAY_SIZE(sromc_save)); /*enable gpio, uart, mmc*/ tmp = __raw_readl(S5P_OTHERS); #if ((defined CONFIG_ARIES_VER_B0) || (defined CONFIG_ARIES_VER_B4) || (defined CONFIG_ARIES_VER_B5)) tmp |= (1<<31) | (1<<28) | (1<<29); #else tmp |= (1<<31) | (0x1<<30) | (1<<28) | (1<<29); #endif __raw_writel(tmp, S5P_OTHERS); /* EINT22 Pending clear */ //s5pc11x_pm_clear_eint(22); //<= do action in s3c-keypad.c // s5pc11x_pm_clear_eint(21); if (!hw_version_check()) { // for evt 0 keypad wakeup workaround s5pc11x_pm_clear_eint(24); s5pc11x_pm_clear_eint(25); s5pc11x_pm_clear_eint(26); s5pc11x_pm_clear_eint(27); s5pc11x_pm_clear_eint(21); } else { /* Clear WAKEUP_STAT register for next wakeup */ tmp = __raw_readl(S5P_WAKEUP_STAT); __raw_writel(tmp, S5P_WAKEUP_STAT); printk("wakeup source is 0x%x \n", tmp); printk(" EXT_INT_0_PEND %x \n", __raw_readl(S5PC11X_EINTPEND(0))); printk(" EXT_INT_1_PEND %x \n", __raw_readl(S5PC11X_EINTPEND(1))); printk(" EXT_INT_2_PEND %x \n", __raw_readl(S5PC11X_EINTPEND(2))); printk(" EXT_INT_3_PEND %x \n", __raw_readl(S5PC11X_EINTPEND(3))); } DBG("\npost sleep, preparing to return 2\n"); s5pc11x_pm_check_restore(); #ifdef CONFIG_HAS_WAKELOCK //wake_lock_timeout(&pm_wake_lock, 5 * HZ); #endif /* ok, let's return from sleep */ DBG("S5PC110 PM Resume (post-restore)\n"); return 0; }
static void s5p6442_enter_idle2(void) { unsigned regs_save[16]; unsigned long tmp; /* store the physical address of the register recovery block */ s5p6442_sleep_save_phys = virt_to_phys(regs_save); /* ensure INF_REG0 has the resume address */ __raw_writel(virt_to_phys(s5p6442_cpu_resume), S5P_INFORM0); /* Save current VIC_INT_ENABLE register*/ vic_regs[0] = __raw_readl(S5P64XX_VIC0INTSELECT); vic_regs[1] = __raw_readl(S5P64XX_VIC1INTSELECT); vic_regs[2] = __raw_readl(S5P64XX_VIC2INTSELECT); vic_regs[3] = __raw_readl(S5P64XX_VIC0INTENABLE); vic_regs[4] = __raw_readl(S5P64XX_VIC1INTENABLE); vic_regs[5] = __raw_readl(S5P64XX_VIC2INTENABLE); vic_regs[6] = __raw_readl(S5P64XX_VIC0SOFTINT); vic_regs[7] = __raw_readl(S5P64XX_VIC1SOFTINT); vic_regs[8] = __raw_readl(S5P64XX_VIC2SOFTINT); /* Disable all interrupt through VIC */ __raw_writel(0xffffffff, S5P64XX_VIC0INTENCLEAR); __raw_writel(0xffffffff, S5P64XX_VIC1INTENCLEAR); __raw_writel(0xffffffff, S5P64XX_VIC2INTENCLEAR); __raw_writel(0xffffffff, S5P64XX_VIC0SOFTINTCLEAR); __raw_writel(0xffffffff, S5P64XX_VIC1SOFTINTCLEAR); __raw_writel(0xffffffff, S5P64XX_VIC2SOFTINTCLEAR); /* GPIO Power Down Control */ s5p6442_gpio_pdn_conf(); /* Wakeup source configuration for idle2 */ tmp = __raw_readl(S5P_WAKEUP_MASK); /* RTC TICK, I2S, Keypad are enabled as wakeup sources */ tmp |= 0xffff; tmp &= ~((1<<2) | (1<<13) | (1<<5)); __raw_writel(tmp, S5P_WAKEUP_MASK); /* Clear wakeup status register */ tmp = __raw_readl(S5P_WAKEUP_STAT); __raw_writel(tmp, S5P_WAKEUP_STAT); /* IDLE config register set */ /* Memory retention off */ /* Memory LP mode */ tmp = __raw_readl(S5P_IDLE_CFG); tmp &= ~(0xf << 28); tmp |= ((1<<30) | (1<<28) | (1<<0)); __raw_writel(tmp, S5P_IDLE_CFG); /* Power mode register configuration */ tmp = __raw_readl(S5P_PWR_CFG); tmp &= S5P_CFG_WFI_CLEAN; tmp |= S5P_CFG_WFI_IDLE; __raw_writel(tmp, S5P_PWR_CFG); /* SYSC INT Disable */ tmp = __raw_readl(S5P_OTHERS); tmp |= S5P_OTHER_SYSC_INTOFF; tmp |= (0x3 << 8); __raw_writel(tmp, S5P_OTHERS); /* Entering idle2 mode with WFI instruction */ if (s5p6442_cpu_save(regs_save) == 0) { flush_cache_all(); pm_cpu_sleep(); } /* restore the cpu state */ cpu_init(); tmp = __raw_readl(S5P_IDLE_CFG); tmp &= ~((3<<30)|(3<<28)|(1<<0)); tmp |= ((2<<30)|(2<<28)); __raw_writel(tmp, S5P_IDLE_CFG); /* Release retention GPIO/MMC/UART IO */ tmp = __raw_readl(S5P_OTHERS); tmp |= ((1<<31) | (1<<30) | (1<<29) | (1<<28)); tmp &= ~(0x3 << 8); __raw_writel(tmp, S5P_OTHERS); __raw_writel(vic_regs[0], S5P64XX_VIC0INTSELECT); __raw_writel(vic_regs[1], S5P64XX_VIC1INTSELECT); __raw_writel(vic_regs[2], S5P64XX_VIC2INTSELECT); __raw_writel(vic_regs[3], S5P64XX_VIC0INTENABLE); __raw_writel(vic_regs[4], S5P64XX_VIC1INTENABLE); __raw_writel(vic_regs[5], S5P64XX_VIC2INTENABLE); __raw_writel(vic_regs[6], S5P64XX_VIC0SOFTINT); __raw_writel(vic_regs[7], S5P64XX_VIC1SOFTINT); __raw_writel(vic_regs[7], S5P64XX_VIC2SOFTINT); tmp = __raw_readl(S5P_WAKEUP_STAT); __raw_writel(tmp, S5P_WAKEUP_STAT); }