From 8fc0a99f32ea083b2e0eee217c813cf36aa8c521 Mon Sep 17 00:00:00 2001 From: Jules Maselbas Date: Thu, 8 Oct 2020 17:11:43 +0200 Subject: usb: dwc2: Uninitialize host and device on remove Device gadget must be properly uninitialized on poweroff however host system might not detect barebox's usb gadget has beeing disconnected. Signed-off-by: Jules Maselbas Signed-off-by: Sascha Hauer --- drivers/usb/dwc2/dwc2.c | 16 ++-------------- drivers/usb/dwc2/dwc2.h | 4 ++++ drivers/usb/dwc2/gadget.c | 6 ++++++ drivers/usb/dwc2/host.c | 13 +++++++++++++ 4 files changed, 25 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc2/dwc2.c b/drivers/usb/dwc2/dwc2.c index 908d624794..282e6754b0 100644 --- a/drivers/usb/dwc2/dwc2.c +++ b/drivers/usb/dwc2/dwc2.c @@ -15,19 +15,6 @@ #include "dwc2.h" -static void dwc2_uninit_common(struct dwc2 *dwc2) -{ - uint32_t hprt0; - - hprt0 = dwc2_readl(dwc2, HPRT0); - - /* Put everything in reset. */ - hprt0 &= ~(HPRT0_ENA | HPRT0_ENACHG | HPRT0_CONNDET | HPRT0_OVRCURRCHG); - hprt0 |= HPRT0_RST; - - dwc2_writel(dwc2, hprt0, HPRT0); -} - static int dwc2_set_mode(void *ctx, enum usb_dr_mode mode) { struct dwc2 *dwc2 = ctx; @@ -98,7 +85,8 @@ static void dwc2_remove(struct device_d *dev) { struct dwc2 *dwc2 = dev->priv; - dwc2_uninit_common(dwc2); + dwc2_host_uninit(dwc2); + dwc2_gadget_uninit(dwc2); } static const struct of_device_id dwc2_platform_dt_ids[] = { diff --git a/drivers/usb/dwc2/dwc2.h b/drivers/usb/dwc2/dwc2.h index 5e845f3491..30ad906656 100644 --- a/drivers/usb/dwc2/dwc2.h +++ b/drivers/usb/dwc2/dwc2.h @@ -34,13 +34,17 @@ int dwc2_submit_roothub(struct dwc2 *dwc2, struct usb_device *dev, unsigned long pipe, void *buf, int len, struct devrequest *setup); int dwc2_register_host(struct dwc2 *dwc2); +void dwc2_host_uninit(struct dwc2 *dwc2); #else static inline int dwc2_register_host(struct dwc2 *dwc2) { return -ENODEV; } +static inline void dwc2_host_uninit(struct dwc2 *dwc2) {}; #endif /* Gadget functions */ #ifdef CONFIG_USB_DWC2_GADGET int dwc2_gadget_init(struct dwc2 *dwc2); +void dwc2_gadget_uninit(struct dwc2 *dwc2); #else static inline int dwc2_gadget_init(struct dwc2 *dwc2) { return -ENODEV; } +static inline void dwc2_gadget_uninit(struct dwc2 *dwc2) {}; #endif diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 6a65b9b117..aa7447c9b4 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2734,3 +2734,9 @@ int dwc2_gadget_init(struct dwc2 *dwc2) return 0; } + +void dwc2_gadget_uninit(struct dwc2 *dwc2) +{ + dwc2_core_disconnect(dwc2); + dwc2_gadget_disconnect(dwc2); +} diff --git a/drivers/usb/dwc2/host.c b/drivers/usb/dwc2/host.c index 13cb3472d7..510a07dfb9 100644 --- a/drivers/usb/dwc2/host.c +++ b/drivers/usb/dwc2/host.c @@ -788,3 +788,16 @@ int dwc2_register_host(struct dwc2 *dwc2) return usb_register_host(host); } + +void dwc2_host_uninit(struct dwc2 *dwc2) +{ + uint32_t hprt0; + + hprt0 = dwc2_readl(dwc2, HPRT0); + + /* Put everything in reset. */ + hprt0 &= ~(HPRT0_ENA | HPRT0_ENACHG | HPRT0_CONNDET | HPRT0_OVRCURRCHG); + hprt0 |= HPRT0_RST; + + dwc2_writel(dwc2, hprt0, HPRT0); +} -- cgit v1.2.3