コード例 #1
0
ファイル: drv_gpio.c プロジェクト: DigFarmer/rt-thread
static void gpio_irq_handler(int irq, void *param)
{
    struct gpio_irq_def *irq_def = (struct gpio_irq_def *)param;
    rt_uint32_t pend, enable;
    int port, pin;
    rt_uint32_t addr;

    pin = 0;
    port = irq - PIOD_INTERRUPT;
    addr = GPIOn_INT_STA_ADDR(port);
    pend = readl(addr);
    addr = GPIOn_INT_CTRL_ADDR(port);
    enable = readl(addr);
    pend &= enable;

    while (pend)
    {
        if ((pend & 0x1) && (irq_def->irq_cb[pin] != RT_NULL))
        {
            dbg_log(DBG_LOG, "do irq callback...\n", port, pin);
            irq_def->irq_cb[pin](irq_def->irq_arg[pin]);
        }
        pin++;
        pend = pend >> 1;
        gpio_ack_irq(port, pin);
    }
}
コード例 #2
0
ファイル: drv_gpio.c プロジェクト: Cheong2K/rt-thread
void gpio_irq_handler(int irq, void *param)
{
    struct jz_gpio_irq_def  *irq_def = (struct jz_gpio_irq_def  *)param;
    uint32_t    pend,mask;
    uint32_t    pin_id;
    enum gpio_port  port = (IRQ_GPIO0 - irq);
    enum gpio_pin   pin;

    RT_ASSERT(param != RT_NULL);
    GPIO_DBG("GPIO irq handler,irq=%d\n",irq);

    pend = readl(GPIO_PXFLG(port));
    mask = readl(GPIO_PXMSK(port));

    GPIO_DBG("port =%d pend =%08x mask =%08x\n",port,pend,mask);

    pend = pend & ~mask;
    while(pend)
    {
        pin_id = _fls(pend) - 1;
        pin    = 0x01 << pin_id;

        GPIO_DBG("PORT%d PIN%d interrupt happened..\n",port,pin_id);
        if(irq_def->irq_cb[pin_id] != RT_NULL)
        {
            GPIO_DBG("do irq callback...\n",port,pin);
            irq_def->irq_cb[pin_id](irq_def->irq_arg[pin_id]);
        }

        pend &= ~(0x01 << pin_id);
        gpio_ack_irq(port, pin);
    }
}
コード例 #3
0
ファイル: gpio.c プロジェクト: 01org/KVMGT-kernel
static int gpio_set_irq_type(struct irq_data *d, unsigned int type)
{
	unsigned int gpio = irq_to_gpio(d->irq);
	unsigned int gpio_mask = 1 << (gpio % 32);
	void __iomem *base = GPIO_BASE(gpio / 32);
	unsigned int reg_both, reg_level, reg_type;

	reg_type = __raw_readl(base + GPIO_INT_TYPE);
	reg_level = __raw_readl(base + GPIO_INT_LEVEL);
	reg_both = __raw_readl(base + GPIO_INT_BOTH_EDGE);

	switch (type) {
	case IRQ_TYPE_EDGE_BOTH:
		reg_type &= ~gpio_mask;
		reg_both |= gpio_mask;
		break;
	case IRQ_TYPE_EDGE_RISING:
		reg_type &= ~gpio_mask;
		reg_both &= ~gpio_mask;
		reg_level &= ~gpio_mask;
		break;
	case IRQ_TYPE_EDGE_FALLING:
		reg_type &= ~gpio_mask;
		reg_both &= ~gpio_mask;
		reg_level |= gpio_mask;
		break;
	case IRQ_TYPE_LEVEL_HIGH:
		reg_type |= gpio_mask;
		reg_level &= ~gpio_mask;
		break;
	case IRQ_TYPE_LEVEL_LOW:
		reg_type |= gpio_mask;
		reg_level |= gpio_mask;
		break;
	default:
		return -EINVAL;
	}

	__raw_writel(reg_type, base + GPIO_INT_TYPE);
	__raw_writel(reg_level, base + GPIO_INT_LEVEL);
	__raw_writel(reg_both, base + GPIO_INT_BOTH_EDGE);

	gpio_ack_irq(d);

	return 0;
}
コード例 #4
0
ファイル: drv_gpio.c プロジェクト: DigFarmer/rt-thread
void gpio_irq_disable(enum gpio_port port,  enum gpio_pin pin)
{
    rt_uint32_t addr;
    rt_uint32_t offset;
    rt_uint32_t data;

    RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
    RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));

    gpio_ack_irq(port - GPIO_PORT_D, pin);
    addr = GPIOn_INT_CTRL_ADDR(port - GPIO_PORT_D);
    offset = pin;

    data = readl(addr);
    data &= ~(0x1 << offset);

    writel(data, addr);
    dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
}