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;

Reply via email to