示例#1
0
文件: pm.c 项目: Arakmar/G3MOD
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;
}
示例#2
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;
}
示例#3
0
文件: pm.c 项目: alsdpf/o2droid
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;
}
示例#4
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;
}
示例#5
0
文件: pm.c 项目: 3sOx/asuswrt-merlin
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;
}
示例#6
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;
}
示例#7
0
文件: cpuidle.c 项目: Arakmar/G3MOD
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);
}