usb: dwc3: use a helper function for operation mode setting
There are two where need to set operational mode: - during initialization while we decide to run in host,device or DRD mode - at runtime via the debugfs interface. This patch provides a new function which sets the operational mode and moves its initialiation to the mode switch instead in the gadget code itself. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
Родитель
c2da2ff006
Коммит
3140e8cbfe
|
@ -103,7 +103,15 @@ void dwc3_put_device_id(int id)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(dwc3_put_device_id);
|
EXPORT_SYMBOL_GPL(dwc3_put_device_id);
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
|
||||||
|
{
|
||||||
|
u32 reg;
|
||||||
|
|
||||||
|
reg = dwc3_readl(dwc->regs, DWC3_GCTL);
|
||||||
|
reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
|
||||||
|
reg |= DWC3_GCTL_PRTCAPDIR(mode);
|
||||||
|
dwc3_writel(dwc->regs, DWC3_GCTL, reg);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dwc3_core_soft_reset - Issues core soft reset and PHY reset
|
* dwc3_core_soft_reset - Issues core soft reset and PHY reset
|
||||||
|
@ -452,6 +460,7 @@ static int __devinit dwc3_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case DWC3_MODE_DEVICE:
|
case DWC3_MODE_DEVICE:
|
||||||
|
dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE);
|
||||||
ret = dwc3_gadget_init(dwc);
|
ret = dwc3_gadget_init(dwc);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "failed to initialize gadget\n");
|
dev_err(&pdev->dev, "failed to initialize gadget\n");
|
||||||
|
@ -459,6 +468,7 @@ static int __devinit dwc3_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DWC3_MODE_HOST:
|
case DWC3_MODE_HOST:
|
||||||
|
dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST);
|
||||||
ret = dwc3_host_init(dwc);
|
ret = dwc3_host_init(dwc);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "failed to initialize host\n");
|
dev_err(&pdev->dev, "failed to initialize host\n");
|
||||||
|
@ -466,6 +476,7 @@ static int __devinit dwc3_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DWC3_MODE_DRD:
|
case DWC3_MODE_DRD:
|
||||||
|
dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG);
|
||||||
ret = dwc3_host_init(dwc);
|
ret = dwc3_host_init(dwc);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "failed to initialize host\n");
|
dev_err(&pdev->dev, "failed to initialize host\n");
|
||||||
|
|
|
@ -786,6 +786,8 @@ union dwc3_event {
|
||||||
#define DWC3_HAS_OTG BIT(3)
|
#define DWC3_HAS_OTG BIT(3)
|
||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
|
void dwc3_set_mode(struct dwc3 *dwc, u32 mode);
|
||||||
|
|
||||||
int dwc3_host_init(struct dwc3 *dwc);
|
int dwc3_host_init(struct dwc3 *dwc);
|
||||||
void dwc3_host_exit(struct dwc3 *dwc);
|
void dwc3_host_exit(struct dwc3 *dwc);
|
||||||
|
|
||||||
|
|
|
@ -443,29 +443,26 @@ static ssize_t dwc3_mode_write(struct file *file,
|
||||||
struct seq_file *s = file->private_data;
|
struct seq_file *s = file->private_data;
|
||||||
struct dwc3 *dwc = s->private;
|
struct dwc3 *dwc = s->private;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 reg;
|
u32 mode = 0;
|
||||||
char buf[32];
|
char buf[32];
|
||||||
|
|
||||||
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
|
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
spin_lock_irqsave(&dwc->lock, flags);
|
|
||||||
reg = dwc3_readl(dwc->regs, DWC3_GCTL);
|
|
||||||
|
|
||||||
reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
|
|
||||||
|
|
||||||
if (!strncmp(buf, "host", 4))
|
if (!strncmp(buf, "host", 4))
|
||||||
reg |= DWC3_GCTL_PRTCAP(DWC3_GCTL_PRTCAP_HOST);
|
mode |= DWC3_GCTL_PRTCAP_HOST;
|
||||||
|
|
||||||
if (!strncmp(buf, "device", 6))
|
if (!strncmp(buf, "device", 6))
|
||||||
reg |= DWC3_GCTL_PRTCAP(DWC3_GCTL_PRTCAP_DEVICE);
|
mode |= DWC3_GCTL_PRTCAP_DEVICE;
|
||||||
|
|
||||||
if (!strncmp(buf, "otg", 3))
|
if (!strncmp(buf, "otg", 3))
|
||||||
reg |= DWC3_GCTL_PRTCAP(DWC3_GCTL_PRTCAP_OTG);
|
mode |= DWC3_GCTL_PRTCAP_OTG;
|
||||||
|
|
||||||
dwc3_writel(dwc->regs, DWC3_GCTL, reg);
|
|
||||||
spin_unlock_irqrestore(&dwc->lock, flags);
|
|
||||||
|
|
||||||
|
if (mode) {
|
||||||
|
spin_lock_irqsave(&dwc->lock, flags);
|
||||||
|
dwc3_set_mode(dwc, mode);
|
||||||
|
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||||
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1158,9 +1158,7 @@ static int dwc3_gadget_start(struct usb_gadget *g,
|
||||||
reg = dwc3_readl(dwc->regs, DWC3_GCTL);
|
reg = dwc3_readl(dwc->regs, DWC3_GCTL);
|
||||||
|
|
||||||
reg &= ~DWC3_GCTL_SCALEDOWN(3);
|
reg &= ~DWC3_GCTL_SCALEDOWN(3);
|
||||||
reg &= ~DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG);
|
|
||||||
reg &= ~DWC3_GCTL_DISSCRAMBLE;
|
reg &= ~DWC3_GCTL_DISSCRAMBLE;
|
||||||
reg |= DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_DEVICE);
|
|
||||||
|
|
||||||
switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams0)) {
|
switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams0)) {
|
||||||
case DWC3_GHWPARAMS1_EN_PWROPT_CLK:
|
case DWC3_GHWPARAMS1_EN_PWROPT_CLK:
|
||||||
|
|
Загрузка…
Ссылка в новой задаче