From 86e6380a5b0dba3fb11c93b3a4347c44efb3ede0 Mon Sep 17 00:00:00 2001 From: Wu Liang feng Date: Wed, 10 Aug 2016 11:17:20 +0800 Subject: [PATCH] Revert "usb: dwc3: add functions to set force mode" This reverts commit 9607f47dfec23c5773d74e45ed561859eabce2b7. --- drivers/usb/dwc3/core.c | 76 +--------- drivers/usb/dwc3/core.h | 15 -- drivers/usb/dwc3/debugfs.c | 10 +- drivers/usb/dwc3/gadget.c | 277 +------------------------------------ 4 files changed, 10 insertions(+), 368 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index b8c39d86f565..8362558acb5f 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -109,7 +109,7 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc) * dwc3_soft_reset - Issue soft reset * @dwc: Pointer to our controller context structure */ -int dwc3_soft_reset(struct dwc3 *dwc) +static int dwc3_soft_reset(struct dwc3 *dwc) { unsigned long timeout; u32 reg; @@ -253,7 +253,7 @@ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length) * * Returns 0 on success otherwise negative errno. */ -int dwc3_event_buffers_setup(struct dwc3 *dwc) +static int dwc3_event_buffers_setup(struct dwc3 *dwc) { struct dwc3_event_buffer *evt; int n; @@ -279,7 +279,7 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc) return 0; } -void dwc3_event_buffers_cleanup(struct dwc3 *dwc) +static void dwc3_event_buffers_cleanup(struct dwc3 *dwc) { struct dwc3_event_buffer *evt; int n; @@ -809,76 +809,6 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc) } } -/* Returns true if the controller is capable of DRD. */ -bool dwc3_hw_is_drd(struct dwc3 *dwc) -{ - u32 op_mode = DWC3_GHWPARAMS0_USB3_MODE(dwc->hwparams.hwparams0); - - return (op_mode == DWC3_GHWPARAMS0_USB3_DRD); -} - -bool dwc3_force_mode(struct dwc3 *dwc, u32 mode) -{ - u32 reg; - unsigned long flags; - struct usb_hcd *hcd; - - /* - * Force mode has no effect if the hardware is not drd mode. - */ - if (!dwc3_hw_is_drd(dwc)) - return false; - /* - * If dr_mode is either peripheral or host only, there is no - * need to ever force the mode to the opposite mode. - */ - if (WARN_ON(mode == DWC3_GCTL_PRTCAP_DEVICE && - dwc->dr_mode == USB_DR_MODE_HOST)) - return false; - - if (WARN_ON(mode == DWC3_GCTL_PRTCAP_HOST && - dwc->dr_mode == USB_DR_MODE_PERIPHERAL)) - return false; - - reg = dwc3_readl(dwc->regs, DWC3_GCTL); - if (DWC3_GCTL_PRTCAP(reg) == mode) - return false; - - hcd = dev_get_drvdata(&dwc->xhci->dev); - - switch (mode) { - case DWC3_GCTL_PRTCAP_DEVICE: - if (hcd->state != HC_STATE_HALT) { - usb_remove_hcd(hcd->shared_hcd); - usb_remove_hcd(hcd); - } - - spin_lock_irqsave(&dwc->lock, flags); - dwc3_set_mode(dwc, mode); - dwc3_gadget_restart(dwc, true); - spin_unlock_irqrestore(&dwc->lock, flags); - - break; - case DWC3_GCTL_PRTCAP_HOST: - spin_lock_irqsave(&dwc->lock, flags); - dwc3_gadget_restart(dwc, false); - dwc3_set_mode(dwc, mode); - spin_unlock_irqrestore(&dwc->lock, flags); - - if (hcd->state == HC_STATE_HALT) { - usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); - usb_add_hcd(hcd->shared_hcd, hcd->irq, IRQF_SHARED); - } - - break; - default: - /* do nothing */ - break; - } - - return true; -} - #define DWC3_ALIGN_MASK (16 - 1) static int dwc3_probe(struct platform_device *pdev) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 142e117d4ac5..c5d7a5e79962 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -30,10 +30,6 @@ #include #include #include -#include -#include -#include -#include #include #include @@ -223,10 +219,6 @@ #define DWC3_GEVNTSIZ_INTMASK (1 << 31) #define DWC3_GEVNTSIZ_SIZE(n) ((n) & 0xffff) -/* Global HWPARAMS0 Register */ -#define DWC3_GHWPARAMS0_USB3_MODE(n) ((n) & 7) -#define DWC3_GHWPARAMS0_USB3_DRD 2 - /* Global HWPARAMS1 Register */ #define DWC3_GHWPARAMS1_EN_PWROPT(n) (((n) & (3 << 24)) >> 24) #define DWC3_GHWPARAMS1_EN_PWROPT_NO 0 @@ -722,7 +714,6 @@ struct dwc3_scratchpad_array { * 1 - utmi_l1_suspend_n * @is_fpga: true when we are using the FPGA board * @needs_fifo_resize: not all users might want fifo resizing, flag it - * @enabled: true when gadget driver is ready * @pullups_connected: true when Run/Stop bit is set * @resize_fifos: tells us it's ok to reconfigure our TxFIFO sizes. * @setup_packet_pending: true when there's a Setup Packet in FIFO. Workaround @@ -876,7 +867,6 @@ struct dwc3 { unsigned is_utmi_l1_suspend:1; unsigned is_fpga:1; unsigned needs_fifo_resize:1; - unsigned enabled:1; unsigned pullups_connected:1; unsigned resize_fifos:1; unsigned setup_packet_pending:1; @@ -1050,11 +1040,6 @@ struct dwc3_gadget_ep_cmd_params { /* prototypes */ void dwc3_set_mode(struct dwc3 *dwc, u32 mode); int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc); -int dwc3_soft_reset(struct dwc3 *dwc); -int dwc3_event_buffers_setup(struct dwc3 *dwc); -void dwc3_event_buffers_cleanup(struct dwc3 *dwc); -int dwc3_gadget_restart(struct dwc3 *dwc, bool start); -bool dwc3_force_mode(struct dwc3 *dwc, u32 mode); #if IS_ENABLED(CONFIG_USB_DWC3_HOST) || IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) int dwc3_host_init(struct dwc3 *dwc); diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index 0f7f702bcbeb..26eb34ce0144 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -402,17 +402,11 @@ static ssize_t dwc3_mode_write(struct file *file, if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) return -EFAULT; - if (!strncmp(buf, "host", 4)) { + if (!strncmp(buf, "host", 4)) mode |= DWC3_GCTL_PRTCAP_HOST; - dwc3_force_mode(dwc, mode); - return count; - } - if (!strncmp(buf, "device", 6)) { + if (!strncmp(buf, "device", 6)) mode |= DWC3_GCTL_PRTCAP_DEVICE; - dwc3_force_mode(dwc, mode); - return count; - } if (!strncmp(buf, "otg", 3)) mode |= DWC3_GCTL_PRTCAP_OTG; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index bc2720108adb..2d981e1b869c 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1579,20 +1579,12 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) { struct dwc3 *dwc = gadget_to_dwc(g); unsigned long flags; - int ret = 0; - u32 reg; + int ret; is_on = !!is_on; spin_lock_irqsave(&dwc->lock, flags); - - dwc->enabled = is_on; - - reg = dwc3_readl(dwc->regs, DWC3_GCTL); - - if (DWC3_GCTL_PRTCAP(reg) == DWC3_GCTL_PRTCAP_DEVICE) - ret = dwc3_gadget_run_stop(dwc, is_on, false); - + ret = dwc3_gadget_run_stop(dwc, is_on, false); spin_unlock_irqrestore(&dwc->lock, flags); return ret; @@ -1656,10 +1648,6 @@ static int dwc3_gadget_start(struct usb_gadget *g, dwc->gadget_driver = driver; - reg = dwc3_readl(dwc->regs, DWC3_GCTL); - if (DWC3_GCTL_PRTCAP(reg) != DWC3_GCTL_PRTCAP_DEVICE) - goto mode_mismatch; - reg = dwc3_readl(dwc->regs, DWC3_DCFG); reg &= ~(DWC3_DCFG_SPEED_MASK); @@ -1722,7 +1710,6 @@ static int dwc3_gadget_start(struct usb_gadget *g, dwc3_gadget_enable_irq(dwc); -mode_mismatch: spin_unlock_irqrestore(&dwc->lock, flags); return 0; @@ -1747,17 +1734,12 @@ static int dwc3_gadget_stop(struct usb_gadget *g) struct dwc3 *dwc = gadget_to_dwc(g); unsigned long flags; int irq; - u32 reg; spin_lock_irqsave(&dwc->lock, flags); - reg = dwc3_readl(dwc->regs, DWC3_GCTL); - - if (DWC3_GCTL_PRTCAP(reg) == DWC3_GCTL_PRTCAP_DEVICE) { - dwc3_gadget_disable_irq(dwc); - __dwc3_gadget_ep_disable(dwc->eps[0]); - __dwc3_gadget_ep_disable(dwc->eps[1]); - } + dwc3_gadget_disable_irq(dwc); + __dwc3_gadget_ep_disable(dwc->eps[0]); + __dwc3_gadget_ep_disable(dwc->eps[1]); dwc->gadget_driver = NULL; @@ -2998,252 +2980,3 @@ err1: err0: return ret; } - -static int dwc3_gadget_reinit(struct dwc3 *dwc) -{ - u32 hwparams4 = dwc->hwparams.hwparams4; - u32 reg; - int ret; - struct dwc3_ep *dep = NULL; - - reg = dwc3_readl(dwc->regs, DWC3_GSNPSID); - /* This should read as U3 followed by revision number */ - if ((reg & DWC3_GSNPSID_MASK) == 0x55330000) { - /* Detected DWC_usb3 IP */ - dwc->revision = reg; - } else if ((reg & DWC3_GSNPSID_MASK) == 0x33310000) { - /* Detected DWC_usb31 IP */ - dwc->revision = dwc3_readl(dwc->regs, DWC3_VER_NUMBER); - dwc->revision |= DWC3_REVISION_IS_DWC31; - } else { - dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n"); - ret = -ENODEV; - goto err0; - } - - /* - * Write Linux Version Code to our GUID register so it's easy to figure - * out which kernel version a bug was found. - */ - dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE); - - /* Handle USB2.0-only core configuration */ - if (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) == - DWC3_GHWPARAMS3_SSPHY_IFC_DIS) { - if (dwc->maximum_speed == USB_SPEED_SUPER) - dwc->maximum_speed = USB_SPEED_HIGH; - } - - /* issue device SoftReset too */ - ret = dwc3_soft_reset(dwc); - if (ret) - goto err0; - - reg = dwc3_readl(dwc->regs, DWC3_GCTL); - reg &= ~DWC3_GCTL_SCALEDOWN_MASK; - - switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1)) { - case DWC3_GHWPARAMS1_EN_PWROPT_CLK: - /** - * WORKAROUND: DWC3 revisions between 2.10a and 2.50a have an - * issue which would cause xHCI compliance tests to fail. - * - * Because of that we cannot enable clock gating on such - * configurations. - * - * Refers to: - * - * STAR#9000588375: Clock Gating, SOF Issues when ref_clk-Based - * SOF/ITP Mode Used - */ - if ((dwc->dr_mode == USB_DR_MODE_HOST || - dwc->dr_mode == USB_DR_MODE_OTG) && - (dwc->revision >= DWC3_REVISION_210A && - dwc->revision <= DWC3_REVISION_250A)) - reg |= DWC3_GCTL_DSBLCLKGTNG | DWC3_GCTL_SOFITPSYNC; - else - reg &= ~DWC3_GCTL_DSBLCLKGTNG; - break; - case DWC3_GHWPARAMS1_EN_PWROPT_HIB: - /* enable hibernation here */ - dwc->nr_scratch = DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(hwparams4); - - /* - * REVISIT Enabling this bit so that host-mode hibernation - * will work. Device-mode hibernation is not yet implemented. - */ - reg |= DWC3_GCTL_GBLHIBERNATIONEN; - break; - default: - dwc3_trace(trace_dwc3_core, - "No power optimization available\n"); - } - - /* check if current dwc3 is on simulation board */ - if (dwc->hwparams.hwparams6 & DWC3_GHWPARAMS6_EN_FPGA) { - dwc3_trace(trace_dwc3_core, - "running on FPGA platform\n"); - dwc->is_fpga = true; - } - - WARN_ONCE(dwc->disable_scramble_quirk && !dwc->is_fpga, - "disable_scramble cannot be used on non-FPGA builds\n"); - - if (dwc->disable_scramble_quirk && dwc->is_fpga) - reg |= DWC3_GCTL_DISSCRAMBLE; - else - reg &= ~DWC3_GCTL_DISSCRAMBLE; - - if (dwc->u2exit_lfps_quirk) - reg |= DWC3_GCTL_U2EXIT_LFPS; - - /* - * WORKAROUND: DWC3 revisions <1.90a have a bug - * where the device can fail to connect at SuperSpeed - * and falls back to high-speed mode which causes - * the device to enter a Connect/Disconnect loop - */ - if (dwc->revision < DWC3_REVISION_190A) - reg |= DWC3_GCTL_U2RSTECN; - dwc3_writel(dwc->regs, DWC3_GCTL, reg); - - ret = dwc3_event_buffers_setup(dwc); - - if (ret) { - dev_err(dwc->dev, "failed to setup event buffers\n"); - goto err1; - } - - reg = dwc3_readl(dwc->regs, DWC3_DCFG); - reg |= DWC3_DCFG_LPM_CAP; - reg &= ~(DWC3_DCFG_SPEED_MASK); - - /** - * WORKAROUND: DWC3 revision < 2.20a have an issue - * which would cause metastability state on Run/Stop - * bit if we try to force the IP to USB2-only mode. - * - * Because of that, we cannot configure the IP to any - * speed other than the SuperSpeed - * - * Refers to: - * - * STAR#9000525659: Clock Domain Crossing on DCTL in - * USB 2.0 Mode - */ - if (dwc->revision < DWC3_REVISION_220A) { - reg |= DWC3_DCFG_SUPERSPEED; - } else { - switch (dwc->maximum_speed) { - case USB_SPEED_LOW: - reg |= DWC3_DSTS_LOWSPEED; - break; - case USB_SPEED_FULL: - reg |= DWC3_DSTS_FULLSPEED1; - break; - case USB_SPEED_HIGH: - reg |= DWC3_DSTS_HIGHSPEED; - break; - case USB_SPEED_SUPER: /* FALLTHROUGH */ - case USB_SPEED_UNKNOWN: /* FALTHROUGH */ - default: - reg |= DWC3_DSTS_SUPERSPEED; - } - } - dwc3_writel(dwc->regs, DWC3_DCFG, reg); - - /* Start with SuperSpeed Default */ - dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512); - - dep = dwc->eps[0]; - ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false, - false); - if (ret) { - dev_err(dwc->dev, "failed to enable %s\n", dep->name); - goto err1; - } - - dep = dwc->eps[1]; - ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false, - false); - if (ret) { - dev_err(dwc->dev, "failed to enable %s\n", dep->name); - goto err2; - } - - /* begin to receive SETUP packets */ - dwc->ep0state = EP0_SETUP_PHASE; - dwc3_ep0_out_start(dwc); - - return 0; -err2: - __dwc3_gadget_ep_disable(dwc->eps[0]); -err1: - dwc3_event_buffers_cleanup(dwc); -err0: - return ret; -} - -int dwc3_gadget_restart(struct dwc3 *dwc, bool start) -{ - struct dwc3_event_buffer *evt; - int ret = 0; - int i; - u32 reg; - - if (start) { - ret = dwc3_gadget_reinit(dwc); - if (ret < 0) { - dev_err(dwc->dev, - "dwc3 gadget reinit error = %d\n", ret); - goto err; - } - - if (dwc->enabled) { - ret = dwc3_gadget_run_stop(dwc, start, false); - if (ret < 0) { - dev_err(dwc->dev, - "dwc3 gadget run stop err = %d\n", ret); - goto err; - } - } - dwc3_gadget_enable_irq(dwc); - } else { - /* - * Per databook, DEVCTRLHLT bit setting requires - * interrupts to be acknowledged. so acknowledge - * the events that are generated (by writing to - * GEVNTCOUNTn) first. And we also mask interrupts - * and clear SW states to avoid generating other - * interrupts after do gadget disconnnect operation. - */ - dwc3_gadget_disable_irq(dwc); - - for (i = 0; i < dwc->num_event_buffers; i++) { - evt = dwc->ev_buffs[i]; - evt->count = 0; - evt->flags &= ~DWC3_EVENT_PENDING; - reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(i)); - reg |= DWC3_GEVNTSIZ_INTMASK; - dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(i), reg); - reg = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(i)); - dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(i), reg); - } - - /* - * DEVCTRLHLT bit sometimes does not get set - * even when GEVNTCOUNT is acked so do not - * care run stop function return value. - */ - dwc3_gadget_run_stop(dwc, start, false); - - if (dwc->gadget.state != USB_STATE_NOTATTACHED) - dwc3_gadget_disconnect_interrupt(dwc); - - __dwc3_gadget_ep_disable(dwc->eps[0]); - __dwc3_gadget_ep_disable(dwc->eps[1]); - } - -err: - return ret; -} -- 2.34.1