Author: hselasky
Date: Thu May 29 10:06:18 2014
New Revision: 266831
URL: http://svnweb.freebsd.org/changeset/base/266831

Log:
  Optimise the ISP/SAF1761 driver:
  - Use an interrupt filter for handling the data path interrupts. This
  increases the throughput significantly.
  - Implement support for USB suspend and resume in USB host mode.
  
  Sponsored by: DARPA, AFRL

Modified:
  head/sys/dev/usb/controller/saf1761_otg.c
  head/sys/dev/usb/controller/saf1761_otg.h
  head/sys/dev/usb/controller/saf1761_otg_fdt.c

Modified: head/sys/dev/usb/controller/saf1761_otg.c
==============================================================================
--- head/sys/dev/usb/controller/saf1761_otg.c   Thu May 29 07:45:45 2014        
(r266830)
+++ head/sys/dev/usb/controller/saf1761_otg.c   Thu May 29 10:06:18 2014        
(r266831)
@@ -84,6 +84,13 @@
    ((struct saf1761_otg_softc *)(((uint8_t *)(bus)) - \
     ((uint8_t *)&(((struct saf1761_otg_softc *)0)->sc_bus))))
 
+#define        SAF1761_OTG_PC2UDEV(pc) \
+   (USB_DMATAG_TO_XROOT((pc)->tag_parent)->udev)
+
+#define        SAF1761_DCINTERRUPT_THREAD_IRQ                  \
+  (SOTG_DCINTERRUPT_IEVBUS | SOTG_DCINTERRUPT_IEBRST | \
+  SOTG_DCINTERRUPT_IERESM | SOTG_DCINTERRUPT_IESUSP)
+
 #ifdef USB_DEBUG
 static int saf1761_otg_debug = 0;
 static int saf1761_otg_forcefs = 0;
@@ -201,7 +208,6 @@ saf1761_otg_wakeup_peer(struct saf1761_o
 
        /* Wait 8ms for remote wakeup to complete. */
        usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 125);
-
 }
 
 static uint8_t
@@ -212,6 +218,10 @@ saf1761_host_channel_alloc(struct saf176
        if (td->channel < SOTG_HOST_CHANNEL_MAX)
                return (0);
 
+       /* check if device is suspended */
+       if (SAF1761_OTG_PC2UDEV(td->pc)->flags.self_suspended != 0)
+               return (1);             /* busy - cannot transfer data */
+
        switch (td->ep_type) {
        case UE_INTERRUPT:
                for (x = 0; x != 32; x++) {
@@ -257,19 +267,25 @@ saf1761_host_channel_free(struct saf1761
                x = td->channel - 32;
                td->channel = SOTG_HOST_CHANNEL_MAX;
                sc->sc_host_intr_map &= ~(1 << x);
-               SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD, 
~sc->sc_host_intr_map);
+               sc->sc_host_intr_suspend_map &= ~(1 << x);
+               SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD,
+                   (~sc->sc_host_intr_map) | sc->sc_host_intr_suspend_map);
                break;
        case UE_ISOCHRONOUS:
                x = td->channel;
                td->channel = SOTG_HOST_CHANNEL_MAX;
                sc->sc_host_isoc_map &= ~(1 << x);
-               SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD, 
~sc->sc_host_isoc_map);
+               sc->sc_host_isoc_suspend_map &= ~(1 << x);
+               SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD,
+                   (~sc->sc_host_isoc_map) | sc->sc_host_isoc_suspend_map);
                break;
        default:
                x = td->channel - 64;
                td->channel = SOTG_HOST_CHANNEL_MAX;
                sc->sc_host_async_map &= ~(1 << x);
-               SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD, 
~sc->sc_host_async_map);
+               sc->sc_host_async_suspend_map &= ~(1 << x);
+               SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD,
+                   (~sc->sc_host_async_map) | sc->sc_host_async_suspend_map);
                break;
        }
 }
@@ -447,7 +463,8 @@ saf1761_host_setup_tx(struct saf1761_otg
        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW0, temp);
 
        /* activate PTD */
