|
@@ -49,6 +49,57 @@
|
|
|
|
|
|
#define DWC3_DEFAULT_AUTOSUSPEND_DELAY 5000 /* ms */
|
|
|
|
|
|
+/**
|
|
|
+ * dwc3_get_dr_mode - Validates and sets dr_mode
|
|
|
+ * @dwc: pointer to our context structure
|
|
|
+ */
|
|
|
+static int dwc3_get_dr_mode(struct dwc3 *dwc)
|
|
|
+{
|
|
|
+ enum usb_dr_mode mode;
|
|
|
+ struct device *dev = dwc->dev;
|
|
|
+ unsigned int hw_mode;
|
|
|
+
|
|
|
+ if (dwc->dr_mode == USB_DR_MODE_UNKNOWN)
|
|
|
+ dwc->dr_mode = USB_DR_MODE_OTG;
|
|
|
+
|
|
|
+ mode = dwc->dr_mode;
|
|
|
+ hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0);
|
|
|
+
|
|
|
+ switch (hw_mode) {
|
|
|
+ case DWC3_GHWPARAMS0_MODE_GADGET:
|
|
|
+ if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) {
|
|
|
+ dev_err(dev,
|
|
|
+ "Controller does not support host mode.\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ mode = USB_DR_MODE_PERIPHERAL;
|
|
|
+ break;
|
|
|
+ case DWC3_GHWPARAMS0_MODE_HOST:
|
|
|
+ if (IS_ENABLED(CONFIG_USB_DWC3_GADGET)) {
|
|
|
+ dev_err(dev,
|
|
|
+ "Controller does not support device mode.\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ mode = USB_DR_MODE_HOST;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ if (IS_ENABLED(CONFIG_USB_DWC3_HOST))
|
|
|
+ mode = USB_DR_MODE_HOST;
|
|
|
+ else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET))
|
|
|
+ mode = USB_DR_MODE_PERIPHERAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (mode != dwc->dr_mode) {
|
|
|
+ dev_warn(dev,
|
|
|
+ "Configuration mismatch. dr_mode forced to %s\n",
|
|
|
+ mode == USB_DR_MODE_HOST ? "host" : "gadget");
|
|
|
+
|
|
|
+ dwc->dr_mode = mode;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
|
|
|
{
|
|
|
u32 reg;
|
|
@@ -1023,17 +1074,9 @@ static int dwc3_probe(struct platform_device *pdev)
|
|
|
goto err2;
|
|
|
}
|
|
|
|
|
|
- if (IS_ENABLED(CONFIG_USB_DWC3_HOST) &&
|
|
|
- (dwc->dr_mode == USB_DR_MODE_OTG ||
|
|
|
- dwc->dr_mode == USB_DR_MODE_UNKNOWN))
|
|
|
- dwc->dr_mode = USB_DR_MODE_HOST;
|
|
|
- else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET) &&
|
|
|
- (dwc->dr_mode == USB_DR_MODE_OTG ||
|
|
|
- dwc->dr_mode == USB_DR_MODE_UNKNOWN))
|
|
|
- dwc->dr_mode = USB_DR_MODE_PERIPHERAL;
|
|
|
-
|
|
|
- if (dwc->dr_mode == USB_DR_MODE_UNKNOWN)
|
|
|
- dwc->dr_mode = USB_DR_MODE_OTG;
|
|
|
+ ret = dwc3_get_dr_mode(dwc);
|
|
|
+ if (ret)
|
|
|
+ goto err3;
|
|
|
|
|
|
ret = dwc3_alloc_scratch_buffers(dwc);
|
|
|
if (ret)
|