dwc_otg: add module parameter int_ep_interval_min
authorP33M <p33m@github.com>
Mon, 12 Jun 2017 15:10:03 +0000 (16:10 +0100)
committerRaspbian kernel package updater <root@raspbian.org>
Sat, 31 Mar 2018 14:54:19 +0000 (15:54 +0100)
Add a module parameter (defaulting to ignored) that clamps the polling rate
of high-speed Interrupt endpoints to a minimum microframe interval.

The parameter is modifiable at runtime as it is used when activating new
endpoints (such as on device connect).

drivers/usb/host/dwc_otg/dwc_otg_driver.c
drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c

index cb060a7179a3eec791506ed2779b553cad9841b0..95943e07528276b26b51ea2d57a1f433f280aaef 100644 (file)
@@ -249,6 +249,7 @@ uint16_t nak_holdoff = 8;
 
 unsigned short fiq_fsm_mask = 0x0F;
 
+unsigned short int_ep_interval_min = 0;
 /**
  * This function shows the Driver Version.
  */
@@ -1398,7 +1399,10 @@ MODULE_PARM_DESC(fiq_fsm_mask, "Bitmask of transactions to perform in the FIQ.\n
                                        "Bit 1 : Periodic split transactions\n"
                                        "Bit 2 : High-speed multi-transfer isochronous\n"
                                        "All other bits should be set 0.");
-
+module_param(int_ep_interval_min, ushort, 0644);
+MODULE_PARM_DESC(int_ep_interval_min, "Clamp high-speed Interrupt endpoints to a minimum polling interval.\n"
+                                       "0..1 = Use endpoint default\n"
+                                       "2..n = Minimum interval n microframes. Use powers of 2.\n");
 
 /** @page "Module Parameters"
  *
index 4b1dd9de99e9e08b2e006fb5f8a7ef92f20c2553..fe8e8f841f03660c2ad49ab8e66193bec62558d3 100644 (file)
@@ -43,6 +43,7 @@
 #include "dwc_otg_regs.h"
 
 extern bool microframe_schedule;
+extern unsigned short int_ep_interval_min;
 
 /**
  * Free each QTD in the QH's QTD-list then free the QH.  QH should already be
@@ -218,21 +219,19 @@ void qh_init(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh, dwc_otg_hcd_urb_t * urb)
                                                    SCHEDULE_SLOP);
                qh->interval = urb->interval;
 
-#if 0
-               /* Increase interrupt polling rate for debugging. */
-               if (qh->ep_type == UE_INTERRUPT) {
-                       qh->interval = 8;
-               }
-#endif
                hprt.d32 = DWC_READ_REG32(hcd->core_if->host_if->hprt0);
-               if ((hprt.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED) &&
-                   ((dev_speed == USB_SPEED_LOW) ||
-                    (dev_speed == USB_SPEED_FULL))) {
-                       qh->interval *= 8;
-                       qh->sched_frame |= 0x7;
-                       qh->start_split_frame = qh->sched_frame;
+               if (hprt.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED) {
+                       if (dev_speed == USB_SPEED_LOW ||
+                                       dev_speed == USB_SPEED_FULL) {
+                               qh->interval *= 8;
+                               qh->sched_frame |= 0x7;
+                               qh->start_split_frame = qh->sched_frame;
+                       } else if (int_ep_interval_min >= 2 &&
+                                       qh->interval < int_ep_interval_min &&
+                                       qh->ep_type == UE_INTERRUPT) {
+                               qh->interval = int_ep_interval_min;
+                       }
                }
-
        }
 
        DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD QH Initialized\n");