-       SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD, ~sc->sc_host_async_map);
+       SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD,
+           (~sc->sc_host_async_map) | sc->sc_host_async_suspend_map);
 
        td->toggle = 1;
 busy:
@@ -553,7 +570,8 @@ saf1761_host_bulk_data_rx(struct saf1761
        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW0, temp);
 
        /* activate PTD */
-       SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD, ~sc->sc_host_async_map);
+       SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD,
+           (~sc->sc_host_async_map) | sc->sc_host_async_suspend_map);
 busy:
        return (1);     /* busy */
 complete:
@@ -639,7 +657,8 @@ saf1761_host_bulk_data_tx(struct saf1761
        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW0, temp);
 
        /* activate PTD */
-       SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD, ~sc->sc_host_async_map);
+       SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD,
+           (~sc->sc_host_async_map) | sc->sc_host_async_suspend_map);
 
        td->toggle ^= 1;
 busy:
@@ -748,7 +767,8 @@ saf1761_host_intr_data_rx(struct saf1761
        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW0, temp);
 
        /* activate PTD */
-       SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD, ~sc->sc_host_intr_map);
+       SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD,
+           (~sc->sc_host_intr_map) | sc->sc_host_intr_suspend_map);
 busy:
        return (1);     /* busy */
 complete:
@@ -838,7 +858,8 @@ saf1761_host_intr_data_tx(struct saf1761
        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW0, temp);
 
        /* activate PTD */
-       SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD, ~sc->sc_host_intr_map);
+       SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD,
+           (~sc->sc_host_intr_map) | sc->sc_host_intr_suspend_map);
 
        td->toggle ^= 1;
 busy:
@@ -852,7 +873,8 @@ static uint8_t
 saf1761_host_isoc_data_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td 
*td)
 {
        /* activate PTD */
-       SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD, ~sc->sc_host_isoc_map);
+       SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD,
+           (~sc->sc_host_isoc_map) | sc->sc_host_isoc_suspend_map);
 
        return (1);     /* busy */
 }
@@ -861,7 +883,8 @@ static uint8_t
 saf1761_host_isoc_data_tx(struct saf1761_otg_softc *sc, struct saf1761_otg_td 
*td)
 {
        /* activate PTD */
-       SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD, ~sc->sc_host_isoc_map);
+       SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD,
+           (~sc->sc_host_isoc_map) | sc->sc_host_isoc_suspend_map);
 
        return (1);     /* busy */
 }
@@ -1222,7 +1245,7 @@ saf1761_device_data_tx_sync(struct saf17
        return (0);                     /* complete */
 }
 
-static uint8_t
+static void
 saf1761_otg_xfer_do_fifo(struct saf1761_otg_softc *sc, struct usb_xfer *xfer)
 {
        struct saf1761_otg_td *td;
@@ -1231,6 +1254,9 @@ saf1761_otg_xfer_do_fifo(struct saf1761_
        DPRINTFN(9, "\n");
 
        td = xfer->td_transfer_cache;
+       if (td == NULL)
+               return;
+
        while (1) {
                if ((td->func) (sc, td)) {
                        /* operation in progress */
@@ -1258,28 +1284,37 @@ saf1761_otg_xfer_do_fifo(struct saf1761_
                td->toggle = toggle;
                xfer->td_transfer_cache = td;
        }
-       return (1);                     /* not complete */
+       return;
 
 done:
        /* compute all actual lengths */
+       xfer->td_transfer_cache = NULL;
+       sc->sc_xfer_complete = 1;
+}
+
+static uint8_t
+saf1761_otg_xfer_do_complete(struct saf1761_otg_softc *sc, struct usb_xfer 
*xfer)
+{
+       struct saf1761_otg_td *td;
 
-       saf1761_otg_standard_done(xfer);
+       DPRINTFN(9, "\n");
 
-       return (0);                     /* complete */
+       td = xfer->td_transfer_cache;
+       if (td == NULL) {
+               /* compute all actual lengths */
+               saf1761_otg_standard_done(xfer);
+               return (1);
+       }
+       return (0);
 }
 
 static void
-saf1761_otg_interrupt_poll(struct saf1761_otg_softc *sc)
+saf1761_otg_interrupt_poll_locked(struct saf1761_otg_softc *sc)
 {
        struct usb_xfer *xfer;
 
-repeat:
-       TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
-               if (!saf1761_otg_xfer_do_fifo(sc, xfer)) {
-                       /* queue has been modified */
-                       goto repeat;
-               }
-       }
+       TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry)
+               saf1761_otg_xfer_do_fifo(sc, xfer);
 }
 
 static void
@@ -1329,13 +1364,27 @@ saf1761_otg_update_vbus(struct saf1761_o
        }
 }
 
