diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-18 20:33:46 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-18 20:33:46 +0300 |
commit | c6b48dad92aedaa9bdc013ee495cb5b1bbdf1f11 (patch) | |
tree | 8d0bbf19d75fc1bf546ed1b05b560ea2df54689e /drivers/usb/mtu3/mtu3_dr.c | |
parent | 1f7d290a7275edb270dbee13212c37cb59940221 (diff) | |
parent | fb9617edf6c0e1b86a6595cd92dd3f84595221d9 (diff) | |
download | linux-c6b48dad92aedaa9bdc013ee495cb5b1bbdf1f11.tar.xz |
Merge tag 'usb-5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB updates from Greg KH:
"Here is the big set of USB patches for 5.4-rc1.
Two major chunks of code are moving out of the tree and into the
staging directory, uwb and wusb (wireless USB support), because there
are no devices that actually use this protocol anymore, and what we
have today probably doesn't work at all given that the maintainers
left many many years ago. So move it to staging where it will be
removed in a few releases if no one screams.
Other than that, lots of little things. The usual gadget and xhci and
usb serial driver updates, along with a bunch of sysfs file cleanups
due to the driver core changes to support that. Nothing really major,
just constant forward progress.
All of these have been in linux-next for a while with no reported
issues"
* tag 'usb-5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (159 commits)
USB: usbcore: Fix slab-out-of-bounds bug during device reset
usb: cdns3: Remove redundant dev_err call in cdns3_probe()
USB: rio500: Fix lockdep violation
USB: rio500: simplify locking
usb: mtu3: register a USB Role Switch for dual role mode
usb: common: add USB GPIO based connection detection driver
usb: common: create Kconfig file
usb: roles: get usb-role-switch from parent
usb: roles: Add fwnode_usb_role_switch_get() function
device connection: Add fwnode_connection_find_match()
usb: roles: Introduce stubs for the exiting functions in role.h
dt-bindings: usb: mtu3: add properties about USB Role Switch
dt-bindings: usb: add binding for USB GPIO based connection detection driver
dt-bindings: connector: add optional properties for Type-B
dt-binding: usb: add usb-role-switch property
usbip: Implement SG support to vhci-hcd and stub driver
usb: roles: intel: Enable static DRD mode for role switch
xhci-ext-caps.c: Add property to disable Intel SW switch
usb: dwc3: remove generic PHY calibrate() calls
usb: core: phy: add support for PHY calibration
...
Diffstat (limited to 'drivers/usb/mtu3/mtu3_dr.c')
-rw-r--r-- | drivers/usb/mtu3/mtu3_dr.c | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/drivers/usb/mtu3/mtu3_dr.c b/drivers/usb/mtu3/mtu3_dr.c index 5fcb71af875a..08e18448e8b8 100644 --- a/drivers/usb/mtu3/mtu3_dr.c +++ b/drivers/usb/mtu3/mtu3_dr.c @@ -7,6 +7,8 @@ * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> */ +#include <linux/usb/role.h> + #include "mtu3.h" #include "mtu3_dr.h" #include "mtu3_debug.h" @@ -280,7 +282,7 @@ static int ssusb_extcon_register(struct otg_switch_mtk *otg_sx) * This is useful in special cases, such as uses TYPE-A receptacle but also * wants to support dual-role mode. */ -void ssusb_mode_manual_switch(struct ssusb_mtk *ssusb, int to_host) +void ssusb_mode_switch(struct ssusb_mtk *ssusb, int to_host) { struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; @@ -318,6 +320,47 @@ void ssusb_set_force_mode(struct ssusb_mtk *ssusb, mtu3_writel(ssusb->ippc_base, SSUSB_U2_CTRL(0), value); } +static int ssusb_role_sw_set(struct device *dev, enum usb_role role) +{ + struct ssusb_mtk *ssusb = dev_get_drvdata(dev); + bool to_host = false; + + if (role == USB_ROLE_HOST) + to_host = true; + + if (to_host ^ ssusb->is_host) + ssusb_mode_switch(ssusb, to_host); + + return 0; +} + +static enum usb_role ssusb_role_sw_get(struct device *dev) +{ + struct ssusb_mtk *ssusb = dev_get_drvdata(dev); + enum usb_role role; + + role = ssusb->is_host ? USB_ROLE_HOST : USB_ROLE_DEVICE; + + return role; +} + +static int ssusb_role_sw_register(struct otg_switch_mtk *otg_sx) +{ + struct usb_role_switch_desc role_sx_desc = { 0 }; + struct ssusb_mtk *ssusb = + container_of(otg_sx, struct ssusb_mtk, otg_switch); + + if (!otg_sx->role_sw_used) + return 0; + + role_sx_desc.set = ssusb_role_sw_set; + role_sx_desc.get = ssusb_role_sw_get; + role_sx_desc.fwnode = dev_fwnode(ssusb->dev); + otg_sx->role_sw = usb_role_switch_register(ssusb->dev, &role_sx_desc); + + return PTR_ERR_OR_ZERO(otg_sx->role_sw); +} + int ssusb_otg_switch_init(struct ssusb_mtk *ssusb) { struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; @@ -328,6 +371,8 @@ int ssusb_otg_switch_init(struct ssusb_mtk *ssusb) if (otg_sx->manual_drd_enabled) ssusb_dr_debugfs_init(ssusb); + else if (otg_sx->role_sw_used) + ret = ssusb_role_sw_register(otg_sx); else ret = ssusb_extcon_register(otg_sx); @@ -340,4 +385,5 @@ void ssusb_otg_switch_exit(struct ssusb_mtk *ssusb) cancel_work_sync(&otg_sx->id_work); cancel_work_sync(&otg_sx->vbus_work); + usb_role_switch_unregister(otg_sx->role_sw); } |