Loading drivers/gpio/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ config GPIO_MXC def_bool y depends on ARCH_MXC select GPIO_GENERIC select GENERIC_IRQ_CHIP config GPIO_MXS def_bool y Loading drivers/gpio/gpio-mxc.c +29 −61 Original line number Diff line number Diff line Loading @@ -65,46 +65,11 @@ static LIST_HEAD(mxc_gpio_ports); /* Note: This driver assumes 32 GPIOs are handled in one register */ static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index) { writel(1 << index, port->base + GPIO_ISR); } static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index, int enable) { u32 l; l = readl(port->base + GPIO_IMR); l = (l & (~(1 << index))) | (!!enable << index); writel(l, port->base + GPIO_IMR); } static void gpio_ack_irq(struct irq_data *d) { struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d); u32 gpio = irq_to_gpio(d->irq); _clear_gpio_irqstatus(port, gpio & 0x1f); } static void gpio_mask_irq(struct irq_data *d) { struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d); u32 gpio = irq_to_gpio(d->irq); _set_gpio_irqenable(port, gpio & 0x1f, 0); } static void gpio_unmask_irq(struct irq_data *d) { struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d); u32 gpio = irq_to_gpio(d->irq); _set_gpio_irqenable(port, gpio & 0x1f, 1); } static int gpio_set_irq_type(struct irq_data *d, u32 type) { u32 gpio = irq_to_gpio(d->irq); struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d); struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); struct mxc_gpio_port *port = gc->private; u32 bit, val; int edge; void __iomem *reg = port->base; Loading Loading @@ -142,7 +107,7 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type) bit = gpio & 0xf; val = readl(reg) & ~(0x3 << (bit << 1)); writel(val | (edge << (bit << 1)), reg); _clear_gpio_irqstatus(port, gpio & 0x1f); writel(1 << (gpio & 0x1f), port->base + GPIO_ISR); return 0; } Loading Loading @@ -231,7 +196,8 @@ static int gpio_set_wake_irq(struct irq_data *d, u32 enable) { u32 gpio = irq_to_gpio(d->irq); u32 gpio_idx = gpio & 0x1F; struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d); struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); struct mxc_gpio_port *port = gc->private; if (enable) { if (port->irq_high && (gpio_idx >= 16)) Loading @@ -248,26 +214,33 @@ static int gpio_set_wake_irq(struct irq_data *d, u32 enable) return 0; } static struct irq_chip gpio_irq_chip = { .name = "GPIO", .irq_ack = gpio_ack_irq, .irq_mask = gpio_mask_irq, .irq_unmask = gpio_unmask_irq, .irq_set_type = gpio_set_irq_type, .irq_set_wake = gpio_set_wake_irq, }; /* * This lock class tells lockdep that GPIO irqs are in a different * category than their parents, so it won't report false recursion. */ static struct lock_class_key gpio_lock_class; static void __init mxc_gpio_init_gc(struct mxc_gpio_port *port) { struct irq_chip_generic *gc; struct irq_chip_type *ct; gc = irq_alloc_generic_chip("gpio-mxc", 1, port->virtual_irq_start, port->base, handle_level_irq); gc->private = port; ct = gc->chip_types; ct->chip.irq_ack = irq_gc_ack, ct->chip.irq_mask = irq_gc_mask_clr_bit; ct->chip.irq_unmask = irq_gc_mask_set_bit; ct->chip.irq_set_type = gpio_set_irq_type; ct->chip.irq_set_wake = gpio_set_wake_irq, ct->regs.ack = GPIO_ISR; ct->regs.mask = GPIO_IMR; irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0); } static int __devinit mxc_gpio_probe(struct platform_device *pdev) { struct mxc_gpio_port *port; struct resource *iores; int err, i; int err; port = kzalloc(sizeof(struct mxc_gpio_port), GFP_KERNEL); if (!port) Loading Loading @@ -304,13 +277,8 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev) writel(0, port->base + GPIO_IMR); writel(~0, port->base + GPIO_ISR); for (i = port->virtual_irq_start; i < port->virtual_irq_start + 32; i++) { irq_set_lockdep_class(i, &gpio_lock_class); irq_set_chip_and_handler(i, &gpio_irq_chip, handle_level_irq); set_irq_flags(i, IRQF_VALID); irq_set_chip_data(i, port); } /* gpio-mxc can be a generic irq chip */ mxc_gpio_init_gc(port); if (cpu_is_mx2()) { /* setup one handler for all GPIO interrupts */ Loading Loading
drivers/gpio/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ config GPIO_MXC def_bool y depends on ARCH_MXC select GPIO_GENERIC select GENERIC_IRQ_CHIP config GPIO_MXS def_bool y Loading
drivers/gpio/gpio-mxc.c +29 −61 Original line number Diff line number Diff line Loading @@ -65,46 +65,11 @@ static LIST_HEAD(mxc_gpio_ports); /* Note: This driver assumes 32 GPIOs are handled in one register */ static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index) { writel(1 << index, port->base + GPIO_ISR); } static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index, int enable) { u32 l; l = readl(port->base + GPIO_IMR); l = (l & (~(1 << index))) | (!!enable << index); writel(l, port->base + GPIO_IMR); } static void gpio_ack_irq(struct irq_data *d) { struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d); u32 gpio = irq_to_gpio(d->irq); _clear_gpio_irqstatus(port, gpio & 0x1f); } static void gpio_mask_irq(struct irq_data *d) { struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d); u32 gpio = irq_to_gpio(d->irq); _set_gpio_irqenable(port, gpio & 0x1f, 0); } static void gpio_unmask_irq(struct irq_data *d) { struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d); u32 gpio = irq_to_gpio(d->irq); _set_gpio_irqenable(port, gpio & 0x1f, 1); } static int gpio_set_irq_type(struct irq_data *d, u32 type) { u32 gpio = irq_to_gpio(d->irq); struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d); struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); struct mxc_gpio_port *port = gc->private; u32 bit, val; int edge; void __iomem *reg = port->base; Loading Loading @@ -142,7 +107,7 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type) bit = gpio & 0xf; val = readl(reg) & ~(0x3 << (bit << 1)); writel(val | (edge << (bit << 1)), reg); _clear_gpio_irqstatus(port, gpio & 0x1f); writel(1 << (gpio & 0x1f), port->base + GPIO_ISR); return 0; } Loading Loading @@ -231,7 +196,8 @@ static int gpio_set_wake_irq(struct irq_data *d, u32 enable) { u32 gpio = irq_to_gpio(d->irq); u32 gpio_idx = gpio & 0x1F; struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d); struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); struct mxc_gpio_port *port = gc->private; if (enable) { if (port->irq_high && (gpio_idx >= 16)) Loading @@ -248,26 +214,33 @@ static int gpio_set_wake_irq(struct irq_data *d, u32 enable) return 0; } static struct irq_chip gpio_irq_chip = { .name = "GPIO", .irq_ack = gpio_ack_irq, .irq_mask = gpio_mask_irq, .irq_unmask = gpio_unmask_irq, .irq_set_type = gpio_set_irq_type, .irq_set_wake = gpio_set_wake_irq, }; /* * This lock class tells lockdep that GPIO irqs are in a different * category than their parents, so it won't report false recursion. */ static struct lock_class_key gpio_lock_class; static void __init mxc_gpio_init_gc(struct mxc_gpio_port *port) { struct irq_chip_generic *gc; struct irq_chip_type *ct; gc = irq_alloc_generic_chip("gpio-mxc", 1, port->virtual_irq_start, port->base, handle_level_irq); gc->private = port; ct = gc->chip_types; ct->chip.irq_ack = irq_gc_ack, ct->chip.irq_mask = irq_gc_mask_clr_bit; ct->chip.irq_unmask = irq_gc_mask_set_bit; ct->chip.irq_set_type = gpio_set_irq_type; ct->chip.irq_set_wake = gpio_set_wake_irq, ct->regs.ack = GPIO_ISR; ct->regs.mask = GPIO_IMR; irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0); } static int __devinit mxc_gpio_probe(struct platform_device *pdev) { struct mxc_gpio_port *port; struct resource *iores; int err, i; int err; port = kzalloc(sizeof(struct mxc_gpio_port), GFP_KERNEL); if (!port) Loading Loading @@ -304,13 +277,8 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev) writel(0, port->base + GPIO_IMR); writel(~0, port->base + GPIO_ISR); for (i = port->virtual_irq_start; i < port->virtual_irq_start + 32; i++) { irq_set_lockdep_class(i, &gpio_lock_class); irq_set_chip_and_handler(i, &gpio_irq_chip, handle_level_irq); set_irq_flags(i, IRQF_VALID); irq_set_chip_data(i, port); } /* gpio-mxc can be a generic irq chip */ mxc_gpio_init_gc(port); if (cpu_is_mx2()) { /* setup one handler for all GPIO interrupts */ Loading