dwc_otg_core_if_t *core_if = otg_dev->core_if;
struct dwc_otg_platform_data *pldata = otg_dev->pldata;
dctl_data_t dctl = {.d32 = 0 };
+ dwc_otg_pcd_t *pcd = core_if->otg_dev->pcd;
DWC_PRINTF("%s: disconnect USB %s mode\n", __func__,
dwc_otg_is_host_mode(core_if) ? "host" : "device");
- if (pldata->dwc_otg_uart_mode != NULL)
- pldata->dwc_otg_uart_mode(pldata, PHY_USB_MODE);
- if (pldata->phy_suspend != NULL)
- pldata->phy_suspend(pldata, USB_PHY_ENABLED);
if (dwc_otg_is_host_mode(core_if)) {
if (core_if->hcd_cb && core_if->hcd_cb->stop)
core_if->hcd_cb->stop(core_if->hcd_cb_p);
} else {
+ cancel_delayed_work_sync(&pcd->check_vbus_work);
/* soft disconnect */
dctl.d32 =
DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
/* Clear any pending interrupts */
DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
+ if (pldata->dwc_otg_uart_mode != NULL)
+ pldata->dwc_otg_uart_mode(pldata, PHY_USB_MODE);
+ if (pldata->phy_suspend != NULL)
+ pldata->phy_suspend(pldata, USB_PHY_ENABLED);
+
}
/**
qh = DWC_LIST_ENTRY(qh_item, dwc_otg_qh_t, qh_list_entry);
DWC_CIRCLEQ_FOREACH_SAFE(qtd, qtd_tmp,
&qh->qtd_list, qtd_list_entry) {
+ if (DWC_CIRCLEQ_EMPTY(&qh->qtd_list))
+ return;
qtd = DWC_CIRCLEQ_FIRST(&qh->qtd_list);
if (qtd->urb != NULL) {
hcd->fops->complete(hcd, qtd->urb->priv,
pldata = hcd->core_if->otg_dev->pldata;
DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD STOP\n");
+ /* Turn off all host-specific interrupts. */
+ dwc_otg_disable_host_interrupts(hcd->core_if);
+
/*
* The root hub should be disconnected before this function is called.
* The disconnect will clear the QTD lists (via ..._hcd_urb_dequeue)
hcd->flags.b.port_connect_status_change = 1;
hcd->flags.b.port_connect_status = 0;
- /* Turn off all host-specific interrupts. */
- dwc_otg_disable_host_interrupts(hcd->core_if);
-
/* Turn off the vbus power */
DWC_PRINTF("PortPower off\n");
hprt0.b.prtpwr = 0;
dwc_hc_t *hc, uint16_t fifo_dwords_avail)
{
int retval;
-
+ if (!hc || !(hc->qh))
+ return -ENODEV;
if (hcd->core_if->dma_enable) {
if (hcd->core_if->dma_desc_enable) {
if (!hc->xfer_started
hc = dwc_otg_hcd->hc_ptr_array[num];
hc_regs = dwc_otg_hcd->core_if->host_if->hc_regs[num];
+ if (DWC_CIRCLEQ_EMPTY(&hc->qh->qtd_list)) {
+ /* All transfer had been killed, clear panding interrupts */
+ hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
+ DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
+ return retval;
+ }
qtd = DWC_CIRCLEQ_FIRST(&hc->qh->qtd_list);
hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);