Module Name: src Committed By: kiyohara Date: Mon Jul 11 14:53:05 UTC 2016
Modified Files: src/sys/arch/arm/omap: omap2_gpio.c Log Message: Support OMAP 4430. tested on Gumstix DuoVero. To generate a diff of this commit: cvs rdiff -u -r1.17 -r1.18 src/sys/arch/arm/omap/omap2_gpio.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/omap/omap2_gpio.c diff -u src/sys/arch/arm/omap/omap2_gpio.c:1.17 src/sys/arch/arm/omap/omap2_gpio.c:1.18 --- src/sys/arch/arm/omap/omap2_gpio.c:1.17 Sat Jul 9 15:04:06 2016 +++ src/sys/arch/arm/omap/omap2_gpio.c Mon Jul 11 14:53:05 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: omap2_gpio.c,v 1.17 2016/07/09 15:04:06 kiyohara Exp $ */ +/* $NetBSD: omap2_gpio.c,v 1.18 2016/07/11 14:53:05 kiyohara Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. * All rights reserved. @@ -28,7 +28,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: omap2_gpio.c,v 1.17 2016/07/09 15:04:06 kiyohara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: omap2_gpio.c,v 1.18 2016/07/11 14:53:05 kiyohara Exp $"); #define _INTR_PRIVATE @@ -61,8 +61,11 @@ __KERNEL_RCSID(0, "$NetBSD: omap2_gpio.c #endif static void gpio_pic_block_irqs(struct pic_softc *, size_t, uint32_t); +static void gpio_pic_block_irqs2(struct pic_softc *, size_t, uint32_t); static void gpio_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t); +static void gpio_pic_unblock_irqs2(struct pic_softc *, size_t, uint32_t); static int gpio_pic_find_pending_irqs(struct pic_softc *); +static int gpio_pic_find_pending_irqs2(struct pic_softc *); static void gpio_pic_establish_irq(struct pic_softc *, struct intrsource *); const struct pic_ops gpio_pic_ops = { @@ -71,6 +74,12 @@ const struct pic_ops gpio_pic_ops = { .pic_find_pending_irqs = gpio_pic_find_pending_irqs, .pic_establish_irq = gpio_pic_establish_irq, }; +const struct pic_ops gpio_pic_ops2 = { + .pic_block_irqs = gpio_pic_block_irqs2, + .pic_unblock_irqs = gpio_pic_unblock_irqs2, + .pic_find_pending_irqs = gpio_pic_find_pending_irqs2, + .pic_establish_irq = gpio_pic_establish_irq, +}; struct gpio_softc { device_t gpio_dev; @@ -78,6 +87,7 @@ struct gpio_softc { struct intrsource *gpio_is; bus_space_tag_t gpio_memt; bus_space_handle_t gpio_memh; + bus_space_handle_t gpio_memh2; uint32_t gpio_enable_mask; uint32_t gpio_edge_mask; uint32_t gpio_edge_falling_mask; @@ -100,6 +110,10 @@ struct gpio_softc { bus_space_read_4((gpio)->gpio_memt, (gpio)->gpio_memh, (reg)) #define GPIO_WRITE(gpio, reg, val) \ bus_space_write_4((gpio)->gpio_memt, (gpio)->gpio_memh, (reg), (val)) +#define GPIO_READ2(gpio, reg) \ + bus_space_read_4((gpio)->gpio_memt, (gpio)->gpio_memh2, (reg)) +#define GPIO_WRITE2(gpio, reg, val) \ + bus_space_write_4((gpio)->gpio_memt, (gpio)->gpio_memh2, (reg), (val)) void gpio_pic_unblock_irqs(struct pic_softc *pic, size_t irq_base, uint32_t irq_mask) @@ -119,6 +133,22 @@ gpio_pic_unblock_irqs(struct pic_softc * } void +gpio_pic_unblock_irqs2(struct pic_softc *pic, size_t irq_base, uint32_t irq_mask) +{ + struct gpio_softc * const gpio = PIC_TO_SOFTC(pic); + KASSERT(irq_base == 0); + + /* + * If this a level source, ack it now. If it's still asserted + * it'll come back. + */ + GPIO_WRITE2(gpio, GPIO_IRQSTATUS_SET_0, irq_mask); + if (irq_mask & gpio->gpio_level_mask) + GPIO_WRITE2(gpio, GPIO_IRQSTATUS_0, + irq_mask & gpio->gpio_level_mask); +} + +void gpio_pic_block_irqs(struct pic_softc *pic, size_t irq_base, uint32_t irq_mask) { struct gpio_softc * const gpio = PIC_TO_SOFTC(pic); @@ -135,6 +165,22 @@ gpio_pic_block_irqs(struct pic_softc *pi irq_mask & gpio->gpio_edge_mask); } +void +gpio_pic_block_irqs2(struct pic_softc *pic, size_t irq_base, uint32_t irq_mask) +{ + struct gpio_softc * const gpio = PIC_TO_SOFTC(pic); + KASSERT(irq_base == 0); + + GPIO_WRITE2(gpio, GPIO_IRQSTATUS_CLR_0, irq_mask); + /* + * If any of the sources are edge triggered, ack them now so + * we won't lose them. + */ + if (irq_mask & gpio->gpio_edge_mask) + GPIO_WRITE2(gpio, GPIO_IRQSTATUS_0, + irq_mask & gpio->gpio_edge_mask); +} + int gpio_pic_find_pending_irqs(struct pic_softc *pic) { @@ -155,6 +201,24 @@ gpio_pic_find_pending_irqs(struct pic_so return 1; } +int +gpio_pic_find_pending_irqs2(struct pic_softc *pic) +{ + struct gpio_softc * const gpio = PIC_TO_SOFTC(pic); + uint32_t pending; + + pending = GPIO_READ2(gpio, GPIO_IRQSTATUS_0); + if (pending == 0) + return 0; + + /* + * Now find all the pending bits and mark them as pending. + */ + (void) pic_mark_pending_sources(&gpio->gpio_pic, 0, pending); + + return 1; +} + void gpio_pic_establish_irq(struct pic_softc *pic, struct intrsource *is) { @@ -170,9 +234,14 @@ gpio_pic_establish_irq(struct pic_softc /* * Make sure the irq isn't enabled and not asserting. */ +#if defined(OMAP_4430) || defined(TI_AM335X) + GPIO_WRITE2(gpio, GPIO_IRQSTATUS_SET_0, irq_mask); + GPIO_WRITE2(gpio, GPIO_IRQSTATUS_0, irq_mask); +#else gpio->gpio_enable_mask &= ~irq_mask; GPIO_WRITE(gpio, GPIO_IRQENABLE1, gpio->gpio_enable_mask); GPIO_WRITE(gpio, GPIO_IRQSTATUS1, irq_mask); +#endif /* * Convert the type to a gpio type and figure out which bits in what @@ -421,9 +490,16 @@ gpio_attach(device_t parent, device_t se panic("\n%s: no size assigned", device_xname(self)); gpio->gpio_memt = oa->obio_iot; +#if defined(OMAP_4430) || defined(TI_AM335X) + error = bus_space_map(oa->obio_iot, oa->obio_addr, oa->obio_size, + 0, &gpio->gpio_memh2); + if (error == 0) + error = bus_space_subregion(gpio->gpio_memt, gpio->gpio_memh2, + GPIO_SIZE2, oa->obio_size - GPIO_SIZE2, &gpio->gpio_memh); +#else error = bus_space_map(oa->obio_iot, oa->obio_addr, oa->obio_size, 0, &gpio->gpio_memh); - +#endif if (error) { aprint_error(": failed to map register %#lx@%#lx: %d\n", oa->obio_size, oa->obio_addr, error); @@ -431,7 +507,11 @@ gpio_attach(device_t parent, device_t se } if (oa->obio_intrbase != OBIOCF_INTRBASE_DEFAULT) { +#if defined(OMAP_4430) || defined(TI_AM335X) + gpio->gpio_pic.pic_ops = &gpio_pic_ops2; +#else gpio->gpio_pic.pic_ops = &gpio_pic_ops; +#endif strlcpy(gpio->gpio_pic.pic_name, device_xname(self), sizeof(gpio->gpio_pic.pic_name)); gpio->gpio_pic.pic_maxsources = 32;