-void
-saf1761_otg_interrupt(struct saf1761_otg_softc *sc)
+static void
+saf1761_otg_interrupt_complete_locked(struct saf1761_otg_softc *sc)
 {
-       uint32_t status;
+       struct usb_xfer *xfer;
+repeat:
+       /* scan for completion events */
+       TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
+               if (saf1761_otg_xfer_do_complete(sc, xfer))
+                       goto repeat;
+       }
+}
+
+int
+saf1761_otg_filter_interrupt(void *arg)
+{
+       struct saf1761_otg_softc *sc = arg;
+       int retval = FILTER_HANDLED;
        uint32_t hcstat;
+       uint32_t status;
 
-       USB_BUS_LOCK(&sc->sc_bus);
+       USB_BUS_SPIN_LOCK(&sc->sc_bus);
 
        hcstat = SAF1761_READ_LE_4(sc, SOTG_HCINTERRUPT);
        /* acknowledge all host controller interrupts */
@@ -1343,17 +1392,47 @@ saf1761_otg_interrupt(struct saf1761_otg
 
        status = SAF1761_READ_LE_4(sc, SOTG_DCINTERRUPT);
        /* acknowledge all device controller interrupts */
-       SAF1761_WRITE_LE_4(sc, SOTG_DCINTERRUPT, status);
-
-       DPRINTF("DCINTERRUPT=0x%08x HCINTERRUPT=0x%08x SOF=0x%08x "
-           "FRINDEX=0x%08x\n", status, hcstat,
-           SAF1761_READ_LE_4(sc, SOTG_FRAME_NUM),
-           SAF1761_READ_LE_4(sc, SOTG_FRINDEX));
+       SAF1761_WRITE_LE_4(sc, SOTG_DCINTERRUPT,
+           status & ~SAF1761_DCINTERRUPT_THREAD_IRQ);
 
        (void) SAF1761_READ_LE_4(sc, SOTG_ATL_PTD_DONE_PTD);
        (void) SAF1761_READ_LE_4(sc, SOTG_INT_PTD_DONE_PTD);
        (void) SAF1761_READ_LE_4(sc, SOTG_ISO_PTD_DONE_PTD);
 
+       if (status & SAF1761_DCINTERRUPT_THREAD_IRQ)
+               retval = FILTER_SCHEDULE_THREAD;
+
+       /* poll FIFOs, if any */
+       saf1761_otg_interrupt_poll_locked(sc);
+
+       if (sc->sc_xfer_complete != 0)
+               retval = FILTER_SCHEDULE_THREAD;
+
+       USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
+
+       return (retval);
+}
+
+void
+saf1761_otg_interrupt(void *arg)
+{
+       struct saf1761_otg_softc *sc = arg;
+       uint32_t status;
+
+       USB_BUS_LOCK(&sc->sc_bus);
+       USB_BUS_SPIN_LOCK(&sc->sc_bus);
+
+       status = SAF1761_READ_LE_4(sc, SOTG_DCINTERRUPT) & 
+           SAF1761_DCINTERRUPT_THREAD_IRQ;
+
+       /* acknowledge all device controller interrupts */
+       SAF1761_WRITE_LE_4(sc, SOTG_DCINTERRUPT, status);
+
+       DPRINTF("DCINTERRUPT=0x%08x SOF=0x%08x "
+           "FRINDEX=0x%08x\n", status,
+           SAF1761_READ_LE_4(sc, SOTG_FRAME_NUM),
+           SAF1761_READ_LE_4(sc, SOTG_FRINDEX));
+
        /* update VBUS and ID bits, if any */
        if (status & SOTG_DCINTERRUPT_IEVBUS)
                saf1761_otg_update_vbus(sc);
@@ -1405,9 +1484,14 @@ saf1761_otg_interrupt(struct saf1761_otg
                        saf1761_otg_root_intr(sc);
                }
        }
-       /* poll all active transfers */
-       saf1761_otg_interrupt_poll(sc);
 
+       if (sc->sc_xfer_complete != 0) {
+               sc->sc_xfer_complete = 0;
+
+               /* complete FIFOs, if any */
+               saf1761_otg_interrupt_complete_locked(sc);
+       }
+       USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
        USB_BUS_UNLOCK(&sc->sc_bus);
 }
 
