Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * drd.c - DesignWare USB3 DRD Controller Dual-role support
0004  *
0005  * Copyright (C) 2017 Texas Instruments Incorporated - https://www.ti.com
0006  *
0007  * Authors: Roger Quadros <rogerq@ti.com>
0008  */
0009 
0010 #include <linux/extcon.h>
0011 #include <linux/of_platform.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/property.h>
0014 
0015 #include "debug.h"
0016 #include "core.h"
0017 #include "gadget.h"
0018 
0019 static void dwc3_otg_disable_events(struct dwc3 *dwc, u32 disable_mask)
0020 {
0021     u32 reg = dwc3_readl(dwc->regs, DWC3_OEVTEN);
0022 
0023     reg &= ~(disable_mask);
0024     dwc3_writel(dwc->regs, DWC3_OEVTEN, reg);
0025 }
0026 
0027 static void dwc3_otg_enable_events(struct dwc3 *dwc, u32 enable_mask)
0028 {
0029     u32 reg = dwc3_readl(dwc->regs, DWC3_OEVTEN);
0030 
0031     reg |= (enable_mask);
0032     dwc3_writel(dwc->regs, DWC3_OEVTEN, reg);
0033 }
0034 
0035 static void dwc3_otg_clear_events(struct dwc3 *dwc)
0036 {
0037     u32 reg = dwc3_readl(dwc->regs, DWC3_OEVT);
0038 
0039     dwc3_writel(dwc->regs, DWC3_OEVTEN, reg);
0040 }
0041 
0042 #define DWC3_OTG_ALL_EVENTS (DWC3_OEVTEN_XHCIRUNSTPSETEN | \
0043         DWC3_OEVTEN_DEVRUNSTPSETEN | DWC3_OEVTEN_HIBENTRYEN | \
0044         DWC3_OEVTEN_CONIDSTSCHNGEN | DWC3_OEVTEN_HRRCONFNOTIFEN | \
0045         DWC3_OEVTEN_HRRINITNOTIFEN | DWC3_OEVTEN_ADEVIDLEEN | \
0046         DWC3_OEVTEN_ADEVBHOSTENDEN | DWC3_OEVTEN_ADEVHOSTEN | \
0047         DWC3_OEVTEN_ADEVHNPCHNGEN | DWC3_OEVTEN_ADEVSRPDETEN | \
0048         DWC3_OEVTEN_ADEVSESSENDDETEN | DWC3_OEVTEN_BDEVBHOSTENDEN | \
0049         DWC3_OEVTEN_BDEVHNPCHNGEN | DWC3_OEVTEN_BDEVSESSVLDDETEN | \
0050         DWC3_OEVTEN_BDEVVBUSCHNGEN)
0051 
0052 static irqreturn_t dwc3_otg_thread_irq(int irq, void *_dwc)
0053 {
0054     struct dwc3 *dwc = _dwc;
0055 
0056     spin_lock(&dwc->lock);
0057     if (dwc->otg_restart_host) {
0058         dwc3_otg_host_init(dwc);
0059         dwc->otg_restart_host = false;
0060     }
0061 
0062     spin_unlock(&dwc->lock);
0063 
0064     dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG);
0065 
0066     return IRQ_HANDLED;
0067 }
0068 
0069 static irqreturn_t dwc3_otg_irq(int irq, void *_dwc)
0070 {
0071     u32 reg;
0072     struct dwc3 *dwc = _dwc;
0073     irqreturn_t ret = IRQ_NONE;
0074 
0075     reg = dwc3_readl(dwc->regs, DWC3_OEVT);
0076     if (reg) {
0077         /* ignore non OTG events, we can't disable them in OEVTEN */
0078         if (!(reg & DWC3_OTG_ALL_EVENTS)) {
0079             dwc3_writel(dwc->regs, DWC3_OEVT, reg);
0080             return IRQ_NONE;
0081         }
0082 
0083         if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST &&
0084             !(reg & DWC3_OEVT_DEVICEMODE))
0085             dwc->otg_restart_host = true;
0086         dwc3_writel(dwc->regs, DWC3_OEVT, reg);
0087         ret = IRQ_WAKE_THREAD;
0088     }
0089 
0090     return ret;
0091 }
0092 
0093 static void dwc3_otgregs_init(struct dwc3 *dwc)
0094 {
0095     u32 reg;
0096 
0097     /*
0098      * Prevent host/device reset from resetting OTG core.
0099      * If we don't do this then xhci_reset (USBCMD.HCRST) will reset
0100      * the signal outputs sent to the PHY, the OTG FSM logic of the
0101      * core and also the resets to the VBUS filters inside the core.
0102      */
0103     reg = dwc3_readl(dwc->regs, DWC3_OCFG);
0104     reg |= DWC3_OCFG_SFTRSTMASK;
0105     dwc3_writel(dwc->regs, DWC3_OCFG, reg);
0106 
0107     /* Disable hibernation for simplicity */
0108     reg = dwc3_readl(dwc->regs, DWC3_GCTL);
0109     reg &= ~DWC3_GCTL_GBLHIBERNATIONEN;
0110     dwc3_writel(dwc->regs, DWC3_GCTL, reg);
0111 
0112     /*
0113      * Initialize OTG registers as per
0114      * Figure 11-4 OTG Driver Overall Programming Flow
0115      */
0116     /* OCFG.SRPCap = 0, OCFG.HNPCap = 0 */
0117     reg = dwc3_readl(dwc->regs, DWC3_OCFG);
0118     reg &= ~(DWC3_OCFG_SRPCAP | DWC3_OCFG_HNPCAP);
0119     dwc3_writel(dwc->regs, DWC3_OCFG, reg);
0120     /* OEVT = FFFF */
0121     dwc3_otg_clear_events(dwc);
0122     /* OEVTEN = 0 */
0123     dwc3_otg_disable_events(dwc, DWC3_OTG_ALL_EVENTS);
0124     /* OEVTEN.ConIDStsChngEn = 1. Instead we enable all events */
0125     dwc3_otg_enable_events(dwc, DWC3_OTG_ALL_EVENTS);
0126     /*
0127      * OCTL.PeriMode = 1, OCTL.DevSetHNPEn = 0, OCTL.HstSetHNPEn = 0,
0128      * OCTL.HNPReq = 0
0129      */
0130     reg = dwc3_readl(dwc->regs, DWC3_OCTL);
0131     reg |= DWC3_OCTL_PERIMODE;
0132     reg &= ~(DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HSTSETHNPEN |
0133          DWC3_OCTL_HNPREQ);
0134     dwc3_writel(dwc->regs, DWC3_OCTL, reg);
0135 }
0136 
0137 static int dwc3_otg_get_irq(struct dwc3 *dwc)
0138 {
0139     struct platform_device *dwc3_pdev = to_platform_device(dwc->dev);
0140     int irq;
0141 
0142     irq = platform_get_irq_byname_optional(dwc3_pdev, "otg");
0143     if (irq > 0)
0144         goto out;
0145 
0146     if (irq == -EPROBE_DEFER)
0147         goto out;
0148 
0149     irq = platform_get_irq_byname_optional(dwc3_pdev, "dwc_usb3");
0150     if (irq > 0)
0151         goto out;
0152 
0153     if (irq == -EPROBE_DEFER)
0154         goto out;
0155 
0156     irq = platform_get_irq(dwc3_pdev, 0);
0157     if (irq > 0)
0158         goto out;
0159 
0160     if (!irq)
0161         irq = -EINVAL;
0162 
0163 out:
0164     return irq;
0165 }
0166 
0167 void dwc3_otg_init(struct dwc3 *dwc)
0168 {
0169     u32 reg;
0170 
0171     /*
0172      * As per Figure 11-4 OTG Driver Overall Programming Flow,
0173      * block "Initialize GCTL for OTG operation".
0174      */
0175     /* GCTL.PrtCapDir=2'b11 */
0176     dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_OTG);
0177     /* GUSB2PHYCFG0.SusPHY=0 */
0178     reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
0179     reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
0180     dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
0181 
0182     /* Initialize OTG registers */
0183     dwc3_otgregs_init(dwc);
0184 }
0185 
0186 void dwc3_otg_exit(struct dwc3 *dwc)
0187 {
0188     /* disable all OTG IRQs */
0189     dwc3_otg_disable_events(dwc, DWC3_OTG_ALL_EVENTS);
0190     /* clear all events */
0191     dwc3_otg_clear_events(dwc);
0192 }
0193 
0194 /* should be called before Host controller driver is started */
0195 void dwc3_otg_host_init(struct dwc3 *dwc)
0196 {
0197     u32 reg;
0198 
0199     /* As per Figure 11-10 A-Device Flow Diagram */
0200     /* OCFG.HNPCap = 0, OCFG.SRPCap = 0. Already 0 */
0201 
0202     /*
0203      * OCTL.PeriMode=0, OCTL.TermSelDLPulse = 0,
0204      * OCTL.DevSetHNPEn = 0, OCTL.HstSetHNPEn = 0
0205      */
0206     reg = dwc3_readl(dwc->regs, DWC3_OCTL);
0207     reg &= ~(DWC3_OCTL_PERIMODE | DWC3_OCTL_TERMSELIDPULSE |
0208             DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HSTSETHNPEN);
0209     dwc3_writel(dwc->regs, DWC3_OCTL, reg);
0210 
0211     /*
0212      * OCFG.DisPrtPwrCutoff = 0/1
0213      */
0214     reg = dwc3_readl(dwc->regs, DWC3_OCFG);
0215     reg &= ~DWC3_OCFG_DISPWRCUTTOFF;
0216     dwc3_writel(dwc->regs, DWC3_OCFG, reg);
0217 
0218     /*
0219      * OCFG.SRPCap = 1, OCFG.HNPCap = GHWPARAMS6.HNP_CAP
0220      * We don't want SRP/HNP for simple dual-role so leave
0221      * these disabled.
0222      */
0223 
0224     /*
0225      * OEVTEN.OTGADevHostEvntEn = 1
0226      * OEVTEN.OTGADevSessEndDetEvntEn = 1
0227      * We don't want HNP/role-swap so leave these disabled.
0228      */
0229 
0230     /* GUSB2PHYCFG.ULPIAutoRes = 1/0, GUSB2PHYCFG.SusPHY = 1 */
0231     if (!dwc->dis_u2_susphy_quirk) {
0232         reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
0233         reg |= DWC3_GUSB2PHYCFG_SUSPHY;
0234         dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
0235     }
0236 
0237     /* Set Port Power to enable VBUS: OCTL.PrtPwrCtl = 1 */
0238     reg = dwc3_readl(dwc->regs, DWC3_OCTL);
0239     reg |= DWC3_OCTL_PRTPWRCTL;
0240     dwc3_writel(dwc->regs, DWC3_OCTL, reg);
0241 }
0242 
0243 /* should be called after Host controller driver is stopped */
0244 static void dwc3_otg_host_exit(struct dwc3 *dwc)
0245 {
0246     u32 reg;
0247 
0248     /*
0249      * Exit from A-device flow as per
0250      * Figure 11-4 OTG Driver Overall Programming Flow
0251      */
0252 
0253     /*
0254      * OEVTEN.OTGADevBHostEndEvntEn=0, OEVTEN.OTGADevHNPChngEvntEn=0
0255      * OEVTEN.OTGADevSessEndDetEvntEn=0,
0256      * OEVTEN.OTGADevHostEvntEn = 0
0257      * But we don't disable any OTG events
0258      */
0259 
0260     /* OCTL.HstSetHNPEn = 0, OCTL.PrtPwrCtl=0 */
0261     reg = dwc3_readl(dwc->regs, DWC3_OCTL);
0262     reg &= ~(DWC3_OCTL_HSTSETHNPEN | DWC3_OCTL_PRTPWRCTL);
0263     dwc3_writel(dwc->regs, DWC3_OCTL, reg);
0264 }
0265 
0266 /* should be called before the gadget controller driver is started */
0267 static void dwc3_otg_device_init(struct dwc3 *dwc)
0268 {
0269     u32 reg;
0270 
0271     /* As per Figure 11-20 B-Device Flow Diagram */
0272 
0273     /*
0274      * OCFG.HNPCap = GHWPARAMS6.HNP_CAP, OCFG.SRPCap = 1
0275      * but we keep them 0 for simple dual-role operation.
0276      */
0277     reg = dwc3_readl(dwc->regs, DWC3_OCFG);
0278     /* OCFG.OTGSftRstMsk = 0/1 */
0279     reg |= DWC3_OCFG_SFTRSTMASK;
0280     dwc3_writel(dwc->regs, DWC3_OCFG, reg);
0281     /*
0282      * OCTL.PeriMode = 1
0283      * OCTL.TermSelDLPulse = 0/1, OCTL.HNPReq = 0
0284      * OCTL.DevSetHNPEn = 0, OCTL.HstSetHNPEn = 0
0285      */
0286     reg = dwc3_readl(dwc->regs, DWC3_OCTL);
0287     reg |= DWC3_OCTL_PERIMODE;
0288     reg &= ~(DWC3_OCTL_TERMSELIDPULSE | DWC3_OCTL_HNPREQ |
0289             DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HSTSETHNPEN);
0290     dwc3_writel(dwc->regs, DWC3_OCTL, reg);
0291     /* OEVTEN.OTGBDevSesVldDetEvntEn = 1 */
0292     dwc3_otg_enable_events(dwc, DWC3_OEVTEN_BDEVSESSVLDDETEN);
0293     /* GUSB2PHYCFG.ULPIAutoRes = 0, GUSB2PHYCFG0.SusPHY = 1 */
0294     if (!dwc->dis_u2_susphy_quirk) {
0295         reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
0296         reg |= DWC3_GUSB2PHYCFG_SUSPHY;
0297         dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
0298     }
0299     /* GCTL.GblHibernationEn = 0. Already 0. */
0300 }
0301 
0302 /* should be called after the gadget controller driver is stopped */
0303 static void dwc3_otg_device_exit(struct dwc3 *dwc)
0304 {
0305     u32 reg;
0306 
0307     /*
0308      * Exit from B-device flow as per
0309      * Figure 11-4 OTG Driver Overall Programming Flow
0310      */
0311 
0312     /*
0313      * OEVTEN.OTGBDevHNPChngEvntEn = 0
0314      * OEVTEN.OTGBDevVBusChngEvntEn = 0
0315      * OEVTEN.OTGBDevBHostEndEvntEn = 0
0316      */
0317     dwc3_otg_disable_events(dwc, DWC3_OEVTEN_BDEVHNPCHNGEN |
0318                 DWC3_OEVTEN_BDEVVBUSCHNGEN |
0319                 DWC3_OEVTEN_BDEVBHOSTENDEN);
0320 
0321     /* OCTL.DevSetHNPEn = 0, OCTL.HNPReq = 0, OCTL.PeriMode=1 */
0322     reg = dwc3_readl(dwc->regs, DWC3_OCTL);
0323     reg &= ~(DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HNPREQ);
0324     reg |= DWC3_OCTL_PERIMODE;
0325     dwc3_writel(dwc->regs, DWC3_OCTL, reg);
0326 }
0327 
0328 void dwc3_otg_update(struct dwc3 *dwc, bool ignore_idstatus)
0329 {
0330     int ret;
0331     u32 reg;
0332     int id;
0333     unsigned long flags;
0334 
0335     if (dwc->dr_mode != USB_DR_MODE_OTG)
0336         return;
0337 
0338     /* don't do anything if debug user changed role to not OTG */
0339     if (dwc->current_dr_role != DWC3_GCTL_PRTCAP_OTG)
0340         return;
0341 
0342     if (!ignore_idstatus) {
0343         reg = dwc3_readl(dwc->regs, DWC3_OSTS);
0344         id = !!(reg & DWC3_OSTS_CONIDSTS);
0345 
0346         dwc->desired_otg_role = id ? DWC3_OTG_ROLE_DEVICE :
0347                     DWC3_OTG_ROLE_HOST;
0348     }
0349 
0350     if (dwc->desired_otg_role == dwc->current_otg_role)
0351         return;
0352 
0353     switch (dwc->current_otg_role) {
0354     case DWC3_OTG_ROLE_HOST:
0355         dwc3_host_exit(dwc);
0356         spin_lock_irqsave(&dwc->lock, flags);
0357         dwc3_otg_host_exit(dwc);
0358         spin_unlock_irqrestore(&dwc->lock, flags);
0359         break;
0360     case DWC3_OTG_ROLE_DEVICE:
0361         dwc3_gadget_exit(dwc);
0362         spin_lock_irqsave(&dwc->lock, flags);
0363         dwc3_event_buffers_cleanup(dwc);
0364         dwc3_otg_device_exit(dwc);
0365         spin_unlock_irqrestore(&dwc->lock, flags);
0366         break;
0367     default:
0368         break;
0369     }
0370 
0371     spin_lock_irqsave(&dwc->lock, flags);
0372 
0373     dwc->current_otg_role = dwc->desired_otg_role;
0374 
0375     spin_unlock_irqrestore(&dwc->lock, flags);
0376 
0377     switch (dwc->desired_otg_role) {
0378     case DWC3_OTG_ROLE_HOST:
0379         spin_lock_irqsave(&dwc->lock, flags);
0380         dwc3_otgregs_init(dwc);
0381         dwc3_otg_host_init(dwc);
0382         spin_unlock_irqrestore(&dwc->lock, flags);
0383         ret = dwc3_host_init(dwc);
0384         if (ret) {
0385             dev_err(dwc->dev, "failed to initialize host\n");
0386         } else {
0387             if (dwc->usb2_phy)
0388                 otg_set_vbus(dwc->usb2_phy->otg, true);
0389             if (dwc->usb2_generic_phy)
0390                 phy_set_mode(dwc->usb2_generic_phy,
0391                          PHY_MODE_USB_HOST);
0392         }
0393         break;
0394     case DWC3_OTG_ROLE_DEVICE:
0395         spin_lock_irqsave(&dwc->lock, flags);
0396         dwc3_otgregs_init(dwc);
0397         dwc3_otg_device_init(dwc);
0398         dwc3_event_buffers_setup(dwc);
0399         spin_unlock_irqrestore(&dwc->lock, flags);
0400 
0401         if (dwc->usb2_phy)
0402             otg_set_vbus(dwc->usb2_phy->otg, false);
0403         if (dwc->usb2_generic_phy)
0404             phy_set_mode(dwc->usb2_generic_phy,
0405                      PHY_MODE_USB_DEVICE);
0406         ret = dwc3_gadget_init(dwc);
0407         if (ret)
0408             dev_err(dwc->dev, "failed to initialize peripheral\n");
0409         break;
0410     default:
0411         break;
0412     }
0413 }
0414 
0415 static void dwc3_drd_update(struct dwc3 *dwc)
0416 {
0417     int id;
0418 
0419     if (dwc->edev) {
0420         id = extcon_get_state(dwc->edev, EXTCON_USB_HOST);
0421         if (id < 0)
0422             id = 0;
0423         dwc3_set_mode(dwc, id ?
0424                   DWC3_GCTL_PRTCAP_HOST :
0425                   DWC3_GCTL_PRTCAP_DEVICE);
0426     }
0427 }
0428 
0429 static int dwc3_drd_notifier(struct notifier_block *nb,
0430                  unsigned long event, void *ptr)
0431 {
0432     struct dwc3 *dwc = container_of(nb, struct dwc3, edev_nb);
0433 
0434     dwc3_set_mode(dwc, event ?
0435               DWC3_GCTL_PRTCAP_HOST :
0436               DWC3_GCTL_PRTCAP_DEVICE);
0437 
0438     return NOTIFY_DONE;
0439 }
0440 
0441 #if IS_ENABLED(CONFIG_USB_ROLE_SWITCH)
0442 #define ROLE_SWITCH 1
0443 static int dwc3_usb_role_switch_set(struct usb_role_switch *sw,
0444                     enum usb_role role)
0445 {
0446     struct dwc3 *dwc = usb_role_switch_get_drvdata(sw);
0447     u32 mode;
0448 
0449     switch (role) {
0450     case USB_ROLE_HOST:
0451         mode = DWC3_GCTL_PRTCAP_HOST;
0452         break;
0453     case USB_ROLE_DEVICE:
0454         mode = DWC3_GCTL_PRTCAP_DEVICE;
0455         break;
0456     default:
0457         if (dwc->role_switch_default_mode == USB_DR_MODE_HOST)
0458             mode = DWC3_GCTL_PRTCAP_HOST;
0459         else
0460             mode = DWC3_GCTL_PRTCAP_DEVICE;
0461         break;
0462     }
0463 
0464     dwc3_set_mode(dwc, mode);
0465     return 0;
0466 }
0467 
0468 static enum usb_role dwc3_usb_role_switch_get(struct usb_role_switch *sw)
0469 {
0470     struct dwc3 *dwc = usb_role_switch_get_drvdata(sw);
0471     unsigned long flags;
0472     enum usb_role role;
0473 
0474     spin_lock_irqsave(&dwc->lock, flags);
0475     switch (dwc->current_dr_role) {
0476     case DWC3_GCTL_PRTCAP_HOST:
0477         role = USB_ROLE_HOST;
0478         break;
0479     case DWC3_GCTL_PRTCAP_DEVICE:
0480         role = USB_ROLE_DEVICE;
0481         break;
0482     case DWC3_GCTL_PRTCAP_OTG:
0483         role = dwc->current_otg_role;
0484         break;
0485     default:
0486         if (dwc->role_switch_default_mode == USB_DR_MODE_HOST)
0487             role = USB_ROLE_HOST;
0488         else
0489             role = USB_ROLE_DEVICE;
0490         break;
0491     }
0492     spin_unlock_irqrestore(&dwc->lock, flags);
0493     return role;
0494 }
0495 
0496 static int dwc3_setup_role_switch(struct dwc3 *dwc)
0497 {
0498     struct usb_role_switch_desc dwc3_role_switch = {NULL};
0499     u32 mode;
0500 
0501     dwc->role_switch_default_mode = usb_get_role_switch_default_mode(dwc->dev);
0502     if (dwc->role_switch_default_mode == USB_DR_MODE_HOST) {
0503         mode = DWC3_GCTL_PRTCAP_HOST;
0504     } else {
0505         dwc->role_switch_default_mode = USB_DR_MODE_PERIPHERAL;
0506         mode = DWC3_GCTL_PRTCAP_DEVICE;
0507     }
0508 
0509     dwc3_role_switch.fwnode = dev_fwnode(dwc->dev);
0510     dwc3_role_switch.set = dwc3_usb_role_switch_set;
0511     dwc3_role_switch.get = dwc3_usb_role_switch_get;
0512     dwc3_role_switch.driver_data = dwc;
0513     dwc->role_sw = usb_role_switch_register(dwc->dev, &dwc3_role_switch);
0514     if (IS_ERR(dwc->role_sw))
0515         return PTR_ERR(dwc->role_sw);
0516 
0517     if (dwc->dev->of_node) {
0518         /* populate connector entry */
0519         int ret = devm_of_platform_populate(dwc->dev);
0520 
0521         if (ret) {
0522             usb_role_switch_unregister(dwc->role_sw);
0523             dwc->role_sw = NULL;
0524             dev_err(dwc->dev, "DWC3 platform devices creation failed: %i\n", ret);
0525             return ret;
0526         }
0527     }
0528 
0529     dwc3_set_mode(dwc, mode);
0530     return 0;
0531 }
0532 #else
0533 #define ROLE_SWITCH 0
0534 #define dwc3_setup_role_switch(x) 0
0535 #endif
0536 
0537 int dwc3_drd_init(struct dwc3 *dwc)
0538 {
0539     int ret, irq;
0540 
0541     if (ROLE_SWITCH &&
0542         device_property_read_bool(dwc->dev, "usb-role-switch"))
0543         return dwc3_setup_role_switch(dwc);
0544 
0545     if (dwc->edev) {
0546         dwc->edev_nb.notifier_call = dwc3_drd_notifier;
0547         ret = extcon_register_notifier(dwc->edev, EXTCON_USB_HOST,
0548                            &dwc->edev_nb);
0549         if (ret < 0) {
0550             dev_err(dwc->dev, "couldn't register cable notifier\n");
0551             return ret;
0552         }
0553 
0554         dwc3_drd_update(dwc);
0555     } else {
0556         dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_OTG);
0557 
0558         /* use OTG block to get ID event */
0559         irq = dwc3_otg_get_irq(dwc);
0560         if (irq < 0)
0561             return irq;
0562 
0563         dwc->otg_irq = irq;
0564 
0565         /* disable all OTG IRQs */
0566         dwc3_otg_disable_events(dwc, DWC3_OTG_ALL_EVENTS);
0567         /* clear all events */
0568         dwc3_otg_clear_events(dwc);
0569 
0570         ret = request_threaded_irq(dwc->otg_irq, dwc3_otg_irq,
0571                        dwc3_otg_thread_irq,
0572                        IRQF_SHARED, "dwc3-otg", dwc);
0573         if (ret) {
0574             dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
0575                 dwc->otg_irq, ret);
0576             ret = -ENODEV;
0577             return ret;
0578         }
0579 
0580         dwc3_otg_init(dwc);
0581         dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG);
0582     }
0583 
0584     return 0;
0585 }
0586 
0587 void dwc3_drd_exit(struct dwc3 *dwc)
0588 {
0589     unsigned long flags;
0590 
0591     if (dwc->role_sw)
0592         usb_role_switch_unregister(dwc->role_sw);
0593 
0594     if (dwc->edev)
0595         extcon_unregister_notifier(dwc->edev, EXTCON_USB_HOST,
0596                        &dwc->edev_nb);
0597 
0598     cancel_work_sync(&dwc->drd_work);
0599 
0600     /* debug user might have changed role, clean based on current role */
0601     switch (dwc->current_dr_role) {
0602     case DWC3_GCTL_PRTCAP_HOST:
0603         dwc3_host_exit(dwc);
0604         break;
0605     case DWC3_GCTL_PRTCAP_DEVICE:
0606         dwc3_gadget_exit(dwc);
0607         dwc3_event_buffers_cleanup(dwc);
0608         break;
0609     case DWC3_GCTL_PRTCAP_OTG:
0610         dwc3_otg_exit(dwc);
0611         spin_lock_irqsave(&dwc->lock, flags);
0612         dwc->desired_otg_role = DWC3_OTG_ROLE_IDLE;
0613         spin_unlock_irqrestore(&dwc->lock, flags);
0614         dwc3_otg_update(dwc, 1);
0615         break;
0616     default:
0617         break;
0618     }
0619 
0620     if (dwc->otg_irq)
0621         free_irq(dwc->otg_irq, dwc);
0622 }