diff options
Diffstat (limited to 'drivers/staging/dwc2/hcd.c')
-rw-r--r-- | drivers/staging/dwc2/hcd.c | 281 |
1 files changed, 125 insertions, 156 deletions
diff --git a/drivers/staging/dwc2/hcd.c b/drivers/staging/dwc2/hcd.c index 2ed54b172a3b..da0d35cc33ce 100644 --- a/drivers/staging/dwc2/hcd.c +++ b/drivers/staging/dwc2/hcd.c @@ -134,11 +134,8 @@ static void dwc2_kill_urbs_in_qh_list(struct dwc2_hsotg *hsotg, list_for_each_entry_safe(qh, qh_tmp, qh_list, qh_list_entry) { list_for_each_entry_safe(qtd, qtd_tmp, &qh->qtd_list, qtd_list_entry) { - if (qtd->urb != NULL) { - dwc2_host_complete(hsotg, qtd->urb->priv, - qtd->urb, -ETIMEDOUT); - dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh); - } + dwc2_host_complete(hsotg, qtd, -ETIMEDOUT); + dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh); } } } @@ -421,6 +418,8 @@ static int dwc2_hcd_urb_dequeue(struct dwc2_hsotg *hsotg, return -EINVAL; } + urb->priv = NULL; + if (urb_qtd->in_process && qh->channel) { dwc2_dump_channel_info(hsotg, qh->channel); @@ -1006,10 +1005,10 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg) dev_vdbg(hsotg->dev, "Queue periodic transactions\n"); tx_status = readl(hsotg->regs + HPTXSTS); - qspcavail = tx_status >> TXSTS_QSPCAVAIL_SHIFT & - TXSTS_QSPCAVAIL_MASK >> TXSTS_QSPCAVAIL_SHIFT; - fspcavail = tx_status >> TXSTS_FSPCAVAIL_SHIFT & - TXSTS_FSPCAVAIL_MASK >> TXSTS_FSPCAVAIL_SHIFT; + qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >> + TXSTS_QSPCAVAIL_SHIFT; + fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >> + TXSTS_FSPCAVAIL_SHIFT; if (dbg_perio()) { dev_vdbg(hsotg->dev, " P Tx Req Queue Space Avail (before queue): %d\n", @@ -1021,7 +1020,9 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg) qh_ptr = hsotg->periodic_sched_assigned.next; while (qh_ptr != &hsotg->periodic_sched_assigned) { tx_status = readl(hsotg->regs + HPTXSTS); - if ((tx_status & TXSTS_QSPCAVAIL_MASK) == 0) { + qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >> + TXSTS_QSPCAVAIL_SHIFT; + if (qspcavail == 0) { no_queue_space = 1; break; } @@ -1047,8 +1048,8 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg) qh->channel->multi_count > 1) hsotg->queuing_high_bandwidth = 1; - fspcavail = tx_status >> TXSTS_FSPCAVAIL_SHIFT & - TXSTS_FSPCAVAIL_MASK >> TXSTS_FSPCAVAIL_SHIFT; + fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >> + TXSTS_FSPCAVAIL_SHIFT; status = dwc2_queue_transaction(hsotg, qh->channel, fspcavail); if (status < 0) { no_fifo_space = 1; @@ -1079,10 +1080,10 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg) if (hsotg->core_params->dma_enable <= 0) { tx_status = readl(hsotg->regs + HPTXSTS); - qspcavail = tx_status >> TXSTS_QSPCAVAIL_SHIFT & - TXSTS_QSPCAVAIL_MASK >> TXSTS_QSPCAVAIL_SHIFT; - fspcavail = tx_status >> TXSTS_FSPCAVAIL_SHIFT & - TXSTS_FSPCAVAIL_MASK >> TXSTS_FSPCAVAIL_SHIFT; + qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >> + TXSTS_QSPCAVAIL_SHIFT; + fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >> + TXSTS_FSPCAVAIL_SHIFT; if (dbg_perio()) { dev_vdbg(hsotg->dev, " P Tx Req Queue Space Avail (after queue): %d\n", @@ -1144,10 +1145,10 @@ static void dwc2_process_non_periodic_channels(struct dwc2_hsotg *hsotg) dev_vdbg(hsotg->dev, "Queue non-periodic transactions\n"); tx_status = readl(hsotg->regs + GNPTXSTS); - qspcavail = tx_status >> TXSTS_QSPCAVAIL_SHIFT & - TXSTS_QSPCAVAIL_MASK >> TXSTS_QSPCAVAIL_SHIFT; - fspcavail = tx_status >> TXSTS_FSPCAVAIL_SHIFT & - TXSTS_FSPCAVAIL_MASK >> TXSTS_FSPCAVAIL_SHIFT; + qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >> + TXSTS_QSPCAVAIL_SHIFT; + fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >> + TXSTS_FSPCAVAIL_SHIFT; dev_vdbg(hsotg->dev, " NP Tx Req Queue Space Avail (before queue): %d\n", qspcavail); dev_vdbg(hsotg->dev, " NP Tx FIFO Space Avail (before queue): %d\n", @@ -1167,8 +1168,8 @@ static void dwc2_process_non_periodic_channels(struct dwc2_hsotg *hsotg) */ do { tx_status = readl(hsotg->regs + GNPTXSTS); - qspcavail = tx_status >> TXSTS_QSPCAVAIL_SHIFT & - TXSTS_QSPCAVAIL_MASK >> TXSTS_QSPCAVAIL_SHIFT; + qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >> + TXSTS_QSPCAVAIL_SHIFT; if (hsotg->core_params->dma_enable <= 0 && qspcavail == 0) { no_queue_space = 1; break; @@ -1183,8 +1184,8 @@ static void dwc2_process_non_periodic_channels(struct dwc2_hsotg *hsotg) if (qh->tt_buffer_dirty) goto next; - fspcavail = tx_status >> TXSTS_FSPCAVAIL_SHIFT & - TXSTS_FSPCAVAIL_MASK >> TXSTS_FSPCAVAIL_SHIFT; + fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >> + TXSTS_FSPCAVAIL_SHIFT; status = dwc2_queue_transaction(hsotg, qh->channel, fspcavail); if (status > 0) { @@ -1204,10 +1205,10 @@ next: if (hsotg->core_params->dma_enable <= 0) { tx_status = readl(hsotg->regs + GNPTXSTS); - qspcavail = tx_status >> TXSTS_QSPCAVAIL_SHIFT & - TXSTS_QSPCAVAIL_MASK >> TXSTS_QSPCAVAIL_SHIFT; - fspcavail = tx_status >> TXSTS_FSPCAVAIL_SHIFT & - TXSTS_FSPCAVAIL_MASK >> TXSTS_FSPCAVAIL_SHIFT; + qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >> + TXSTS_QSPCAVAIL_SHIFT; + fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >> + TXSTS_FSPCAVAIL_SHIFT; dev_vdbg(hsotg->dev, " NP Tx Req Queue Space Avail (after queue): %d\n", qspcavail); @@ -1613,7 +1614,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, if (hprt0 & HPRT0_PWR) port_status |= USB_PORT_STAT_POWER; - speed = hprt0 & HPRT0_SPD_MASK; + speed = (hprt0 & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT; if (speed == HPRT0_SPD_HIGH_SPEED) port_status |= USB_PORT_STAT_HIGH_SPEED; else if (speed == HPRT0_SPD_LOW_SPEED) @@ -1762,11 +1763,9 @@ int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg) #ifdef DWC2_DEBUG_SOF dev_vdbg(hsotg->dev, "DWC OTG HCD GET FRAME NUMBER %d\n", - hfnum >> HFNUM_FRNUM_SHIFT & - HFNUM_FRNUM_MASK >> HFNUM_FRNUM_SHIFT); + (hfnum & HFNUM_FRNUM_MASK) >> HFNUM_FRNUM_SHIFT); #endif - return hfnum >> HFNUM_FRNUM_SHIFT & - HFNUM_FRNUM_MASK >> HFNUM_FRNUM_SHIFT; + return (hfnum & HFNUM_FRNUM_MASK) >> HFNUM_FRNUM_SHIFT; } int dwc2_hcd_is_b_host(struct dwc2_hsotg *hsotg) @@ -1917,18 +1916,14 @@ void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, " periodic_usecs: %d\n", hsotg->periodic_usecs); np_tx_status = readl(hsotg->regs + GNPTXSTS); dev_dbg(hsotg->dev, " NP Tx Req Queue Space Avail: %d\n", - np_tx_status >> TXSTS_QSPCAVAIL_SHIFT & - TXSTS_QSPCAVAIL_MASK >> TXSTS_QSPCAVAIL_SHIFT); + (np_tx_status & TXSTS_QSPCAVAIL_MASK) >> TXSTS_QSPCAVAIL_SHIFT); dev_dbg(hsotg->dev, " NP Tx FIFO Space Avail: %d\n", - np_tx_status >> TXSTS_FSPCAVAIL_SHIFT & - TXSTS_FSPCAVAIL_MASK >> TXSTS_FSPCAVAIL_SHIFT); + (np_tx_status & TXSTS_FSPCAVAIL_MASK) >> TXSTS_FSPCAVAIL_SHIFT); p_tx_status = readl(hsotg->regs + HPTXSTS); dev_dbg(hsotg->dev, " P Tx Req Queue Space Avail: %d\n", - p_tx_status >> TXSTS_QSPCAVAIL_SHIFT & - TXSTS_QSPCAVAIL_MASK >> TXSTS_QSPCAVAIL_SHIFT); + (p_tx_status & TXSTS_QSPCAVAIL_MASK) >> TXSTS_QSPCAVAIL_SHIFT); dev_dbg(hsotg->dev, " P Tx FIFO Space Avail: %d\n", - p_tx_status >> TXSTS_FSPCAVAIL_SHIFT & - TXSTS_FSPCAVAIL_MASK >> TXSTS_FSPCAVAIL_SHIFT); + (p_tx_status & TXSTS_FSPCAVAIL_MASK) >> TXSTS_FSPCAVAIL_SHIFT); dwc2_hcd_dump_frrem(hsotg); dwc2_dump_global_registers(hsotg); dwc2_dump_host_registers(hsotg); @@ -2088,23 +2083,29 @@ static void dwc2_free_bus_bandwidth(struct usb_hcd *hcd, u16 bw, * * Must be called with interrupt disabled and spinlock held */ -void dwc2_host_complete(struct dwc2_hsotg *hsotg, void *context, - struct dwc2_hcd_urb *dwc2_urb, int status) +void dwc2_host_complete(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, + int status) { - struct urb *urb = context; + struct urb *urb; int i; - if (!urb) { - dev_dbg(hsotg->dev, "## %s: context is NULL ##\n", __func__); + if (!qtd) { + dev_dbg(hsotg->dev, "## %s: qtd is NULL ##\n", __func__); return; } - if (!dwc2_urb) { - dev_dbg(hsotg->dev, "## %s: dwc2_urb is NULL ##\n", __func__); + if (!qtd->urb) { + dev_dbg(hsotg->dev, "## %s: qtd->urb is NULL ##\n", __func__); + return; + } + + urb = qtd->urb->priv; + if (!urb) { + dev_dbg(hsotg->dev, "## %s: urb->priv is NULL ##\n", __func__); return; } - urb->actual_length = dwc2_hcd_urb_get_actual_length(dwc2_urb); + urb->actual_length = dwc2_hcd_urb_get_actual_length(qtd->urb); if (dbg_urb(urb)) dev_vdbg(hsotg->dev, @@ -2121,18 +2122,17 @@ void dwc2_host_complete(struct dwc2_hsotg *hsotg, void *context, } if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { - urb->error_count = dwc2_hcd_urb_get_error_count(dwc2_urb); + urb->error_count = dwc2_hcd_urb_get_error_count(qtd->urb); for (i = 0; i < urb->number_of_packets; ++i) { urb->iso_frame_desc[i].actual_length = dwc2_hcd_urb_get_iso_desc_actual_length( - dwc2_urb, i); + qtd->urb, i); urb->iso_frame_desc[i].status = - dwc2_hcd_urb_get_iso_desc_status(dwc2_urb, i); + dwc2_hcd_urb_get_iso_desc_status(qtd->urb, i); } } urb->status = status; - urb->hcpriv = NULL; if (!status) { if ((urb->transfer_flags & URB_SHORT_NOT_OK) && urb->actual_length < urb->transfer_buffer_length) @@ -2149,7 +2149,10 @@ void dwc2_host_complete(struct dwc2_hsotg *hsotg, void *context, urb); } - kfree(dwc2_urb); + usb_hcd_unlink_urb_from_ep(dwc2_hsotg_to_hcd(hsotg), urb); + urb->hcpriv = NULL; + kfree(qtd->urb); + qtd->urb = NULL; spin_unlock(&hsotg->lock); usb_hcd_giveback_urb(dwc2_hsotg_to_hcd(hsotg), urb, status); @@ -2337,8 +2340,8 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, struct usb_host_endpoint *ep = urb->ep; struct dwc2_hcd_urb *dwc2_urb; int i; + int retval; int alloc_bandwidth = 0; - int retval = 0; u8 ep_type = 0; u32 tflags = 0; void *buf; @@ -2389,14 +2392,15 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, !(usb_pipein(urb->pipe)))); buf = urb->transfer_buffer; + if (hcd->self.uses_dma) { - /* - * Calculate virtual address from physical address, because - * some class driver may not fill transfer_buffer. - * In Buffer DMA mode virtual address is used, when handling - * non-DWORD aligned buffers. - */ - buf = bus_to_virt(urb->transfer_dma); + if (!buf && (urb->transfer_dma & 3)) { + dev_err(hsotg->dev, + "%s: unaligned transfer with no transfer_buffer", + __func__); + retval = -EINVAL; + goto fail1; + } } if (!(urb->transfer_flags & URB_NO_INTERRUPT)) @@ -2420,21 +2424,36 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, urb->iso_frame_desc[i].length); urb->hcpriv = dwc2_urb; - retval = dwc2_hcd_urb_enqueue(hsotg, dwc2_urb, &ep->hcpriv, - mem_flags); - if (retval) { - urb->hcpriv = NULL; - kfree(dwc2_urb); - } else { - if (alloc_bandwidth) { - spin_lock_irqsave(&hsotg->lock, flags); - dwc2_allocate_bus_bandwidth(hcd, - dwc2_hcd_get_ep_bandwidth(hsotg, ep), - urb); - spin_unlock_irqrestore(&hsotg->lock, flags); - } + + spin_lock_irqsave(&hsotg->lock, flags); + retval = usb_hcd_link_urb_to_ep(hcd, urb); + spin_unlock_irqrestore(&hsotg->lock, flags); + if (retval) + goto fail1; + + retval = dwc2_hcd_urb_enqueue(hsotg, dwc2_urb, &ep->hcpriv, mem_flags); + if (retval) + goto fail2; + + if (alloc_bandwidth) { + spin_lock_irqsave(&hsotg->lock, flags); + dwc2_allocate_bus_bandwidth(hcd, + dwc2_hcd_get_ep_bandwidth(hsotg, ep), + urb); + spin_unlock_irqrestore(&hsotg->lock, flags); } + return 0; + +fail2: + spin_lock_irqsave(&hsotg->lock, flags); + dwc2_urb->priv = NULL; + usb_hcd_unlink_urb_from_ep(hcd, urb); + spin_unlock_irqrestore(&hsotg->lock, flags); +fail1: + urb->hcpriv = NULL; + kfree(dwc2_urb); + return retval; } @@ -2445,7 +2464,7 @@ static int _dwc2_hcd_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) { struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); - int rc = 0; + int rc; unsigned long flags; dev_dbg(hsotg->dev, "DWC OTG HCD URB Dequeue\n"); @@ -2453,6 +2472,10 @@ static int _dwc2_hcd_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, spin_lock_irqsave(&hsotg->lock, flags); + rc = usb_hcd_check_unlink_urb(hcd, urb, status); + if (rc) + goto out; + if (!urb->hcpriv) { dev_dbg(hsotg->dev, "## urb->hcpriv is NULL ##\n"); goto out; @@ -2460,6 +2483,8 @@ static int _dwc2_hcd_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, rc = dwc2_hcd_urb_dequeue(hsotg, urb->hcpriv); + usb_hcd_unlink_urb_from_ep(hcd, urb); + kfree(urb->hcpriv); urb->hcpriv = NULL; @@ -2653,7 +2678,7 @@ static void dwc2_hcd_free(struct dwc2_hsotg *hsotg) writel(ahbcfg, hsotg->regs + GAHBCFG); writel(0, hsotg->regs + GINTMSK); - if (hsotg->snpsid >= DWC2_CORE_REV_3_00a) { + if (hsotg->hw_params.snpsid >= DWC2_CORE_REV_3_00a) { dctl = readl(hsotg->regs + DCTL); dctl |= DCTL_SFTDISCON; writel(dctl, hsotg->regs + DCTL); @@ -2690,7 +2715,7 @@ void dwc2_set_all_params(struct dwc2_core_params *params, int value) int i; for (i = 0; i < size; i++) - p[i] = -1; + p[i] = value; } EXPORT_SYMBOL_GPL(dwc2_set_all_params); @@ -2705,79 +2730,22 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, { struct usb_hcd *hcd; struct dwc2_host_chan *channel; - u32 snpsid, gusbcfg, hcfg; + u32 hcfg; int i, num_channels; - int retval = -ENOMEM; + int retval; dev_dbg(hsotg->dev, "DWC OTG HCD INIT\n"); - /* - * Attempt to ensure this device is really a DWC_otg Controller. - * Read and verify the GSNPSID register contents. The value should be - * 0x45f42xxx or 0x45f43xxx, which corresponds to either "OT2" or "OT3", - * as in "OTG version 2.xx" or "OTG version 3.xx". - */ - snpsid = readl(hsotg->regs + GSNPSID); - if ((snpsid & 0xfffff000) != 0x4f542000 && - (snpsid & 0xfffff000) != 0x4f543000) { - dev_err(hsotg->dev, "Bad value for GSNPSID: 0x%08x\n", snpsid); - retval = -ENODEV; - goto error1; - } + /* Detect config values from hardware */ + retval = dwc2_get_hwparams(hsotg); - /* - * Store the contents of the hardware configuration registers here for - * easy access later - */ - hsotg->hwcfg1 = readl(hsotg->regs + GHWCFG1); - hsotg->hwcfg2 = readl(hsotg->regs + GHWCFG2); - hsotg->hwcfg3 = readl(hsotg->regs + GHWCFG3); - hsotg->hwcfg4 = readl(hsotg->regs + GHWCFG4); - - dev_dbg(hsotg->dev, "hwcfg1=%08x\n", hsotg->hwcfg1); - dev_dbg(hsotg->dev, "hwcfg2=%08x\n", hsotg->hwcfg2); - dev_dbg(hsotg->dev, "hwcfg3=%08x\n", hsotg->hwcfg3); - dev_dbg(hsotg->dev, "hwcfg4=%08x\n", hsotg->hwcfg4); - - /* Force host mode to get HPTXFSIZ exact power on value */ - gusbcfg = readl(hsotg->regs + GUSBCFG); - gusbcfg |= GUSBCFG_FORCEHOSTMODE; - writel(gusbcfg, hsotg->regs + GUSBCFG); - usleep_range(100000, 150000); - - hsotg->hptxfsiz = readl(hsotg->regs + HPTXFSIZ); - dev_dbg(hsotg->dev, "hptxfsiz=%08x\n", hsotg->hptxfsiz); - gusbcfg = readl(hsotg->regs + GUSBCFG); - gusbcfg &= ~GUSBCFG_FORCEHOSTMODE; - writel(gusbcfg, hsotg->regs + GUSBCFG); - usleep_range(100000, 150000); + if (retval) + return retval; + + retval = -ENOMEM; hcfg = readl(hsotg->regs + HCFG); dev_dbg(hsotg->dev, "hcfg=%08x\n", hcfg); - dev_dbg(hsotg->dev, "op_mode=%0x\n", - hsotg->hwcfg2 >> GHWCFG2_OP_MODE_SHIFT & - GHWCFG2_OP_MODE_MASK >> GHWCFG2_OP_MODE_SHIFT); - dev_dbg(hsotg->dev, "arch=%0x\n", - hsotg->hwcfg2 >> GHWCFG2_ARCHITECTURE_SHIFT & - GHWCFG2_ARCHITECTURE_MASK >> GHWCFG2_ARCHITECTURE_SHIFT); - dev_dbg(hsotg->dev, "num_dev_ep=%d\n", - hsotg->hwcfg2 >> GHWCFG2_NUM_DEV_EP_SHIFT & - GHWCFG2_NUM_DEV_EP_MASK >> GHWCFG2_NUM_DEV_EP_SHIFT); - dev_dbg(hsotg->dev, "max_host_chan=%d\n", - hsotg->hwcfg2 >> GHWCFG2_NUM_HOST_CHAN_SHIFT & - GHWCFG2_NUM_HOST_CHAN_MASK >> GHWCFG2_NUM_HOST_CHAN_SHIFT); - dev_dbg(hsotg->dev, "nonperio_tx_q_depth=0x%0x\n", - hsotg->hwcfg2 >> GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT & - GHWCFG2_NONPERIO_TX_Q_DEPTH_MASK >> - GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT); - dev_dbg(hsotg->dev, "host_perio_tx_q_depth=0x%0x\n", - hsotg->hwcfg2 >> GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT & - GHWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK >> - GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT); - dev_dbg(hsotg->dev, "dev_token_q_depth=0x%0x\n", - hsotg->hwcfg2 >> GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT & - GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK >> - GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT); #ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS hsotg->frame_num_array = kzalloc(sizeof(*hsotg->frame_num_array) * @@ -2801,22 +2769,30 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, /* Validate parameter values */ dwc2_set_parameters(hsotg, params); + /* Check if the bus driver or platform code has setup a dma_mask */ + if (hsotg->core_params->dma_enable > 0 && + hsotg->dev->dma_mask == NULL) { + dev_warn(hsotg->dev, + "dma_mask not set, disabling DMA\n"); + hsotg->core_params->dma_enable = 0; + hsotg->core_params->dma_desc_enable = 0; + } + /* Set device flags indicating whether the HCD supports DMA */ if (hsotg->core_params->dma_enable > 0) { if (dma_set_mask(hsotg->dev, DMA_BIT_MASK(32)) < 0) dev_warn(hsotg->dev, "can't set DMA mask\n"); - if (dma_set_coherent_mask(hsotg->dev, DMA_BIT_MASK(31)) < 0) - dev_warn(hsotg->dev, - "can't enable workaround for >2GB RAM\n"); - } else { - dma_set_mask(hsotg->dev, 0); - dma_set_coherent_mask(hsotg->dev, 0); + if (dma_set_coherent_mask(hsotg->dev, DMA_BIT_MASK(32)) < 0) + dev_warn(hsotg->dev, "can't set coherent DMA mask\n"); } hcd = usb_create_hcd(&dwc2_hc_driver, hsotg->dev, dev_name(hsotg->dev)); if (!hcd) goto error1; + if (hsotg->core_params->dma_enable <= 0) + hcd->self.uses_dma = 0; + hcd->has_tt = 1; spin_lock_init(&hsotg->lock); @@ -2843,11 +2819,6 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, } INIT_WORK(&hsotg->wf_otg, dwc2_conn_id_status_change); - hsotg->snpsid = readl(hsotg->regs + GSNPSID); - dev_dbg(hsotg->dev, "Core Release: %1x.%1x%1x%1x\n", - hsotg->snpsid >> 12 & 0xf, hsotg->snpsid >> 8 & 0xf, - hsotg->snpsid >> 4 & 0xf, hsotg->snpsid & 0xf); - setup_timer(&hsotg->wkp_timer, dwc2_wakeup_detected, (unsigned long)hsotg); @@ -2922,8 +2893,6 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, if (retval < 0) goto error3; - dwc2_dump_global_registers(hsotg); - dwc2_dump_host_registers(hsotg); dwc2_hcd_dump_state(hsotg); dwc2_enable_global_interrupts(hsotg); |