@@ -1694,9 +1778,12 @@ saf1761_otg_start_standard_chain(struct 
 
        DPRINTFN(9, "\n");
 
+       USB_BUS_SPIN_LOCK(&sc->sc_bus);
+
        /* poll one time */
-       if (saf1761_otg_xfer_do_fifo(sc, xfer)) {
+       saf1761_otg_xfer_do_fifo(sc, xfer);
 
+       if (xfer->td_transfer_cache != NULL) {
                /*
                 * Only enable the endpoint interrupt when we are
                 * actually waiting for data, hence we are dealing
@@ -1712,7 +1799,11 @@ saf1761_otg_start_standard_chain(struct 
                        usbd_transfer_timeout_ms(xfer,
                            &saf1761_otg_timeout, xfer->timeout);
                }
+       } else {
+               /* catch completion, if any */
+               saf1761_otg_interrupt_complete_locked(sc);
        }
+       USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
 }
 
 static void
@@ -1856,6 +1947,8 @@ saf1761_otg_device_done(struct usb_xfer 
        DPRINTFN(2, "xfer=%p, endpoint=%p, error=%d\n",
            xfer, xfer->endpoint, error);
 
+       USB_BUS_SPIN_LOCK(&sc->sc_bus);
+
        if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) {
                saf1761_otg_intr_set(xfer, 0);
        } else {
@@ -1869,6 +1962,8 @@ saf1761_otg_device_done(struct usb_xfer 
 
        /* dequeue transfer and start next transfer */
        usbd_transfer_done(xfer, error);
+
+       USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
 }
 
 static void
@@ -1896,8 +1991,9 @@ saf1761_otg_set_stall(struct usb_device 
 
        DPRINTFN(5, "endpoint=%p\n", ep);
 
-       /* set FORCESTALL */
+       /* set STALL bit */
        sc = SAF1761_OTG_BUS2SC(udev->bus);
+
        ep_no = (ep->edesc->bEndpointAddress & UE_ADDR);
        ep_dir = (ep->edesc->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT));
        ep_type = (ep->edesc->bmAttributes & UE_XFERTYPE);
@@ -1906,6 +2002,8 @@ saf1761_otg_set_stall(struct usb_device 
                /* should not happen */
                return;
        }
+       USB_BUS_SPIN_LOCK(&sc->sc_bus);
+
        /* select the correct endpoint */
        SAF1761_WRITE_LE_4(sc, SOTG_EP_INDEX,
            (ep_no << SOTG_EP_INDEX_ENDP_INDEX_SHIFT) |
@@ -1914,10 +2012,12 @@ saf1761_otg_set_stall(struct usb_device 
 
        /* set stall */
        SAF1761_WRITE_LE_4(sc, SOTG_CTRL_FUNC, SOTG_CTRL_FUNC_STALL);
+
+       USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
 }
 
 static void
-saf1761_otg_clear_stall_sub(struct saf1761_otg_softc *sc,
+saf1761_otg_clear_stall_sub_locked(struct saf1761_otg_softc *sc,
     uint8_t ep_no, uint8_t ep_type, uint8_t ep_dir)
 {
        if (ep_type == UE_CONTROL) {
@@ -1959,14 +2059,18 @@ saf1761_otg_clear_stall(struct usb_devic
        /* get softc */
        sc = SAF1761_OTG_BUS2SC(udev->bus);
 
+       USB_BUS_SPIN_LOCK(&sc->sc_bus);
+
        /* get endpoint descriptor */
        ed = ep->edesc;
 
        /* reset endpoint */
-       saf1761_otg_clear_stall_sub(sc,
+       saf1761_otg_clear_stall_sub_locked(sc,
            (ed->bEndpointAddress & UE_ADDR),
            (ed->bmAttributes & UE_XFERTYPE),
            (ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT)));
+
+       USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
 }
 
 usb_error_t
@@ -2218,7 +2322,10 @@ saf1761_otg_do_poll(struct usb_bus *bus)
        struct saf1761_otg_softc *sc = SAF1761_OTG_BUS2SC(bus);
 
        USB_BUS_LOCK(&sc->sc_bus);
-       saf1761_otg_interrupt_poll(sc);
+       USB_BUS_SPIN_LOCK(&sc->sc_bus);
+       saf1761_otg_interrupt_poll_locked(sc);
+       saf1761_otg_interrupt_complete_locked(sc);
+       USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
        USB_BUS_UNLOCK(&sc->sc_bus);
 }
 
@@ -3150,6 +3257,115 @@ saf1761_otg_set_hw_power_sleep(struct us
        }
 }
 
+static void
+saf1761_otg_device_resume(struct usb_device *udev)
+{
+       struct saf1761_otg_softc *sc;
+       struct saf1761_otg_td *td;
+       struct usb_xfer *xfer;
+       uint8_t x;
+
+       DPRINTF("\n");
+
+       if (udev->flags.usb_mode != USB_MODE_HOST)
+               return;
+
+       sc = SAF1761_OTG_BUS2SC(udev->bus);
+
+       USB_BUS_LOCK(&sc->sc_bus);
+       USB_BUS_SPIN_LOCK(&sc->sc_bus);
+
+       TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
+
+               if (xfer->xroot->udev != udev)
+                       continue;
+
+               td = xfer->td_transfer_cache;
+               if (td == NULL || td->channel >= SOTG_HOST_CHANNEL_MAX)
+                       continue;
+
+               switch (td->ep_type) {
+               case UE_INTERRUPT:
+                       x = td->channel - 32;
+                       sc->sc_host_intr_suspend_map &= ~(1 << x);
+                       SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD,
+                           (~sc->sc_host_intr_map) | 
sc->sc_host_intr_suspend_map);
+                       break;
+               case UE_ISOCHRONOUS:
+                       x = td->channel;
+                       sc->sc_host_isoc_suspend_map &= ~(1 << x);
+                       SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD,
+                           (~sc->sc_host_isoc_map) | 
sc->sc_host_isoc_suspend_map);
+                       break;
+               default:
+                       x = td->channel - 64;
+                       sc->sc_host_async_suspend_map &= ~(1 << x);
+                       SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD,
+                           (~sc->sc_host_async_map) | 
sc->sc_host_async_suspend_map);
+                       break;
+               }
+       }
+
+       USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
+       USB_BUS_UNLOCK(&sc->sc_bus);
+
+       /* poll all transfers again to restart resumed ones */
+       saf1761_otg_do_poll(&sc->sc_bus);
+}
+
+static void
+saf1761_otg_device_suspend(struct usb_device *udev)
+{
+       struct saf1761_otg_softc *sc;
+       struct saf1761_otg_td *td;
+       struct usb_xfer *xfer;
+       uint8_t x;
+
+       DPRINTF("\n");
+
+       if (udev->flags.usb_mode != USB_MODE_HOST)
+               return;
+
+       sc = SAF1761_OTG_BUS2SC(udev->bus);
+
+       USB_BUS_LOCK(&sc->sc_bus);
+       USB_BUS_SPIN_LOCK(&sc->sc_bus);
+
+       TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
+
+               if (xfer->xroot->udev != udev)
+                       continue;
+
+               td = xfer->td_transfer_cache;
+               if (td == NULL || td->channel >= SOTG_HOST_CHANNEL_MAX)
+                       continue;
+
+               switch (td->ep_type) {
+               case UE_INTERRUPT:
+                       x = td->channel - 32;
+                       sc->sc_host_intr_suspend_map |= (1 << x);
+                       SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD,
+                           (~sc->sc_host_intr_map) | 
sc->sc_host_intr_suspend_map);
+                       break;
+               case UE_ISOCHRONOUS:
+                       x = td->channel;
+                       sc->sc_host_isoc_suspend_map |= (1 << x);
+                       SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD,
+                           (~sc->sc_host_isoc_map) | 
sc->sc_host_isoc_suspend_map);
+                       break;
+               default:
+                       x = td->channel - 64;
+                       sc->sc_host_async_suspend_map |= (1 << x);
+                       SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD,
+                           (~sc->sc_host_async_map) | 
sc->sc_host_async_suspend_map);
+                       break;
+               }
+       }
+
+       USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
+       USB_BUS_UNLOCK(&sc->sc_bus);
+}
+
 static const struct usb_bus_methods saf1761_otg_bus_methods =
 {
        .endpoint_init = &saf1761_otg_ep_init,
@@ -3162,4 +3378,6 @@ static const struct usb_bus_methods saf1
        .roothub_exec = &saf1761_otg_roothub_exec,
        .xfer_poll = &saf1761_otg_do_poll,
        .set_hw_power_sleep = saf1761_otg_set_hw_power_sleep,
+       .device_resume = &saf1761_otg_device_resume,
+       .device_suspend = &saf1761_otg_device_suspend,
 };

Modified: head/sys/dev/usb/controller/saf1761_otg.h
==============================================================================
--- head/sys/dev/usb/controller/saf1761_otg.h   Thu May 29 07:45:45 2014        
(r266830)
+++ head/sys/dev/usb/controller/saf1761_otg.h   Thu May 29 10:06:18 2014        
(r266831)
@@ -140,11 +140,15 @@ struct saf1761_otg_softc {
        bus_space_handle_t sc_io_hdl;
 
        uint32_t sc_host_async_map;
+       uint32_t sc_host_async_suspend_map;
        uint32_t sc_host_intr_map;
+       uint32_t sc_host_intr_suspend_map;
        uint32_t sc_host_isoc_map;
+       uint32_t sc_host_isoc_suspend_map;
        uint32_t sc_intr_enable;        /* enabled interrupts */
        uint32_t sc_hw_mode;            /* hardware mode */
        uint32_t sc_interrupt_cfg;      /* interrupt configuration */
+       uint32_t sc_xfer_complete;
 
        uint32_t sc_bounce_buffer[1024 / 4];
 
@@ -162,6 +166,7 @@ struct saf1761_otg_softc {
 
 usb_error_t saf1761_otg_init(struct saf1761_otg_softc *sc);
 void   saf1761_otg_uninit(struct saf1761_otg_softc *sc);
-void   saf1761_otg_interrupt(struct saf1761_otg_softc *sc);
+driver_filter_t saf1761_otg_filter_interrupt;
+driver_intr_t saf1761_otg_interrupt;
 
 #endif                                 /* _SAF1761_OTG_H_ */

Modified: head/sys/dev/usb/controller/saf1761_otg_fdt.c
==============================================================================
--- head/sys/dev/usb/controller/saf1761_otg_fdt.c       Thu May 29 07:45:45 
2014        (r266830)
+++ head/sys/dev/usb/controller/saf1761_otg_fdt.c       Thu May 29 10:06:18 
2014        (r266831)
@@ -210,8 +210,8 @@ saf1761_otg_fdt_attach(device_t dev)
 
        device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
 
-       err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
-           NULL, (driver_intr_t *)saf1761_otg_interrupt, sc, &sc->sc_intr_hdl);
+       err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_TTY | INTR_MPSAFE,
+           &saf1761_otg_filter_interrupt, &saf1761_otg_interrupt, sc, 
&sc->sc_intr_hdl);
        if (err) {
                sc->sc_intr_hdl = NULL;
                goto error;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to