Commit 347052e3 authored by Martin Blumenstingl's avatar Martin Blumenstingl Committed by Greg Kroah-Hartman

usb: dwc3: meson-g12a: fix USB2 PHY initialization on G12A and A1 SoCs

dwc3_meson_g12a_usb2_init_phy() crashes with NULL pointer on an SM1
board (which uses the same USB setup as G12A) dereference as reported
by the Kernel CI bot. This is because of the following call flow:
  dwc3_meson_g12a_probe
    priv->drvdata->setup_regmaps
      dwc3_meson_g12a_setup_regmaps
        priv->usb2_ports is still 0 so priv->u2p_regmap[i] will be NULL
    dwc3_meson_g12a_get_phys
      initializes priv->usb2_ports
    priv->drvdata->usb_init
      dwc3_meson_g12a_usb_init
        dwc3_meson_g12a_usb_init_glue
          dwc3_meson_g12a_usb2_init
            priv->drvdata->usb2_init_phy
              dwc3_meson_g12a_usb2_init_phy
                dereferences priv->u2p_regmap[i]

Call priv->drvdata->setup_regmaps only after dwc3_meson_g12a_get_phys so
priv->usb2_ports is initialized and the regmaps will be set up
correctly. This fixes the NULL dereference later on.

Fixes: 013af227 ("usb: dwc3: meson-g12a: handle the phy and glue registers separately")
Reported-by: default avatar"kernelci.org bot" <bot@kernelci.org>
Acked-by: default avatarFelipe Balbi <balbi@kernel.org>
Acked-by: default avatarNeil Armstrong <narmstron@baylibre.com>
Signed-off-by: default avatarMartin Blumenstingl <martin.blumenstingl@googlemail.com>
Link: https://lore.kernel.org/r/20200526202943.715220-3-martin.blumenstingl@googlemail.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent be8c1001
...@@ -708,11 +708,7 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev) ...@@ -708,11 +708,7 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)
return PTR_ERR(base); return PTR_ERR(base);
priv->drvdata = of_device_get_match_data(&pdev->dev); priv->drvdata = of_device_get_match_data(&pdev->dev);
priv->dev = dev; priv->dev = dev;
ret = priv->drvdata->setup_regmaps(priv, base);
if (ret)
return ret;
priv->vbus = devm_regulator_get_optional(dev, "vbus"); priv->vbus = devm_regulator_get_optional(dev, "vbus");
if (IS_ERR(priv->vbus)) { if (IS_ERR(priv->vbus)) {
...@@ -749,6 +745,10 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev) ...@@ -749,6 +745,10 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)
if (ret) if (ret)
goto err_disable_clks; goto err_disable_clks;
ret = priv->drvdata->setup_regmaps(priv, base);
if (ret)
return ret;
if (priv->vbus) { if (priv->vbus) {
ret = regulator_enable(priv->vbus); ret = regulator_enable(priv->vbus);
if (ret) if (ret)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment