Пример #1
0
// intr_mode 0x2=>falling edge, 0x3=>rising dege, 0x4=>Both edge
static void s5pc11x_pm_set_eint(unsigned int irq, unsigned int intr_mode)
{
    int offs = (irq);
    int shift;
    u32 ctrl, mask, tmp;
    //u32 newvalue = 0x2; // Falling edge

    shift = (offs & 0x7) * 4;
    if((0 <= offs) && (offs < 8)) {
        tmp = readl(S5PC11X_GPH0CON);
        tmp |= (0xf << shift);
        writel(tmp , S5PC11X_GPH0CON);
#ifdef S5PC11X_ALIVEGPIO_STORE
        readl(S5PC11X_GPH0CON); // FIX for EVT0 bug
#endif
        /*pull up disable*/
    }
    else if((8 <= offs) && (offs < 16)) {
        tmp = readl(S5PC11X_GPH1CON);
        tmp |= (0xf << shift);
        writel(tmp , S5PC11X_GPH1CON);
#ifdef S5PC11X_ALIVEGPIO_STORE
        readl(S5PC11X_GPH1CON); // FIX for EVT0 bug
#endif
    }
    else if((16 <= offs) && (offs < 24)) {
        tmp = readl(S5PC11X_GPH2CON);
        tmp |= (0xf << shift);
        writel(tmp , S5PC11X_GPH2CON);
#ifdef S5PC11X_ALIVEGPIO_STORE
        readl(S5PC11X_GPH2CON); // FIX for EVT0 bug
#endif
    }
    else if((24 <= offs) && (offs < 32)) {
        tmp = readl(S5PC11X_GPH3CON);
        tmp |= (0xf << shift);
        writel(tmp , S5PC11X_GPH3CON);
#ifdef S5PC11X_ALIVEGPIO_STORE
        readl(S5PC11X_GPH3CON); // FIX for EVT0 bug
#endif
    }
    else {
        printk(KERN_ERR "No such irq number %d", offs);
        return;
    }

    /*special handling for keypad eint*/
    if( (24 <= irq) && (irq <= 27))
    {   // disable the pull up
        tmp = readl(S5PC11X_GPH3PUD);
        tmp &= ~(0x3 << ((offs & 0x7) * 2));
        writel(tmp, S5PC11X_GPH3PUD);
#ifdef S5PC11X_ALIVEGPIO_STORE
        readl(S5PC11X_GPH3PUD); // FIX for EVT0 bug
#endif
        DBG("S5PC11X_GPH3PUD = %x\n",readl(S5PC11X_GPH3PUD));
    }


    /*Set irq type*/
    mask = 0x7 << shift;
    ctrl = readl(S5PC11X_EINTCON(eint_conf_reg(irq)));
    ctrl &= ~mask;
    //ctrl |= newvalue << shift;
    ctrl |= intr_mode << shift;

    writel(ctrl, S5PC11X_EINTCON(eint_conf_reg(irq)));
#ifdef S5PC11X_ALIVEGPIO_STORE
    readl(S5PC11X_EINTCON(eint_conf_reg(irq)));
#endif
    /*clear mask*/
    mask = readl(S5PC11X_EINTMASK(eint_mask_reg(irq)));
    mask &= ~(eint_irq_to_bit(irq));
    writel(mask, S5PC11X_EINTMASK(eint_mask_reg(irq)));
#ifdef S5PC11X_ALIVEGPIO_STORE
    readl(S5PC11X_EINTMASK(eint_mask_reg(irq)));
#endif

    /*clear pending*/
    mask = readl(S5PC11X_EINTPEND(eint_pend_reg(irq)));
    mask &= (eint_irq_to_bit(irq));
    writel(mask, S5PC11X_EINTPEND(eint_pend_reg(irq)));
#ifdef S5PC11X_ALIVEGPIO_STORE
    readl(S5PC11X_EINTPEND(eint_pend_reg(irq)));
#endif

    /*Enable wake up mask*/
    tmp = readl(S5P_EINT_WAKEUP_MASK);
    tmp &= ~(1 << (irq));
    writel(tmp , S5P_EINT_WAKEUP_MASK);

    DBG("S5PC11X_EINTCON = %x\n",readl(S5PC11X_EINTCON(eint_conf_reg(irq))));
    DBG("S5PC11X_EINTMASK = %x\n",readl(S5PC11X_EINTMASK(eint_mask_reg(irq))));
    DBG("S5PC11X_EINTPEND = %x\n",readl(S5PC11X_EINTPEND(eint_pend_reg(irq))));

    return;
}
Пример #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
static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type)
{
	int offs = eint_offset(irq);
	int shift;
	u32 ctrl, mask;
	u32 newvalue = 0;

	switch (type) {
	case IRQ_TYPE_NONE:
		printk(KERN_WARNING "No edge setting!\n");
		break;

	case IRQ_TYPE_EDGE_RISING:
		newvalue = S5P_EXTINT_RISEEDGE;
		break;

	case IRQ_TYPE_EDGE_FALLING:
		newvalue = S5P_EXTINT_FALLEDGE;
		break;

	case IRQ_TYPE_EDGE_BOTH:
		newvalue = S5P_EXTINT_BOTHEDGE;
		break;

	case IRQ_TYPE_LEVEL_LOW:
		newvalue = S5P_EXTINT_LOWLEV;
		break;

	case IRQ_TYPE_LEVEL_HIGH:
		newvalue = S5P_EXTINT_HILEV;
		break;

	default:
		printk(KERN_ERR "No such irq type %d", type);
		return -1;
	}

	shift = (offs & 0x7) * 4;
	mask = 0x7 << shift;

	ctrl = __raw_readl(S5PC11X_EINTCON(eint_conf_reg(irq)));
	ctrl &= ~mask;
	ctrl |= newvalue << shift;
	__raw_writel(ctrl, S5PC11X_EINTCON(eint_conf_reg(irq)));
#ifdef  S5PC11X_ALIVEGPIO_STORE
	ctrl = __raw_readl(S5PC11X_EINTCON(eint_conf_reg(irq)));
#endif

	if((0 <= offs) && (offs < 8))
		s3c_gpio_cfgpin(S5PC11X_GPH0(offs&0x7), 0xf<<((offs&0x7)*4));
	else if((8 <= offs) && (offs < 16))
		s3c_gpio_cfgpin(S5PC11X_GPH1(offs&0x7), 0xf<<((offs&0x7)*4));
	else if((16 <= offs) && (offs < 24))
		s3c_gpio_cfgpin(S5PC11X_GPH2(offs&0x7), 0xf<<((offs&0x7)*4));
	else if((24 <= offs) && (offs < 32))
		s3c_gpio_cfgpin(S5PC11X_GPH3(offs&0x7), 0xf<<((offs&0x7)*4));
	else
		printk(KERN_ERR "No such irq number %d", offs);

	return 0;
}