From 91b0b7c961b5f50fd10bf949b4ed8b87280042a3 Mon Sep 17 00:00:00 2001 From: Alexander Reinert Date: Fri, 15 Dec 2017 10:43:49 +0100 Subject: [PATCH] Adde kernel patch for Rockchip mainline inspired by https://github.com/TinkerBoard/debian_kernel/commit/cfe2329be3af16b324a2e338ad29484f36e753ab#diff-3a905b19fc3744269a82aeec54a7e405 to avoid 100% cpu usage when using two usb uart devices like the FT232 --- .../1008-dwc2-avoid_nak_for_csplit.patch | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 patch/kernel/rockchip-next/1008-dwc2-avoid_nak_for_csplit.patch diff --git a/patch/kernel/rockchip-next/1008-dwc2-avoid_nak_for_csplit.patch b/patch/kernel/rockchip-next/1008-dwc2-avoid_nak_for_csplit.patch new file mode 100644 index 0000000000..571f734366 --- /dev/null +++ b/patch/kernel/rockchip-next/1008-dwc2-avoid_nak_for_csplit.patch @@ -0,0 +1,83 @@ +diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c +index 7b6eb0ad513b..96b6935dc0d7 100644 +--- a/drivers/usb/dwc2/hcd.c ++++ b/drivers/usb/dwc2/hcd.c +@@ -2748,6 +2748,8 @@ static int dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) + chan->xfer_len = urb->length - urb->actual_length; + chan->xfer_count = 0; + ++ chan->csplit_nak = 0; ++ + /* Set the split attributes if required */ + if (qh->do_split) + dwc2_hc_init_split(hsotg, chan, qtd, urb); +diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h +index 78e9e01051b5..e54f1351225b 100644 +--- a/drivers/usb/dwc2/hcd.h ++++ b/drivers/usb/dwc2/hcd.h +@@ -143,6 +143,7 @@ struct dwc2_host_chan { + u8 halt_pending; + u8 do_split; + u8 complete_split; ++ u8 csplit_nak; + u8 hub_addr; + u8 hub_port; + u8 xact_pos; +diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c +index 916d991b96b8..551cfacd2252 100644 +--- a/drivers/usb/dwc2/hcd_intr.c ++++ b/drivers/usb/dwc2/hcd_intr.c +@@ -691,6 +691,7 @@ static void dwc2_release_channel(struct dwc2_hsotg *hsotg, + enum dwc2_transaction_type tr_type; + u32 haintmsk; + int free_qtd = 0; ++ int continue_trans = 1; + + if (dbg_hc(chan)) + dev_vdbg(hsotg->dev, " %s: channel %d, halt_status %d\n", +@@ -719,6 +720,7 @@ static void dwc2_release_channel(struct dwc2_hsotg *hsotg, + * deactivated. Don't want to do anything except release the + * host channel and try to queue more transfers. + */ ++ continue_trans = 0; + goto cleanup; + case DWC2_HC_XFER_PERIODIC_INCOMPLETE: + dev_vdbg(hsotg->dev, " Complete URB with I/O error\n"); +@@ -730,6 +732,11 @@ static void dwc2_release_channel(struct dwc2_hsotg *hsotg, + break; + } + ++ if (chan->csplit_nak) { ++ continue_trans = 0; ++ chan->csplit_nak = 0; ++ } ++ + dwc2_deactivate_qh(hsotg, chan->qh, free_qtd); + + cleanup: +@@ -767,9 +774,11 @@ static void dwc2_release_channel(struct dwc2_hsotg *hsotg, + dwc2_writel(haintmsk, hsotg->regs + HAINTMSK); + + /* Try to queue more transfers now that there's a free channel */ +- tr_type = dwc2_hcd_select_transactions(hsotg); +- if (tr_type != DWC2_TRANSACTION_NONE) +- dwc2_hcd_queue_transactions(hsotg, tr_type); ++ if (continue_trans) { ++ tr_type = dwc2_hcd_select_transactions(hsotg); ++ if (tr_type != DWC2_TRANSACTION_NONE) ++ dwc2_hcd_queue_transactions(hsotg, tr_type); ++ } + } + + /* +@@ -1205,6 +1214,7 @@ static void dwc2_hc_nak_intr(struct dwc2_hsotg *hsotg, + if (chan->do_split) { + if (chan->complete_split) + qtd->error_count = 0; ++ chan->csplit_nak = 1; + qtd->complete_split = 0; + dwc2_halt_channel(hsotg, chan, qtd, DWC2_HC_XFER_NAK); + goto handle_nak_done; +-- +2.11.0 +