Commit 0d36dede authored by Thinh Nguyen's avatar Thinh Nguyen Committed by Felipe Balbi
Browse files

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: default avatarThinh Nguyen <thinhn@synopsys.com>
Signed-off-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
parent 62ba09d6
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -116,6 +116,35 @@ dwc3_gadget_link_string(enum dwc3_link_state link_state)
	}
}

/**
 * dwc3_gadget_hs_link_string - returns highspeed and below link name
 * @link_state: link state code
 */
static inline const char *
dwc3_gadget_hs_link_string(enum dwc3_link_state link_state)
{
	switch (link_state) {
	case DWC3_LINK_STATE_U0:
		return "On";
	case DWC3_LINK_STATE_U2:
		return "Sleep";
	case DWC3_LINK_STATE_U3:
		return "Suspend";
	case DWC3_LINK_STATE_SS_DIS:
		return "Disconnected";
	case DWC3_LINK_STATE_RX_DET:
		return "Early Suspend";
	case DWC3_LINK_STATE_RECOV:
		return "Recovery";
	case DWC3_LINK_STATE_RESET:
		return "Reset";
	case DWC3_LINK_STATE_RESUME:
		return "Resume";
	default:
		return "UNKNOWN link state\n";
	}
}

/**
 * dwc3_trb_type_string - returns TRB type as a string
 * @type: the type of the TRB
+17 −2
Original line number Diff line number Diff line
@@ -539,13 +539,17 @@ static int dwc3_link_state_show(struct seq_file *s, void *unused)
	unsigned long		flags;
	enum dwc3_link_state	state;
	u32			reg;
	u8			speed;

	spin_lock_irqsave(&dwc->lock, flags);
	reg = dwc3_readl(dwc->regs, DWC3_DSTS);
	state = DWC3_DSTS_USBLNKST(reg);
	spin_unlock_irqrestore(&dwc->lock, flags);
	speed = reg & DWC3_DSTS_CONNECTSPD;

	seq_printf(s, "%s\n", dwc3_gadget_link_string(state));
	seq_printf(s, "%s\n", (speed >= DWC3_DSTS_SUPERSPEED) ?
		   dwc3_gadget_link_string(state) :
		   dwc3_gadget_hs_link_string(state));
	spin_unlock_irqrestore(&dwc->lock, flags);

	return 0;
}
@@ -563,6 +567,8 @@ static ssize_t dwc3_link_state_write(struct file *file,
	unsigned long		flags;
	enum dwc3_link_state	state = 0;
	char			buf[32];
	u32			reg;
	u8			speed;

	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
		return -EFAULT;
@@ -583,6 +589,15 @@ static ssize_t dwc3_link_state_write(struct file *file,
		return -EINVAL;

	spin_lock_irqsave(&dwc->lock, flags);
	reg = dwc3_readl(dwc->regs, DWC3_DSTS);
	speed = reg & DWC3_DSTS_CONNECTSPD;

	if (speed < DWC3_DSTS_SUPERSPEED &&
	    state != DWC3_LINK_STATE_RECOV) {
		spin_unlock_irqrestore(&dwc->lock, flags);
		return -EINVAL;
	}

	dwc3_gadget_set_link_state(dwc, state);
	spin_unlock_irqrestore(&dwc->lock, flags);