Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 10 Sep 2012 13:50:34 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r240314 - head/sys/dev/usb/controller
Message-ID:  <201209101350.q8ADoYvl063455@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Mon Sep 10 13:50:34 2012
New Revision: 240314
URL: http://svn.freebsd.org/changeset/base/240314

Log:
  Poll VBUS status every second, hence the AT91 GPIO library doesn't support
  registering interrupt handlers yet for GPIO events.

Modified:
  head/sys/dev/usb/controller/at91dci.c
  head/sys/dev/usb/controller/at91dci_atmelarm.c

Modified: head/sys/dev/usb/controller/at91dci.c
==============================================================================
--- head/sys/dev/usb/controller/at91dci.c	Mon Sep 10 12:25:57 2012	(r240313)
+++ head/sys/dev/usb/controller/at91dci.c	Mon Sep 10 13:50:34 2012	(r240314)
@@ -740,7 +740,6 @@ at91dci_vbus_interrupt(struct at91dci_so
 {
 	DPRINTFN(5, "vbus = %u\n", is_on);
 
-	USB_BUS_LOCK(&sc->sc_bus);
 	if (is_on) {
 		if (!sc->sc_flags.status_vbus) {
 			sc->sc_flags.status_vbus = 1;
@@ -760,7 +759,6 @@ at91dci_vbus_interrupt(struct at91dci_so
 			at91dci_root_intr(sc);
 		}
 	}
-	USB_BUS_UNLOCK(&sc->sc_bus);
 }
 
 void

Modified: head/sys/dev/usb/controller/at91dci_atmelarm.c
==============================================================================
--- head/sys/dev/usb/controller/at91dci_atmelarm.c	Mon Sep 10 12:25:57 2012	(r240313)
+++ head/sys/dev/usb/controller/at91dci_atmelarm.c	Mon Sep 10 13:50:34 2012	(r240314)
@@ -83,24 +83,18 @@ struct at91_udp_softc {
 	struct at91_pmc_clock *sc_mclk;
 	struct at91_pmc_clock *sc_iclk;
 	struct at91_pmc_clock *sc_fclk;
-	struct resource *sc_vbus_irq_res;
-	void   *sc_vbus_intr_hdl;
+	struct callout sc_vbus;
 };
 
 static void
 at91_vbus_poll(struct at91_udp_softc *sc)
 {
-	uint32_t temp;
 	uint8_t vbus_val;
 
-	/* XXX temporary clear interrupts here */
-
-	temp = at91_pio_gpio_clear_interrupt(VBUS_BASE);
-
-	/* just forward it */
-
 	vbus_val = at91_pio_gpio_get(VBUS_BASE, VBUS_MASK);
 	at91dci_vbus_interrupt(&sc->sc_dci, vbus_val);
+
+	callout_reset(&sc->sc_vbus, hz, (void *)&at91_vbus_poll, sc);
 }
 
 static void
@@ -168,6 +162,8 @@ at91_udp_attach(device_t dev)
 	    USB_GET_DMA_TAG(dev), NULL)) {
 		return (ENOMEM);
 	}
