usb: dwc_otg: fix some issues of dwc_otg_310

1.disable host interrupts when id changed so that no more host
  interrupt will happen after otg disconnect
2.hold hcd->lock in hcd_reinit function to protect qtd list
3.recheck USB_STATUS_ID in vbus detect thread make sure it indeed
  in device mode
4.fix some null pointer dereference
5.otg disconnect threshold set to 575mv in case of disconnect
  interrupt lose
This commit is contained in:
lyz
2015-01-15 13:13:03 +08:00
parent 491715787b
commit 2ac8753a2a
6 changed files with 16 additions and 7 deletions

View File

@@ -389,6 +389,7 @@ int32_t dwc_otg_handle_conn_id_status_change_intr(dwc_otg_core_if_t *core_if)
gintmsk_data_t gintmsk = {.d32 = 0 };
gintsts_data_t gintsts = {.d32 = 0 };
dwc_otg_disable_host_interrupts(core_if);
if (core_if->usb_mode != USB_MODE_NORMAL)
goto out;

View File

@@ -179,6 +179,8 @@ static void kill_urbs_in_qh_list(dwc_otg_hcd_t *hcd, dwc_list_link_t *qh_list)
hcd->fops->complete(hcd, qtd->urb->priv,
qtd->urb, -DWC_E_SHUTDOWN);
dwc_otg_hcd_qtd_remove_and_free(hcd, qtd, qh);
} else {
return;
}
}
@@ -953,6 +955,7 @@ static void dwc_otg_hcd_reinit(dwc_otg_hcd_t *hcd)
int i;
dwc_hc_t *channel;
dwc_hc_t *channel_tmp;
dwc_irqflags_t flags;
hcd->flags.d32 = 0;
@@ -960,6 +963,7 @@ static void dwc_otg_hcd_reinit(dwc_otg_hcd_t *hcd)
hcd->non_periodic_channels = 0;
hcd->periodic_channels = 0;
DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
/*
* Put all channels in the free channel list and clean up channel
* states.
@@ -976,7 +980,7 @@ static void dwc_otg_hcd_reinit(dwc_otg_hcd_t *hcd)
hc_list_entry);
dwc_otg_hc_cleanup(hcd->core_if, channel);
}
DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
/* Initialize the DWC core for host mode operation. */
dwc_otg_core_host_init(hcd->core_if);
@@ -1334,6 +1338,8 @@ static int queue_transaction(dwc_otg_hcd_t *hcd,
hc->qh->ping_state = 0;
}
} else if (!hc->xfer_started) {
if (!hc || !(hc->qh))
return -ENODEV;
dwc_otg_hc_start_transfer(hcd->core_if, hc);
hc->qh->ping_state = 0;
}

View File

@@ -239,6 +239,8 @@ static int _complete(dwc_otg_hcd_t *hcd, void *urb_handle,
dwc_otg_hcd_urb_t *dwc_otg_urb, int32_t status)
{
struct urb *urb = (struct urb *)urb_handle;
if (!urb)
return 0;
#ifdef DEBUG
if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
DWC_PRINTF("%s: urb %p, device %d, ep %d %s, status=%d\n",

View File

@@ -58,8 +58,7 @@ void dwc_otg_hcd_qh_free(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh)
/* Free each QTD in the QTD list */
DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
DWC_CIRCLEQ_FOREACH_SAFE(qtd, qtd_tmp, &qh->qtd_list, qtd_list_entry) {
DWC_CIRCLEQ_REMOVE(&qh->qtd_list, qtd, qtd_list_entry);
dwc_otg_hcd_qtd_free(qtd);
dwc_otg_hcd_qtd_remove_and_free(hcd, qtd, qh);
}
if (hcd->core_if->dma_desc_enable) {

View File

@@ -1605,7 +1605,8 @@ static void dwc_otg_pcd_check_vbus_work(struct work_struct *work)
struct dwc_otg_device *otg_dev = _pcd->otg_dev;
struct dwc_otg_platform_data *pldata = otg_dev->pldata;
if (pldata->get_status(USB_STATUS_BVABLID)) {
if (pldata->get_status(USB_STATUS_BVABLID) &&
pldata->get_status(USB_STATUS_ID)) {
/* if usb not connect before ,then start connect */
if (_pcd->vbus_status == USB_BC_TYPE_DISCNT) {
printk("***************vbus detect*****************\n");

View File

@@ -8,10 +8,10 @@ static void usb20otg_hw_init(void)
{
/* Turn off differential receiver in suspend mode */
writel(UOC_HIWORD_UPDATE(0, 1, 2),
RK_GRF_VIRT + RK312X_GRF_USBPHY0_CON6);
RK_GRF_VIRT + RK312X_GRF_USBPHY0_CON6);
/* Set disconnect detection trigger point to 600mv */
writel(UOC_HIWORD_UPDATE(1, 0xf, 11),
RK_GRF_VIRT + RK312X_GRF_USBPHY0_CON7);
writel(UOC_HIWORD_UPDATE(0, 0xf, 11),
RK_GRF_VIRT + RK312X_GRF_USBPHY0_CON7);
/* other haredware init,include:
* DRV_VBUS GPIO init */
if (gpio_is_valid(control_usb->otg_gpios->gpio)) {