mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
hwrng: starfive - propagate clock and reset errors
The StarFive TRNG probe and resume paths ignore failures from their clock
and reset operations. That lets the driver register or resume while its
hardware access prerequisites were not established.
Check each transition, unwind only the previously enabled clock on failure,
and propagate the error to the probe or PM core.
Fixes: c388f458bc ("hwrng: starfive - Add TRNG driver for StarFive SoC")
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
553c623a12
commit
ace145efdd
|
|
@ -320,9 +320,17 @@ static int starfive_trng_probe(struct platform_device *pdev)
|
|||
return dev_err_probe(&pdev->dev, PTR_ERR(trng->rst),
|
||||
"Error getting hardware reset line\n");
|
||||
|
||||
clk_prepare_enable(trng->hclk);
|
||||
clk_prepare_enable(trng->ahb);
|
||||
reset_control_deassert(trng->rst);
|
||||
ret = clk_prepare_enable(trng->hclk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_prepare_enable(trng->ahb);
|
||||
if (ret)
|
||||
goto disable_hclk;
|
||||
|
||||
ret = reset_control_deassert(trng->rst);
|
||||
if (ret)
|
||||
goto disable_ahb;
|
||||
|
||||
trng->rng.name = dev_driver_string(&pdev->dev);
|
||||
trng->rng.init = starfive_trng_init;
|
||||
|
|
@ -342,13 +350,18 @@ static int starfive_trng_probe(struct platform_device *pdev)
|
|||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
reset_control_assert(trng->rst);
|
||||
clk_disable_unprepare(trng->ahb);
|
||||
clk_disable_unprepare(trng->hclk);
|
||||
|
||||
return dev_err_probe(&pdev->dev, ret, "Failed to register hwrng\n");
|
||||
ret = dev_err_probe(&pdev->dev, ret, "Failed to register hwrng\n");
|
||||
goto disable_ahb;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
disable_ahb:
|
||||
clk_disable_unprepare(trng->ahb);
|
||||
disable_hclk:
|
||||
clk_disable_unprepare(trng->hclk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __maybe_unused starfive_trng_suspend(struct device *dev)
|
||||
|
|
@ -364,11 +377,17 @@ static int __maybe_unused starfive_trng_suspend(struct device *dev)
|
|||
static int __maybe_unused starfive_trng_resume(struct device *dev)
|
||||
{
|
||||
struct starfive_trng *trng = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
clk_prepare_enable(trng->hclk);
|
||||
clk_prepare_enable(trng->ahb);
|
||||
ret = clk_prepare_enable(trng->hclk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
ret = clk_prepare_enable(trng->ahb);
|
||||
if (ret)
|
||||
clk_disable_unprepare(trng->hclk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops starfive_trng_pm_ops = {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user