static int gpio_set_irq_type(u32 irq, u32 type) { u32 gpio = irq_to_gpio(irq); struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; u32 bit, val; int edge; void __iomem *reg = port->base; switch (type) { case IRQ_TYPE_EDGE_RISING: edge = GPIO_INT_RISE_EDGE; break; case IRQ_TYPE_EDGE_FALLING: edge = GPIO_INT_FALL_EDGE; break; case IRQ_TYPE_LEVEL_LOW: edge = GPIO_INT_LOW_LEV; break; case IRQ_TYPE_LEVEL_HIGH: edge = GPIO_INT_HIGH_LEV; break; default: /* this includes IRQ_TYPE_EDGE_BOTH */ return -EINVAL; } reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ bit = gpio & 0xf; val = __raw_readl(reg) & ~(0x3 << (bit << 1)); __raw_writel(val | (edge << (bit << 1)), reg); _clear_gpio_irqstatus(port, gpio & 0x1f); return 0; }
/*! * Release ownership for a GPIO pin * @param pin a name defined by \b iomux_pin_name_t */ void mxc_free_gpio(iomux_pin_name_t pin) { struct gpio_port *port; u32 index, gpio = IOMUX_TO_GPIO(pin); if (check_gpio(gpio) < 0) return; port = get_gpio_port(gpio); index = GPIO_TO_INDEX(gpio); spin_lock(&port->lock); if ((!(port->reserved_map & (1 << index)))) { printk(KERN_ERR "GPIO port %d, pin %d wasn't reserved!\n", port->num, index); dump_stack(); spin_unlock(&port->lock); return; } port->reserved_map &= ~(1 << index); port->irq_is_level_map &= ~(1 << index); _set_gpio_direction(port, index, 1); _set_gpio_irqenable(port, index, 0); _clear_gpio_irqstatus(port, index); spin_unlock(&port->lock); }
/* * Acknowledge a gpio pin's interrupt by clearing the bit in the isr. * If the GPIO interrupt is level triggered, it also disables the interrupt. * @param irq a gpio virtual irq number */ static void gpio_ack_irq(u32 irq) { u32 gpio = MXC_IRQ_TO_GPIO(irq); u32 index = GPIO_TO_INDEX(gpio); struct gpio_port *port = get_gpio_port(gpio); _clear_gpio_irqstatus(port, GPIO_TO_INDEX(gpio)); if (port->irq_is_level_map & (1 << index)) { gpio_mask_irq(irq); } }
/* * Set a GPIO pin's interrupt edge * @param port pointer to a gpio_port * @param index gpio pin index value (0~31) * @param icr one of the values defined in \b gpio_int_cfg * to indicate how to generate an interrupt */ static void _set_gpio_edge_ctrl(struct gpio_port *port, u32 index, enum gpio_int_cfg edge) { u32 reg = port->base; u32 l, sig; reg += (index <= 15) ? GPIO_ICR1 : GPIO_ICR2; sig = (index <= 15) ? index : (index - 16); l = __raw_readl(reg); l = (l & (~(0x3 << (sig * 2)))) | (edge << (sig * 2)); __raw_writel(l, reg); _clear_gpio_irqstatus(port, index); }
static void gpio_ack_irq(u32 irq) { u32 gpio = irq_to_gpio(irq); _clear_gpio_irqstatus(&mxc_gpio_ports[gpio / 32], gpio & 0x1f); }