static void set_gpio_irqenable(struct mxs_gpio_port *port, u32 index, int enable) { if (enable) { __mxs_setl(1 << index, port->base + PINCTRL_IRQEN(port->id)); __mxs_setl(1 << index, port->base + PINCTRL_PIN2IRQ(port->id)); } else { __mxs_clrl(1 << index, port->base + PINCTRL_IRQEN(port->id)); } }
void mxs_gpio_init(void) { int i; for (i = 0; i < PINCTRL_BANKS; i++) { writel(0, MXS_PINCTRL_BASE + PINCTRL_PIN2IRQ(i)); writel(0, MXS_PINCTRL_BASE + PINCTRL_IRQEN(i)); /* Use SCT address here to clear the IRQSTAT bits */ writel(0xffffffff, MXS_PINCTRL_BASE + PINCTRL_IRQSTAT(i) + 8); } }
int __init mxs_gpio_init(struct mxs_gpio_port *port, int cnt) { int i, j; /* save for local usage */ mxs_gpio_ports = port; gpio_table_size = cnt; pr_info("MXS GPIO hardware\n"); for (i = 0; i < cnt; i++) { /* disable the interrupt and clear the status */ __raw_writel(0, port[i].base + PINCTRL_PIN2IRQ(i)); __raw_writel(0, port[i].base + PINCTRL_IRQEN(i)); /* clear address has to be used to clear IRQSTAT bits */ __mxs_clrl(~0U, port[i].base + PINCTRL_IRQSTAT(i)); for (j = port[i].virtual_irq_start; j < port[i].virtual_irq_start + 32; j++) { set_irq_chip(j, &gpio_irq_chip); set_irq_handler(j, handle_level_irq); set_irq_flags(j, IRQF_VALID); } /* setup one handler for each entry */ set_irq_chained_handler(port[i].irq, mxs_gpio_irq_handler); set_irq_data(port[i].irq, &port[i]); /* register gpio chip */ port[i].chip.direction_input = mxs_gpio_direction_input; port[i].chip.direction_output = mxs_gpio_direction_output; port[i].chip.get = mxs_gpio_get; port[i].chip.set = mxs_gpio_set; port[i].chip.to_irq = mxs_gpio_to_irq; port[i].chip.base = i * 32; port[i].chip.ngpio = 32; /* its a serious configuration bug when it fails */ BUG_ON(gpiochip_add(&port[i].chip) < 0); } return 0; }