usb: gadget: udc: renesas_usb3: add a safety connection way for forced_b_device
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: Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com> Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
This commit is contained in:
parent
268784ba14
commit
ceb94bc52c
|
@ -358,6 +358,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) \
|
||||
|
@ -476,7 +477,8 @@ 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);
|
||||
usb3_enable_irq_1(usb3, USB_INT_1_VBUS_CNG);
|
||||
if (!usb3->workaround_for_vbus)
|
||||
usb3_enable_irq_1(usb3, USB_INT_1_VBUS_CNG);
|
||||
}
|
||||
|
||||
static bool usb3_wakeup_usb2_phy(struct renesas_usb3 *usb3)
|
||||
|
@ -700,8 +702,7 @@ static void usb3_mode_config(struct renesas_usb3 *usb3, bool host, bool a_dev)
|
|||
usb3_set_mode_by_role_sw(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);
|
||||
}
|
||||
|
@ -2432,7 +2433,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;
|
||||
|
@ -2440,7 +2445,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;
|
||||
|
|
Loading…
Reference in New Issue