usb: fotg210: Check role register in core
authorLinus Walleij <linus.walleij@linaro.org>
Wed, 18 Jan 2023 07:09:19 +0000 (08:09 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 19 Jan 2023 13:10:44 +0000 (14:10 +0100)
Read the role register and check that we are in host/peripheral
mode and issue warnings if we're not in the right role when
probing respective driver.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20230103-gemini-fotg210-usb-v2-5-100388af9810@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/fotg210/fotg210-core.c

index f90b2ae..b69167b 100644 (file)
 
 #include "fotg210.h"
 
+/* Role Register 0x80 */
+#define FOTG210_RR                     0x80
+#define FOTG210_RR_ID                  BIT(21) /* 1 = B-device, 0 = A-device */
+#define FOTG210_RR_CROLE               BIT(20) /* 1 = device, 0 = host */
+
 /*
  * Gemini-specific initialization function, only executed on the
  * Gemini SoC using the global misc control register.
@@ -95,6 +100,7 @@ static int fotg210_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        enum usb_dr_mode mode;
        struct fotg210 *fotg;
+       u32 val;
        int ret;
 
        fotg = devm_kzalloc(dev, sizeof(*fotg), GFP_KERNEL);
@@ -122,10 +128,16 @@ static int fotg210_probe(struct platform_device *pdev)
                        return ret;
        }
 
-       if (mode == USB_DR_MODE_PERIPHERAL)
+       val = readl(fotg->base + FOTG210_RR);
+       if (mode == USB_DR_MODE_PERIPHERAL) {
+               if (!(val & FOTG210_RR_CROLE))
+                       dev_err(dev, "block not in device role\n");
                ret = fotg210_udc_probe(pdev, fotg);
-       else
+       } else {
+               if (val & FOTG210_RR_CROLE)
+                       dev_err(dev, "block not in host role\n");
                ret = fotg210_hcd_probe(pdev, fotg);
+       }
 
        return ret;
 }