Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: dwc3: debugfs: Properly print/set link state for HS

Highspeed device and below has different state names than superspeed and
higher. Add proper checks and printouts of link states for highspeed and
below.

Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>

authored by

Thinh Nguyen and committed by
Felipe Balbi
0d36dede 62ba09d6

+46 -2
+29
drivers/usb/dwc3/debug.h
··· 117 117 } 118 118 119 119 /** 120 + * dwc3_gadget_hs_link_string - returns highspeed and below link name 121 + * @link_state: link state code 122 + */ 123 + static inline const char * 124 + dwc3_gadget_hs_link_string(enum dwc3_link_state link_state) 125 + { 126 + switch (link_state) { 127 + case DWC3_LINK_STATE_U0: 128 + return "On"; 129 + case DWC3_LINK_STATE_U2: 130 + return "Sleep"; 131 + case DWC3_LINK_STATE_U3: 132 + return "Suspend"; 133 + case DWC3_LINK_STATE_SS_DIS: 134 + return "Disconnected"; 135 + case DWC3_LINK_STATE_RX_DET: 136 + return "Early Suspend"; 137 + case DWC3_LINK_STATE_RECOV: 138 + return "Recovery"; 139 + case DWC3_LINK_STATE_RESET: 140 + return "Reset"; 141 + case DWC3_LINK_STATE_RESUME: 142 + return "Resume"; 143 + default: 144 + return "UNKNOWN link state\n"; 145 + } 146 + } 147 + 148 + /** 120 149 * dwc3_trb_type_string - returns TRB type as a string 121 150 * @type: the type of the TRB 122 151 */
+17 -2
drivers/usb/dwc3/debugfs.c
··· 539 539 unsigned long flags; 540 540 enum dwc3_link_state state; 541 541 u32 reg; 542 + u8 speed; 542 543 543 544 spin_lock_irqsave(&dwc->lock, flags); 544 545 reg = dwc3_readl(dwc->regs, DWC3_DSTS); 545 546 state = DWC3_DSTS_USBLNKST(reg); 546 - spin_unlock_irqrestore(&dwc->lock, flags); 547 + speed = reg & DWC3_DSTS_CONNECTSPD; 547 548 548 - seq_printf(s, "%s\n", dwc3_gadget_link_string(state)); 549 + seq_printf(s, "%s\n", (speed >= DWC3_DSTS_SUPERSPEED) ? 550 + dwc3_gadget_link_string(state) : 551 + dwc3_gadget_hs_link_string(state)); 552 + spin_unlock_irqrestore(&dwc->lock, flags); 549 553 550 554 return 0; 551 555 } ··· 567 563 unsigned long flags; 568 564 enum dwc3_link_state state = 0; 569 565 char buf[32]; 566 + u32 reg; 567 + u8 speed; 570 568 571 569 if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) 572 570 return -EFAULT; ··· 589 583 return -EINVAL; 590 584 591 585 spin_lock_irqsave(&dwc->lock, flags); 586 + reg = dwc3_readl(dwc->regs, DWC3_DSTS); 587 + speed = reg & DWC3_DSTS_CONNECTSPD; 588 + 589 + if (speed < DWC3_DSTS_SUPERSPEED && 590 + state != DWC3_LINK_STATE_RECOV) { 591 + spin_unlock_irqrestore(&dwc->lock, flags); 592 + return -EINVAL; 593 + } 594 + 592 595 dwc3_gadget_set_link_state(dwc, state); 593 596 spin_unlock_irqrestore(&dwc->lock, flags); 594 597