Loading drivers/usb/dwc3/core.h +14 −0 Original line number Diff line number Diff line Loading @@ -717,6 +717,8 @@ struct dwc3_scratchpad_array { #define DWC3_CORE_PM_RESUME_EVENT 6 #define DWC3_CONTROLLER_POST_INITIALIZATION_EVENT 7 #define DWC3_CONTROLLER_CONNDONE_EVENT 8 #define MAX_INTR_STATS 10 /** * struct dwc3 - representation of our controller * @ctrl_req: usb control request which is used for ep0 Loading Loading @@ -773,6 +775,11 @@ struct dwc3_scratchpad_array { * @usb3_u1u2_disable: if true, disable U1U2 low power modes in Superspeed mode. * @hird_thresh: value to configure in DCTL[HIRD_Thresh] * @in_lpm: if 1, indicates that the controller is in low power mode (no clocks) * @irq: irq number * @bh: tasklet which handles the interrupt * @bh_completion_time: time taken for taklet completion * @bh_handled_evt_cnt: no. of events handled by tasklet per interrupt * @bh_dbg_index: index for capturing bh_completion_time and bh_handled_evt_cnt */ struct dwc3 { struct usb_ctrlrequest *ctrl_req; Loading Loading @@ -886,6 +893,13 @@ struct dwc3 { u8 hird_thresh; atomic_t in_lpm; struct dwc3_gadget_events dbg_gadget_events; /* offload IRQ handling to tasklet */ int irq; struct tasklet_struct bh; unsigned bh_completion_time[MAX_INTR_STATS]; unsigned bh_handled_evt_cnt[MAX_INTR_STATS]; unsigned bh_dbg_index; }; /* -------------------------------------------------------------------------- */ Loading drivers/usb/dwc3/debugfs.c +9 −0 Original line number Diff line number Diff line Loading @@ -1174,6 +1174,15 @@ static int dwc3_gadget_int_events_show(struct seq_file *s, void *unused) dbg_gadget_events->cmdcmplt); seq_printf(s, "unknown_event:%u\n", dbg_gadget_events->unknown_event); seq_printf(s, "\n\t== Last %d interrupts stats ==\t\n", MAX_INTR_STATS); seq_puts(s, "events count:\t"); for (i = 0; i < MAX_INTR_STATS; i++) seq_printf(s, "%d\t", dwc->bh_handled_evt_cnt[i]); seq_puts(s, "\ntasklet time:\t"); for (i = 0; i < MAX_INTR_STATS; i++) seq_printf(s, "%d\t", dwc->bh_completion_time[i]); seq_puts(s, "\n(usec)\n"); spin_unlock_irqrestore(&dwc->lock, flags); return 0; } Loading drivers/usb/dwc3/gadget.c +34 −7 Original line number Diff line number Diff line Loading @@ -2131,8 +2131,8 @@ static int dwc3_gadget_start(struct usb_gadget *g, pm_runtime_get_sync(dwc->dev); irq = platform_get_irq(to_platform_device(dwc->dev), 0); ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt, IRQF_SHARED | IRQF_ONESHOT, "dwc3", dwc); dwc->irq = irq; ret = request_irq(irq, dwc3_interrupt, IRQF_SHARED, "dwc3", dwc); if (ret) { dev_err(dwc->dev, "failed to request irq #%d --> %d\n", irq, ret); Loading Loading @@ -2185,9 +2185,12 @@ static int dwc3_gadget_stop(struct usb_gadget *g, unsigned long flags; int irq; dwc3_gadget_disable_irq(dwc); tasklet_kill(&dwc->bh); spin_lock_irqsave(&dwc->lock, flags); dwc3_gadget_disable_irq(dwc); __dwc3_gadget_ep_disable(dwc->eps[0]); __dwc3_gadget_ep_disable(dwc->eps[1]); Loading Loading @@ -3316,6 +3319,10 @@ static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc) unsigned long flags; irqreturn_t ret = IRQ_NONE; int i; unsigned temp_cnt = 0, temp_time; ktime_t start_time; start_time = ktime_get(); spin_lock_irqsave(&dwc->lock, flags); Loading @@ -3325,6 +3332,7 @@ static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc) evt = dwc->ev_buffs[i]; left = evt->count; temp_cnt = temp_cnt + evt->count; if (!(evt->flags & DWC3_EVENT_PENDING)) continue; Loading Loading @@ -3358,6 +3366,12 @@ static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc) spin_unlock_irqrestore(&dwc->lock, flags); temp_time = ktime_to_us(ktime_sub(ktime_get(), start_time)); temp_cnt = temp_cnt / 4; dwc->bh_handled_evt_cnt[dwc->bh_dbg_index] = temp_cnt; dwc->bh_completion_time[dwc->bh_dbg_index] = temp_time; dwc->bh_dbg_index = (dwc->bh_dbg_index + 1) % 10; pm_runtime_put(dwc->dev); return ret; } Loading @@ -3380,6 +3394,15 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf) return IRQ_WAKE_THREAD; } static void dwc3_interrupt_bh(unsigned long param) { struct dwc3 *dwc = (struct dwc3 *) param; pm_runtime_get(dwc->dev); dwc3_thread_interrupt(dwc->irq, dwc); enable_irq(dwc->irq); } static irqreturn_t dwc3_interrupt(int irq, void *_dwc) { struct dwc3 *dwc = _dwc; Loading @@ -3398,10 +3421,11 @@ static irqreturn_t dwc3_interrupt(int irq, void *_dwc) spin_unlock(&dwc->lock); if (ret == IRQ_WAKE_THREAD) pm_runtime_get(dwc->dev); return ret; if (ret == IRQ_WAKE_THREAD) { disable_irq_nosync(irq); tasklet_schedule(&dwc->bh); } return IRQ_HANDLED; } /** Loading Loading @@ -3457,6 +3481,9 @@ int dwc3_gadget_init(struct dwc3 *dwc) goto err3; } dwc->bh.func = dwc3_interrupt_bh; dwc->bh.data = (unsigned long)dwc; dwc->gadget.ops = &dwc3_gadget_ops; if (dwc->maximum_speed == USB_SPEED_SUPER) dwc->gadget.max_speed = USB_SPEED_SUPER; Loading Loading
drivers/usb/dwc3/core.h +14 −0 Original line number Diff line number Diff line Loading @@ -717,6 +717,8 @@ struct dwc3_scratchpad_array { #define DWC3_CORE_PM_RESUME_EVENT 6 #define DWC3_CONTROLLER_POST_INITIALIZATION_EVENT 7 #define DWC3_CONTROLLER_CONNDONE_EVENT 8 #define MAX_INTR_STATS 10 /** * struct dwc3 - representation of our controller * @ctrl_req: usb control request which is used for ep0 Loading Loading @@ -773,6 +775,11 @@ struct dwc3_scratchpad_array { * @usb3_u1u2_disable: if true, disable U1U2 low power modes in Superspeed mode. * @hird_thresh: value to configure in DCTL[HIRD_Thresh] * @in_lpm: if 1, indicates that the controller is in low power mode (no clocks) * @irq: irq number * @bh: tasklet which handles the interrupt * @bh_completion_time: time taken for taklet completion * @bh_handled_evt_cnt: no. of events handled by tasklet per interrupt * @bh_dbg_index: index for capturing bh_completion_time and bh_handled_evt_cnt */ struct dwc3 { struct usb_ctrlrequest *ctrl_req; Loading Loading @@ -886,6 +893,13 @@ struct dwc3 { u8 hird_thresh; atomic_t in_lpm; struct dwc3_gadget_events dbg_gadget_events; /* offload IRQ handling to tasklet */ int irq; struct tasklet_struct bh; unsigned bh_completion_time[MAX_INTR_STATS]; unsigned bh_handled_evt_cnt[MAX_INTR_STATS]; unsigned bh_dbg_index; }; /* -------------------------------------------------------------------------- */ Loading
drivers/usb/dwc3/debugfs.c +9 −0 Original line number Diff line number Diff line Loading @@ -1174,6 +1174,15 @@ static int dwc3_gadget_int_events_show(struct seq_file *s, void *unused) dbg_gadget_events->cmdcmplt); seq_printf(s, "unknown_event:%u\n", dbg_gadget_events->unknown_event); seq_printf(s, "\n\t== Last %d interrupts stats ==\t\n", MAX_INTR_STATS); seq_puts(s, "events count:\t"); for (i = 0; i < MAX_INTR_STATS; i++) seq_printf(s, "%d\t", dwc->bh_handled_evt_cnt[i]); seq_puts(s, "\ntasklet time:\t"); for (i = 0; i < MAX_INTR_STATS; i++) seq_printf(s, "%d\t", dwc->bh_completion_time[i]); seq_puts(s, "\n(usec)\n"); spin_unlock_irqrestore(&dwc->lock, flags); return 0; } Loading
drivers/usb/dwc3/gadget.c +34 −7 Original line number Diff line number Diff line Loading @@ -2131,8 +2131,8 @@ static int dwc3_gadget_start(struct usb_gadget *g, pm_runtime_get_sync(dwc->dev); irq = platform_get_irq(to_platform_device(dwc->dev), 0); ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt, IRQF_SHARED | IRQF_ONESHOT, "dwc3", dwc); dwc->irq = irq; ret = request_irq(irq, dwc3_interrupt, IRQF_SHARED, "dwc3", dwc); if (ret) { dev_err(dwc->dev, "failed to request irq #%d --> %d\n", irq, ret); Loading Loading @@ -2185,9 +2185,12 @@ static int dwc3_gadget_stop(struct usb_gadget *g, unsigned long flags; int irq; dwc3_gadget_disable_irq(dwc); tasklet_kill(&dwc->bh); spin_lock_irqsave(&dwc->lock, flags); dwc3_gadget_disable_irq(dwc); __dwc3_gadget_ep_disable(dwc->eps[0]); __dwc3_gadget_ep_disable(dwc->eps[1]); Loading Loading @@ -3316,6 +3319,10 @@ static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc) unsigned long flags; irqreturn_t ret = IRQ_NONE; int i; unsigned temp_cnt = 0, temp_time; ktime_t start_time; start_time = ktime_get(); spin_lock_irqsave(&dwc->lock, flags); Loading @@ -3325,6 +3332,7 @@ static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc) evt = dwc->ev_buffs[i]; left = evt->count; temp_cnt = temp_cnt + evt->count; if (!(evt->flags & DWC3_EVENT_PENDING)) continue; Loading Loading @@ -3358,6 +3366,12 @@ static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc) spin_unlock_irqrestore(&dwc->lock, flags); temp_time = ktime_to_us(ktime_sub(ktime_get(), start_time)); temp_cnt = temp_cnt / 4; dwc->bh_handled_evt_cnt[dwc->bh_dbg_index] = temp_cnt; dwc->bh_completion_time[dwc->bh_dbg_index] = temp_time; dwc->bh_dbg_index = (dwc->bh_dbg_index + 1) % 10; pm_runtime_put(dwc->dev); return ret; } Loading @@ -3380,6 +3394,15 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf) return IRQ_WAKE_THREAD; } static void dwc3_interrupt_bh(unsigned long param) { struct dwc3 *dwc = (struct dwc3 *) param; pm_runtime_get(dwc->dev); dwc3_thread_interrupt(dwc->irq, dwc); enable_irq(dwc->irq); } static irqreturn_t dwc3_interrupt(int irq, void *_dwc) { struct dwc3 *dwc = _dwc; Loading @@ -3398,10 +3421,11 @@ static irqreturn_t dwc3_interrupt(int irq, void *_dwc) spin_unlock(&dwc->lock); if (ret == IRQ_WAKE_THREAD) pm_runtime_get(dwc->dev); return ret; if (ret == IRQ_WAKE_THREAD) { disable_irq_nosync(irq); tasklet_schedule(&dwc->bh); } return IRQ_HANDLED; } /** Loading Loading @@ -3457,6 +3481,9 @@ int dwc3_gadget_init(struct dwc3 *dwc) goto err3; } dwc->bh.func = dwc3_interrupt_bh; dwc->bh.data = (unsigned long)dwc; dwc->gadget.ops = &dwc3_gadget_ops; if (dwc->maximum_speed == USB_SPEED_SUPER) dwc->gadget.max_speed = USB_SPEED_SUPER; Loading