Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6f1fe97b authored by Masahiro Yamada's avatar Masahiro Yamada Committed by Miquel Raynal
Browse files

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: default avatarMasahiro Yamada <yamada.masahiro@socionext.com>
Reviewed-by: default avatarRichard Weinberger <richard@nod.at>
Tested-by: default avatarRichard Weinberger <richard@nod.at>
Reviewed-by: default avatarBoris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
parent d91e8a3e
Loading
Loading
Loading
Loading
+45 −8
Original line number Diff line number Diff line
@@ -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);

	/*
	 * 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;

	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 rate for the backward compatibility.
		 * 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;