mtd: rawnand: denali_dt: add more clocks based on IP datasheet
Currently, denali_dt.c requires a single anonymous clock, but the Denali User's Guide requires three clocks for this IP: - clk: controller core clock - clk_x: bus interface clock - ecc_clk: clock at which ECC circuitry is run This commit supports these named clocks to represent the real hardware. For the backward compatibility, the driver still accepts a single clock just as before. The clk_x_rate is taken from the clock driver again if the named clock "clk_x" is available. This will happen only for future DT, hence the existing DT files are not affected. Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com> Reviewed-by: Richard Weinberger <richard@nod.at> Tested-by: Richard Weinberger <richard@nod.at> Reviewed-by: Boris Brezillon <boris.brezillon@bootlin.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
This commit is contained in:
parent
d91e8a3eec
commit
6f1fe97bec
|
@ -27,7 +27,9 @@
|
|||
|
||||
struct denali_dt {
|
||||
struct denali_nand_info denali;
|
||||
struct clk *clk;
|
||||
struct clk *clk; /* core clock */
|
||||
struct clk *clk_x; /* bus interface clock */
|
||||
struct clk *clk_ecc; /* ECC circuit clock */
|
||||
};
|
||||
|
||||
struct denali_dt_data {
|
||||
|
@ -115,28 +117,61 @@ static int denali_dt_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(denali->host))
|
||||
return PTR_ERR(denali->host);
|
||||
|
||||
dt->clk = devm_clk_get(dev, NULL);
|
||||
/*
|
||||
* A single anonymous clock is supported for the backward compatibility.
|
||||
* New platforms should support all the named clocks.
|
||||
*/
|
||||
dt->clk = devm_clk_get(dev, "nand");
|
||||
if (IS_ERR(dt->clk))
|
||||
dt->clk = devm_clk_get(dev, NULL);
|
||||
if (IS_ERR(dt->clk)) {
|
||||
dev_err(dev, "no clk available\n");
|
||||
return PTR_ERR(dt->clk);
|
||||
}
|
||||
|
||||
dt->clk_x = devm_clk_get(dev, "nand_x");
|
||||
if (IS_ERR(dt->clk_x))
|
||||
dt->clk_x = NULL;
|
||||
|
||||
dt->clk_ecc = devm_clk_get(dev, "ecc");
|
||||
if (IS_ERR(dt->clk_ecc))
|
||||
dt->clk_ecc = NULL;
|
||||
|
||||
ret = clk_prepare_enable(dt->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Hardcode the clock rate for the backward compatibility.
|
||||
* This works for both SOCFPGA and UniPhier.
|
||||
*/
|
||||
denali->clk_x_rate = 200000000;
|
||||
ret = clk_prepare_enable(dt->clk_x);
|
||||
if (ret)
|
||||
goto out_disable_clk;
|
||||
|
||||
ret = clk_prepare_enable(dt->clk_ecc);
|
||||
if (ret)
|
||||
goto out_disable_clk_x;
|
||||
|
||||
if (dt->clk_x) {
|
||||
denali->clk_x_rate = clk_get_rate(dt->clk_x);
|
||||
} else {
|
||||
/*
|
||||
* Hardcode the clock rates for the backward compatibility.
|
||||
* This works for both SOCFPGA and UniPhier.
|
||||
*/
|
||||
dev_notice(dev,
|
||||
"necessary clock is missing. default clock rates are used.\n");
|
||||
denali->clk_x_rate = 200000000;
|
||||
}
|
||||
|
||||
ret = denali_init(denali);
|
||||
if (ret)
|
||||
goto out_disable_clk;
|
||||
goto out_disable_clk_ecc;
|
||||
|
||||
platform_set_drvdata(pdev, dt);
|
||||
return 0;
|
||||
|
||||
out_disable_clk_ecc:
|
||||
clk_disable_unprepare(dt->clk_ecc);
|
||||
out_disable_clk_x:
|
||||
clk_disable_unprepare(dt->clk_x);
|
||||
out_disable_clk:
|
||||
clk_disable_unprepare(dt->clk);
|
||||
|
||||
|
@ -148,6 +183,8 @@ static int denali_dt_remove(struct platform_device *pdev)
|
|||
struct denali_dt *dt = platform_get_drvdata(pdev);
|
||||
|
||||
denali_remove(&dt->denali);
|
||||
clk_disable_unprepare(dt->clk_ecc);
|
||||
clk_disable_unprepare(dt->clk_x);
|
||||
clk_disable_unprepare(dt->clk);
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue