summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRadhey Shyam Pandey <radhey.shyam.pandey@amd.com>2026-07-17 23:55:26 +0530
committerDamien Le Moal <dlemoal@kernel.org>2026-07-18 10:37:02 +0900
commit4d99a91574c420decab56cc880fad0dc15b8a7a3 (patch)
tree0fd8f540b659b49f789393c514e7bbb4355b4f64
parentef19a9cf037957fe3a35df8355c76ff0a63a0436 (diff)
ata: ahci_ceva: fix error paths in ceva_ahci_platform_enable_resources()
On phy_init() failure the error path fallsthrough to disable_rsts, which deasserts the controller reset and then enters disable_phys calling phy_power_off() on PHYs that were never powered on. That corrupts the PHY power_count and triggers an extra runtime PM put. Use a separate exit_phys path that unwinds with phy_exit() only and falls through to disable_clks while the controller remains in reset. Reserve phy_power_off() for the phy_power_on() failure path only, and skip masked-out ports in both unwind loops. On phy_power_on() failure re-assert the controller reset before disabling clocks and regulators, matching the teardown order used by ahci_platform_enable_resources() and ahci_platform_disable_resources(). Fixes: 26c8404e162b ("ata: ahci_ceva: fix error handling for Xilinx GT PHY support") Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
-rw-r--r--drivers/ata/ahci_ceva.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/ata/ahci_ceva.c b/drivers/ata/ahci_ceva.c
index 2d6a08c23d6a..2961e53288f4 100644
--- a/drivers/ata/ahci_ceva.c
+++ b/drivers/ata/ahci_ceva.c
@@ -211,7 +211,7 @@ static int ceva_ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
rc = phy_init(hpriv->phys[i]);
if (rc)
- goto disable_rsts;
+ goto exit_phys;
}
/* De-assert the controller reset */
@@ -230,14 +230,24 @@ static int ceva_ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
return 0;
-disable_rsts:
- ahci_platform_deassert_rsts(hpriv);
-
disable_phys:
while (--i >= 0) {
+ if (ahci_ignore_port(hpriv, i))
+ continue;
+
phy_power_off(hpriv->phys[i]);
phy_exit(hpriv->phys[i]);
}
+ ahci_platform_assert_rsts(hpriv);
+ goto disable_clks;
+
+exit_phys:
+ while (--i >= 0) {
+ if (ahci_ignore_port(hpriv, i))
+ continue;
+
+ phy_exit(hpriv->phys[i]);
+ }
disable_clks:
ahci_platform_disable_clks(hpriv);