Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8f472434 authored by Yoshihiro Shimoda's avatar Yoshihiro Shimoda Committed by Greg Kroah-Hartman
Browse files

usb: gadget: udc: renesas_usb3: add a safety connection way for forced_b_device



[ Upstream commit ceb94bc52c437463f0903e61060a94a2226fb672 ]

This patch adds a safety connection way for "forced_b_device" with
"workaround_for_vbus" like below:

< Example for R-Car E3 Ebisu >
 # modprobe <any usb gadget driver>
 # echo 1 > /sys/kernel/debug/ee020000.usb/b_device
 (connect a usb cable to host side.)
 # echo 2 > /sys/kernel/debug/ee020000.usb/b_device

Previous code should have connected a usb cable before the "b_device"
is set to 1 on the Ebisu board. However, if xHCI driver on the board
is probed, it causes some troubles:
 - Conflicts USB VBUS/signals between the board and another host.
 - "Cannot enable. Maybe the USB cable is bad?" might happen on
   both the board and another host with a usb hub.
 - Cannot enumerate a usb gadget correctly because an interruption
   of VBUS change happens unexpectedly.

Reported-by: default avatarKazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com>
Signed-off-by: default avatarYoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 85a3e682
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -352,6 +352,7 @@ struct renesas_usb3 {
	bool extcon_host;		/* check id and set EXTCON_USB_HOST */
	bool extcon_usb;		/* check vbus and set EXTCON_USB */
	bool forced_b_device;
	bool start_to_connect;
};

#define gadget_to_renesas_usb3(_gadget)	\
@@ -470,6 +471,7 @@ static void usb3_init_axi_bridge(struct renesas_usb3 *usb3)
static void usb3_init_epc_registers(struct renesas_usb3 *usb3)
{
	usb3_write(usb3, ~0, USB3_USB_INT_STA_1);
	if (!usb3->workaround_for_vbus)
		usb3_enable_irq_1(usb3, USB_INT_1_VBUS_CNG);
}

@@ -676,8 +678,7 @@ static void usb3_mode_config(struct renesas_usb3 *usb3, bool host, bool a_dev)
	usb3_set_mode(usb3, host);
	usb3_vbus_out(usb3, a_dev);
	/* for A-Peripheral or forced B-device mode */
	if ((!host && a_dev) ||
	    (usb3->workaround_for_vbus && usb3->forced_b_device))
	if ((!host && a_dev) || usb3->start_to_connect)
		usb3_connect(usb3);
	spin_unlock_irqrestore(&usb3->lock, flags);
}
@@ -2369,7 +2370,11 @@ static ssize_t renesas_usb3_b_device_write(struct file *file,
	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
		return -EFAULT;

	if (!strncmp(buf, "1", 1))
	usb3->start_to_connect = false;
	if (usb3->workaround_for_vbus && usb3->forced_b_device &&
	    !strncmp(buf, "2", 1))
		usb3->start_to_connect = true;
	else if (!strncmp(buf, "1", 1))
		usb3->forced_b_device = true;
	else
		usb3->forced_b_device = false;
@@ -2377,7 +2382,7 @@ static ssize_t renesas_usb3_b_device_write(struct file *file,
	if (usb3->workaround_for_vbus)
		usb3_disconnect(usb3);

	/* Let this driver call usb3_connect() anyway */
	/* Let this driver call usb3_connect() if needed */
	usb3_check_id(usb3);

	return count;