Message ID | 1529683598-25783-5-git-send-email-yamada.masahiro@socionext.com |
---|---|
State | New |
Headers | show |
Series | None | expand |
On Sat, 23 Jun 2018 01:06:37 +0900 Masahiro Yamada <yamada.masahiro@socionext.com> wrote: > 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: Miquel Raynal <miquel.raynal@bootlin.com> > Reviewed-by: Richard Weinberger <richard@nod.at> > Tested-by: Richard Weinberger <richard@nod.at> > --- > > Changes in v4: None > Changes in v3: > - Change the patch order so that the bug-fix one comes the first > > Changes in v2: > - Split patches into sensible chunks > > drivers/mtd/nand/raw/denali_dt.c | 53 ++++++++++++++++++++++++++++++++++------ > 1 file changed, 45 insertions(+), 8 deletions(-) > > diff --git a/drivers/mtd/nand/raw/denali_dt.c b/drivers/mtd/nand/raw/denali_dt.c > index 6b4bd16..afaae37 100644 > --- a/drivers/mtd/nand/raw/denali_dt.c > +++ b/drivers/mtd/nand/raw/denali_dt.c > @@ -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 */ Probably better to use a kernel-doc header to document those fields. Anyway, Reviewed-by: Boris Brezillon <boris.brezillon@bootlin.com> > }; > > 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;
diff --git a/drivers/mtd/nand/raw/denali_dt.c b/drivers/mtd/nand/raw/denali_dt.c index 6b4bd16..afaae37 100644 --- a/drivers/mtd/nand/raw/denali_dt.c +++ b/drivers/mtd/nand/raw/denali_dt.c @@ -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;