cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

drd.c (15526B)


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