phy: tegra: xusb: Fix crash during pad power on/down
authorJon Hunter <jonathanh@nvidia.com>
Mon, 10 Oct 2022 13:51:32 +0000 (14:51 +0100)
committerVinod Koul <vkoul@kernel.org>
Mon, 17 Oct 2022 05:37:37 +0000 (11:07 +0530)
Commit a88520bfc0ec ("usb: gadget: tegra: Reduce pad power") added calls
to tegra_phy_xusb_utmi_pad_power_on/down in the Tegra XUDC driver to
control the pad power. This change is causing a kernel panic when
powering down the pads on entering suspend with the Jetson TX2 platform.
The panic occurs because the 'xudc->curr_utmi_phy' is not configured on
this platform and we do not check to see if the pointer is valid before
attempting to deference the pointer. Fix this by checking to see if the
'phy' pointer passed to tegra_phy_xusb_utmi_pad_power_on/down is valid.

Fixes: a88520bfc0ec ("usb: gadget: tegra: Reduce pad power")
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Link: https://lore.kernel.org/r/20221010135132.30809-1-jonathanh@nvidia.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/phy/tegra/xusb.c

index 95091876c422230af448470035362725be9bf2c2..dce45fbbd699c12c668e17d4cd62d301c96096b2 100644 (file)
@@ -1461,8 +1461,14 @@ EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_port_reset);
 
 void tegra_phy_xusb_utmi_pad_power_on(struct phy *phy)
 {
-       struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
-       struct tegra_xusb_padctl *padctl = lane->pad->padctl;
+       struct tegra_xusb_lane *lane;
+       struct tegra_xusb_padctl *padctl;
+
+       if (!phy)
+               return;
+
+       lane = phy_get_drvdata(phy);
+       padctl = lane->pad->padctl;
 
        if (padctl->soc->ops->utmi_pad_power_on)
                padctl->soc->ops->utmi_pad_power_on(phy);
@@ -1471,8 +1477,14 @@ EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_power_on);
 
 void tegra_phy_xusb_utmi_pad_power_down(struct phy *phy)
 {
-       struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
-       struct tegra_xusb_padctl *padctl = lane->pad->padctl;
+       struct tegra_xusb_lane *lane;
+       struct tegra_xusb_padctl *padctl;
+
+       if (!phy)
+               return;
+
+       lane = phy_get_drvdata(phy);
+       padctl = lane->pad->padctl;
 
        if (padctl->soc->ops->utmi_pad_power_down)
                padctl->soc->ops->utmi_pad_power_down(phy);