^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * drd.c - DesignWare USB3 DRD Controller Dual-role support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2017 Texas Instruments Incorporated - https://www.ti.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Authors: Roger Quadros <rogerq@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/extcon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/of_graph.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/property.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "gadget.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) static void dwc3_otg_disable_events(struct dwc3 *dwc, u32 disable_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) u32 reg = dwc3_readl(dwc->regs, DWC3_OEVTEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) reg &= ~(disable_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) dwc3_writel(dwc->regs, DWC3_OEVTEN, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static void dwc3_otg_enable_events(struct dwc3 *dwc, u32 enable_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) u32 reg = dwc3_readl(dwc->regs, DWC3_OEVTEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) reg |= (enable_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) dwc3_writel(dwc->regs, DWC3_OEVTEN, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static void dwc3_otg_clear_events(struct dwc3 *dwc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) u32 reg = dwc3_readl(dwc->regs, DWC3_OEVT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) dwc3_writel(dwc->regs, DWC3_OEVTEN, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define DWC3_OTG_ALL_EVENTS (DWC3_OEVTEN_XHCIRUNSTPSETEN | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) DWC3_OEVTEN_DEVRUNSTPSETEN | DWC3_OEVTEN_HIBENTRYEN | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) DWC3_OEVTEN_CONIDSTSCHNGEN | DWC3_OEVTEN_HRRCONFNOTIFEN | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) DWC3_OEVTEN_HRRINITNOTIFEN | DWC3_OEVTEN_ADEVIDLEEN | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) DWC3_OEVTEN_ADEVBHOSTENDEN | DWC3_OEVTEN_ADEVHOSTEN | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) DWC3_OEVTEN_ADEVHNPCHNGEN | DWC3_OEVTEN_ADEVSRPDETEN | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) DWC3_OEVTEN_ADEVSESSENDDETEN | DWC3_OEVTEN_BDEVBHOSTENDEN | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) DWC3_OEVTEN_BDEVHNPCHNGEN | DWC3_OEVTEN_BDEVSESSVLDDETEN | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) DWC3_OEVTEN_BDEVVBUSCHNGEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static irqreturn_t dwc3_otg_thread_irq(int irq, void *_dwc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct dwc3 *dwc = _dwc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) spin_lock(&dwc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (dwc->otg_restart_host) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) dwc3_otg_host_init(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) dwc->otg_restart_host = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) spin_unlock(&dwc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static irqreturn_t dwc3_otg_irq(int irq, void *_dwc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct dwc3 *dwc = _dwc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) irqreturn_t ret = IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) reg = dwc3_readl(dwc->regs, DWC3_OEVT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* ignore non OTG events, we can't disable them in OEVTEN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (!(reg & DWC3_OTG_ALL_EVENTS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) dwc3_writel(dwc->regs, DWC3_OEVT, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) !(reg & DWC3_OEVT_DEVICEMODE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) dwc->otg_restart_host = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) dwc3_writel(dwc->regs, DWC3_OEVT, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) ret = IRQ_WAKE_THREAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static void dwc3_otgregs_init(struct dwc3 *dwc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * Prevent host/device reset from resetting OTG core.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * If we don't do this then xhci_reset (USBCMD.HCRST) will reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * the signal outputs sent to the PHY, the OTG FSM logic of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * core and also the resets to the VBUS filters inside the core.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) reg = dwc3_readl(dwc->regs, DWC3_OCFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) reg |= DWC3_OCFG_SFTRSTMASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) dwc3_writel(dwc->regs, DWC3_OCFG, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* Disable hibernation for simplicity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) reg = dwc3_readl(dwc->regs, DWC3_GCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) reg &= ~DWC3_GCTL_GBLHIBERNATIONEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) dwc3_writel(dwc->regs, DWC3_GCTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * Initialize OTG registers as per
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * Figure 11-4 OTG Driver Overall Programming Flow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /* OCFG.SRPCap = 0, OCFG.HNPCap = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) reg = dwc3_readl(dwc->regs, DWC3_OCFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) reg &= ~(DWC3_OCFG_SRPCAP | DWC3_OCFG_HNPCAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) dwc3_writel(dwc->regs, DWC3_OCFG, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* OEVT = FFFF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) dwc3_otg_clear_events(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /* OEVTEN = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) dwc3_otg_disable_events(dwc, DWC3_OTG_ALL_EVENTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* OEVTEN.ConIDStsChngEn = 1. Instead we enable all events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) dwc3_otg_enable_events(dwc, DWC3_OTG_ALL_EVENTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * OCTL.PeriMode = 1, OCTL.DevSetHNPEn = 0, OCTL.HstSetHNPEn = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * OCTL.HNPReq = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) reg = dwc3_readl(dwc->regs, DWC3_OCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) reg |= DWC3_OCTL_PERIMODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) reg &= ~(DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HSTSETHNPEN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) DWC3_OCTL_HNPREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) dwc3_writel(dwc->regs, DWC3_OCTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static int dwc3_otg_get_irq(struct dwc3 *dwc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct platform_device *dwc3_pdev = to_platform_device(dwc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) irq = platform_get_irq_byname_optional(dwc3_pdev, "otg");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (irq > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (irq == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) irq = platform_get_irq_byname_optional(dwc3_pdev, "dwc_usb3");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (irq > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (irq == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) irq = platform_get_irq(dwc3_pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (irq > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (!irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) irq = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) void dwc3_otg_init(struct dwc3 *dwc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * As per Figure 11-4 OTG Driver Overall Programming Flow,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * block "Initialize GCTL for OTG operation".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* GCTL.PrtCapDir=2'b11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_OTG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /* GUSB2PHYCFG0.SusPHY=0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /* Initialize OTG registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) dwc3_otgregs_init(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) void dwc3_otg_exit(struct dwc3 *dwc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* disable all OTG IRQs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) dwc3_otg_disable_events(dwc, DWC3_OTG_ALL_EVENTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* clear all events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) dwc3_otg_clear_events(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* should be called before Host controller driver is started */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) void dwc3_otg_host_init(struct dwc3 *dwc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /* As per Figure 11-10 A-Device Flow Diagram */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* OCFG.HNPCap = 0, OCFG.SRPCap = 0. Already 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * OCTL.PeriMode=0, OCTL.TermSelDLPulse = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * OCTL.DevSetHNPEn = 0, OCTL.HstSetHNPEn = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) reg = dwc3_readl(dwc->regs, DWC3_OCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) reg &= ~(DWC3_OCTL_PERIMODE | DWC3_OCTL_TERMSELIDPULSE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HSTSETHNPEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) dwc3_writel(dwc->regs, DWC3_OCTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * OCFG.DisPrtPwrCutoff = 0/1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) reg = dwc3_readl(dwc->regs, DWC3_OCFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) reg &= ~DWC3_OCFG_DISPWRCUTTOFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) dwc3_writel(dwc->regs, DWC3_OCFG, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * OCFG.SRPCap = 1, OCFG.HNPCap = GHWPARAMS6.HNP_CAP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * We don't want SRP/HNP for simple dual-role so leave
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * these disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * OEVTEN.OTGADevHostEvntEn = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * OEVTEN.OTGADevSessEndDetEvntEn = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * We don't want HNP/role-swap so leave these disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /* GUSB2PHYCFG.ULPIAutoRes = 1/0, GUSB2PHYCFG.SusPHY = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (!dwc->dis_u2_susphy_quirk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) reg |= DWC3_GUSB2PHYCFG_SUSPHY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /* Set Port Power to enable VBUS: OCTL.PrtPwrCtl = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) reg = dwc3_readl(dwc->regs, DWC3_OCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) reg |= DWC3_OCTL_PRTPWRCTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) dwc3_writel(dwc->regs, DWC3_OCTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /* should be called after Host controller driver is stopped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static void dwc3_otg_host_exit(struct dwc3 *dwc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * Exit from A-device flow as per
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * Figure 11-4 OTG Driver Overall Programming Flow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * OEVTEN.OTGADevBHostEndEvntEn=0, OEVTEN.OTGADevHNPChngEvntEn=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * OEVTEN.OTGADevSessEndDetEvntEn=0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * OEVTEN.OTGADevHostEvntEn = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * But we don't disable any OTG events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /* OCTL.HstSetHNPEn = 0, OCTL.PrtPwrCtl=0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) reg = dwc3_readl(dwc->regs, DWC3_OCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) reg &= ~(DWC3_OCTL_HSTSETHNPEN | DWC3_OCTL_PRTPWRCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) dwc3_writel(dwc->regs, DWC3_OCTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /* should be called before the gadget controller driver is started */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static void dwc3_otg_device_init(struct dwc3 *dwc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* As per Figure 11-20 B-Device Flow Diagram */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * OCFG.HNPCap = GHWPARAMS6.HNP_CAP, OCFG.SRPCap = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * but we keep them 0 for simple dual-role operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) reg = dwc3_readl(dwc->regs, DWC3_OCFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /* OCFG.OTGSftRstMsk = 0/1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) reg |= DWC3_OCFG_SFTRSTMASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) dwc3_writel(dwc->regs, DWC3_OCFG, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * OCTL.PeriMode = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * OCTL.TermSelDLPulse = 0/1, OCTL.HNPReq = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * OCTL.DevSetHNPEn = 0, OCTL.HstSetHNPEn = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) reg = dwc3_readl(dwc->regs, DWC3_OCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) reg |= DWC3_OCTL_PERIMODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) reg &= ~(DWC3_OCTL_TERMSELIDPULSE | DWC3_OCTL_HNPREQ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HSTSETHNPEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) dwc3_writel(dwc->regs, DWC3_OCTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /* OEVTEN.OTGBDevSesVldDetEvntEn = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) dwc3_otg_enable_events(dwc, DWC3_OEVTEN_BDEVSESSVLDDETEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /* GUSB2PHYCFG.ULPIAutoRes = 0, GUSB2PHYCFG0.SusPHY = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (!dwc->dis_u2_susphy_quirk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) reg |= DWC3_GUSB2PHYCFG_SUSPHY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /* GCTL.GblHibernationEn = 0. Already 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /* should be called after the gadget controller driver is stopped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) static void dwc3_otg_device_exit(struct dwc3 *dwc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * Exit from B-device flow as per
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * Figure 11-4 OTG Driver Overall Programming Flow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * OEVTEN.OTGBDevHNPChngEvntEn = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * OEVTEN.OTGBDevVBusChngEvntEn = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * OEVTEN.OTGBDevBHostEndEvntEn = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) dwc3_otg_disable_events(dwc, DWC3_OEVTEN_BDEVHNPCHNGEN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) DWC3_OEVTEN_BDEVVBUSCHNGEN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) DWC3_OEVTEN_BDEVBHOSTENDEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /* OCTL.DevSetHNPEn = 0, OCTL.HNPReq = 0, OCTL.PeriMode=1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) reg = dwc3_readl(dwc->regs, DWC3_OCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) reg &= ~(DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HNPREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) reg |= DWC3_OCTL_PERIMODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) dwc3_writel(dwc->regs, DWC3_OCTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) void dwc3_otg_update(struct dwc3 *dwc, bool ignore_idstatus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (dwc->dr_mode != USB_DR_MODE_OTG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) /* don't do anything if debug user changed role to not OTG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (dwc->current_dr_role != DWC3_GCTL_PRTCAP_OTG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (!ignore_idstatus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) reg = dwc3_readl(dwc->regs, DWC3_OSTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) id = !!(reg & DWC3_OSTS_CONIDSTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) dwc->desired_otg_role = id ? DWC3_OTG_ROLE_DEVICE :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) DWC3_OTG_ROLE_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (dwc->desired_otg_role == dwc->current_otg_role)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) switch (dwc->current_otg_role) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) case DWC3_OTG_ROLE_HOST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) dwc3_host_exit(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) spin_lock_irqsave(&dwc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) dwc3_otg_host_exit(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) spin_unlock_irqrestore(&dwc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) case DWC3_OTG_ROLE_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) dwc3_gadget_exit(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) spin_lock_irqsave(&dwc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) dwc3_event_buffers_cleanup(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) dwc3_otg_device_exit(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) spin_unlock_irqrestore(&dwc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) spin_lock_irqsave(&dwc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) dwc->current_otg_role = dwc->desired_otg_role;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) spin_unlock_irqrestore(&dwc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) switch (dwc->desired_otg_role) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) case DWC3_OTG_ROLE_HOST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) spin_lock_irqsave(&dwc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) dwc3_otgregs_init(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) dwc3_otg_host_init(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) spin_unlock_irqrestore(&dwc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) ret = dwc3_host_init(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) dev_err(dwc->dev, "failed to initialize host\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (dwc->usb2_phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) otg_set_vbus(dwc->usb2_phy->otg, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (dwc->usb2_generic_phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) phy_set_mode(dwc->usb2_generic_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) PHY_MODE_USB_HOST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) case DWC3_OTG_ROLE_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) spin_lock_irqsave(&dwc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) dwc3_otgregs_init(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) dwc3_otg_device_init(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) dwc3_event_buffers_setup(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) spin_unlock_irqrestore(&dwc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (dwc->usb2_phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) otg_set_vbus(dwc->usb2_phy->otg, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (dwc->usb2_generic_phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) phy_set_mode(dwc->usb2_generic_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) PHY_MODE_USB_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) ret = dwc3_gadget_init(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) dev_err(dwc->dev, "failed to initialize peripheral\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static void dwc3_drd_update(struct dwc3 *dwc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (dwc->edev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) id = extcon_get_state(dwc->edev, EXTCON_USB_HOST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (id < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) #if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (extcon_get_state(dwc->edev, EXTCON_USB))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) dwc->desired_role_sw_mode = USB_DR_MODE_PERIPHERAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) dwc3_set_mode(dwc, id ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) DWC3_GCTL_PRTCAP_HOST :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) DWC3_GCTL_PRTCAP_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) static int dwc3_drd_notifier(struct notifier_block *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) unsigned long event, void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) struct dwc3 *dwc = container_of(nb, struct dwc3, edev_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) #if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (extcon_get_state(dwc->edev, EXTCON_USB))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) dwc->desired_role_sw_mode = USB_DR_MODE_PERIPHERAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) else if (extcon_get_state(dwc->edev, EXTCON_USB_HOST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) dwc->desired_role_sw_mode = USB_DR_MODE_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) dwc->desired_role_sw_mode = USB_DR_MODE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) dwc3_set_mode(dwc, event ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) DWC3_GCTL_PRTCAP_HOST :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) DWC3_GCTL_PRTCAP_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct device *dev = dwc->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) struct device_node *np_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct extcon_dev *edev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (device_property_read_bool(dev, "extcon"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return extcon_get_edev_by_phandle(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * Device tree platforms should get extcon via phandle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) * On ACPI platforms, we get the name from a device property.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * This device property is for kernel internal use only and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * is expected to be set by the glue code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (device_property_read_string(dev, "linux,extcon-name", &name) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) edev = extcon_get_extcon_dev(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (!edev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) return ERR_PTR(-EPROBE_DEFER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return edev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * Try to get an extcon device from the USB PHY controller's "port"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * node. Check if it has the "port" node first, to avoid printing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * error message from underlying code, as it's a valid case: extcon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * device (and "port" node) may be missing in case of "usb-role-switch"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * or OTG mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) np_phy = of_parse_phandle(dev->of_node, "phys", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (of_graph_is_present(np_phy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) struct device_node *np_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) np_conn = of_graph_get_remote_node(np_phy, -1, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (np_conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) edev = extcon_find_edev_by_node(np_conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) of_node_put(np_conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) of_node_put(np_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return edev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) #if IS_ENABLED(CONFIG_USB_ROLE_SWITCH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) #define ROLE_SWITCH 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) static int dwc3_usb_role_switch_set(struct usb_role_switch *sw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) enum usb_role role)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) struct dwc3 *dwc = usb_role_switch_get_drvdata(sw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) u32 mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) #if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) dwc->desired_role_sw_mode = role;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) phy_set_mode_ext(dwc->usb2_generic_phy, PHY_MODE_USB_OTG, role);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) switch (role) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) case USB_ROLE_HOST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) mode = DWC3_GCTL_PRTCAP_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) case USB_ROLE_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) mode = DWC3_GCTL_PRTCAP_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (dwc->role_switch_default_mode == USB_DR_MODE_HOST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) mode = DWC3_GCTL_PRTCAP_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) mode = DWC3_GCTL_PRTCAP_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) dwc3_set_mode(dwc, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) static enum usb_role dwc3_usb_role_switch_get(struct usb_role_switch *sw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) struct dwc3 *dwc = usb_role_switch_get_drvdata(sw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) enum usb_role role;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) spin_lock_irqsave(&dwc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) switch (dwc->current_dr_role) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) case DWC3_GCTL_PRTCAP_HOST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) role = USB_ROLE_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) case DWC3_GCTL_PRTCAP_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) role = USB_ROLE_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) case DWC3_GCTL_PRTCAP_OTG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) role = dwc->current_otg_role;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (dwc->role_switch_default_mode == USB_DR_MODE_HOST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) role = USB_ROLE_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) role = USB_ROLE_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) spin_unlock_irqrestore(&dwc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return role;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) static int dwc3_setup_role_switch(struct dwc3 *dwc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) struct usb_role_switch_desc dwc3_role_switch = {NULL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) const char *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) u32 mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) ret = device_property_read_string(dwc->dev, "role-switch-default-mode",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) &str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (ret >= 0 && !strncmp(str, "host", strlen("host"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) dwc->role_switch_default_mode = USB_DR_MODE_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) mode = DWC3_GCTL_PRTCAP_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) dwc->role_switch_default_mode = USB_DR_MODE_PERIPHERAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) mode = DWC3_GCTL_PRTCAP_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) dwc3_role_switch.fwnode = dev_fwnode(dwc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) dwc3_role_switch.set = dwc3_usb_role_switch_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) dwc3_role_switch.get = dwc3_usb_role_switch_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) dwc3_role_switch.driver_data = dwc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) dwc->role_sw = usb_role_switch_register(dwc->dev, &dwc3_role_switch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (IS_ERR(dwc->role_sw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return PTR_ERR(dwc->role_sw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) dwc3_set_mode(dwc, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) #define ROLE_SWITCH 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) #define dwc3_setup_role_switch(x) 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) int dwc3_drd_init(struct dwc3 *dwc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) int ret, irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) dwc->edev = dwc3_get_extcon(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (IS_ERR(dwc->edev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) return PTR_ERR(dwc->edev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (ROLE_SWITCH &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) device_property_read_bool(dwc->dev, "usb-role-switch")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) ret = dwc3_setup_role_switch(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) } else if (dwc->edev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) dwc->edev_nb.notifier_call = dwc3_drd_notifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) ret = extcon_register_notifier(dwc->edev, EXTCON_USB_HOST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) &dwc->edev_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) dev_err(dwc->dev, "couldn't register cable notifier\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) dwc3_drd_update(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_OTG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) dwc->current_dr_role = DWC3_GCTL_PRTCAP_OTG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) /* use OTG block to get ID event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) irq = dwc3_otg_get_irq(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) dwc->otg_irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) /* disable all OTG IRQs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) dwc3_otg_disable_events(dwc, DWC3_OTG_ALL_EVENTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) /* clear all events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) dwc3_otg_clear_events(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) ret = request_threaded_irq(dwc->otg_irq, dwc3_otg_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) dwc3_otg_thread_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) IRQF_SHARED, "dwc3-otg", dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) dwc->otg_irq, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) dwc3_otg_init(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) void dwc3_drd_exit(struct dwc3 *dwc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (dwc->role_sw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) usb_role_switch_unregister(dwc->role_sw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) if (dwc->edev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) extcon_unregister_notifier(dwc->edev, EXTCON_USB_HOST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) &dwc->edev_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) cancel_work_sync(&dwc->drd_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) /* debug user might have changed role, clean based on current role */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) switch (dwc->current_dr_role) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) case DWC3_GCTL_PRTCAP_HOST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) dwc3_host_exit(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) case DWC3_GCTL_PRTCAP_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) dwc3_gadget_exit(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) dwc3_event_buffers_cleanup(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) case DWC3_GCTL_PRTCAP_OTG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) dwc3_otg_exit(dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) spin_lock_irqsave(&dwc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) dwc->desired_otg_role = DWC3_OTG_ROLE_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) spin_unlock_irqrestore(&dwc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) dwc3_otg_update(dwc, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (dwc->otg_irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) free_irq(dwc->otg_irq, dwc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }