mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
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:
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user