usb: gadget: udc: renesas_usb3: Add role switch support for RZ/V2M
As RZ/V2M has both HOST and PERI reset module, we need to do reset release before accessing registers in respective IP module. This patch adds role switch support for RZ/V2M. Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com> Link: https://lore.kernel.org/r/20230121145853.4792-7-biju.das.jz@bp.renesas.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
9cad72dfc5
commit
3827fa1ef3
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/extcon-provider.h>
|
||||
@@ -2366,6 +2367,9 @@ static int renesas_usb3_start(struct usb_gadget *gadget,
|
||||
|
||||
usb3 = gadget_to_renesas_usb3(gadget);
|
||||
|
||||
if (usb3->is_rzv2m && usb3_is_a_device(usb3))
|
||||
return -EBUSY;
|
||||
|
||||
/* hook up the driver */
|
||||
usb3->driver = driver;
|
||||
|
||||
@@ -2374,6 +2378,10 @@ static int renesas_usb3_start(struct usb_gadget *gadget,
|
||||
|
||||
pm_runtime_get_sync(usb3_to_dev(usb3));
|
||||
|
||||
/* Peripheral Reset */
|
||||
if (usb3->is_rzv2m)
|
||||
rzv2m_usb3drd_reset(usb3_to_dev(usb3)->parent, false);
|
||||
|
||||
renesas_usb3_init_controller(usb3);
|
||||
|
||||
return 0;
|
||||
@@ -2386,8 +2394,10 @@ static int renesas_usb3_stop(struct usb_gadget *gadget)
|
||||
usb3->softconnect = false;
|
||||
usb3->gadget.speed = USB_SPEED_UNKNOWN;
|
||||
usb3->driver = NULL;
|
||||
renesas_usb3_stop_controller(usb3);
|
||||
if (usb3->is_rzv2m)
|
||||
rzv2m_usb3drd_reset(usb3_to_dev(usb3)->parent, false);
|
||||
|
||||
renesas_usb3_stop_controller(usb3);
|
||||
if (usb3->phy)
|
||||
phy_exit(usb3->phy);
|
||||
|
||||
@@ -2447,18 +2457,29 @@ static void handle_ext_role_switch_states(struct device *dev,
|
||||
switch (role) {
|
||||
case USB_ROLE_NONE:
|
||||
usb3->connection_state = USB_ROLE_NONE;
|
||||
if (cur_role == USB_ROLE_HOST)
|
||||
if (!usb3->is_rzv2m && cur_role == USB_ROLE_HOST)
|
||||
device_release_driver(host);
|
||||
if (usb3->driver)
|
||||
if (usb3->driver) {
|
||||
if (usb3->is_rzv2m)
|
||||
rzv2m_usb3drd_reset(dev->parent, false);
|
||||
usb3_disconnect(usb3);
|
||||
}
|
||||
usb3_vbus_out(usb3, false);
|
||||
|
||||
if (usb3->is_rzv2m) {
|
||||
rzv2m_usb3drd_reset(dev->parent, true);
|
||||
device_release_driver(host);
|
||||
}
|
||||
break;
|
||||
case USB_ROLE_DEVICE:
|
||||
if (usb3->connection_state == USB_ROLE_NONE) {
|
||||
usb3->connection_state = USB_ROLE_DEVICE;
|
||||
usb3_set_mode(usb3, false);
|
||||
if (usb3->driver)
|
||||
if (usb3->driver) {
|
||||
if (usb3->is_rzv2m)
|
||||
renesas_usb3_init_controller(usb3);
|
||||
usb3_connect(usb3);
|
||||
}
|
||||
} else if (cur_role == USB_ROLE_HOST) {
|
||||
device_release_driver(host);
|
||||
usb3_set_mode(usb3, false);
|
||||
@@ -2469,8 +2490,11 @@ static void handle_ext_role_switch_states(struct device *dev,
|
||||
break;
|
||||
case USB_ROLE_HOST:
|
||||
if (usb3->connection_state == USB_ROLE_NONE) {
|
||||
if (usb3->driver)
|
||||
if (usb3->driver) {
|
||||
if (usb3->is_rzv2m)
|
||||
rzv2m_usb3drd_reset(dev->parent, false);
|
||||
usb3_disconnect(usb3);
|
||||
}
|
||||
|
||||
usb3->connection_state = USB_ROLE_HOST;
|
||||
usb3_set_mode(usb3, true);
|
||||
|
||||
Reference in New Issue
Block a user