Exemple #1
0
static int s5p_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(S5P_EINTCON(eint_conf_reg(irq)));
	ctrl &= ~mask;
	ctrl |= newvalue << shift;
	__raw_writel(ctrl, S5P_EINTCON(eint_conf_reg(irq)));

	if ((0 <= offs) && (offs < 8))
		s3c_gpio_cfgpin(S5P_EXT_INT0(offs&0x7), 0xf<<((offs&0x7)*4));

	else if ((8 <= offs) && (offs < 16))
		s3c_gpio_cfgpin(S5P_EXT_INT1(offs&0x7), 0xf<<((offs&0x7)*4));

	else if ((16 <= offs) && (offs < 24))
		s3c_gpio_cfgpin(S5P_EXT_INT2(offs&0x7), 0xf<<((offs&0x7)*4));

	else if ((24 <= offs) && (offs < 32))
		s3c_gpio_cfgpin(S5P_EXT_INT3(offs&0x7), 0xf<<((offs&0x7)*4));

	else
		printk(KERN_ERR "No such irq number %d", offs);

	return 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;
}
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 = S3C2410_EXTINT_RISEEDGE;
		break;

	case IRQ_TYPE_EDGE_FALLING:
		newvalue = S3C2410_EXTINT_FALLEDGE;
		break;

	case IRQ_TYPE_EDGE_BOTH:
		newvalue = S3C2410_EXTINT_BOTHEDGE;
		break;

	case IRQ_TYPE_LEVEL_LOW:
		newvalue = S3C2410_EXTINT_LOWLEV;
		break;

	case IRQ_TYPE_LEVEL_HIGH:
		newvalue = S3C2410_EXTINT_HILEV;
		break;

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

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

#if 0
	int flt_shift;
	int target_offset;
	flt_shift = (offs & 0x7)*8;
	target_offset = flt_shift/32;
	flt_shift = flt_shift%32;
	ctrl = __raw_readl((S5PC1XX_EINT30FLTCON0+target_offset));
	ctrl &= ~(0xff<<flt_shift);
	ctrl |= (0x80 | 0x40 | 0x1) << flt_shift;  //0x80:filter enable, 0x40:digital filter, 0x1: delay clocks
	__raw_writel(ctrl, (S5PC1XX_EINT30FLTCON0+target_offset));
#endif

	ctrl = __raw_readl(S5PC1XX_EINTCON(eint_conf_reg(irq)));
	ctrl &= ~mask;
	ctrl |= newvalue << shift;
	__raw_writel(ctrl, S5PC1XX_EINTCON(eint_conf_reg(irq)));

#if defined(CONFIG_CPU_S5PC100)
	if((0 <= offs) && (offs < 8))
		s3c_gpio_cfgpin(S5PC1XX_GPH0(offs&0x7), 0x2<<((offs&0x7)*4));
	else if((8 <= offs) && (offs < 16))
		s3c_gpio_cfgpin(S5PC1XX_GPH1(offs&0x7), 0x2<<((offs&0x7)*4));
	else if((16 <= offs) && (offs < 24))
		s3c_gpio_cfgpin(S5PC1XX_GPH2(offs&0x7), 0x2<<((offs&0x7)*4));
	else if((24 <= offs) && (offs < 32))
		s3c_gpio_cfgpin(S5PC1XX_GPH3(offs&0x7), 0x2<<((offs&0x7)*4));
	else
		printk(KERN_ERR "No such irq number %d", offs);
#elif defined(CONFIG_CPU_S5PC110)
	if((0 <= offs) && (offs < 8))
		s3c_gpio_cfgpin(S5PC1XX_GPH0(offs&0x7), 0xf<<((offs&0x7)*4));
	else if((8 <= offs) && (offs < 16))
		s3c_gpio_cfgpin(S5PC1XX_GPH1(offs&0x7), 0xf<<((offs&0x7)*4));
	else if((16 <= offs) && (offs < 24))
		s3c_gpio_cfgpin(S5PC1XX_GPH2(offs&0x7), 0xf<<((offs&0x7)*4));
	else if((24 <= offs) && (offs < 32))
		s3c_gpio_cfgpin(S5PC1XX_GPH3(offs&0x7), 0xf<<((offs&0x7)*4));
	else
		printk(KERN_ERR "No such irq number %d", offs);
#endif
	return 0;
}