summaryrefslogtreecommitdiff
path: root/drivers/usb/dwc3
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/dwc3')
-rw-r--r--drivers/usb/dwc3/Kconfig11
-rw-r--r--drivers/usb/dwc3/Makefile1
-rw-r--r--drivers/usb/dwc3/core.c215
-rw-r--r--drivers/usb/dwc3/core.h14
-rw-r--r--drivers/usb/dwc3/debugfs.c44
-rw-r--r--drivers/usb/dwc3/drd.c86
-rw-r--r--drivers/usb/dwc3/dwc3-google.c626
-rw-r--r--drivers/usb/dwc3/dwc3-imx8mp.c47
-rw-r--r--drivers/usb/dwc3/dwc3-xilinx.c71
-rw-r--r--drivers/usb/dwc3/ep0.c22
-rw-r--r--drivers/usb/dwc3/gadget.c172
-rw-r--r--drivers/usb/dwc3/gadget.h4
-rw-r--r--drivers/usb/dwc3/io.h11
-rw-r--r--drivers/usb/dwc3/trace.h88
-rw-r--r--drivers/usb/dwc3/ulpi.c10
15 files changed, 1065 insertions, 357 deletions
diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index bf3e04635131..240b15bc52cb 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -211,4 +211,15 @@ config USB_DWC3_APPLE
mode on these machines.
Say 'Y' or 'M' if you have such device.
+config USB_DWC3_GOOGLE
+ tristate "Google Platform"
+ help
+ Support the DesignWare Core USB3 IP found on Google Tensor SoCs,
+ starting with the G5 generation (Laguna). This driver includes
+ support for hibernation in host mode.
+ Say 'Y' or 'M' if you have one such device.
+
+ To compile this driver as a module, choose M here: the
+ module will be called dwc3-google.ko.
+
endif
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index 89d46ab50068..073bef5309b5 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -59,3 +59,4 @@ obj-$(CONFIG_USB_DWC3_XILINX) += dwc3-xilinx.o
obj-$(CONFIG_USB_DWC3_OCTEON) += dwc3-octeon.o
obj-$(CONFIG_USB_DWC3_RTK) += dwc3-rtk.o
obj-$(CONFIG_USB_DWC3_GENERIC_PLAT) += dwc3-generic-plat.o
+obj-$(CONFIG_USB_DWC3_GOOGLE) += dwc3-google.o
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 93fd5fdf95cb..161a4d58b2ce 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -114,23 +114,23 @@ void dwc3_enable_susphy(struct dwc3 *dwc, bool enable)
int i;
for (i = 0; i < dwc->num_usb3_ports; i++) {
- reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(i));
+ reg = dwc3_readl(dwc, DWC3_GUSB3PIPECTL(i));
if (enable && !dwc->dis_u3_susphy_quirk)
reg |= DWC3_GUSB3PIPECTL_SUSPHY;
else
reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
- dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(i), reg);
+ dwc3_writel(dwc, DWC3_GUSB3PIPECTL(i), reg);
}
for (i = 0; i < dwc->num_usb2_ports; i++) {
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(i));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(i));
if (enable && !dwc->dis_u2_susphy_quirk)
reg |= DWC3_GUSB2PHYCFG_SUSPHY;
else
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(i), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(i), reg);
}
}
EXPORT_SYMBOL_GPL(dwc3_enable_susphy);
@@ -140,7 +140,7 @@ void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode, bool ignore_susphy)
unsigned int hw_mode;
u32 reg;
- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+ reg = dwc3_readl(dwc, DWC3_GCTL);
/*
* For DRD controllers, GUSB3PIPECTL.SUSPENDENABLE and
@@ -155,10 +155,10 @@ void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode, bool ignore_susphy)
reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
reg |= DWC3_GCTL_PRTCAPDIR(mode);
- dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+ dwc3_writel(dwc, DWC3_GCTL, reg);
dwc->current_dr_role = mode;
- trace_dwc3_set_prtcap(mode);
+ trace_dwc3_set_prtcap(dwc, mode);
}
EXPORT_SYMBOL_GPL(dwc3_set_prtcap);
@@ -216,9 +216,9 @@ static void __dwc3_set_mode(struct work_struct *work)
if (dwc->current_dr_role && ((DWC3_IP_IS(DWC3) ||
DWC3_VER_IS_PRIOR(DWC31, 190A)) &&
desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) {
- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+ reg = dwc3_readl(dwc, DWC3_GCTL);
reg |= DWC3_GCTL_CORESOFTRESET;
- dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+ dwc3_writel(dwc, DWC3_GCTL, reg);
/*
* Wait for internal clocks to synchronized. DWC_usb31 and
@@ -228,9 +228,9 @@ static void __dwc3_set_mode(struct work_struct *work)
*/
msleep(100);
- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+ reg = dwc3_readl(dwc, DWC3_GCTL);
reg &= ~DWC3_GCTL_CORESOFTRESET;
- dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+ dwc3_writel(dwc, DWC3_GCTL, reg);
}
spin_lock_irqsave(&dwc->lock, flags);
@@ -254,9 +254,9 @@ static void __dwc3_set_mode(struct work_struct *work)
phy_set_mode(dwc->usb3_generic_phy[i], PHY_MODE_USB_HOST);
if (dwc->dis_split_quirk) {
- reg = dwc3_readl(dwc->regs, DWC3_GUCTL3);
+ reg = dwc3_readl(dwc, DWC3_GUCTL3);
reg |= DWC3_GUCTL3_SPLITDISABLE;
- dwc3_writel(dwc->regs, DWC3_GUCTL3, reg);
+ dwc3_writel(dwc, DWC3_GUCTL3, reg);
}
}
break;
@@ -306,11 +306,11 @@ u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type)
struct dwc3 *dwc = dep->dwc;
u32 reg;
- dwc3_writel(dwc->regs, DWC3_GDBGFIFOSPACE,
- DWC3_GDBGFIFOSPACE_NUM(dep->number) |
- DWC3_GDBGFIFOSPACE_TYPE(type));
+ dwc3_writel(dwc, DWC3_GDBGFIFOSPACE,
+ DWC3_GDBGFIFOSPACE_NUM(dep->number) |
+ DWC3_GDBGFIFOSPACE_TYPE(type));
- reg = dwc3_readl(dwc->regs, DWC3_GDBGFIFOSPACE);
+ reg = dwc3_readl(dwc, DWC3_GDBGFIFOSPACE);
return DWC3_GDBGFIFOSPACE_SPACE_AVAILABLE(reg);
}
@@ -332,7 +332,7 @@ int dwc3_core_soft_reset(struct dwc3 *dwc)
if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST)
return 0;
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
reg |= DWC3_DCTL_CSFTRST;
reg &= ~DWC3_DCTL_RUN_STOP;
dwc3_gadget_dctl_write_safe(dwc, reg);
@@ -347,7 +347,7 @@ int dwc3_core_soft_reset(struct dwc3 *dwc)
retries = 10;
do {
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
if (!(reg & DWC3_DCTL_CSFTRST))
goto done;
@@ -387,12 +387,12 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc)
if (dwc->fladj == 0)
return;
- reg = dwc3_readl(dwc->regs, DWC3_GFLADJ);
+ reg = dwc3_readl(dwc, DWC3_GFLADJ);
dft = reg & DWC3_GFLADJ_30MHZ_MASK;
if (dft != dwc->fladj) {
reg &= ~DWC3_GFLADJ_30MHZ_MASK;
reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | dwc->fladj;
- dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
+ dwc3_writel(dwc, DWC3_GFLADJ, reg);
}
}
@@ -424,10 +424,10 @@ static void dwc3_ref_clk_period(struct dwc3 *dwc)
return;
}
- reg = dwc3_readl(dwc->regs, DWC3_GUCTL);
+ reg = dwc3_readl(dwc, DWC3_GUCTL);
reg &= ~DWC3_GUCTL_REFCLKPER_MASK;
reg |= FIELD_PREP(DWC3_GUCTL_REFCLKPER_MASK, period);
- dwc3_writel(dwc->regs, DWC3_GUCTL, reg);
+ dwc3_writel(dwc, DWC3_GUCTL, reg);
if (DWC3_VER_IS_PRIOR(DWC3, 250A))
return;
@@ -455,7 +455,7 @@ static void dwc3_ref_clk_period(struct dwc3 *dwc)
*/
decr = 480000000 / rate;
- reg = dwc3_readl(dwc->regs, DWC3_GFLADJ);
+ reg = dwc3_readl(dwc, DWC3_GFLADJ);
reg &= ~DWC3_GFLADJ_REFCLK_FLADJ_MASK
& ~DWC3_GFLADJ_240MHZDECR
& ~DWC3_GFLADJ_240MHZDECR_PLS1;
@@ -466,7 +466,7 @@ static void dwc3_ref_clk_period(struct dwc3 *dwc)
if (dwc->gfladj_refclk_lpm_sel)
reg |= DWC3_GFLADJ_REFCLK_LPM_SEL;
- dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
+ dwc3_writel(dwc, DWC3_GFLADJ, reg);
}
/**
@@ -569,16 +569,16 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc)
evt = dwc->ev_buf;
evt->lpos = 0;
- dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0),
- lower_32_bits(evt->dma));
- dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0),
- upper_32_bits(evt->dma));
- dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0),
- DWC3_GEVNTSIZ_SIZE(evt->length));
+ dwc3_writel(dwc, DWC3_GEVNTADRLO(0),
+ lower_32_bits(evt->dma));
+ dwc3_writel(dwc, DWC3_GEVNTADRHI(0),
+ upper_32_bits(evt->dma));
+ dwc3_writel(dwc, DWC3_GEVNTSIZ(0),
+ DWC3_GEVNTSIZ_SIZE(evt->length));
/* Clear any stale event */
- reg = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
- dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), reg);
+ reg = dwc3_readl(dwc, DWC3_GEVNTCOUNT(0));
+ dwc3_writel(dwc, DWC3_GEVNTCOUNT(0), reg);
return 0;
}
@@ -593,7 +593,7 @@ void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
* Exynos platforms may not be able to access event buffer if the
* controller failed to halt on dwc3_core_exit().
*/
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+ reg = dwc3_readl(dwc, DWC3_DSTS);
if (!(reg & DWC3_DSTS_DEVCTRLHLT))
return;
@@ -601,14 +601,14 @@ void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
evt->lpos = 0;
- dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0), 0);
- dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), 0);
- dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK
+ dwc3_writel(dwc, DWC3_GEVNTADRLO(0), 0);
+ dwc3_writel(dwc, DWC3_GEVNTADRHI(0), 0);
+ dwc3_writel(dwc, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK
| DWC3_GEVNTSIZ_SIZE(0));
/* Clear any stale event */
- reg = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
- dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), reg);
+ reg = dwc3_readl(dwc, DWC3_GEVNTCOUNT(0));
+ dwc3_writel(dwc, DWC3_GEVNTCOUNT(0), reg);
}
static void dwc3_core_num_eps(struct dwc3 *dwc)
@@ -622,18 +622,18 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
{
struct dwc3_hwparams *parms = &dwc->hwparams;
- parms->hwparams0 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS0);
- parms->hwparams1 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS1);
- parms->hwparams2 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS2);
- parms->hwparams3 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS3);
- parms->hwparams4 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS4);
- parms->hwparams5 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS5);
- parms->hwparams6 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
- parms->hwparams7 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS7);
- parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8);
+ parms->hwparams0 = dwc3_readl(dwc, DWC3_GHWPARAMS0);
+ parms->hwparams1 = dwc3_readl(dwc, DWC3_GHWPARAMS1);
+ parms->hwparams2 = dwc3_readl(dwc, DWC3_GHWPARAMS2);
+ parms->hwparams3 = dwc3_readl(dwc, DWC3_GHWPARAMS3);
+ parms->hwparams4 = dwc3_readl(dwc, DWC3_GHWPARAMS4);
+ parms->hwparams5 = dwc3_readl(dwc, DWC3_GHWPARAMS5);
+ parms->hwparams6 = dwc3_readl(dwc, DWC3_GHWPARAMS6);
+ parms->hwparams7 = dwc3_readl(dwc, DWC3_GHWPARAMS7);
+ parms->hwparams8 = dwc3_readl(dwc, DWC3_GHWPARAMS8);
if (DWC3_IP_IS(DWC32))
- parms->hwparams9 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS9);
+ parms->hwparams9 = dwc3_readl(dwc, DWC3_GHWPARAMS9);
}
static void dwc3_config_soc_bus(struct dwc3 *dwc)
@@ -641,10 +641,10 @@ static void dwc3_config_soc_bus(struct dwc3 *dwc)
if (dwc->gsbuscfg0_reqinfo != DWC3_GSBUSCFG0_REQINFO_UNSPECIFIED) {
u32 reg;
- reg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG0);
+ reg = dwc3_readl(dwc, DWC3_GSBUSCFG0);
reg &= ~DWC3_GSBUSCFG0_REQINFO(~0);
reg |= DWC3_GSBUSCFG0_REQINFO(dwc->gsbuscfg0_reqinfo);
- dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, reg);
+ dwc3_writel(dwc, DWC3_GSBUSCFG0, reg);
}
}
@@ -668,7 +668,7 @@ static int dwc3_ss_phy_setup(struct dwc3 *dwc, int index)
{
u32 reg;
- reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(index));
+ reg = dwc3_readl(dwc, DWC3_GUSB3PIPECTL(index));
/*
* Make sure UX_EXIT_PX is cleared as that causes issues with some
@@ -706,7 +706,7 @@ static int dwc3_ss_phy_setup(struct dwc3 *dwc, int index)
if (dwc->dis_del_phy_power_chg_quirk)
reg &= ~DWC3_GUSB3PIPECTL_DEPOCHANGE;
- dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(index), reg);
+ dwc3_writel(dwc, DWC3_GUSB3PIPECTL(index), reg);
return 0;
}
@@ -715,7 +715,7 @@ static int dwc3_hs_phy_setup(struct dwc3 *dwc, int index)
{
u32 reg;
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(index));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(index));
/* Select the HS PHY interface */
switch (DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3)) {
@@ -727,7 +727,7 @@ static int dwc3_hs_phy_setup(struct dwc3 *dwc, int index)
} else if (dwc->hsphy_interface &&
!strncmp(dwc->hsphy_interface, "ulpi", 4)) {
reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(index), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(index), reg);
} else {
/* Relying on default value. */
if (!(reg & DWC3_GUSB2PHYCFG_ULPI_UTMI))
@@ -777,7 +777,7 @@ static int dwc3_hs_phy_setup(struct dwc3 *dwc, int index)
if (dwc->ulpi_ext_vbus_drv)
reg |= DWC3_GUSB2PHYCFG_ULPIEXTVBUSDRV;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(index), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(index), reg);
return 0;
}
@@ -991,7 +991,7 @@ static bool dwc3_core_is_valid(struct dwc3 *dwc)
{
u32 reg;
- reg = dwc3_readl(dwc->regs, DWC3_GSNPSID);
+ reg = dwc3_readl(dwc, DWC3_GSNPSID);
dwc->ip = DWC3_GSNPS_ID(reg);
if (dwc->ip == DWC4_IP)
dwc->ip = DWC32_IP;
@@ -1000,8 +1000,8 @@ static bool dwc3_core_is_valid(struct dwc3 *dwc)
if (DWC3_IP_IS(DWC3)) {
dwc->revision = reg;
} else if (DWC3_IP_IS(DWC31) || DWC3_IP_IS(DWC32)) {
- dwc->revision = dwc3_readl(dwc->regs, DWC3_VER_NUMBER);
- dwc->version_type = dwc3_readl(dwc->regs, DWC3_VER_TYPE);
+ dwc->revision = dwc3_readl(dwc, DWC3_VER_NUMBER);
+ dwc->version_type = dwc3_readl(dwc, DWC3_VER_TYPE);
} else {
return false;
}
@@ -1015,7 +1015,7 @@ static void dwc3_core_setup_global_control(struct dwc3 *dwc)
unsigned int hw_mode;
u32 reg;
- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+ reg = dwc3_readl(dwc, DWC3_GCTL);
reg &= ~DWC3_GCTL_SCALEDOWN_MASK;
hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0);
power_opt = DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1);
@@ -1093,7 +1093,7 @@ static void dwc3_core_setup_global_control(struct dwc3 *dwc)
if (DWC3_VER_IS_PRIOR(DWC3, 190A))
reg |= DWC3_GCTL_U2RSTECN;
- dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+ dwc3_writel(dwc, DWC3_GCTL, reg);
}
static int dwc3_core_get_phy(struct dwc3 *dwc);
@@ -1113,7 +1113,7 @@ static void dwc3_set_incr_burst_type(struct dwc3 *dwc)
int ret;
int i;
- cfg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG0);
+ cfg = dwc3_readl(dwc, DWC3_GSBUSCFG0);
/*
* Handle property "snps,incr-burst-type-adjustment".
@@ -1188,7 +1188,7 @@ static void dwc3_set_incr_burst_type(struct dwc3 *dwc)
break;
}
- dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, cfg);
+ dwc3_writel(dwc, DWC3_GSBUSCFG0, cfg);
}
static void dwc3_set_power_down_clk_scale(struct dwc3 *dwc)
@@ -1213,12 +1213,12 @@ static void dwc3_set_power_down_clk_scale(struct dwc3 *dwc)
* (3x or more) to be within the requirement.
*/
scale = DIV_ROUND_UP(clk_get_rate(dwc->susp_clk), 16000);
- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+ reg = dwc3_readl(dwc, DWC3_GCTL);
if ((reg & DWC3_GCTL_PWRDNSCALE_MASK) < DWC3_GCTL_PWRDNSCALE(scale) ||
(reg & DWC3_GCTL_PWRDNSCALE_MASK) > DWC3_GCTL_PWRDNSCALE(scale*3)) {
reg &= ~(DWC3_GCTL_PWRDNSCALE_MASK);
reg |= DWC3_GCTL_PWRDNSCALE(scale);
- dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+ dwc3_writel(dwc, DWC3_GCTL, reg);
}
}
@@ -1241,7 +1241,7 @@ static void dwc3_config_threshold(struct dwc3 *dwc)
tx_maxburst = dwc->tx_max_burst_prd;
if (rx_thr_num && rx_maxburst) {
- reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG);
+ reg = dwc3_readl(dwc, DWC3_GRXTHRCFG);
reg |= DWC31_RXTHRNUMPKTSEL_PRD;
reg &= ~DWC31_RXTHRNUMPKT_PRD(~0);
@@ -1250,11 +1250,11 @@ static void dwc3_config_threshold(struct dwc3 *dwc)
reg &= ~DWC31_MAXRXBURSTSIZE_PRD(~0);
reg |= DWC31_MAXRXBURSTSIZE_PRD(rx_maxburst);
- dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg);
+ dwc3_writel(dwc, DWC3_GRXTHRCFG, reg);
}
if (tx_thr_num && tx_maxburst) {
- reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG);
+ reg = dwc3_readl(dwc, DWC3_GTXTHRCFG);
reg |= DWC31_TXTHRNUMPKTSEL_PRD;
reg &= ~DWC31_TXTHRNUMPKT_PRD(~0);
@@ -1263,7 +1263,7 @@ static void dwc3_config_threshold(struct dwc3 *dwc)
reg &= ~DWC31_MAXTXBURSTSIZE_PRD(~0);
reg |= DWC31_MAXTXBURSTSIZE_PRD(tx_maxburst);
- dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg);
+ dwc3_writel(dwc, DWC3_GTXTHRCFG, reg);
}
}
@@ -1274,7 +1274,7 @@ static void dwc3_config_threshold(struct dwc3 *dwc)
if (DWC3_IP_IS(DWC3)) {
if (rx_thr_num && rx_maxburst) {
- reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG);
+ reg = dwc3_readl(dwc, DWC3_GRXTHRCFG);
reg |= DWC3_GRXTHRCFG_PKTCNTSEL;
reg &= ~DWC3_GRXTHRCFG_RXPKTCNT(~0);
@@ -1283,11 +1283,11 @@ static void dwc3_config_threshold(struct dwc3 *dwc)
reg &= ~DWC3_GRXTHRCFG_MAXRXBURSTSIZE(~0);
reg |= DWC3_GRXTHRCFG_MAXRXBURSTSIZE(rx_maxburst);
- dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg);
+ dwc3_writel(dwc, DWC3_GRXTHRCFG, reg);
}
if (tx_thr_num && tx_maxburst) {
- reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG);
+ reg = dwc3_readl(dwc, DWC3_GTXTHRCFG);
reg |= DWC3_GTXTHRCFG_PKTCNTSEL;
reg &= ~DWC3_GTXTHRCFG_TXPKTCNT(~0);
@@ -1296,11 +1296,11 @@ static void dwc3_config_threshold(struct dwc3 *dwc)
reg &= ~DWC3_GTXTHRCFG_MAXTXBURSTSIZE(~0);
reg |= DWC3_GTXTHRCFG_MAXTXBURSTSIZE(tx_maxburst);
- dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg);
+ dwc3_writel(dwc, DWC3_GTXTHRCFG, reg);
}
} else {
if (rx_thr_num && rx_maxburst) {
- reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG);
+ reg = dwc3_readl(dwc, DWC3_GRXTHRCFG);
reg |= DWC31_GRXTHRCFG_PKTCNTSEL;
reg &= ~DWC31_GRXTHRCFG_RXPKTCNT(~0);
@@ -1309,11 +1309,11 @@ static void dwc3_config_threshold(struct dwc3 *dwc)
reg &= ~DWC31_GRXTHRCFG_MAXRXBURSTSIZE(~0);
reg |= DWC31_GRXTHRCFG_MAXRXBURSTSIZE(rx_maxburst);
- dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg);
+ dwc3_writel(dwc, DWC3_GRXTHRCFG, reg);
}
if (tx_thr_num && tx_maxburst) {
- reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG);
+ reg = dwc3_readl(dwc, DWC3_GTXTHRCFG);
reg |= DWC31_GTXTHRCFG_PKTCNTSEL;
reg &= ~DWC31_GTXTHRCFG_TXPKTCNT(~0);
@@ -1322,7 +1322,7 @@ static void dwc3_config_threshold(struct dwc3 *dwc)
reg &= ~DWC31_GTXTHRCFG_MAXTXBURSTSIZE(~0);
reg |= DWC31_GTXTHRCFG_MAXTXBURSTSIZE(tx_maxburst);
- dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg);
+ dwc3_writel(dwc, DWC3_GTXTHRCFG, reg);
}
}
}
@@ -1345,7 +1345,7 @@ int dwc3_core_init(struct dwc3 *dwc)
* 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);
+ dwc3_writel(dwc, DWC3_GUID, LINUX_VERSION_CODE);
ret = dwc3_phy_setup(dwc);
if (ret)
@@ -1410,9 +1410,9 @@ int dwc3_core_init(struct dwc3 *dwc)
* DWC_usb31 controller.
*/
if (DWC3_VER_IS_WITHIN(DWC3, 310A, ANY)) {
- reg = dwc3_readl(dwc->regs, DWC3_GUCTL2);
+ reg = dwc3_readl(dwc, DWC3_GUCTL2);
reg |= DWC3_GUCTL2_RST_ACTBITLATER;
- dwc3_writel(dwc->regs, DWC3_GUCTL2, reg);
+ dwc3_writel(dwc, DWC3_GUCTL2, reg);
}
/*
@@ -1425,9 +1425,9 @@ int dwc3_core_init(struct dwc3 *dwc)
* setting GUCTL2[19] by default; instead, use GUCTL2[19] = 0.
*/
if (DWC3_VER_IS(DWC3, 320A)) {
- reg = dwc3_readl(dwc->regs, DWC3_GUCTL2);
+ reg = dwc3_readl(dwc, DWC3_GUCTL2);
reg &= ~DWC3_GUCTL2_LC_TIMER;
- dwc3_writel(dwc->regs, DWC3_GUCTL2, reg);
+ dwc3_writel(dwc, DWC3_GUCTL2, reg);
}
/*
@@ -1440,13 +1440,13 @@ int dwc3_core_init(struct dwc3 *dwc)
* legacy ULPI PHYs.
*/
if (dwc->resume_hs_terminations) {
- reg = dwc3_readl(dwc->regs, DWC3_GUCTL1);
+ reg = dwc3_readl(dwc, DWC3_GUCTL1);
reg |= DWC3_GUCTL1_RESUME_OPMODE_HS_HOST;
- dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
+ dwc3_writel(dwc, DWC3_GUCTL1, reg);
}
if (!DWC3_VER_IS_PRIOR(DWC3, 250A)) {
- reg = dwc3_readl(dwc->regs, DWC3_GUCTL1);
+ reg = dwc3_readl(dwc, DWC3_GUCTL1);
/*
* Enable hardware control of sending remote wakeup
@@ -1481,7 +1481,7 @@ int dwc3_core_init(struct dwc3 *dwc)
reg &= ~DWC3_GUCTL1_DEV_FORCE_20_CLK_FOR_30_CLK;
}
- dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
+ dwc3_writel(dwc, DWC3_GUCTL1, reg);
}
dwc3_config_threshold(dwc);
@@ -1492,9 +1492,9 @@ int dwc3_core_init(struct dwc3 *dwc)
int i;
for (i = 0; i < dwc->num_usb3_ports; i++) {
- reg = dwc3_readl(dwc->regs, DWC3_LLUCTL(i));
+ reg = dwc3_readl(dwc, DWC3_LLUCTL(i));
reg |= DWC3_LLUCTL_FORCE_GEN1;
- dwc3_writel(dwc->regs, DWC3_LLUCTL(i), reg);
+ dwc3_writel(dwc, DWC3_LLUCTL(i), reg);
}
}
@@ -1513,9 +1513,9 @@ int dwc3_core_init(struct dwc3 *dwc)
* function is available only from version 1.70a.
*/
if (DWC3_VER_IS_WITHIN(DWC31, 170A, 180A)) {
- reg = dwc3_readl(dwc->regs, DWC3_GUCTL3);
+ reg = dwc3_readl(dwc, DWC3_GUCTL3);
reg |= DWC3_GUCTL3_USB20_RETRY_DISABLE;
- dwc3_writel(dwc->regs, DWC3_GUCTL3, reg);
+ dwc3_writel(dwc, DWC3_GUCTL3, reg);
}
return 0;
@@ -2155,6 +2155,20 @@ static int dwc3_get_num_ports(struct dwc3 *dwc)
return 0;
}
+static void dwc3_vbus_draw_work(struct work_struct *work)
+{
+ struct dwc3 *dwc = container_of(work, struct dwc3, vbus_draw_work);
+ union power_supply_propval val = {0};
+ int ret;
+
+ val.intval = 1000 * (dwc->current_limit);
+ ret = power_supply_set_property(dwc->usb_psy, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &val);
+
+ if (ret < 0)
+ dev_dbg(dwc->dev, "Error (%d) setting vbus draw (%d mA)\n",
+ ret, dwc->current_limit);
+}
+
static struct power_supply *dwc3_get_usb_power_supply(struct dwc3 *dwc)
{
struct power_supply *usb_psy;
@@ -2169,6 +2183,7 @@ static struct power_supply *dwc3_get_usb_power_supply(struct dwc3 *dwc)
if (!usb_psy)
return ERR_PTR(-EPROBE_DEFER);
+ INIT_WORK(&dwc->vbus_draw_work, dwc3_vbus_draw_work);
return usb_psy;
}
@@ -2395,8 +2410,10 @@ void dwc3_core_remove(struct dwc3 *dwc)
dwc3_free_event_buffers(dwc);
- if (dwc->usb_psy)
+ if (dwc->usb_psy) {
+ cancel_work_sync(&dwc->vbus_draw_work);
power_supply_put(dwc->usb_psy);
+ }
}
EXPORT_SYMBOL_GPL(dwc3_core_remove);
@@ -2439,9 +2456,9 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
int ret;
if (!pm_runtime_suspended(dwc->dev) && !PMSG_IS_AUTO(msg)) {
- dwc->susphy_state = (dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)) &
+ dwc->susphy_state = (dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0)) &
DWC3_GUSB2PHYCFG_SUSPHY) ||
- (dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)) &
+ (dwc3_readl(dwc, DWC3_GUSB3PIPECTL(0)) &
DWC3_GUSB3PIPECTL_SUSPHY);
/*
* TI AM62 platform requires SUSPHY to be
@@ -2471,10 +2488,10 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
if (dwc->dis_u2_susphy_quirk ||
dwc->dis_enblslpm_quirk) {
for (i = 0; i < dwc->num_usb2_ports; i++) {
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(i));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(i));
reg |= DWC3_GUSB2PHYCFG_ENBLSLPM |
DWC3_GUSB2PHYCFG_SUSPHY;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(i), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(i), reg);
}
/* Give some time for USB2 PHY to suspend */
@@ -2534,14 +2551,14 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg)
}
/* Restore GUSB2PHYCFG bits that were modified in suspend */
for (i = 0; i < dwc->num_usb2_ports; i++) {
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(i));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(i));
if (dwc->dis_u2_susphy_quirk)
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
if (dwc->dis_enblslpm_quirk)
reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(i), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(i), reg);
}
for (i = 0; i < dwc->num_usb2_ports; i++)
@@ -2723,9 +2740,9 @@ void dwc3_pm_complete(struct dwc3 *dwc)
if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST &&
dwc->dis_split_quirk) {
- reg = dwc3_readl(dwc->regs, DWC3_GUCTL3);
+ reg = dwc3_readl(dwc, DWC3_GUCTL3);
reg |= DWC3_GUCTL3_SPLITDISABLE;
- dwc3_writel(dwc->regs, DWC3_GUCTL3, reg);
+ dwc3_writel(dwc, DWC3_GUCTL3, reg);
}
}
EXPORT_SYMBOL_GPL(dwc3_pm_complete);
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 45757169b672..a35b3db1f9f3 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -165,10 +165,10 @@
#define DWC3_DCFG1 0xc740 /* DWC_usb32 only */
#define DWC3_DEP_BASE(n) (0xc800 + ((n) * 0x10))
-#define DWC3_DEPCMDPAR2 0x00
-#define DWC3_DEPCMDPAR1 0x04
-#define DWC3_DEPCMDPAR0 0x08
-#define DWC3_DEPCMD 0x0c
+#define DWC3_DEPCMDPAR2(n) (DWC3_DEP_BASE(n) + 0x00)
+#define DWC3_DEPCMDPAR1(n) (DWC3_DEP_BASE(n) + 0x04)
+#define DWC3_DEPCMDPAR0(n) (DWC3_DEP_BASE(n) + 0x08)
+#define DWC3_DEPCMD(n) (DWC3_DEP_BASE(n) + 0x0c)
#define DWC3_DEV_IMOD(n) (0xca00 + ((n) * 0x4))
@@ -749,8 +749,6 @@ struct dwc3_ep {
struct list_head pending_list;
struct list_head started_list;
- void __iomem *regs;
-
struct dwc3_trb *trb_pool;
dma_addr_t trb_pool_dma;
struct dwc3 *dwc;
@@ -1060,6 +1058,8 @@ struct dwc3_glue_ops {
* @role_switch_default_mode: default operation mode of controller while
* usb role is USB_ROLE_NONE.
* @usb_psy: pointer to power supply interface.
+ * @vbus_draw_work: Work to set the vbus drawing limit
+ * @current_limit: How much current to draw from vbus, in milliAmperes.
* @usb2_phy: pointer to USB2 PHY
* @usb3_phy: pointer to USB3 PHY
* @usb2_generic_phy: pointer to array of USB2 PHYs
@@ -1246,6 +1246,8 @@ struct dwc3 {
enum usb_dr_mode role_switch_default_mode;
struct power_supply *usb_psy;
+ struct work_struct vbus_draw_work;
+ unsigned int current_limit;
u32 fladj;
u32 ref_clk_per;
diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c
index d18bf5e32cc8..ffb1101f55c7 100644
--- a/drivers/usb/dwc3/debugfs.c
+++ b/drivers/usb/dwc3/debugfs.c
@@ -36,23 +36,19 @@
#define dump_ep_register_set(n) \
{ \
.name = "DEPCMDPAR2("__stringify(n)")", \
- .offset = DWC3_DEP_BASE(n) + \
- DWC3_DEPCMDPAR2, \
+ .offset = DWC3_DEPCMDPAR2(n), \
}, \
{ \
.name = "DEPCMDPAR1("__stringify(n)")", \
- .offset = DWC3_DEP_BASE(n) + \
- DWC3_DEPCMDPAR1, \
+ .offset = DWC3_DEPCMDPAR1(n), \
}, \
{ \
.name = "DEPCMDPAR0("__stringify(n)")", \
- .offset = DWC3_DEP_BASE(n) + \
- DWC3_DEPCMDPAR0, \
+ .offset = DWC3_DEPCMDPAR0(n), \
}, \
{ \
.name = "DEPCMD("__stringify(n)")", \
- .offset = DWC3_DEP_BASE(n) + \
- DWC3_DEPCMD, \
+ .offset = DWC3_DEPCMD(n), \
}
@@ -300,14 +296,14 @@ static void dwc3_host_lsp(struct seq_file *s)
reg = DWC3_GDBGLSPMUX_HOSTSELECT(sel);
- dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg);
- val = dwc3_readl(dwc->regs, DWC3_GDBGLSP);
+ dwc3_writel(dwc, DWC3_GDBGLSPMUX, reg);
+ val = dwc3_readl(dwc, DWC3_GDBGLSP);
seq_printf(s, "GDBGLSP[%d] = 0x%08x\n", sel, val);
if (dbc_enabled && sel < 256) {
reg |= DWC3_GDBGLSPMUX_ENDBC;
- dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg);
- val = dwc3_readl(dwc->regs, DWC3_GDBGLSP);
+ dwc3_writel(dwc, DWC3_GDBGLSPMUX, reg);
+ val = dwc3_readl(dwc, DWC3_GDBGLSP);
seq_printf(s, "GDBGLSP_DBC[%d] = 0x%08x\n", sel, val);
}
}
@@ -320,8 +316,8 @@ static void dwc3_gadget_lsp(struct seq_file *s)
for (i = 0; i < 16; i++) {
reg = DWC3_GDBGLSPMUX_DEVSELECT(i);
- dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg);
- reg = dwc3_readl(dwc->regs, DWC3_GDBGLSP);
+ dwc3_writel(dwc, DWC3_GDBGLSPMUX, reg);
+ reg = dwc3_readl(dwc, DWC3_GDBGLSP);
seq_printf(s, "GDBGLSP[%d] = 0x%08x\n", i, reg);
}
}
@@ -339,7 +335,7 @@ static int dwc3_lsp_show(struct seq_file *s, void *unused)
return ret;
spin_lock_irqsave(&dwc->lock, flags);
- reg = dwc3_readl(dwc->regs, DWC3_GSTS);
+ reg = dwc3_readl(dwc, DWC3_GSTS);
current_mode = DWC3_GSTS_CURMOD(reg);
switch (current_mode) {
@@ -410,7 +406,7 @@ static int dwc3_mode_show(struct seq_file *s, void *unused)
return ret;
spin_lock_irqsave(&dwc->lock, flags);
- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+ reg = dwc3_readl(dwc, DWC3_GCTL);
spin_unlock_irqrestore(&dwc->lock, flags);
mode = DWC3_GCTL_PRTCAP(reg);
@@ -482,7 +478,7 @@ static int dwc3_testmode_show(struct seq_file *s, void *unused)
return ret;
spin_lock_irqsave(&dwc->lock, flags);
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
reg &= DWC3_DCTL_TSTCTRL_MASK;
reg >>= 1;
spin_unlock_irqrestore(&dwc->lock, flags);
@@ -581,7 +577,7 @@ static int dwc3_link_state_show(struct seq_file *s, void *unused)
return ret;
spin_lock_irqsave(&dwc->lock, flags);
- reg = dwc3_readl(dwc->regs, DWC3_GSTS);
+ reg = dwc3_readl(dwc, DWC3_GSTS);
if (DWC3_GSTS_CURMOD(reg) != DWC3_GSTS_CURMOD_DEVICE) {
seq_puts(s, "Not available\n");
spin_unlock_irqrestore(&dwc->lock, flags);
@@ -589,7 +585,7 @@ static int dwc3_link_state_show(struct seq_file *s, void *unused)
return 0;
}
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+ reg = dwc3_readl(dwc, DWC3_DSTS);
state = DWC3_DSTS_USBLNKST(reg);
speed = reg & DWC3_DSTS_CONNECTSPD;
@@ -643,14 +639,14 @@ static ssize_t dwc3_link_state_write(struct file *file,
return ret;
spin_lock_irqsave(&dwc->lock, flags);
- reg = dwc3_readl(dwc->regs, DWC3_GSTS);
+ reg = dwc3_readl(dwc, DWC3_GSTS);
if (DWC3_GSTS_CURMOD(reg) != DWC3_GSTS_CURMOD_DEVICE) {
spin_unlock_irqrestore(&dwc->lock, flags);
pm_runtime_put_sync(dwc->dev);
return -EINVAL;
}
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+ reg = dwc3_readl(dwc, DWC3_DSTS);
speed = reg & DWC3_DSTS_CONNECTSPD;
if (speed < DWC3_DSTS_SUPERSPEED &&
@@ -946,10 +942,10 @@ static int dwc3_ep_info_register_show(struct seq_file *s, void *unused)
spin_lock_irqsave(&dwc->lock, flags);
reg = DWC3_GDBGLSPMUX_EPSELECT(dep->number);
- dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg);
+ dwc3_writel(dwc, DWC3_GDBGLSPMUX, reg);
- lower_32_bits = dwc3_readl(dwc->regs, DWC3_GDBGEPINFO0);
- upper_32_bits = dwc3_readl(dwc->regs, DWC3_GDBGEPINFO1);
+ lower_32_bits = dwc3_readl(dwc, DWC3_GDBGEPINFO0);
+ upper_32_bits = dwc3_readl(dwc, DWC3_GDBGEPINFO1);
ep_info = ((u64)upper_32_bits << 32) | lower_32_bits;
seq_printf(s, "0x%016llx\n", ep_info);
diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c
index 589bbeb27454..f3e37d383627 100644
--- a/drivers/usb/dwc3/drd.c
+++ b/drivers/usb/dwc3/drd.c
@@ -18,25 +18,25 @@
static void dwc3_otg_disable_events(struct dwc3 *dwc, u32 disable_mask)
{
- u32 reg = dwc3_readl(dwc->regs, DWC3_OEVTEN);
+ u32 reg = dwc3_readl(dwc, DWC3_OEVTEN);
reg &= ~(disable_mask);
- dwc3_writel(dwc->regs, DWC3_OEVTEN, reg);
+ dwc3_writel(dwc, DWC3_OEVTEN, reg);
}
static void dwc3_otg_enable_events(struct dwc3 *dwc, u32 enable_mask)
{
- u32 reg = dwc3_readl(dwc->regs, DWC3_OEVTEN);
+ u32 reg = dwc3_readl(dwc, DWC3_OEVTEN);
reg |= (enable_mask);
- dwc3_writel(dwc->regs, DWC3_OEVTEN, reg);
+ dwc3_writel(dwc, DWC3_OEVTEN, reg);
}
static void dwc3_otg_clear_events(struct dwc3 *dwc)
{
- u32 reg = dwc3_readl(dwc->regs, DWC3_OEVT);
+ u32 reg = dwc3_readl(dwc, DWC3_OEVT);
- dwc3_writel(dwc->regs, DWC3_OEVTEN, reg);
+ dwc3_writel(dwc, DWC3_OEVTEN, reg);
}
#define DWC3_OTG_ALL_EVENTS (DWC3_OEVTEN_XHCIRUNSTPSETEN | \
@@ -72,18 +72,18 @@ static irqreturn_t dwc3_otg_irq(int irq, void *_dwc)
struct dwc3 *dwc = _dwc;
irqreturn_t ret = IRQ_NONE;
- reg = dwc3_readl(dwc->regs, DWC3_OEVT);
+ reg = dwc3_readl(dwc, DWC3_OEVT);
if (reg) {
/* ignore non OTG events, we can't disable them in OEVTEN */
if (!(reg & DWC3_OTG_ALL_EVENTS)) {
- dwc3_writel(dwc->regs, DWC3_OEVT, reg);
+ dwc3_writel(dwc, DWC3_OEVT, reg);
return IRQ_NONE;
}
if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST &&
!(reg & DWC3_OEVT_DEVICEMODE))
dwc->otg_restart_host = true;
- dwc3_writel(dwc->regs, DWC3_OEVT, reg);
+ dwc3_writel(dwc, DWC3_OEVT, reg);
ret = IRQ_WAKE_THREAD;
}
@@ -100,23 +100,23 @@ static void dwc3_otgregs_init(struct dwc3 *dwc)
* the signal outputs sent to the PHY, the OTG FSM logic of the
* core and also the resets to the VBUS filters inside the core.
*/
- reg = dwc3_readl(dwc->regs, DWC3_OCFG);
+ reg = dwc3_readl(dwc, DWC3_OCFG);
reg |= DWC3_OCFG_SFTRSTMASK;
- dwc3_writel(dwc->regs, DWC3_OCFG, reg);
+ dwc3_writel(dwc, DWC3_OCFG, reg);
/* Disable hibernation for simplicity */
- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+ reg = dwc3_readl(dwc, DWC3_GCTL);
reg &= ~DWC3_GCTL_GBLHIBERNATIONEN;
- dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+ dwc3_writel(dwc, DWC3_GCTL, reg);
/*
* Initialize OTG registers as per
* Figure 11-4 OTG Driver Overall Programming Flow
*/
/* OCFG.SRPCap = 0, OCFG.HNPCap = 0 */
- reg = dwc3_readl(dwc->regs, DWC3_OCFG);
+ reg = dwc3_readl(dwc, DWC3_OCFG);
reg &= ~(DWC3_OCFG_SRPCAP | DWC3_OCFG_HNPCAP);
- dwc3_writel(dwc->regs, DWC3_OCFG, reg);
+ dwc3_writel(dwc, DWC3_OCFG, reg);
/* OEVT = FFFF */
dwc3_otg_clear_events(dwc);
/* OEVTEN = 0 */
@@ -127,11 +127,11 @@ static void dwc3_otgregs_init(struct dwc3 *dwc)
* OCTL.PeriMode = 1, OCTL.DevSetHNPEn = 0, OCTL.HstSetHNPEn = 0,
* OCTL.HNPReq = 0
*/
- reg = dwc3_readl(dwc->regs, DWC3_OCTL);
+ reg = dwc3_readl(dwc, DWC3_OCTL);
reg |= DWC3_OCTL_PERIMODE;
reg &= ~(DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HSTSETHNPEN |
DWC3_OCTL_HNPREQ);
- dwc3_writel(dwc->regs, DWC3_OCTL, reg);
+ dwc3_writel(dwc, DWC3_OCTL, reg);
}
static int dwc3_otg_get_irq(struct dwc3 *dwc)
@@ -175,9 +175,9 @@ void dwc3_otg_init(struct dwc3 *dwc)
/* GCTL.PrtCapDir=2'b11 */
dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_OTG, true);
/* GUSB2PHYCFG0.SusPHY=0 */
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0));
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(0), reg);
/* Initialize OTG registers */
dwc3_otgregs_init(dwc);
@@ -203,17 +203,17 @@ void dwc3_otg_host_init(struct dwc3 *dwc)
* OCTL.PeriMode=0, OCTL.TermSelDLPulse = 0,
* OCTL.DevSetHNPEn = 0, OCTL.HstSetHNPEn = 0
*/
- reg = dwc3_readl(dwc->regs, DWC3_OCTL);
+ reg = dwc3_readl(dwc, DWC3_OCTL);
reg &= ~(DWC3_OCTL_PERIMODE | DWC3_OCTL_TERMSELIDPULSE |
DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HSTSETHNPEN);
- dwc3_writel(dwc->regs, DWC3_OCTL, reg);
+ dwc3_writel(dwc, DWC3_OCTL, reg);
/*
* OCFG.DisPrtPwrCutoff = 0/1
*/
- reg = dwc3_readl(dwc->regs, DWC3_OCFG);
+ reg = dwc3_readl(dwc, DWC3_OCFG);
reg &= ~DWC3_OCFG_DISPWRCUTTOFF;
- dwc3_writel(dwc->regs, DWC3_OCFG, reg);
+ dwc3_writel(dwc, DWC3_OCFG, reg);
/*
* OCFG.SRPCap = 1, OCFG.HNPCap = GHWPARAMS6.HNP_CAP
@@ -229,15 +229,15 @@ void dwc3_otg_host_init(struct dwc3 *dwc)
/* GUSB2PHYCFG.ULPIAutoRes = 1/0, GUSB2PHYCFG.SusPHY = 1 */
if (!dwc->dis_u2_susphy_quirk) {
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0));
reg |= DWC3_GUSB2PHYCFG_SUSPHY;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(0), reg);
}
/* Set Port Power to enable VBUS: OCTL.PrtPwrCtl = 1 */
- reg = dwc3_readl(dwc->regs, DWC3_OCTL);
+ reg = dwc3_readl(dwc, DWC3_OCTL);
reg |= DWC3_OCTL_PRTPWRCTL;
- dwc3_writel(dwc->regs, DWC3_OCTL, reg);
+ dwc3_writel(dwc, DWC3_OCTL, reg);
}
/* should be called after Host controller driver is stopped */
@@ -258,9 +258,9 @@ static void dwc3_otg_host_exit(struct dwc3 *dwc)
*/
/* OCTL.HstSetHNPEn = 0, OCTL.PrtPwrCtl=0 */
- reg = dwc3_readl(dwc->regs, DWC3_OCTL);
+ reg = dwc3_readl(dwc, DWC3_OCTL);
reg &= ~(DWC3_OCTL_HSTSETHNPEN | DWC3_OCTL_PRTPWRCTL);
- dwc3_writel(dwc->regs, DWC3_OCTL, reg);
+ dwc3_writel(dwc, DWC3_OCTL, reg);
}
/* should be called before the gadget controller driver is started */
@@ -274,27 +274,27 @@ static void dwc3_otg_device_init(struct dwc3 *dwc)
* OCFG.HNPCap = GHWPARAMS6.HNP_CAP, OCFG.SRPCap = 1
* but we keep them 0 for simple dual-role operation.
*/
- reg = dwc3_readl(dwc->regs, DWC3_OCFG);
+ reg = dwc3_readl(dwc, DWC3_OCFG);
/* OCFG.OTGSftRstMsk = 0/1 */
reg |= DWC3_OCFG_SFTRSTMASK;
- dwc3_writel(dwc->regs, DWC3_OCFG, reg);
+ dwc3_writel(dwc, DWC3_OCFG, reg);
/*
* OCTL.PeriMode = 1
* OCTL.TermSelDLPulse = 0/1, OCTL.HNPReq = 0
* OCTL.DevSetHNPEn = 0, OCTL.HstSetHNPEn = 0
*/
- reg = dwc3_readl(dwc->regs, DWC3_OCTL);
+ reg = dwc3_readl(dwc, DWC3_OCTL);
reg |= DWC3_OCTL_PERIMODE;
reg &= ~(DWC3_OCTL_TERMSELIDPULSE | DWC3_OCTL_HNPREQ |
DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HSTSETHNPEN);
- dwc3_writel(dwc->regs, DWC3_OCTL, reg);
+ dwc3_writel(dwc, DWC3_OCTL, reg);
/* OEVTEN.OTGBDevSesVldDetEvntEn = 1 */
dwc3_otg_enable_events(dwc, DWC3_OEVTEN_BDEVSESSVLDDETEN);
/* GUSB2PHYCFG.ULPIAutoRes = 0, GUSB2PHYCFG0.SusPHY = 1 */
if (!dwc->dis_u2_susphy_quirk) {
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0));
reg |= DWC3_GUSB2PHYCFG_SUSPHY;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(0), reg);
}
/* GCTL.GblHibernationEn = 0. Already 0. */
}
@@ -319,10 +319,10 @@ static void dwc3_otg_device_exit(struct dwc3 *dwc)
DWC3_OEVTEN_BDEVBHOSTENDEN);
/* OCTL.DevSetHNPEn = 0, OCTL.HNPReq = 0, OCTL.PeriMode=1 */
- reg = dwc3_readl(dwc->regs, DWC3_OCTL);
+ reg = dwc3_readl(dwc, DWC3_OCTL);
reg &= ~(DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HNPREQ);
reg |= DWC3_OCTL_PERIMODE;
- dwc3_writel(dwc->regs, DWC3_OCTL, reg);
+ dwc3_writel(dwc, DWC3_OCTL, reg);
}
void dwc3_otg_update(struct dwc3 *dwc, bool ignore_idstatus)
@@ -341,7 +341,7 @@ void dwc3_otg_update(struct dwc3 *dwc, bool ignore_idstatus)
return;
if (!ignore_idstatus) {
- reg = dwc3_readl(dwc->regs, DWC3_OSTS);
+ reg = dwc3_readl(dwc, DWC3_OSTS);
id = !!(reg & DWC3_OSTS_CONIDSTS);
dwc->desired_otg_role = id ? DWC3_OTG_ROLE_DEVICE :
@@ -381,6 +381,7 @@ void dwc3_otg_update(struct dwc3 *dwc, bool ignore_idstatus)
dwc3_otgregs_init(dwc);
dwc3_otg_host_init(dwc);
spin_unlock_irqrestore(&dwc->lock, flags);
+ dwc3_pre_set_role(dwc, USB_ROLE_HOST);
ret = dwc3_host_init(dwc);
if (ret) {
dev_err(dwc->dev, "failed to initialize host\n");
@@ -406,6 +407,7 @@ void dwc3_otg_update(struct dwc3 *dwc, bool ignore_idstatus)
otg_set_vbus(dwc->usb2_phy->otg, false);
if (dwc->usb2_generic_phy[0])
phy_set_mode(dwc->usb2_generic_phy[0], PHY_MODE_USB_DEVICE);
+ dwc3_pre_set_role(dwc, USB_ROLE_DEVICE);
ret = dwc3_gadget_init(dwc);
if (ret)
dev_err(dwc->dev, "failed to initialize peripheral\n");
@@ -433,10 +435,12 @@ static int dwc3_drd_notifier(struct notifier_block *nb,
unsigned long event, void *ptr)
{
struct dwc3 *dwc = container_of(nb, struct dwc3, edev_nb);
+ u32 mode = event ? DWC3_GCTL_PRTCAP_HOST : DWC3_GCTL_PRTCAP_DEVICE;
+ enum usb_role role = mode == DWC3_GCTL_PRTCAP_HOST ?
+ USB_ROLE_HOST : USB_ROLE_DEVICE;
- dwc3_set_mode(dwc, event ?
- DWC3_GCTL_PRTCAP_HOST :
- DWC3_GCTL_PRTCAP_DEVICE);
+ dwc3_pre_set_role(dwc, role);
+ dwc3_set_mode(dwc, mode);
return NOTIFY_DONE;
}
diff --git a/drivers/usb/dwc3/dwc3-google.c b/drivers/usb/dwc3/dwc3-google.c
new file mode 100644
index 000000000000..2105c72af753
--- /dev/null
+++ b/drivers/usb/dwc3/dwc3-google.c
@@ -0,0 +1,626 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dwc3-google.c - Google DWC3 Specific Glue Layer
+ *
+ * Copyright (c) 2025, Google LLC
+ * Author: Roy Luo <royluo@google.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/iopoll.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include "core.h"
+#include "glue.h"
+
+/* HOST CFG registers */
+#define HC_STATUS_OFFSET 0x0
+#define HC_STATUS_CURRENT_POWER_STATE_U2PMU GENMASK(1, 0)
+#define HC_STATUS_CURRENT_POWER_STATE_U3PMU GENMASK(4, 3)
+
+#define HOST_CFG1_OFFSET 0x4
+#define HOST_CFG1_PME_EN BIT(3)
+#define HOST_CFG1_PM_POWER_STATE_REQUEST GENMASK(5, 4)
+#define HOST_CFG1_PM_POWER_STATE_D0 0x0
+#define HOST_CFG1_PM_POWER_STATE_D3 0x3
+
+/* USBINT registers */
+#define USBINT_CFG1_OFFSET 0x0
+#define USBINT_CFG1_USBDRD_PME_GEN_U2P_INTR_MSK BIT(2)
+#define USBINT_CFG1_USBDRD_PME_GEN_U3P_INTR_MSK BIT(3)
+#define USBINT_CFG1_USBDRD_PME_GEN_U2P_INTR_INT_EN BIT(8)
+#define USBINT_CFG1_USBDRD_PME_GEN_U3P_INTR_INT_EN BIT(9)
+#define USBINT_CFG1_USBDRD_PME_GEN_U2_INTR_CLR BIT(14)
+#define USBINT_CFG1_USBDRD_PME_GEN_U3_INTR_CLR BIT(15)
+
+#define USBINT_STATUS_OFFSET 0x4
+#define USBINT_STATUS_USBDRD_PME_GEN_U2P_INTR_STS_RAW BIT(2)
+#define USBINT_STATUS_USBDRD_PME_GEN_U3P_INTR_STS_RAW BIT(3)
+
+#define USBCS_TOP_CTRL_CFG1_OFFSET 0xc
+#define USBCS_TOP_CTRL_CFG1_USB2ONLY_MODE BIT(5)
+
+#define DWC3_GOOGLE_MAX_RESETS 4
+
+struct dwc3_google {
+ struct device *dev;
+ struct dwc3 dwc;
+ struct clk_bulk_data *clks;
+ int num_clks;
+ struct reset_control_bulk_data rsts[DWC3_GOOGLE_MAX_RESETS];
+ int num_rsts;
+ struct reset_control *non_sticky_rst;
+ struct device *usb_psw_pd;
+ struct device_link *usb_psw_pd_dl;
+ struct notifier_block usb_psw_pd_nb;
+ struct device *usb_top_pd;
+ struct device_link *usb_top_pd_dl;
+ struct regmap *usb_cfg_regmap;
+ unsigned int host_cfg_offset;
+ unsigned int usbint_cfg_offset;
+ int hs_pme_irq;
+ int ss_pme_irq;
+ bool is_usb2only;
+ bool is_hibernation;
+};
+
+#define to_dwc3_google(d) container_of_const((d), struct dwc3_google, dwc)
+
+static int dwc3_google_rst_init(struct dwc3_google *google)
+{
+ int ret;
+
+ google->num_rsts = 4;
+ google->rsts[0].id = "non_sticky";
+ google->rsts[1].id = "sticky";
+ google->rsts[2].id = "drd_bus";
+ google->rsts[3].id = "top";
+
+ ret = devm_reset_control_bulk_get_exclusive(google->dev,
+ google->num_rsts,
+ google->rsts);
+
+ if (ret < 0)
+ return ret;
+
+ google->non_sticky_rst = google->rsts[0].rstc;
+
+ return 0;
+}
+
+static int dwc3_google_set_pmu_state(struct dwc3_google *google, int state)
+{
+ u32 reg;
+ int ret;
+
+ regmap_read(google->usb_cfg_regmap,
+ google->host_cfg_offset + HOST_CFG1_OFFSET, &reg);
+
+ reg &= ~HOST_CFG1_PM_POWER_STATE_REQUEST;
+ reg |= (FIELD_PREP(HOST_CFG1_PM_POWER_STATE_REQUEST, state) |
+ HOST_CFG1_PME_EN);
+ regmap_write(google->usb_cfg_regmap,
+ google->host_cfg_offset + HOST_CFG1_OFFSET, reg);
+
+ ret = regmap_read_poll_timeout(google->usb_cfg_regmap,
+ google->host_cfg_offset + HC_STATUS_OFFSET, reg,
+ (FIELD_GET(HC_STATUS_CURRENT_POWER_STATE_U2PMU,
+ reg) == state &&
+ FIELD_GET(HC_STATUS_CURRENT_POWER_STATE_U3PMU,
+ reg) == state),
+ 10, 10000);
+
+ if (ret)
+ dev_err(google->dev, "failed to set PMU state %d\n", state);
+
+ return ret;
+}
+
+/*
+ * Clear pme interrupts and report their status.
+ * The hardware requires write-1 then write-0 sequence to clear the interrupt bits.
+ */
+static u32 dwc3_google_clear_pme_irqs(struct dwc3_google *google)
+{
+ u32 irq_status, reg_set, reg_clear;
+
+ regmap_read(google->usb_cfg_regmap,
+ google->usbint_cfg_offset + USBINT_STATUS_OFFSET, &irq_status);
+
+ irq_status &= (USBINT_STATUS_USBDRD_PME_GEN_U2P_INTR_STS_RAW |
+ USBINT_STATUS_USBDRD_PME_GEN_U3P_INTR_STS_RAW);
+ if (!irq_status)
+ return irq_status;
+
+ regmap_read(google->usb_cfg_regmap,
+ google->usbint_cfg_offset + USBINT_CFG1_OFFSET, &reg_set);
+
+ reg_clear = reg_set;
+ if (irq_status & USBINT_STATUS_USBDRD_PME_GEN_U2P_INTR_STS_RAW) {
+ reg_set |= USBINT_CFG1_USBDRD_PME_GEN_U2_INTR_CLR;
+ reg_clear &= ~USBINT_CFG1_USBDRD_PME_GEN_U2_INTR_CLR;
+ }
+ if (irq_status & USBINT_STATUS_USBDRD_PME_GEN_U3P_INTR_STS_RAW) {
+ reg_set |= USBINT_CFG1_USBDRD_PME_GEN_U3_INTR_CLR;
+ reg_clear &= ~USBINT_CFG1_USBDRD_PME_GEN_U3_INTR_CLR;
+ }
+
+ regmap_write(google->usb_cfg_regmap,
+ google->usbint_cfg_offset + USBINT_CFG1_OFFSET, reg_set);
+ regmap_write(google->usb_cfg_regmap,
+ google->usbint_cfg_offset + USBINT_CFG1_OFFSET, reg_clear);
+
+ return irq_status;
+}
+
+static void dwc3_google_enable_pme_irq(struct dwc3_google *google)
+{
+ u32 reg;
+
+ regmap_read(google->usb_cfg_regmap,
+ google->usbint_cfg_offset + USBINT_CFG1_OFFSET, &reg);
+ reg &= ~(USBINT_CFG1_USBDRD_PME_GEN_U2P_INTR_MSK |
+ USBINT_CFG1_USBDRD_PME_GEN_U3P_INTR_MSK);
+ reg |= (USBINT_CFG1_USBDRD_PME_GEN_U2P_INTR_INT_EN |
+ USBINT_CFG1_USBDRD_PME_GEN_U3P_INTR_INT_EN);
+ regmap_write(google->usb_cfg_regmap,
+ google->usbint_cfg_offset + USBINT_CFG1_OFFSET, reg);
+
+ enable_irq(google->hs_pme_irq);
+ enable_irq(google->ss_pme_irq);
+ enable_irq_wake(google->hs_pme_irq);
+ enable_irq_wake(google->ss_pme_irq);
+}
+
+static void dwc3_google_disable_pme_irq(struct dwc3_google *google)
+{
+ u32 reg;
+
+ regmap_read(google->usb_cfg_regmap,
+ google->usbint_cfg_offset + USBINT_CFG1_OFFSET, &reg);
+ reg &= ~(USBINT_CFG1_USBDRD_PME_GEN_U2P_INTR_INT_EN |
+ USBINT_CFG1_USBDRD_PME_GEN_U3P_INTR_INT_EN);
+ reg |= (USBINT_CFG1_USBDRD_PME_GEN_U2P_INTR_MSK |
+ USBINT_CFG1_USBDRD_PME_GEN_U3P_INTR_MSK);
+ regmap_write(google->usb_cfg_regmap,
+ google->usbint_cfg_offset + USBINT_CFG1_OFFSET, reg);
+
+ disable_irq_wake(google->hs_pme_irq);
+ disable_irq_wake(google->ss_pme_irq);
+ disable_irq_nosync(google->hs_pme_irq);
+ disable_irq_nosync(google->ss_pme_irq);
+}
+
+static irqreturn_t dwc3_google_resume_irq(int irq, void *data)
+{
+ struct dwc3_google *google = data;
+ struct dwc3 *dwc = &google->dwc;
+ u32 irq_status, dr_role;
+
+ irq_status = dwc3_google_clear_pme_irqs(google);
+ dr_role = dwc->current_dr_role;
+
+ if (!irq_status || !google->is_hibernation ||
+ dr_role != DWC3_GCTL_PRTCAP_HOST) {
+ dev_dbg(google->dev, "spurious pme irq %d, hibernation %d, dr_role %u\n",
+ irq, google->is_hibernation, dr_role);
+ return IRQ_HANDLED;
+ }
+
+ if (dwc->xhci)
+ pm_runtime_resume(&dwc->xhci->dev);
+
+ return IRQ_HANDLED;
+}
+
+static int dwc3_google_request_irq(struct dwc3_google *google, struct platform_device *pdev,
+ const char *irq_name, const char *req_name)
+{
+ int ret;
+ int irq;
+
+ irq = platform_get_irq_byname(pdev, irq_name);
+ if (irq < 0)
+ return irq;
+
+ irq_set_status_flags(irq, IRQ_NOAUTOEN);
+ ret = devm_request_threaded_irq(google->dev, irq, NULL,
+ dwc3_google_resume_irq,
+ IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+ req_name, google);
+ if (ret < 0) {
+ dev_err(google->dev, "failed to request irq %s\n", req_name);
+ return ret;
+ }
+
+ return irq;
+}
+
+static int dwc3_google_usb_psw_pd_notifier(struct notifier_block *nb, unsigned long action, void *d)
+{
+ struct dwc3_google *google = container_of(nb, struct dwc3_google, usb_psw_pd_nb);
+ int ret;
+
+ if (!google->is_hibernation)
+ return NOTIFY_OK;
+
+ if (action == GENPD_NOTIFY_OFF) {
+ dev_dbg(google->dev, "enter D3 power state\n");
+ dwc3_google_set_pmu_state(google, HOST_CFG1_PM_POWER_STATE_D3);
+ ret = reset_control_assert(google->non_sticky_rst);
+ if (ret)
+ dev_err(google->dev, "non sticky reset assert failed: %d\n", ret);
+ } else if (action == GENPD_NOTIFY_ON) {
+ dev_dbg(google->dev, "enter D0 power state\n");
+ dwc3_google_clear_pme_irqs(google);
+ ret = reset_control_deassert(google->non_sticky_rst);
+ if (ret)
+ dev_err(google->dev, "non sticky reset deassert failed: %d\n", ret);
+ dwc3_google_set_pmu_state(google, HOST_CFG1_PM_POWER_STATE_D0);
+ }
+
+ return NOTIFY_OK;
+}
+
+static void dwc3_google_pm_domain_deinit(struct dwc3_google *google)
+{
+ if (google->usb_top_pd_dl)
+ device_link_del(google->usb_top_pd_dl);
+
+ if (!IS_ERR_OR_NULL(google->usb_top_pd)) {
+ device_set_wakeup_capable(google->usb_top_pd, false);
+ dev_pm_domain_detach(google->usb_top_pd, true);
+ }
+
+ if (google->usb_psw_pd_dl)
+ device_link_del(google->usb_psw_pd_dl);
+
+ if (!IS_ERR_OR_NULL(google->usb_psw_pd)) {
+ dev_pm_genpd_remove_notifier(google->usb_psw_pd);
+ dev_pm_domain_detach(google->usb_psw_pd, true);
+ }
+}
+
+static int dwc3_google_pm_domain_init(struct dwc3_google *google)
+{
+ int ret;
+
+ /*
+ * Establish PM RUNTIME link between dwc dev and its power domain usb_psw_pd,
+ * register notifier block to handle hibernation.
+ */
+ google->usb_psw_pd = dev_pm_domain_attach_by_name(google->dev, "psw");
+ if (IS_ERR_OR_NULL(google->usb_psw_pd)) {
+ dev_err(google->dev, "failed to get psw pd");
+ ret = google->usb_psw_pd ? PTR_ERR(google->usb_psw_pd) : -ENODATA;
+ return ret;
+ }
+
+ google->usb_psw_pd_nb.notifier_call = dwc3_google_usb_psw_pd_notifier;
+ ret = dev_pm_genpd_add_notifier(google->usb_psw_pd, &google->usb_psw_pd_nb);
+ if (ret) {
+ dev_err(google->dev, "failed to add psw pd notifier");
+ goto err;
+ }
+
+ google->usb_psw_pd_dl = device_link_add(google->dev, google->usb_psw_pd,
+ DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
+ DL_FLAG_RPM_ACTIVE);
+ if (!google->usb_psw_pd_dl) {
+ dev_err(google->usb_psw_pd, "failed to add device link");
+ ret = -ENODEV;
+ goto err;
+ }
+
+ /*
+ * usb_top_pd is the parent power domain of usb_psw_pd. Keeping usb_top_pd on
+ * while usb_psw_pd is off places the controller in a power-gated state,
+ * essential for hibernation. Acquire a handle to usb_top_pd and sets it as
+ * wakeup-capable to allow the domain to be left on during system suspend.
+ */
+ google->usb_top_pd = dev_pm_domain_attach_by_name(google->dev, "top");
+ if (IS_ERR_OR_NULL(google->usb_top_pd)) {
+ dev_err(google->dev, "failed to get top pd");
+ ret = google->usb_top_pd ? PTR_ERR(google->usb_top_pd) : -ENODATA;
+ goto err;
+ }
+ device_set_wakeup_capable(google->usb_top_pd, true);
+
+ google->usb_top_pd_dl = device_link_add(google->dev, google->usb_top_pd,
+ DL_FLAG_STATELESS);
+ if (!google->usb_top_pd_dl) {
+ dev_err(google->usb_top_pd, "failed to add device link");
+ ret = -ENODEV;
+ goto err;
+ }
+
+ return 0;
+
+err:
+ dwc3_google_pm_domain_deinit(google);
+
+ return ret;
+}
+
+static void dwc3_google_program_usb2only(struct dwc3_google *google)
+{
+ u32 reg;
+
+ regmap_read(google->usb_cfg_regmap,
+ google->usbint_cfg_offset + USBCS_TOP_CTRL_CFG1_OFFSET, &reg);
+ reg |= USBCS_TOP_CTRL_CFG1_USB2ONLY_MODE;
+ regmap_write(google->usb_cfg_regmap,
+ google->usbint_cfg_offset + USBCS_TOP_CTRL_CFG1_OFFSET, reg);
+}
+
+static int dwc3_google_probe(struct platform_device *pdev)
+{
+ struct dwc3_probe_data probe_data = {};
+ struct device *dev = &pdev->dev;
+ struct dwc3_google *google;
+ struct resource *res;
+ int ret;
+ u32 args[2];
+
+ google = devm_kzalloc(&pdev->dev, sizeof(*google), GFP_KERNEL);
+ if (!google)
+ return -ENOMEM;
+
+ google->dev = &pdev->dev;
+
+ ret = dwc3_google_pm_domain_init(google);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "failed to init pdom\n");
+
+ google->usb_cfg_regmap =
+ syscon_regmap_lookup_by_phandle_args(dev->of_node,
+ "google,usb-cfg-csr",
+ ARRAY_SIZE(args), args);
+ if (IS_ERR(google->usb_cfg_regmap)) {
+ return dev_err_probe(dev, PTR_ERR(google->usb_cfg_regmap),
+ "invalid usb cfg csr\n");
+ }
+
+ google->host_cfg_offset = args[0];
+ google->usbint_cfg_offset = args[1];
+
+ if (device_property_match_string(dev, "phy-names", "usb3-phy") < 0) {
+ google->is_usb2only = true;
+ dwc3_google_program_usb2only(google);
+ }
+
+ ret = devm_clk_bulk_get_all_enabled(dev, &google->clks);
+ if (ret < 0) {
+ ret = dev_err_probe(dev, ret, "failed to get and enable clks\n");
+ goto err_deinit_pdom;
+ }
+ google->num_clks = ret;
+
+ ret = dwc3_google_rst_init(google);
+ if (ret) {
+ ret = dev_err_probe(dev, ret, "failed to get resets\n");
+ goto err_deinit_pdom;
+ }
+
+ ret = reset_control_bulk_deassert(google->num_rsts, google->rsts);
+ if (ret) {
+ ret = dev_err_probe(dev, ret, "failed to deassert rsts\n");
+ goto err_deinit_pdom;
+ }
+
+ ret = dwc3_google_request_irq(google, pdev, "hs_pme", "USB HS wakeup");
+ if (ret < 0) {
+ ret = dev_err_probe(dev, ret, "failed to request hs pme irq");
+ goto err_reset_assert;
+ }
+ google->hs_pme_irq = ret;
+
+ ret = dwc3_google_request_irq(google, pdev, "ss_pme", "USB SS wakeup");
+ if (ret < 0) {
+ ret = dev_err_probe(dev, ret, "failed to request ss pme irq");
+ goto err_reset_assert;
+ }
+ google->ss_pme_irq = ret;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ ret = dev_err_probe(dev, -ENODEV, "invalid memory\n");
+ goto err_reset_assert;
+ }
+
+ device_init_wakeup(dev, true);
+
+ google->dwc.dev = dev;
+ probe_data.dwc = &google->dwc;
+ probe_data.res = res;
+ probe_data.ignore_clocks_and_resets = true;
+ ret = dwc3_core_probe(&probe_data);
+ if (ret) {
+ ret = dev_err_probe(dev, ret, "failed to register DWC3 Core\n");
+ goto err_reset_assert;
+ }
+
+ return 0;
+
+err_reset_assert:
+ reset_control_bulk_assert(google->num_rsts, google->rsts);
+
+err_deinit_pdom:
+ dwc3_google_pm_domain_deinit(google);
+
+ return ret;
+}
+
+static void dwc3_google_remove(struct platform_device *pdev)
+{
+ struct dwc3 *dwc = platform_get_drvdata(pdev);
+ struct dwc3_google *google = to_dwc3_google(dwc);
+
+ dwc3_core_remove(&google->dwc);
+
+ reset_control_bulk_assert(google->num_rsts, google->rsts);
+
+ dwc3_google_pm_domain_deinit(google);
+}
+
+static int dwc3_google_suspend(struct dwc3_google *google, pm_message_t msg)
+{
+ if (pm_runtime_suspended(google->dev))
+ return 0;
+
+ if (google->dwc.current_dr_role == DWC3_GCTL_PRTCAP_HOST) {
+ /*
+ * Follow dwc3_suspend_common() guidelines for deciding between
+ * a full teardown and hibernation.
+ */
+ if (PMSG_IS_AUTO(msg) || device_may_wakeup(google->dev)) {
+ dev_dbg(google->dev, "enter hibernation");
+ pm_runtime_get_sync(google->usb_top_pd);
+ device_wakeup_enable(google->usb_top_pd);
+ dwc3_google_enable_pme_irq(google);
+ google->is_hibernation = true;
+ return 0;
+ }
+ }
+
+ reset_control_bulk_assert(google->num_rsts, google->rsts);
+ clk_bulk_disable_unprepare(google->num_clks, google->clks);
+
+ return 0;
+}
+
+static int dwc3_google_resume(struct dwc3_google *google, pm_message_t msg)
+{
+ int ret;
+
+ if (google->is_hibernation) {
+ dev_dbg(google->dev, "exit hibernation");
+ dwc3_google_disable_pme_irq(google);
+ device_wakeup_disable(google->usb_top_pd);
+ pm_runtime_put_sync(google->usb_top_pd);
+ google->is_hibernation = false;
+ return 0;
+ }
+
+ if (google->is_usb2only)
+ dwc3_google_program_usb2only(google);
+
+ ret = clk_bulk_prepare_enable(google->num_clks, google->clks);
+ if (ret)
+ return ret;
+
+ ret = reset_control_bulk_deassert(google->num_rsts, google->rsts);
+ if (ret) {
+ clk_bulk_disable_unprepare(google->num_clks, google->clks);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int dwc3_google_pm_suspend(struct device *dev)
+{
+ struct dwc3 *dwc = dev_get_drvdata(dev);
+ struct dwc3_google *google = to_dwc3_google(dwc);
+ int ret;
+
+ ret = dwc3_pm_suspend(&google->dwc);
+ if (ret)
+ return ret;
+
+ return dwc3_google_suspend(google, PMSG_SUSPEND);
+}
+
+static int dwc3_google_pm_resume(struct device *dev)
+{
+ struct dwc3 *dwc = dev_get_drvdata(dev);
+ struct dwc3_google *google = to_dwc3_google(dwc);
+ int ret;
+
+ ret = dwc3_google_resume(google, PMSG_RESUME);
+ if (ret)
+ return ret;
+
+ return dwc3_pm_resume(&google->dwc);
+}
+
+static void dwc3_google_complete(struct device *dev)
+{
+ struct dwc3 *dwc = dev_get_drvdata(dev);
+
+ dwc3_pm_complete(dwc);
+}
+
+static int dwc3_google_prepare(struct device *dev)
+{
+ struct dwc3 *dwc = dev_get_drvdata(dev);
+
+ return dwc3_pm_prepare(dwc);
+}
+
+static int dwc3_google_runtime_suspend(struct device *dev)
+{
+ struct dwc3 *dwc = dev_get_drvdata(dev);
+ struct dwc3_google *google = to_dwc3_google(dwc);
+ int ret;
+
+ ret = dwc3_runtime_suspend(&google->dwc);
+ if (ret)
+ return ret;
+
+ return dwc3_google_suspend(google, PMSG_AUTO_SUSPEND);
+}
+
+static int dwc3_google_runtime_resume(struct device *dev)
+{
+ struct dwc3 *dwc = dev_get_drvdata(dev);
+ struct dwc3_google *google = to_dwc3_google(dwc);
+ int ret;
+
+ ret = dwc3_google_resume(google, PMSG_AUTO_RESUME);
+ if (ret)
+ return ret;
+
+ return dwc3_runtime_resume(&google->dwc);
+}
+
+static int dwc3_google_runtime_idle(struct device *dev)
+{
+ return dwc3_runtime_idle(dev_get_drvdata(dev));
+}
+
+static const struct dev_pm_ops dwc3_google_dev_pm_ops = {
+ SYSTEM_SLEEP_PM_OPS(dwc3_google_pm_suspend, dwc3_google_pm_resume)
+ RUNTIME_PM_OPS(dwc3_google_runtime_suspend, dwc3_google_runtime_resume,
+ dwc3_google_runtime_idle)
+ .complete = pm_sleep_ptr(dwc3_google_complete),
+ .prepare = pm_sleep_ptr(dwc3_google_prepare),
+};
+
+static const struct of_device_id dwc3_google_of_match[] = {
+ { .compatible = "google,lga-dwc3" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, dwc3_google_of_match);
+
+static struct platform_driver dwc3_google_driver = {
+ .probe = dwc3_google_probe,
+ .remove = dwc3_google_remove,
+ .driver = {
+ .name = "dwc3-google",
+ .pm = pm_ptr(&dwc3_google_dev_pm_ops),
+ .of_match_table = dwc3_google_of_match,
+ },
+};
+
+module_platform_driver(dwc3_google_driver);
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("DesignWare DWC3 Google Glue Driver");
diff --git a/drivers/usb/dwc3/dwc3-imx8mp.c b/drivers/usb/dwc3/dwc3-imx8mp.c
index 45c276a31d84..b3d7252bd910 100644
--- a/drivers/usb/dwc3/dwc3-imx8mp.c
+++ b/drivers/usb/dwc3/dwc3-imx8mp.c
@@ -51,7 +51,7 @@
struct dwc3_imx8mp {
struct device *dev;
- struct platform_device *dwc3;
+ struct platform_device *dwc3_pdev;
void __iomem *hsio_blk_base;
void __iomem *glue_base;
struct clk *hsio_clk;
@@ -100,7 +100,7 @@ static void imx8mp_configure_glue(struct dwc3_imx8mp *dwc3_imx)
static void dwc3_imx8mp_wakeup_enable(struct dwc3_imx8mp *dwc3_imx,
pm_message_t msg)
{
- struct dwc3 *dwc3 = platform_get_drvdata(dwc3_imx->dwc3);
+ struct dwc3 *dwc3 = platform_get_drvdata(dwc3_imx->dwc3_pdev);
u32 val;
if (!dwc3)
@@ -142,7 +142,7 @@ static const struct software_node dwc3_imx8mp_swnode = {
static irqreturn_t dwc3_imx8mp_interrupt(int irq, void *_dwc3_imx)
{
struct dwc3_imx8mp *dwc3_imx = _dwc3_imx;
- struct dwc3 *dwc = platform_get_drvdata(dwc3_imx->dwc3);
+ struct dwc3 *dwc = platform_get_drvdata(dwc3_imx->dwc3_pdev);
if (!dwc3_imx->pm_suspended)
return IRQ_HANDLED;
@@ -158,11 +158,31 @@ static irqreturn_t dwc3_imx8mp_interrupt(int irq, void *_dwc3_imx)
return IRQ_HANDLED;
}
+static void dwc3_imx_pre_set_role(struct dwc3 *dwc, enum usb_role role)
+{
+ if (role == USB_ROLE_HOST)
+ /*
+ * For xhci host, we need disable dwc core auto
+ * suspend, because during this auto suspend delay(5s),
+ * xhci host RUN_STOP is cleared and wakeup is not
+ * enabled, if device is inserted, xhci host can't
+ * response the connection.
+ */
+ pm_runtime_dont_use_autosuspend(dwc->dev);
+ else
+ pm_runtime_use_autosuspend(dwc->dev);
+}
+
+struct dwc3_glue_ops dwc3_imx_glue_ops = {
+ .pre_set_role = dwc3_imx_pre_set_role,
+};
+
static int dwc3_imx8mp_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *node = dev->of_node;
struct dwc3_imx8mp *dwc3_imx;
+ struct dwc3 *dwc3;
struct resource *res;
int err, irq;
@@ -233,13 +253,24 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev)
goto remove_swnode;
}
- dwc3_imx->dwc3 = of_find_device_by_node(dwc3_np);
- if (!dwc3_imx->dwc3) {
+ dwc3_imx->dwc3_pdev = of_find_device_by_node(dwc3_np);
+ if (!dwc3_imx->dwc3_pdev) {
dev_err(dev, "failed to get dwc3 platform device\n");
err = -ENODEV;
goto depopulate;
}
+ dwc3 = platform_get_drvdata(dwc3_imx->dwc3_pdev);
+ if (!dwc3) {
+ err = dev_err_probe(dev, -EPROBE_DEFER, "failed to get dwc3 platform data\n");
+ goto depopulate;
+ }
+
+ dwc3->glue_ops = &dwc3_imx_glue_ops;
+
+ if (dwc3->dr_mode == USB_DR_MODE_HOST)
+ pm_runtime_dont_use_autosuspend(dwc3->dev);
+
err = devm_request_threaded_irq(dev, irq, NULL, dwc3_imx8mp_interrupt,
IRQF_ONESHOT, dev_name(dev), dwc3_imx);
if (err) {
@@ -253,7 +284,7 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev)
return 0;
put_dwc3:
- put_device(&dwc3_imx->dwc3->dev);
+ put_device(&dwc3_imx->dwc3_pdev->dev);
depopulate:
of_platform_depopulate(dev);
remove_swnode:
@@ -270,7 +301,7 @@ static void dwc3_imx8mp_remove(struct platform_device *pdev)
struct dwc3_imx8mp *dwc3_imx = platform_get_drvdata(pdev);
struct device *dev = &pdev->dev;
- put_device(&dwc3_imx->dwc3->dev);
+ put_device(&dwc3_imx->dwc3_pdev->dev);
pm_runtime_get_sync(dev);
of_platform_depopulate(dev);
@@ -296,7 +327,7 @@ static int dwc3_imx8mp_suspend(struct dwc3_imx8mp *dwc3_imx, pm_message_t msg)
static int dwc3_imx8mp_resume(struct dwc3_imx8mp *dwc3_imx, pm_message_t msg)
{
- struct dwc3 *dwc = platform_get_drvdata(dwc3_imx->dwc3);
+ struct dwc3 *dwc = platform_get_drvdata(dwc3_imx->dwc3_pdev);
int ret = 0;
if (!dwc3_imx->pm_suspended)
diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c
index 0a8c47876ff9..f41b0da5e89d 100644
--- a/drivers/usb/dwc3/dwc3-xilinx.c
+++ b/drivers/usb/dwc3/dwc3-xilinx.c
@@ -132,21 +132,6 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data)
goto err;
}
- /*
- * The following core resets are not required unless a USB3 PHY
- * is used, and the subsequent register settings are not required
- * unless a core reset is performed (they should be set properly
- * by the first-stage boot loader, but may be reverted by a core
- * reset). They may also break the configuration if USB3 is actually
- * in use but the usb3-phy entry is missing from the device tree.
- * Therefore, skip these operations in this case.
- */
- if (!priv_data->usb3_phy) {
- /* Deselect the PIPE Clock Select bit in FPD PIPE Clock register */
- writel(PIPE_CLK_DESELECT, priv_data->regs + XLNX_USB_FPD_PIPE_CLK);
- goto skip_usb3_phy;
- }
-
crst = devm_reset_control_get_exclusive(dev, "usb_crst");
if (IS_ERR(crst)) {
ret = PTR_ERR(crst);
@@ -171,22 +156,31 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data)
goto err;
}
- ret = reset_control_assert(crst);
- if (ret < 0) {
- dev_err(dev, "Failed to assert core reset\n");
- goto err;
- }
-
- ret = reset_control_assert(hibrst);
- if (ret < 0) {
- dev_err(dev, "Failed to assert hibernation reset\n");
- goto err;
- }
-
- ret = reset_control_assert(apbrst);
- if (ret < 0) {
- dev_err(dev, "Failed to assert APB reset\n");
- goto err;
+ /*
+ * Asserting the core resets is not required unless a USB3 PHY is used.
+ * They may also break the configuration if USB3 is actually in use but
+ * the usb3-phy entry is missing from the device tree. Therefore, skip
+ * a full reset cycle and just deassert the resets if the phy is
+ * absent.
+ */
+ if (priv_data->usb3_phy) {
+ ret = reset_control_assert(crst);
+ if (ret < 0) {
+ dev_err(dev, "Failed to assert core reset\n");
+ goto err;
+ }
+
+ ret = reset_control_assert(hibrst);
+ if (ret < 0) {
+ dev_err(dev, "Failed to assert hibernation reset\n");
+ goto err;
+ }
+
+ ret = reset_control_assert(apbrst);
+ if (ret < 0) {
+ dev_err(dev, "Failed to assert APB reset\n");
+ goto err;
+ }
}
ret = phy_init(priv_data->usb3_phy);
@@ -201,11 +195,15 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data)
goto err;
}
- /* Set PIPE Power Present signal in FPD Power Present Register*/
- writel(FPD_POWER_PRSNT_OPTION, priv_data->regs + XLNX_USB_FPD_POWER_PRSNT);
-
- /* Set the PIPE Clock Select bit in FPD PIPE Clock register */
- writel(PIPE_CLK_SELECT, priv_data->regs + XLNX_USB_FPD_PIPE_CLK);
+ if (priv_data->usb3_phy) {
+ /* Set PIPE Power Present signal in FPD Power Present Register*/
+ writel(FPD_POWER_PRSNT_OPTION, priv_data->regs + XLNX_USB_FPD_POWER_PRSNT);
+ /* Set the PIPE Clock Select bit in FPD PIPE Clock register */
+ writel(PIPE_CLK_SELECT, priv_data->regs + XLNX_USB_FPD_PIPE_CLK);
+ } else {
+ /* Deselect the PIPE Clock Select bit in FPD PIPE Clock register */
+ writel(PIPE_CLK_DESELECT, priv_data->regs + XLNX_USB_FPD_PIPE_CLK);
+ }
ret = reset_control_deassert(crst);
if (ret < 0) {
@@ -225,7 +223,6 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data)
goto err;
}
-skip_usb3_phy:
/* ulpi reset via gpio-modepin or gpio-framework driver */
reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(reset_gpio)) {
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index e0bad5708664..bfe616194dfa 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -361,7 +361,7 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc,
if ((dwc->speed == DWC3_DSTS_SUPERSPEED) ||
(dwc->speed == DWC3_DSTS_SUPERSPEED_PLUS)) {
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
if (reg & DWC3_DCTL_INITU1ENA)
usb_status |= 1 << USB_DEV_STAT_U1_ENABLED;
if (reg & DWC3_DCTL_INITU2ENA)
@@ -417,12 +417,12 @@ static int dwc3_ep0_handle_u1(struct dwc3 *dwc, enum usb_device_state state,
if (set && dwc->dis_u1_entry_quirk)
return -EINVAL;
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
if (set)
reg |= DWC3_DCTL_INITU1ENA;
else
reg &= ~DWC3_DCTL_INITU1ENA;
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+ dwc3_writel(dwc, DWC3_DCTL, reg);
return 0;
}
@@ -441,12 +441,12 @@ static int dwc3_ep0_handle_u2(struct dwc3 *dwc, enum usb_device_state state,
if (set && dwc->dis_u2_entry_quirk)
return -EINVAL;
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
if (set)
reg |= DWC3_DCTL_INITU2ENA;
else
reg &= ~DWC3_DCTL_INITU2ENA;
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+ dwc3_writel(dwc, DWC3_DCTL, reg);
return 0;
}
@@ -612,10 +612,10 @@ static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
return -EINVAL;
}
- reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+ reg = dwc3_readl(dwc, DWC3_DCFG);
reg &= ~(DWC3_DCFG_DEVADDR_MASK);
reg |= DWC3_DCFG_DEVADDR(addr);
- dwc3_writel(dwc->regs, DWC3_DCFG, reg);
+ dwc3_writel(dwc, DWC3_DCFG, reg);
if (addr)
usb_gadget_set_state(dwc->gadget, USB_STATE_ADDRESS);
@@ -672,12 +672,12 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
* Enable transition to U1/U2 state when
* nothing is pending from application.
*/
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
if (!dwc->dis_u1_entry_quirk)
reg |= DWC3_DCTL_ACCEPTU1ENA;
if (!dwc->dis_u2_entry_quirk)
reg |= DWC3_DCTL_ACCEPTU2ENA;
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+ dwc3_writel(dwc, DWC3_DCTL, reg);
}
break;
@@ -717,7 +717,7 @@ static void dwc3_ep0_set_sel_cmpl(struct usb_ep *ep, struct usb_request *req)
dwc->u2sel = le16_to_cpu(timing.u2sel);
dwc->u2pel = le16_to_cpu(timing.u2pel);
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
if (reg & DWC3_DCTL_INITU2ENA)
param = dwc->u2pel;
if (reg & DWC3_DCTL_INITU1ENA)
@@ -833,7 +833,7 @@ static void dwc3_ep0_inspect_setup(struct dwc3 *dwc,
if (!dwc->gadget_driver || !dwc->softconnect || !dwc->connected)
goto out;
- trace_dwc3_ctrl_req(ctrl);
+ trace_dwc3_ctrl_req(dwc, ctrl);
len = le16_to_cpu(ctrl->wLength);
if (!len) {
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 8a35a6901db7..c65291e7b8d9 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -42,7 +42,7 @@ int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode)
{
u32 reg;
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
reg &= ~DWC3_DCTL_TSTCTRL_MASK;
switch (mode) {
@@ -73,7 +73,7 @@ int dwc3_gadget_get_link_state(struct dwc3 *dwc)
{
u32 reg;
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+ reg = dwc3_readl(dwc, DWC3_DSTS);
return DWC3_DSTS_USBLNKST(reg);
}
@@ -97,7 +97,7 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state)
*/
if (!DWC3_VER_IS_PRIOR(DWC3, 194A)) {
while (--retries) {
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+ reg = dwc3_readl(dwc, DWC3_DSTS);
if (reg & DWC3_DSTS_DCNRD)
udelay(5);
else
@@ -108,15 +108,15 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state)
return -ETIMEDOUT;
}
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK;
/* set no action before sending new link state change */
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+ dwc3_writel(dwc, DWC3_DCTL, reg);
/* set requested state */
reg |= DWC3_DCTL_ULSTCHNGREQ(state);
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+ dwc3_writel(dwc, DWC3_DCTL, reg);
/*
* The following code is racy when called from dwc3_gadget_wakeup,
@@ -128,7 +128,7 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state)
/* wait for a change in DSTS */
retries = 10000;
while (--retries) {
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+ reg = dwc3_readl(dwc, DWC3_DSTS);
if (DWC3_DSTS_USBLNKST(reg) == state)
return 0;
@@ -260,11 +260,11 @@ int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned int cmd,
int ret = 0;
u32 reg;
- dwc3_writel(dwc->regs, DWC3_DGCMDPAR, param);
- dwc3_writel(dwc->regs, DWC3_DGCMD, cmd | DWC3_DGCMD_CMDACT);
+ dwc3_writel(dwc, DWC3_DGCMDPAR, param);
+ dwc3_writel(dwc, DWC3_DGCMD, cmd | DWC3_DGCMD_CMDACT);
do {
- reg = dwc3_readl(dwc->regs, DWC3_DGCMD);
+ reg = dwc3_readl(dwc, DWC3_DGCMD);
if (!(reg & DWC3_DGCMD_CMDACT)) {
status = DWC3_DGCMD_STATUS(reg);
if (status)
@@ -278,7 +278,7 @@ int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned int cmd,
status = -ETIMEDOUT;
}
- trace_dwc3_gadget_generic_cmd(cmd, param, status);
+ trace_dwc3_gadget_generic_cmd(dwc, cmd, param, status);
return ret;
}
@@ -320,6 +320,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
int cmd_status = 0;
int ret = -EINVAL;
+ u8 epnum = dep->number;
/*
* When operating in USB 2.0 speeds (HS/FS), if GUSB2PHYCFG.ENBLSLPM or
@@ -333,7 +334,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
*/
if (dwc->gadget->speed <= USB_SPEED_HIGH ||
DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_ENDTRANSFER) {
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0));
if (unlikely(reg & DWC3_GUSB2PHYCFG_SUSPHY)) {
saved_config |= DWC3_GUSB2PHYCFG_SUSPHY;
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
@@ -345,7 +346,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
}
if (saved_config)
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(0), reg);
}
/*
@@ -355,9 +356,9 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
* improve performance.
*/
if (DWC3_DEPCMD_CMD(cmd) != DWC3_DEPCMD_UPDATETRANSFER) {
- dwc3_writel(dep->regs, DWC3_DEPCMDPAR0, params->param0);
- dwc3_writel(dep->regs, DWC3_DEPCMDPAR1, params->param1);
- dwc3_writel(dep->regs, DWC3_DEPCMDPAR2, params->param2);
+ dwc3_writel(dwc, DWC3_DEPCMDPAR0(epnum), params->param0);
+ dwc3_writel(dwc, DWC3_DEPCMDPAR1(epnum), params->param1);
+ dwc3_writel(dwc, DWC3_DEPCMDPAR2(epnum), params->param2);
}
/*
@@ -381,7 +382,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
else
cmd |= DWC3_DEPCMD_CMDACT;
- dwc3_writel(dep->regs, DWC3_DEPCMD, cmd);
+ dwc3_writel(dwc, DWC3_DEPCMD(epnum), cmd);
if (!(cmd & DWC3_DEPCMD_CMDACT) ||
(DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_ENDTRANSFER &&
@@ -391,7 +392,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
}
do {
- reg = dwc3_readl(dep->regs, DWC3_DEPCMD);
+ reg = dwc3_readl(dwc, DWC3_DEPCMD(epnum));
if (!(reg & DWC3_DEPCMD_CMDACT)) {
cmd_status = DWC3_DEPCMD_STATUS(reg);
@@ -447,9 +448,9 @@ skip_status:
mdelay(1);
if (saved_config) {
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0));
reg |= saved_config;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(0), reg);
}
return ret;
@@ -726,7 +727,7 @@ static int dwc3_gadget_calc_ram_depth(struct dwc3 *dwc)
u32 reg;
/* Check if TXFIFOs start at non-zero addr */
- reg = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(0));
+ reg = dwc3_readl(dwc, DWC3_GTXFIFOSIZ(0));
fifo_0_start = DWC3_GTXFIFOSIZ_TXFSTADDR(reg);
ram_depth -= (fifo_0_start >> 16);
@@ -754,7 +755,7 @@ void dwc3_gadget_clear_tx_fifos(struct dwc3 *dwc)
/* Read ep0IN related TXFIFO size */
dep = dwc->eps[1];
- size = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(0));
+ size = dwc3_readl(dwc, DWC3_GTXFIFOSIZ(0));
if (DWC3_IP_IS(DWC3))
fifo_depth = DWC3_GTXFIFOSIZ_TXFDEP(size);
else
@@ -769,10 +770,10 @@ void dwc3_gadget_clear_tx_fifos(struct dwc3 *dwc)
/* Don't change TXFRAMNUM on usb31 version */
size = DWC3_IP_IS(DWC3) ? 0 :
- dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(num >> 1)) &
+ dwc3_readl(dwc, DWC3_GTXFIFOSIZ(num >> 1)) &
DWC31_GTXFIFOSIZ_TXFRAMNUM;
- dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(num >> 1), size);
+ dwc3_writel(dwc, DWC3_GTXFIFOSIZ(num >> 1), size);
dep->flags &= ~DWC3_EP_TXFIFO_RESIZED;
}
dwc->num_ep_resized = 0;
@@ -875,7 +876,7 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep)
fifo_size++;
/* Check if TXFIFOs start at non-zero addr */
- tmp = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(0));
+ tmp = dwc3_readl(dwc, DWC3_GTXFIFOSIZ(0));
fifo_0_start = DWC3_GTXFIFOSIZ_TXFSTADDR(tmp);
fifo_size |= (fifo_0_start + (dwc->last_fifo_depth << 16));
@@ -898,7 +899,7 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep)
return -ENOMEM;
}
- dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(dep->number >> 1), fifo_size);
+ dwc3_writel(dwc, DWC3_GTXFIFOSIZ(dep->number >> 1), fifo_size);
dep->flags |= DWC3_EP_TXFIFO_RESIZED;
dwc->num_ep_resized++;
@@ -942,9 +943,9 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, unsigned int action)
dep->type = usb_endpoint_type(desc);
dep->flags |= DWC3_EP_ENABLED;
- reg = dwc3_readl(dwc->regs, DWC3_DALEPENA);
+ reg = dwc3_readl(dwc, DWC3_DALEPENA);
reg |= DWC3_DALEPENA_EP(dep->number);
- dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
+ dwc3_writel(dwc, DWC3_DALEPENA, reg);
dep->trb_dequeue = 0;
dep->trb_enqueue = 0;
@@ -1079,9 +1080,9 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
if (dep->flags & DWC3_EP_STALL)
__dwc3_gadget_ep_set_halt(dep, 0, false);
- reg = dwc3_readl(dwc->regs, DWC3_DALEPENA);
+ reg = dwc3_readl(dwc, DWC3_DALEPENA);
reg &= ~DWC3_DALEPENA_EP(dep->number);
- dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
+ dwc3_writel(dwc, DWC3_DALEPENA, reg);
dwc3_remove_requests(dwc, dep, -ESHUTDOWN);
@@ -1742,7 +1743,7 @@ static int __dwc3_gadget_get_frame(struct dwc3 *dwc)
{
u32 reg;
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+ reg = dwc3_readl(dwc, DWC3_DSTS);
return DWC3_DSTS_SOFFN(reg);
}
@@ -2350,13 +2351,13 @@ static void dwc3_gadget_enable_linksts_evts(struct dwc3 *dwc, bool set)
if (DWC3_VER_IS_PRIOR(DWC3, 250A))
return;
- reg = dwc3_readl(dwc->regs, DWC3_DEVTEN);
+ reg = dwc3_readl(dwc, DWC3_DEVTEN);
if (set)
reg |= DWC3_DEVTEN_ULSTCNGEN;
else
reg &= ~DWC3_DEVTEN_ULSTCNGEN;
- dwc3_writel(dwc->regs, DWC3_DEVTEN, reg);
+ dwc3_writel(dwc, DWC3_DEVTEN, reg);
}
static int dwc3_gadget_get_frame(struct usb_gadget *g)
@@ -2379,7 +2380,7 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc)
*
* We can check that via USB Link State bits in DSTS register.
*/
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+ reg = dwc3_readl(dwc, DWC3_DSTS);
link_state = DWC3_DSTS_USBLNKST(reg);
@@ -2407,9 +2408,9 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc)
/* Recent versions do this automatically */
if (DWC3_VER_IS_PRIOR(DWC3, 194A)) {
/* write zeroes to Link Change Request */
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK;
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+ dwc3_writel(dwc, DWC3_DCTL, reg);
}
/*
@@ -2529,7 +2530,7 @@ static void __dwc3_gadget_set_ssp_rate(struct dwc3 *dwc)
if (ssp_rate == USB_SSP_GEN_UNKNOWN)
ssp_rate = dwc->max_ssp_rate;
- reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+ reg = dwc3_readl(dwc, DWC3_DCFG);
reg &= ~DWC3_DCFG_SPEED_MASK;
reg &= ~DWC3_DCFG_NUMLANES(~0);
@@ -2542,7 +2543,7 @@ static void __dwc3_gadget_set_ssp_rate(struct dwc3 *dwc)
dwc->max_ssp_rate != USB_SSP_GEN_2x1)
reg |= DWC3_DCFG_NUMLANES(1);
- dwc3_writel(dwc->regs, DWC3_DCFG, reg);
+ dwc3_writel(dwc, DWC3_DCFG, reg);
}
static void __dwc3_gadget_set_speed(struct dwc3 *dwc)
@@ -2560,7 +2561,7 @@ static void __dwc3_gadget_set_speed(struct dwc3 *dwc)
return;
}
- reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+ reg = dwc3_readl(dwc, DWC3_DCFG);
reg &= ~(DWC3_DCFG_SPEED_MASK);
/*
@@ -2611,7 +2612,7 @@ static void __dwc3_gadget_set_speed(struct dwc3 *dwc)
speed < USB_SPEED_SUPER_PLUS)
reg &= ~DWC3_DCFG_NUMLANES(~0);
- dwc3_writel(dwc->regs, DWC3_DCFG, reg);
+ dwc3_writel(dwc, DWC3_DCFG, reg);
}
static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on)
@@ -2636,7 +2637,7 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on)
* mentioned in the dwc3 programming guide. It has been tested on an
* Exynos platforms.
*/
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0));
if (reg & DWC3_GUSB2PHYCFG_SUSPHY) {
saved_config |= DWC3_GUSB2PHYCFG_SUSPHY;
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
@@ -2648,9 +2649,9 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on)
}
if (saved_config)
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(0), reg);
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
if (is_on) {
if (DWC3_VER_IS_WITHIN(DWC3, ANY, 187A)) {
reg &= ~DWC3_DCTL_TRGTULST_MASK;
@@ -2674,14 +2675,14 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on)
do {
usleep_range(1000, 2000);
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+ reg = dwc3_readl(dwc, DWC3_DSTS);
reg &= DWC3_DSTS_DEVCTRLHLT;
} while (--timeout && !(!is_on ^ !reg));
if (saved_config) {
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0));
reg |= saved_config;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(0), reg);
}
if (!timeout)
@@ -2857,13 +2858,13 @@ static void dwc3_gadget_enable_irq(struct dwc3 *dwc)
if (!DWC3_VER_IS_PRIOR(DWC3, 230A))
reg |= DWC3_DEVTEN_U3L2L1SUSPEN;
- dwc3_writel(dwc->regs, DWC3_DEVTEN, reg);
+ dwc3_writel(dwc, DWC3_DEVTEN, reg);
}
static void dwc3_gadget_disable_irq(struct dwc3 *dwc)
{
/* mask all interrupts */
- dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00);
+ dwc3_writel(dwc, DWC3_DEVTEN, 0x00);
}
static irqreturn_t dwc3_interrupt(int irq, void *_dwc);
@@ -2904,10 +2905,10 @@ static void dwc3_gadget_setup_nump(struct dwc3 *dwc)
nump = min_t(u32, nump, 16);
/* update NumP */
- reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+ reg = dwc3_readl(dwc, DWC3_DCFG);
reg &= ~DWC3_DCFG_NUMP_MASK;
reg |= nump << DWC3_DCFG_NUMP_SHIFT;
- dwc3_writel(dwc->regs, DWC3_DCFG, reg);
+ dwc3_writel(dwc, DWC3_DCFG, reg);
}
static int __dwc3_gadget_start(struct dwc3 *dwc)
@@ -2921,10 +2922,10 @@ static int __dwc3_gadget_start(struct dwc3 *dwc)
* the core supports IMOD, disable it.
*/
if (dwc->imod_interval) {
- dwc3_writel(dwc->regs, DWC3_DEV_IMOD(0), dwc->imod_interval);
- dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), DWC3_GEVNTCOUNT_EHB);
+ dwc3_writel(dwc, DWC3_DEV_IMOD(0), dwc->imod_interval);
+ dwc3_writel(dwc, DWC3_GEVNTCOUNT(0), DWC3_GEVNTCOUNT_EHB);
} else if (dwc3_has_imod(dwc)) {
- dwc3_writel(dwc->regs, DWC3_DEV_IMOD(0), 0);
+ dwc3_writel(dwc, DWC3_DEV_IMOD(0), 0);
}
/*
@@ -2934,13 +2935,13 @@ static int __dwc3_gadget_start(struct dwc3 *dwc)
* This way, we maximize the chances that we'll be able to get several
* bursts of data without going through any sort of endpoint throttling.
*/
- reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG);
+ reg = dwc3_readl(dwc, DWC3_GRXTHRCFG);
if (DWC3_IP_IS(DWC3))
reg &= ~DWC3_GRXTHRCFG_PKTCNTSEL;
else
reg &= ~DWC31_GRXTHRCFG_PKTCNTSEL;
- dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg);
+ dwc3_writel(dwc, DWC3_GRXTHRCFG, reg);
dwc3_gadget_setup_nump(dwc);
@@ -2951,15 +2952,15 @@ static int __dwc3_gadget_start(struct dwc3 *dwc)
* ACK with NumP=0 and PP=0 (for IN direction). This slightly improves
* the stream performance.
*/
- reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+ reg = dwc3_readl(dwc, DWC3_DCFG);
reg |= DWC3_DCFG_IGNSTRMPP;
- dwc3_writel(dwc->regs, DWC3_DCFG, reg);
+ dwc3_writel(dwc, DWC3_DCFG, reg);
/* Enable MST by default if the device is capable of MST */
if (DWC3_MST_CAPABLE(&dwc->hwparams)) {
- reg = dwc3_readl(dwc->regs, DWC3_DCFG1);
+ reg = dwc3_readl(dwc, DWC3_DCFG1);
reg &= ~DWC3_DCFG1_DIS_MST_ENH;
- dwc3_writel(dwc->regs, DWC3_DCFG1, reg);
+ dwc3_writel(dwc, DWC3_DCFG1, reg);
}
/* Start with SuperSpeed Default */
@@ -3123,8 +3124,6 @@ static void dwc3_gadget_set_ssp_rate(struct usb_gadget *g,
static int dwc3_gadget_vbus_draw(struct usb_gadget *g, unsigned int mA)
{
struct dwc3 *dwc = gadget_to_dwc(g);
- union power_supply_propval val = {0};
- int ret;
if (dwc->usb2_phy)
return usb_phy_set_power(dwc->usb2_phy, mA);
@@ -3132,10 +3131,10 @@ static int dwc3_gadget_vbus_draw(struct usb_gadget *g, unsigned int mA)
if (!dwc->usb_psy)
return -EOPNOTSUPP;
- val.intval = 1000 * mA;
- ret = power_supply_set_property(dwc->usb_psy, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &val);
+ dwc->current_limit = mA;
+ schedule_work(&dwc->vbus_draw_work);
- return ret;
+ return 0;
}
/**
@@ -3239,7 +3238,7 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep)
/* MDWIDTH is represented in bits, we need it in bytes */
mdwidth /= 8;
- size = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(dep->number >> 1));
+ size = dwc3_readl(dwc, DWC3_GTXFIFOSIZ(dep->number >> 1));
if (DWC3_IP_IS(DWC3))
size = DWC3_GTXFIFOSIZ_TXFDEP(size);
else
@@ -3288,7 +3287,7 @@ static int dwc3_gadget_init_out_endpoint(struct dwc3_ep *dep)
mdwidth /= 8;
/* All OUT endpoints share a single RxFIFO space */
- size = dwc3_readl(dwc->regs, DWC3_GRXFIFOSIZ(0));
+ size = dwc3_readl(dwc, DWC3_GRXFIFOSIZ(0));
if (DWC3_IP_IS(DWC3))
size = DWC3_GRXFIFOSIZ_RXFDEP(size);
else
@@ -3381,7 +3380,6 @@ static int dwc3_gadget_init_endpoint(struct dwc3 *dwc, u8 epnum)
dep->dwc = dwc;
dep->number = epnum;
dep->direction = direction;
- dep->regs = dwc->regs + DWC3_DEP_BASE(epnum);
dwc->eps[epnum] = dep;
dep->combo_num = 0;
dep->start_cmd_status = 0;
@@ -3742,9 +3740,9 @@ out:
return no_started_trb;
}
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
reg |= dwc->u1u2;
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+ dwc3_writel(dwc, DWC3_DCTL, reg);
dwc->u1u2 = 0;
}
@@ -4074,7 +4072,7 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc)
dwc3_gadget_set_link_state(dwc, DWC3_LINK_STATE_RX_DET);
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
reg &= ~DWC3_DCTL_INITU1ENA;
reg &= ~DWC3_DCTL_INITU2ENA;
dwc3_gadget_dctl_write_safe(dwc, reg);
@@ -4163,7 +4161,7 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
dwc3_stop_active_transfers(dwc);
dwc->connected = true;
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
reg &= ~DWC3_DCTL_TSTCTRL_MASK;
dwc3_gadget_dctl_write_safe(dwc, reg);
dwc->test_mode = false;
@@ -4172,9 +4170,9 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
dwc3_clear_stall_all_ep(dwc);
/* Reset device address to zero */
- reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+ reg = dwc3_readl(dwc, DWC3_DCFG);
reg &= ~(DWC3_DCFG_DEVADDR_MASK);
- dwc3_writel(dwc->regs, DWC3_DCFG, reg);
+ dwc3_writel(dwc, DWC3_DCFG, reg);
}
static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
@@ -4188,7 +4186,7 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
if (!dwc->softconnect)
return;
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+ reg = dwc3_readl(dwc, DWC3_DSTS);
speed = reg & DWC3_DSTS_CONNECTSPD;
dwc->speed = speed;
@@ -4263,11 +4261,11 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
!dwc->usb2_gadget_lpm_disable &&
(speed != DWC3_DSTS_SUPERSPEED) &&
(speed != DWC3_DSTS_SUPERSPEED_PLUS)) {
- reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+ reg = dwc3_readl(dwc, DWC3_DCFG);
reg |= DWC3_DCFG_LPM_CAP;
- dwc3_writel(dwc->regs, DWC3_DCFG, reg);
+ dwc3_writel(dwc, DWC3_DCFG, reg);
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
reg &= ~(DWC3_DCTL_HIRD_THRES_MASK | DWC3_DCTL_L1_HIBER_EN);
reg |= DWC3_DCTL_HIRD_THRES(dwc->hird_threshold |
@@ -4290,12 +4288,12 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
dwc3_gadget_dctl_write_safe(dwc, reg);
} else {
if (dwc->usb2_gadget_lpm_disable) {
- reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+ reg = dwc3_readl(dwc, DWC3_DCFG);
reg &= ~DWC3_DCFG_LPM_CAP;
- dwc3_writel(dwc->regs, DWC3_DCFG, reg);
+ dwc3_writel(dwc, DWC3_DCFG, reg);
}
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
reg &= ~DWC3_DCTL_HIRD_THRES_MASK;
dwc3_gadget_dctl_write_safe(dwc, reg);
}
@@ -4401,7 +4399,7 @@ static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc,
switch (dwc->link_state) {
case DWC3_LINK_STATE_U1:
case DWC3_LINK_STATE_U2:
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg = dwc3_readl(dwc, DWC3_DCTL);
u1u2 = reg & (DWC3_DCTL_INITU2ENA
| DWC3_DCTL_ACCEPTU2ENA
| DWC3_DCTL_INITU1ENA
@@ -4558,7 +4556,7 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3_event_buffer *evt)
ret = IRQ_HANDLED;
/* Unmask interrupt */
- dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0),
+ dwc3_writel(dwc, DWC3_GEVNTSIZ(0),
DWC3_GEVNTSIZ_SIZE(evt->length));
evt->flags &= ~DWC3_EVENT_PENDING;
@@ -4569,8 +4567,8 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3_event_buffer *evt)
wmb();
if (dwc->imod_interval) {
- dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), DWC3_GEVNTCOUNT_EHB);
- dwc3_writel(dwc->regs, DWC3_DEV_IMOD(0), dwc->imod_interval);
+ dwc3_writel(dwc, DWC3_GEVNTCOUNT(0), DWC3_GEVNTCOUNT_EHB);
+ dwc3_writel(dwc, DWC3_DEV_IMOD(0), dwc->imod_interval);
}
return ret;
@@ -4619,7 +4617,7 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt)
if (evt->flags & DWC3_EVENT_PENDING)
return IRQ_HANDLED;
- count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
+ count = dwc3_readl(dwc, DWC3_GEVNTCOUNT(0));
count &= DWC3_GEVNTCOUNT_MASK;
if (!count)
return IRQ_NONE;
@@ -4634,7 +4632,7 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt)
evt->flags |= DWC3_EVENT_PENDING;
/* Mask interrupt */
- dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0),
+ dwc3_writel(dwc, DWC3_GEVNTSIZ(0),
DWC3_GEVNTSIZ_INTMASK | DWC3_GEVNTSIZ_SIZE(evt->length));
amount = min(count, evt->length - evt->lpos);
@@ -4643,7 +4641,7 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt)
if (amount < count)
memcpy(evt->cache, evt->buf, count - amount);
- dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), count);
+ dwc3_writel(dwc, DWC3_GEVNTCOUNT(0), count);
return IRQ_WAKE_THREAD;
}
diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h
index d73e735e4081..45f113b3c146 100644
--- a/drivers/usb/dwc3/gadget.h
+++ b/drivers/usb/dwc3/gadget.h
@@ -132,7 +132,7 @@ static inline void dwc3_gadget_ep_get_transfer_index(struct dwc3_ep *dep)
{
u32 res_id;
- res_id = dwc3_readl(dep->regs, DWC3_DEPCMD);
+ res_id = dwc3_readl(dep->dwc, DWC3_DEPCMD(dep->number));
dep->resource_index = DWC3_DEPCMD_GET_RSC_IDX(res_id);
}
@@ -147,7 +147,7 @@ static inline void dwc3_gadget_ep_get_transfer_index(struct dwc3_ep *dep)
static inline void dwc3_gadget_dctl_write_safe(struct dwc3 *dwc, u32 value)
{
value &= ~DWC3_DCTL_ULSTCHNGREQ_MASK;
- dwc3_writel(dwc->regs, DWC3_DCTL, value);
+ dwc3_writel(dwc, DWC3_DCTL, value);
}
#endif /* __DRIVERS_USB_DWC3_GADGET_H */
diff --git a/drivers/usb/dwc3/io.h b/drivers/usb/dwc3/io.h
index 1e96ea339d48..cad9a2ae1547 100644
--- a/drivers/usb/dwc3/io.h
+++ b/drivers/usb/dwc3/io.h
@@ -16,9 +16,10 @@
#include "debug.h"
#include "core.h"
-static inline u32 dwc3_readl(void __iomem *base, u32 offset)
+static inline u32 dwc3_readl(struct dwc3 *dwc, u32 offset)
{
u32 value;
+ void __iomem *base = dwc->regs;
/*
* We requested the mem region starting from the Globals address
@@ -32,13 +33,15 @@ static inline u32 dwc3_readl(void __iomem *base, u32 offset)
* documentation, so we revert it back to the proper addresses, the
* same way they are described on SNPS documentation
*/
- trace_dwc3_readl(base - DWC3_GLOBALS_REGS_START, offset, value);
+ trace_dwc3_readl(dwc, base - DWC3_GLOBALS_REGS_START, offset, value);
return value;
}
-static inline void dwc3_writel(void __iomem *base, u32 offset, u32 value)
+static inline void dwc3_writel(struct dwc3 *dwc, u32 offset, u32 value)
{
+ void __iomem *base = dwc->regs;
+
/*
* We requested the mem region starting from the Globals address
* space, see dwc3_probe in core.c.
@@ -51,7 +54,7 @@ static inline void dwc3_writel(void __iomem *base, u32 offset, u32 value)
* documentation, so we revert it back to the proper addresses, the
* same way they are described on SNPS documentation
*/
- trace_dwc3_writel(base - DWC3_GLOBALS_REGS_START, offset, value);
+ trace_dwc3_writel(dwc, base - DWC3_GLOBALS_REGS_START, offset, value);
}
#endif /* __DRIVERS_USB_DWC3_IO_H */
diff --git a/drivers/usb/dwc3/trace.h b/drivers/usb/dwc3/trace.h
index b6ba984bafcd..5253da23d8b0 100644
--- a/drivers/usb/dwc3/trace.h
+++ b/drivers/usb/dwc3/trace.h
@@ -20,63 +20,70 @@
#include "debug.h"
DECLARE_EVENT_CLASS(dwc3_log_set_prtcap,
- TP_PROTO(u32 mode),
- TP_ARGS(mode),
+ TP_PROTO(struct dwc3 *dwc, u32 mode),
+ TP_ARGS(dwc, mode),
TP_STRUCT__entry(
+ __field(phys_addr_t, base_address)
__field(u32, mode)
),
TP_fast_assign(
+ __entry->base_address = dwc->xhci_resources[0].start;
__entry->mode = mode;
),
- TP_printk("mode %s", dwc3_mode_string(__entry->mode))
+ TP_printk("%pa: mode %s", &__entry->base_address, dwc3_mode_string(__entry->mode))
);
DEFINE_EVENT(dwc3_log_set_prtcap, dwc3_set_prtcap,
- TP_PROTO(u32 mode),
- TP_ARGS(mode)
+ TP_PROTO(struct dwc3 *dwc, u32 mode),
+ TP_ARGS(dwc, mode)
);
DECLARE_EVENT_CLASS(dwc3_log_io,
- TP_PROTO(void *base, u32 offset, u32 value),
- TP_ARGS(base, offset, value),
+ TP_PROTO(struct dwc3 *dwc, void *base, u32 offset, u32 value),
+ TP_ARGS(dwc, base, offset, value),
TP_STRUCT__entry(
+ __field(phys_addr_t, base_address)
__field(void *, base)
__field(u32, offset)
__field(u32, value)
),
TP_fast_assign(
+ __entry->base_address = dwc->xhci_resources[0].start;
__entry->base = base;
__entry->offset = offset;
__entry->value = value;
),
- TP_printk("addr %p offset %04x value %08x",
+ TP_printk("%pa: addr %p offset %04x value %08x",
+ &__entry->base_address,
__entry->base + __entry->offset,
__entry->offset,
__entry->value)
);
DEFINE_EVENT(dwc3_log_io, dwc3_readl,
- TP_PROTO(void __iomem *base, u32 offset, u32 value),
- TP_ARGS(base, offset, value)
+ TP_PROTO(struct dwc3 *dwc, void __iomem *base, u32 offset, u32 value),
+ TP_ARGS(dwc, base, offset, value)
);
DEFINE_EVENT(dwc3_log_io, dwc3_writel,
- TP_PROTO(void __iomem *base, u32 offset, u32 value),
- TP_ARGS(base, offset, value)
+ TP_PROTO(struct dwc3 *dwc, void __iomem *base, u32 offset, u32 value),
+ TP_ARGS(dwc, base, offset, value)
);
DECLARE_EVENT_CLASS(dwc3_log_event,
TP_PROTO(u32 event, struct dwc3 *dwc),
TP_ARGS(event, dwc),
TP_STRUCT__entry(
+ __field(phys_addr_t, base_address)
__field(u32, event)
__field(u32, ep0state)
),
TP_fast_assign(
+ __entry->base_address = dwc->xhci_resources[0].start;
__entry->event = event;
__entry->ep0state = dwc->ep0state;
),
- TP_printk("event (%08x): %s", __entry->event,
+ TP_printk("%pa: event (%08x): %s", &__entry->base_address, __entry->event,
dwc3_decode_event(__get_buf(DWC3_MSG_MAX), DWC3_MSG_MAX,
__entry->event, __entry->ep0state))
);
@@ -87,9 +94,10 @@ DEFINE_EVENT(dwc3_log_event, dwc3_event,
);
DECLARE_EVENT_CLASS(dwc3_log_ctrl,
- TP_PROTO(struct usb_ctrlrequest *ctrl),
- TP_ARGS(ctrl),
+ TP_PROTO(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl),
+ TP_ARGS(dwc, ctrl),
TP_STRUCT__entry(
+ __field(phys_addr_t, base_address)
__field(__u8, bRequestType)
__field(__u8, bRequest)
__field(__u16, wValue)
@@ -97,13 +105,15 @@ DECLARE_EVENT_CLASS(dwc3_log_ctrl,
__field(__u16, wLength)
),
TP_fast_assign(
+ __entry->base_address = dwc->xhci_resources[0].start;
__entry->bRequestType = ctrl->bRequestType;
__entry->bRequest = ctrl->bRequest;
__entry->wValue = le16_to_cpu(ctrl->wValue);
__entry->wIndex = le16_to_cpu(ctrl->wIndex);
__entry->wLength = le16_to_cpu(ctrl->wLength);
),
- TP_printk("%s", usb_decode_ctrl(__get_buf(DWC3_MSG_MAX), DWC3_MSG_MAX,
+ TP_printk("%pa: %s", &__entry->base_address, usb_decode_ctrl(__get_buf(DWC3_MSG_MAX),
+ DWC3_MSG_MAX,
__entry->bRequestType,
__entry->bRequest, __entry->wValue,
__entry->wIndex, __entry->wLength)
@@ -111,14 +121,15 @@ DECLARE_EVENT_CLASS(dwc3_log_ctrl,
);
DEFINE_EVENT(dwc3_log_ctrl, dwc3_ctrl_req,
- TP_PROTO(struct usb_ctrlrequest *ctrl),
- TP_ARGS(ctrl)
+ TP_PROTO(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl),
+ TP_ARGS(dwc, ctrl)
);
DECLARE_EVENT_CLASS(dwc3_log_request,
TP_PROTO(struct dwc3_request *req),
TP_ARGS(req),
TP_STRUCT__entry(
+ __field(phys_addr_t, base_address)
__string(name, req->dep->name)
__field(struct dwc3_request *, req)
__field(unsigned int, actual)
@@ -129,7 +140,7 @@ DECLARE_EVENT_CLASS(dwc3_log_request,
__field(int, no_interrupt)
),
TP_fast_assign(
- __assign_str(name);
+ __entry->base_address = req->dep->dwc->xhci_resources[0].start;
__entry->req = req;
__entry->actual = req->request.actual;
__entry->length = req->request.length;
@@ -138,8 +149,10 @@ DECLARE_EVENT_CLASS(dwc3_log_request,
__entry->short_not_ok = req->request.short_not_ok;
__entry->no_interrupt = req->request.no_interrupt;
),
- TP_printk("%s: req %p length %u/%u %s%s%s ==> %d",
- __get_str(name), __entry->req, __entry->actual, __entry->length,
+ TP_printk("%pa: %s: req %p length %u/%u %s%s%s ==> %d",
+ &__entry->base_address,
+ __get_str(name), __entry->req,
+ __entry->actual, __entry->length,
__entry->zero ? "Z" : "z",
__entry->short_not_ok ? "S" : "s",
__entry->no_interrupt ? "i" : "I",
@@ -173,28 +186,30 @@ DEFINE_EVENT(dwc3_log_request, dwc3_gadget_giveback,
);
DECLARE_EVENT_CLASS(dwc3_log_generic_cmd,
- TP_PROTO(unsigned int cmd, u32 param, int status),
- TP_ARGS(cmd, param, status),
+ TP_PROTO(struct dwc3 *dwc, unsigned int cmd, u32 param, int status),
+ TP_ARGS(dwc, cmd, param, status),
TP_STRUCT__entry(
+ __field(phys_addr_t, base_address)
__field(unsigned int, cmd)
__field(u32, param)
__field(int, status)
),
TP_fast_assign(
+ __entry->base_address = dwc->xhci_resources[0].start;
__entry->cmd = cmd;
__entry->param = param;
__entry->status = status;
),
- TP_printk("cmd '%s' [%x] param %08x --> status: %s",
- dwc3_gadget_generic_cmd_string(__entry->cmd),
+ TP_printk("%pa: cmd '%s' [%x] param %08x --> status: %s",
+ &__entry->base_address, dwc3_gadget_generic_cmd_string(__entry->cmd),
__entry->cmd, __entry->param,
dwc3_gadget_generic_cmd_status_string(__entry->status)
)
);
DEFINE_EVENT(dwc3_log_generic_cmd, dwc3_gadget_generic_cmd,
- TP_PROTO(unsigned int cmd, u32 param, int status),
- TP_ARGS(cmd, param, status)
+ TP_PROTO(struct dwc3 *dwc, unsigned int cmd, u32 param, int status),
+ TP_ARGS(dwc, cmd, param, status)
);
DECLARE_EVENT_CLASS(dwc3_log_gadget_ep_cmd,
@@ -202,6 +217,7 @@ DECLARE_EVENT_CLASS(dwc3_log_gadget_ep_cmd,
struct dwc3_gadget_ep_cmd_params *params, int cmd_status),
TP_ARGS(dep, cmd, params, cmd_status),
TP_STRUCT__entry(
+ __field(phys_addr_t, base_address)
__string(name, dep->name)
__field(unsigned int, cmd)
__field(u32, param0)
@@ -210,6 +226,7 @@ DECLARE_EVENT_CLASS(dwc3_log_gadget_ep_cmd,
__field(int, cmd_status)
),
TP_fast_assign(
+ __entry->base_address = dep->dwc->xhci_resources[0].start;
__assign_str(name);
__entry->cmd = cmd;
__entry->param0 = params->param0;
@@ -217,8 +234,9 @@ DECLARE_EVENT_CLASS(dwc3_log_gadget_ep_cmd,
__entry->param2 = params->param2;
__entry->cmd_status = cmd_status;
),
- TP_printk("%s: cmd '%s' [%x] params %08x %08x %08x --> status: %s",
- __get_str(name), dwc3_gadget_ep_cmd_string(__entry->cmd),
+ TP_printk("%pa: %s: cmd '%s' [%x] params %08x %08x %08x --> status: %s",
+ &__entry->base_address, __get_str(name),
+ dwc3_gadget_ep_cmd_string(__entry->cmd),
__entry->cmd, __entry->param0,
__entry->param1, __entry->param2,
dwc3_ep_cmd_status_string(__entry->cmd_status)
@@ -235,6 +253,7 @@ DECLARE_EVENT_CLASS(dwc3_log_trb,
TP_PROTO(struct dwc3_ep *dep, struct dwc3_trb *trb),
TP_ARGS(dep, trb),
TP_STRUCT__entry(
+ __field(phys_addr_t, base_address)
__string(name, dep->name)
__field(struct dwc3_trb *, trb)
__field(u32, bpl)
@@ -246,6 +265,7 @@ DECLARE_EVENT_CLASS(dwc3_log_trb,
__field(u32, dequeue)
),
TP_fast_assign(
+ __entry->base_address = dep->dwc->xhci_resources[0].start;
__assign_str(name);
__entry->trb = trb;
__entry->bpl = trb->bpl;
@@ -256,8 +276,8 @@ DECLARE_EVENT_CLASS(dwc3_log_trb,
__entry->enqueue = dep->trb_enqueue;
__entry->dequeue = dep->trb_dequeue;
),
- TP_printk("%s: trb %p (E%d:D%d) buf %08x%08x size %s%d ctrl %08x sofn %08x (%c%c%c%c:%c%c:%s)",
- __get_str(name), __entry->trb, __entry->enqueue,
+ TP_printk("%pa: %s: trb %p (E%d:D%d) buf %08x%08x size %s%d ctrl %08x sofn %08x (%c%c%c%c:%c%c:%s)",
+ &__entry->base_address, __get_str(name), __entry->trb, __entry->enqueue,
__entry->dequeue, __entry->bph, __entry->bpl,
({char *s;
int pcm = ((__entry->size >> 24) & 3) + 1;
@@ -307,6 +327,7 @@ DECLARE_EVENT_CLASS(dwc3_log_ep,
TP_PROTO(struct dwc3_ep *dep),
TP_ARGS(dep),
TP_STRUCT__entry(
+ __field(phys_addr_t, base_address)
__string(name, dep->name)
__field(unsigned int, maxpacket)
__field(unsigned int, maxpacket_limit)
@@ -318,6 +339,7 @@ DECLARE_EVENT_CLASS(dwc3_log_ep,
__field(u8, trb_dequeue)
),
TP_fast_assign(
+ __entry->base_address = dep->dwc->xhci_resources[0].start;
__assign_str(name);
__entry->maxpacket = dep->endpoint.maxpacket;
__entry->maxpacket_limit = dep->endpoint.maxpacket_limit;
@@ -328,8 +350,8 @@ DECLARE_EVENT_CLASS(dwc3_log_ep,
__entry->trb_enqueue = dep->trb_enqueue;
__entry->trb_dequeue = dep->trb_dequeue;
),
- TP_printk("%s: mps %d/%d streams %d burst %d ring %d/%d flags %c:%c%c%c%c:%c",
- __get_str(name), __entry->maxpacket,
+ TP_printk("%pa: %s: mps %d/%d streams %d burst %d ring %d/%d flags %c:%c%c%c%c:%c",
+ &__entry->base_address, __get_str(name), __entry->maxpacket,
__entry->maxpacket_limit, __entry->max_streams,
__entry->maxburst, __entry->trb_enqueue,
__entry->trb_dequeue,
diff --git a/drivers/usb/dwc3/ulpi.c b/drivers/usb/dwc3/ulpi.c
index f23f4c9a557e..57daad15f502 100644
--- a/drivers/usb/dwc3/ulpi.c
+++ b/drivers/usb/dwc3/ulpi.c
@@ -33,13 +33,13 @@ static int dwc3_ulpi_busyloop(struct dwc3 *dwc, u8 addr, bool read)
if (read)
ns += DWC3_ULPI_BASE_DELAY;
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0));
if (reg & DWC3_GUSB2PHYCFG_SUSPHY)
usleep_range(1000, 1200);
while (count--) {
ndelay(ns);
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYACC(0));
if (reg & DWC3_GUSB2PHYACC_DONE)
return 0;
cpu_relax();
@@ -55,13 +55,13 @@ static int dwc3_ulpi_read(struct device *dev, u8 addr)
int ret;
reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr);
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYACC(0), reg);
ret = dwc3_ulpi_busyloop(dwc, addr, true);
if (ret)
return ret;
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0));
+ reg = dwc3_readl(dwc, DWC3_GUSB2PHYACC(0));
return DWC3_GUSB2PHYACC_DATA(reg);
}
@@ -73,7 +73,7 @@ static int dwc3_ulpi_write(struct device *dev, u8 addr, u8 val)
reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr);
reg |= DWC3_GUSB2PHYACC_WRITE | val;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg);
+ dwc3_writel(dwc, DWC3_GUSB2PHYACC(0), reg);
return dwc3_ulpi_busyloop(dwc, addr, false);
}