summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiklas Cassel <cassel@kernel.org>2026-09-15 10:41:27 +0200
committerNiklas Cassel <cassel@kernel.org>2026-09-15 11:50:37 +0200
commitc74ee9230a8d1d2f6fcbceff55f56f7dd9b9cccd (patch)
treefa1c68a14a3c33634828cb62effe1dc48e419db2
parent96fdeb7e3fd8d937f8351ed90824c9d904e590a1 (diff)
downloadlinux-next-c74ee9230a8d1d2f6fcbceff55f56f7dd9b9cccd.tar.gz
linux-next-c74ee9230a8d1d2f6fcbceff55f56f7dd9b9cccd.zip
ata: ahci_st: Do not ignore errors when getting the reset controls
st_ahci_probe_resets() treats any error from devm_reset_control_get() as "reset control not defined" and continues with a NULL reset control: drv_data->pwr = devm_reset_control_get(dev, "pwr-dwn"); if (IS_ERR(drv_data->pwr)) { dev_info(dev, "power reset control not defined\n"); drv_data->pwr = NULL; } This also swallows -EPROBE_DEFER, which is returned when the reset controller providing the reset has not been probed yet. probe() then continues as if the device tree did not specify any reset, so the resets of the SATA IP are never deasserted, and st_ahci_configure_oob() and ahci_platform_init_host() access the MMIO of an IP which is still held in reset and powered down, which can result in an external abort. The resets are optional in the binding, as they are not part of its required properties, so use devm_reset_control_get_optional(), which returns NULL if the reset is not specified in the device tree, and propagate all other errors. Note that an absent reset is now indicated by a NULL reset control instead of an error, so the "reset control not defined" messages are dropped. Fixes: 76884cb2f7da ("ahci: st: Add support for ST's SATA IP") Cc: stable@vger.kernel.org Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Link: https://lore.kernel.org/r/20260915084127.692494-9-cassel@kernel.org Signed-off-by: Niklas Cassel <cassel@kernel.org>
-rw-r--r--drivers/ata/ahci_st.c31
1 files changed, 14 insertions, 17 deletions
diff --git a/drivers/ata/ahci_st.c b/drivers/ata/ahci_st.c
index 4336c8a6e208..819269a022ef 100644
--- a/drivers/ata/ahci_st.c
+++ b/drivers/ata/ahci_st.c
@@ -104,23 +104,20 @@ static int st_ahci_probe_resets(struct ahci_host_priv *hpriv,
{
struct st_ahci_drv_data *drv_data = hpriv->plat_data;
- drv_data->pwr = devm_reset_control_get(dev, "pwr-dwn");
- if (IS_ERR(drv_data->pwr)) {
- dev_info(dev, "power reset control not defined\n");
- drv_data->pwr = NULL;
- }
-
- drv_data->sw_rst = devm_reset_control_get(dev, "sw-rst");
- if (IS_ERR(drv_data->sw_rst)) {
- dev_info(dev, "soft reset control not defined\n");
- drv_data->sw_rst = NULL;
- }
-
- drv_data->pwr_rst = devm_reset_control_get(dev, "pwr-rst");
- if (IS_ERR(drv_data->pwr_rst)) {
- dev_dbg(dev, "power soft reset control not defined\n");
- drv_data->pwr_rst = NULL;
- }
+ drv_data->pwr = devm_reset_control_get_optional(dev, "pwr-dwn");
+ if (IS_ERR(drv_data->pwr))
+ return dev_err_probe(dev, PTR_ERR(drv_data->pwr),
+ "failed to get pwr-dwn reset\n");
+
+ drv_data->sw_rst = devm_reset_control_get_optional(dev, "sw-rst");
+ if (IS_ERR(drv_data->sw_rst))
+ return dev_err_probe(dev, PTR_ERR(drv_data->sw_rst),
+ "failed to get sw-rst reset\n");
+
+ drv_data->pwr_rst = devm_reset_control_get_optional(dev, "pwr-rst");
+ if (IS_ERR(drv_data->pwr_rst))
+ return dev_err_probe(dev, PTR_ERR(drv_data->pwr_rst),
+ "failed to get pwr-rst reset\n");
return st_ahci_deassert_resets(hpriv, dev);
}