+	callout_init_mtx(&sc->sc_vbus, &sc->sc_dci.sc_bus.bus_mtx, 0);
+
 	/*
 	 * configure VBUS input pin, enable deglitch and enable
 	 * interrupt :
@@ -175,7 +171,7 @@ at91_udp_attach(device_t dev)
 	at91_pio_use_gpio(VBUS_BASE, VBUS_MASK);
 	at91_pio_gpio_input(VBUS_BASE, VBUS_MASK);
 	at91_pio_gpio_set_deglitch(VBUS_BASE, VBUS_MASK, 1);
-	at91_pio_gpio_set_interrupt(VBUS_BASE, VBUS_MASK, 1);
+	at91_pio_gpio_set_interrupt(VBUS_BASE, VBUS_MASK, 0);
 
 	/*
 	 * configure PULLUP output pin :
@@ -210,13 +206,6 @@ at91_udp_attach(device_t dev)
 	if (!(sc->sc_dci.sc_irq_res)) {
 		goto error;
 	}
-	rid = 1;
-	sc->sc_vbus_irq_res =
-	    bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
-	if (sc->sc_vbus_irq_res == NULL) {
-		at91_pio_gpio_set_interrupt(VBUS_BASE, VBUS_MASK, 0);
-		device_printf(dev, "No VBUS IRQ!\n");
-	}
 	sc->sc_dci.sc_bus.bdev = device_add_child(dev, "usbus", -1);
 	if (!(sc->sc_dci.sc_bus.bdev)) {
 		goto error;
@@ -234,25 +223,7 @@ at91_udp_attach(device_t dev)
 		sc->sc_dci.sc_intr_hdl = NULL;
 		goto error;
 	}
-#if (__FreeBSD_version >= 700031)
-	if (sc->sc_vbus_irq_res != NULL) {
-		err = bus_setup_intr(dev, sc->sc_vbus_irq_res,
-		    INTR_TYPE_BIO | INTR_MPSAFE,
-		    NULL, (driver_intr_t *)at91_vbus_poll, sc,
-		    &sc->sc_vbus_intr_hdl);
-	}
-#else
-	if (sc->sc_vbus_irq_res != NULL) {
-		err = bus_setup_intr(dev, sc->sc_vbus_irq_res,
-		    INTR_TYPE_BIO | INTR_MPSAFE,
-		    (driver_intr_t *)at91_vbus_poll, sc,
-		    &sc->sc_vbus_intr_hdl);
-	}
-#endif
-	if (err) {
-		sc->sc_vbus_intr_hdl = NULL;
-		goto error;
-	}
+
 	err = at91dci_init(&sc->sc_dci);
 	if (!err) {
 		err = device_probe_and_attach(sc->sc_dci.sc_bus.bdev);
@@ -261,7 +232,9 @@ at91_udp_attach(device_t dev)
 		goto error;
 	} else {
 		/* poll VBUS one time */
+		USB_BUS_LOCK(&sc->sc_dci.sc_bus);
 		at91_vbus_poll(sc);
+		USB_BUS_UNLOCK(&sc->sc_dci.sc_bus);
 	}
 	return (0);
 
@@ -285,6 +258,12 @@ at91_udp_detach(device_t dev)
 	/* during module unload there are lots of children leftover */
 	device_delete_children(dev);
 
+	USB_BUS_LOCK(&sc->sc_dci.sc_bus);
+	callout_stop(&sc->sc_vbus);
+	USB_BUS_UNLOCK(&sc->sc_dci.sc_bus);
+
+	callout_drain(&sc->sc_vbus);
+
 	/* disable Transceiver */
 	AT91_UDP_WRITE_4(&sc->sc_dci, AT91_UDP_TXVC, AT91_UDP_TXVC_DIS);
 
@@ -292,19 +271,6 @@ at91_udp_detach(device_t dev)
 	AT91_UDP_WRITE_4(&sc->sc_dci, AT91_UDP_IDR, 0xFFFFFFFF);
 	AT91_UDP_WRITE_4(&sc->sc_dci, AT91_UDP_ICR, 0xFFFFFFFF);
 
-	/* disable VBUS interrupt */
-	at91_pio_gpio_set_interrupt(VBUS_BASE, VBUS_MASK, 0);
-
-	if (sc->sc_vbus_irq_res && sc->sc_vbus_intr_hdl) {
-		err = bus_teardown_intr(dev, sc->sc_vbus_irq_res,
-		    sc->sc_vbus_intr_hdl);
-		sc->sc_vbus_intr_hdl = NULL;
-	}
-	if (sc->sc_vbus_irq_res) {
-		bus_release_resource(dev, SYS_RES_IRQ, 1,
-		    sc->sc_vbus_irq_res);
-		sc->sc_vbus_irq_res = NULL;
-	}
 	if (sc->sc_dci.sc_irq_res && sc->sc_dci.sc_intr_hdl) {
 		/*
 		 * only call at91_udp_uninit() after at91_udp_init()



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201209101350.q8ADoYvl063455>