spi: qcom-geni: Fix missing error check on pm_runtime_get_sync()

spi_geni_init() calls pm_runtime_get_sync() to power up the device
before accessing hardware registers, but never checks the return value.
If the runtime resume fails, the function silently proceeds to read and
write hardware registers on a device that may not be powered up, leading
to register access faults.

Fix this by replacing pm_runtime_get_sync() with the
PM_RUNTIME_ACQUIRE_IF_ENABLED() macro and checking the result via
PM_RUNTIME_ACQUIRE_ERR(), propagating any error back to the caller
immediately before any hardware access occurs.

Since the macro handles its own cleanup on failure, the out_pm label and
the corresponding pm_runtime_put() call are no longer needed. Replace
all goto out_pm paths with direct return ret statements and remove the
label entirely.

Fixes: 561de45f72 ("spi: spi-geni-qcom: Add SPI driver support for GENI based QUP")
Reviewed-by: Rafael J. Wysocki (Intel) <rafael@kernel.org>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
Link: https://patch.msgid.link/20260710-fix_sticky_-einval_after_pm_runtime_api_failure-v4-2-be81d6c15043@oss.qualcomm.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Praveen Talari 2026-07-10 15:42:44 +05:30 committed by Mark Brown
parent 4f98f533f6
commit d8e9ea989a
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0

View File

@ -622,25 +622,30 @@ static int spi_geni_init(struct spi_geni_master *mas)
u32 spi_tx_cfg, fifo_disable;
int ret = -ENXIO;
pm_runtime_get_sync(mas->dev);
PM_RUNTIME_ACQUIRE_IF_ENABLED(mas->dev, pm);
ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
if (ret < 0) {
dev_err(mas->dev, "Failed to resume and get %d\n", ret);
return ret;
}
proto = geni_se_read_proto(se);
if (spi->target) {
if (proto != GENI_SE_SPI_SLAVE) {
dev_err(mas->dev, "Invalid proto %d\n", proto);
goto out_pm;
return ret;
}
spi_slv_setup(mas);
} else if (proto == GENI_SE_INVALID_PROTO) {
ret = geni_load_se_firmware(se, GENI_SE_SPI);
if (ret) {
dev_err(mas->dev, "spi master firmware load failed ret: %d\n", ret);
goto out_pm;
return ret;
}
} else if (proto != GENI_SE_SPI) {
dev_err(mas->dev, "Invalid proto %d\n", proto);
goto out_pm;
return ret;
}
mas->tx_fifo_depth = geni_se_get_tx_fifo_depth(se);
@ -673,7 +678,7 @@ static int spi_geni_init(struct spi_geni_master *mas)
dev_dbg(mas->dev, "Using GPI DMA mode for SPI\n");
break;
} else if (ret == -EPROBE_DEFER) {
goto out_pm;
return ret;
}
/*
* in case of failure to get gpi dma channel, we can still do the
@ -702,8 +707,6 @@ static int spi_geni_init(struct spi_geni_master *mas)
writel(spi_tx_cfg, se->base + SE_SPI_TRANS_CFG);
}
out_pm:
pm_runtime_put(mas->dev);
return ret;
}