linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] Non-urgent fixes and improvments for omap3-rom-rng
@ 2019-09-13 22:09 Tony Lindgren
  2019-09-13 22:09 ` [PATCH 1/6] ARM: OMAP2+: Check omap3-rom-rng for GP device instead of HS device Tony Lindgren
                   ` (6 more replies)
  0 siblings, 7 replies; 11+ messages in thread
From: Tony Lindgren @ 2019-09-13 22:09 UTC (permalink / raw)
  To: Matt Mackall, Herbert Xu, linux-kernel, linux-omap
  Cc: linux-crypto, Aaro Koskinen, Adam Ford, Pali Rohár,
	Rob Herring, Tero Kristo, devicetree

Hi all,

Here are fixes and improvments for omap3-rom-rng that's been broken for
a while.

The first four patches get it working, and then the last two patches add
support for runtime PM.

Regards,

Tony


Tony Lindgren (6):
  ARM: OMAP2+: Check omap3-rom-rng for GP device instead of HS device
  hwrng: omap3-rom - Fix missing clock by probing with device tree
  hwrng: omap3-rom - Call clk_prepare() on init and exit only
  hwrng: omap3-rom - Initialize default quality to get data
  hwrng: omap3-rom - Update to use standard driver data
  hwrng: omap3-rom - Use runtime PM instead of custom functions

 .../devicetree/bindings/rng/omap3_rom_rng.txt |  27 +++
 arch/arm/boot/dts/omap3-n900.dts              |   6 +
 arch/arm/mach-omap2/pdata-quirks.c            |  14 +-
 drivers/char/hw_random/omap3-rom-rng.c        | 186 ++++++++++++------
 4 files changed, 162 insertions(+), 71 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/rng/omap3_rom_rng.txt

-- 
2.23.0

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/6] ARM: OMAP2+: Check omap3-rom-rng for GP device instead of HS device
  2019-09-13 22:09 [PATCH 0/6] Non-urgent fixes and improvments for omap3-rom-rng Tony Lindgren
@ 2019-09-13 22:09 ` Tony Lindgren
  2019-09-13 22:09 ` [PATCH 2/6] hwrng: omap3-rom - Fix missing clock by probing with device tree Tony Lindgren
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Tony Lindgren @ 2019-09-13 22:09 UTC (permalink / raw)
  To: Matt Mackall, Herbert Xu, linux-kernel, linux-omap
  Cc: linux-crypto, Aaro Koskinen, Adam Ford, Pali Rohár,
	Tero Kristo, Rob Herring, devicetree

In general we should check for GP device instead of HS device unless
the other options such as EMU are also checked. Otherwise omap3-rom-rng
won't probe on few of the old n900 macro boards still in service in
automated build and boot test systems.

Cc: Aaro Koskinen <aaro.koskinen@iki.fi>
Cc: Adam Ford <aford173@gmail.com>
Cc: Pali Rohár <pali.rohar@gmail.com>
Cc: Tero Kristo <t-kristo@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap2/pdata-quirks.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -276,7 +276,7 @@ static void __init nokia_n900_legacy_init(void)
 	mmc_pdata[0].name = "external";
 	mmc_pdata[1].name = "internal";
 
-	if (omap_type() == OMAP2_DEVICE_TYPE_SEC) {
+	if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
 		if (IS_ENABLED(CONFIG_ARM_ERRATA_430973)) {
 			pr_info("RX-51: Enabling ARM errata 430973 workaround\n");
 			/* set IBE to 1 */
-- 
2.23.0

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 2/6] hwrng: omap3-rom - Fix missing clock by probing with device tree
  2019-09-13 22:09 [PATCH 0/6] Non-urgent fixes and improvments for omap3-rom-rng Tony Lindgren
  2019-09-13 22:09 ` [PATCH 1/6] ARM: OMAP2+: Check omap3-rom-rng for GP device instead of HS device Tony Lindgren
@ 2019-09-13 22:09 ` Tony Lindgren
  2019-09-13 22:09 ` [PATCH 3/6] hwrng: omap3-rom - Call clk_prepare() on init and exit only Tony Lindgren
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Tony Lindgren @ 2019-09-13 22:09 UTC (permalink / raw)
  To: Matt Mackall, Herbert Xu, linux-kernel, linux-omap
  Cc: linux-crypto, devicetree, Aaro Koskinen, Adam Ford,
	Pali Rohár, Rob Herring, Tero Kristo

Commit 0ed266d7ae5e ("clk: ti: omap3: cleanup unnecessary clock aliases")
removed old omap3 clock framework aliases but caused omap3-rom-rng to
stop working with clock not found error.

Based on discussions on the mailing list it was requested by Tero Kristo
that it would be best to fix this issue by probing omap3-rom-rng using
device tree to provide a proper clk property. The other option would be
to add back the missing clock alias, but that does not help moving things
forward with removing old legacy platform_data.

Let's also add a proper device tree binding and keep it together with
the fix.

Cc: devicetree@vger.kernel.org
Cc: Aaro Koskinen <aaro.koskinen@iki.fi>
Cc: Adam Ford <aford173@gmail.com>
Cc: Pali Rohár <pali.rohar@gmail.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Tero Kristo <t-kristo@ti.com>
Fixes: 0ed266d7ae5e ("clk: ti: omap3: cleanup unnecessary clock aliases")
Reported-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 .../devicetree/bindings/rng/omap3_rom_rng.txt | 27 +++++++++++++++++++
 arch/arm/boot/dts/omap3-n900.dts              |  6 +++++
 arch/arm/mach-omap2/pdata-quirks.c            | 12 +--------
 drivers/char/hw_random/omap3-rom-rng.c        | 17 ++++++++++--
 4 files changed, 49 insertions(+), 13 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/rng/omap3_rom_rng.txt

diff --git a/Documentation/devicetree/bindings/rng/omap3_rom_rng.txt b/Documentation/devicetree/bindings/rng/omap3_rom_rng.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/devicetree/bindings/rng/omap3_rom_rng.txt
@@ -0,0 +1,27 @@
+OMAP ROM RNG driver binding
+
+Secure SoCs may provide RNG via secure ROM calls like Nokia N900 does. The
+implementation can depend on the SoC secure ROM used.
+
+- compatible:
+	Usage: required
+	Value type: <string>
+	Definition: must be "nokia,n900-rom-rng"
+
+- clocks:
+	Usage: required
+	Value type: <prop-encoded-array>
+	Definition: reference to the the RNG interface clock
+
+- clock-names:
+	Usage: required
+	Value type: <stringlist>
+	Definition: must be "ick"
+
+Example:
+
+	rom_rng: rng {
+		compatible = "nokia,n900-rom-rng";
+		clocks = <&rng_ick>;
+		clock-names = "ick";
+	};
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -155,6 +155,12 @@
 		pwms = <&pwm9 0 26316 0>; /* 38000 Hz */
 	};
 
+	rom_rng: rng {
+		compatible = "nokia,n900-rom-rng";
+		clocks = <&rng_ick>;
+		clock-names = "ick";
+	};
+
 	/* controlled (enabled/disabled) directly by bcm2048 and wl1251 */
 	vctcxo: vctcxo {
 		compatible = "fixed-clock";
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -262,14 +262,6 @@ static void __init am3517_evm_legacy_init(void)
 	am35xx_emac_reset();
 }
 
-static struct platform_device omap3_rom_rng_device = {
-	.name		= "omap3-rom-rng",
-	.id		= -1,
-	.dev	= {
-		.platform_data	= rx51_secure_rng_call,
-	},
-};
-
 static void __init nokia_n900_legacy_init(void)
 {
 	hsmmc2_internal_input_clk();
@@ -285,9 +277,6 @@ static void __init nokia_n900_legacy_init(void)
 			pr_warn("RX-51: Not enabling ARM errata 430973 workaround\n");
 			pr_warn("Thumb binaries may crash randomly without this workaround\n");
 		}
-
-		pr_info("RX-51: Registering OMAP3 HWRNG device\n");
-		platform_device_register(&omap3_rom_rng_device);
 	}
 }
 
@@ -627,6 +616,7 @@ static struct of_dev_auxdata omap_auxdata_lookup[] = {
 	OF_DEV_AUXDATA("ti,davinci_mdio", 0x5c030000, "davinci_mdio.0", NULL),
 	OF_DEV_AUXDATA("ti,am3517-emac", 0x5c000000, "davinci_emac.0",
 		       &am35xx_emac_pdata),
+	OF_DEV_AUXDATA("nokia,n900-rom-rng", 0, NULL, rx51_secure_rng_call),
 	/* McBSP modules with sidetone core */
 #if IS_ENABLED(CONFIG_SND_SOC_OMAP_MCBSP)
 	OF_DEV_AUXDATA("ti,omap3-mcbsp", 0x49022000, "49022000.mcbsp", &mcbsp_pdata),
diff --git a/drivers/char/hw_random/omap3-rom-rng.c b/drivers/char/hw_random/omap3-rom-rng.c
--- a/drivers/char/hw_random/omap3-rom-rng.c
+++ b/drivers/char/hw_random/omap3-rom-rng.c
@@ -20,6 +20,8 @@
 #include <linux/workqueue.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 
 #define RNG_RESET			0x01
@@ -86,14 +88,18 @@ static int omap3_rom_rng_read(struct hwrng *rng, void *data, size_t max, bool w)
 
 static struct hwrng omap3_rom_rng_ops = {
 	.name		= "omap3-rom",
-	.read		= omap3_rom_rng_read,
 };
 
 static int omap3_rom_rng_probe(struct platform_device *pdev)
 {
 	int ret = 0;
 
-	pr_info("initializing\n");
+	omap3_rom_rng_ops.read = of_device_get_match_data(&pdev->dev);
+	if (!omap3_rom_rng_ops.read) {
+		dev_err(&pdev->dev, "missing rom code handler\n");
+
+		return -ENODEV;
+	}
 
 	omap3_rom_rng_call = pdev->dev.platform_data;
 	if (!omap3_rom_rng_call) {
@@ -125,9 +131,16 @@ static int omap3_rom_rng_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct of_device_id omap_rom_rng_match[] = {
+	{ .compatible = "nokia,n900-rom-rng", .data = omap3_rom_rng_read, },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, omap_rom_rng_match);
+
 static struct platform_driver omap3_rom_rng_driver = {
 	.driver = {
 		.name		= "omap3-rom-rng",
+		.of_match_table = omap_rom_rng_match,
 	},
 	.probe		= omap3_rom_rng_probe,
 	.remove		= omap3_rom_rng_remove,
-- 
2.23.0

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/6] hwrng: omap3-rom - Call clk_prepare() on init and exit only
  2019-09-13 22:09 [PATCH 0/6] Non-urgent fixes and improvments for omap3-rom-rng Tony Lindgren
  2019-09-13 22:09 ` [PATCH 1/6] ARM: OMAP2+: Check omap3-rom-rng for GP device instead of HS device Tony Lindgren
  2019-09-13 22:09 ` [PATCH 2/6] hwrng: omap3-rom - Fix missing clock by probing with device tree Tony Lindgren
@ 2019-09-13 22:09 ` Tony Lindgren
  2019-09-14 12:54   ` Sebastian Reichel
  2019-09-13 22:09 ` [PATCH 4/6] hwrng: omap3-rom - Initialize default quality to get data Tony Lindgren
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 11+ messages in thread
From: Tony Lindgren @ 2019-09-13 22:09 UTC (permalink / raw)
  To: Matt Mackall, Herbert Xu, linux-kernel, linux-omap
  Cc: linux-crypto, Aaro Koskinen, Adam Ford, Pali Rohár,
	Tero Kristo, Rob Herring, devicetree

When unloading omap3-rom-rng, we'll get the following:

WARNING: CPU: 0 PID: 100 at drivers/clk/clk.c:948 clk_core_disable

This is because the clock is already disabled by omap3_rom_rng_idle().

Also, we should not call prepare and unprepare except during init, and
only call enable and disable during use.

Cc: Aaro Koskinen <aaro.koskinen@iki.fi>
Cc: Adam Ford <aford173@gmail.com>
Cc: Pali Rohár <pali.rohar@gmail.com>
Cc: Tero Kristo <t-kristo@ti.com>
Fixes: 1c6b7c2108bd ("hwrng: OMAP3 ROM Random Number Generator support")
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/char/hw_random/omap3-rom-rng.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/char/hw_random/omap3-rom-rng.c b/drivers/char/hw_random/omap3-rom-rng.c
--- a/drivers/char/hw_random/omap3-rom-rng.c
+++ b/drivers/char/hw_random/omap3-rom-rng.c
@@ -44,7 +44,7 @@ static void omap3_rom_rng_idle(struct work_struct *work)
 		pr_err("reset failed: %d\n", r);
 		return;
 	}
-	clk_disable_unprepare(rng_clk);
+	clk_disable(rng_clk);
 	rng_idle = 1;
 }
 
@@ -55,13 +55,13 @@ static int omap3_rom_rng_get_random(void *buf, unsigned int count)
 
 	cancel_delayed_work_sync(&idle_work);
 	if (rng_idle) {
-		r = clk_prepare_enable(rng_clk);
+		r = clk_enable(rng_clk);
 		if (r)
 			return r;
 
 		r = omap3_rom_rng_call(0, 0, RNG_GEN_PRNG_HW_INIT);
 		if (r != 0) {
-			clk_disable_unprepare(rng_clk);
+			clk_disable(rng_clk);
 			pr_err("HW init failed: %d\n", r);
 			return -EIO;
 		}
@@ -114,20 +114,32 @@ static int omap3_rom_rng_probe(struct platform_device *pdev)
 		return PTR_ERR(rng_clk);
 	}
 
+	ret = clk_prepare(rng_clk);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "clk_prepare failed: %i\n", ret);
+		return ret;
+	}
+
 	/* Leave the RNG in reset state. */
-	ret = clk_prepare_enable(rng_clk);
+	ret = clk_enable(rng_clk);
 	if (ret)
-		return ret;
+		goto err_unprepare;
 	omap3_rom_rng_idle(0);
 
 	return hwrng_register(&omap3_rom_rng_ops);
+
+err_unprepare:
+	clk_unprepare(rng_clk);
+
+	return ret;
 }
 
 static int omap3_rom_rng_remove(struct platform_device *pdev)
 {
 	cancel_delayed_work_sync(&idle_work);
 	hwrng_unregister(&omap3_rom_rng_ops);
-	clk_disable_unprepare(rng_clk);
+	clk_unprepare(rng_clk);
+
 	return 0;
 }
 
-- 
2.23.0

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 4/6] hwrng: omap3-rom - Initialize default quality to get data
  2019-09-13 22:09 [PATCH 0/6] Non-urgent fixes and improvments for omap3-rom-rng Tony Lindgren
                   ` (2 preceding siblings ...)
  2019-09-13 22:09 ` [PATCH 3/6] hwrng: omap3-rom - Call clk_prepare() on init and exit only Tony Lindgren
@ 2019-09-13 22:09 ` Tony Lindgren
  2019-09-13 22:09 ` [PATCH 5/6] hwrng: omap3-rom - Update to use standard driver data Tony Lindgren
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Tony Lindgren @ 2019-09-13 22:09 UTC (permalink / raw)
  To: Matt Mackall, Herbert Xu, linux-kernel, linux-omap
  Cc: linux-crypto, Aaro Koskinen, Adam Ford, Pali Rohár,
	Rob Herring, Tero Kristo, devicetree

Similar to commit 62f95ae805fa ("hwrng: omap - Set default quality")
we need to initialize the default quality for the RNG to be used.

The symptoms of this problem is that doing hd /dev/random does not
produce much data at all.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/char/hw_random/omap3-rom-rng.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/char/hw_random/omap3-rom-rng.c b/drivers/char/hw_random/omap3-rom-rng.c
--- a/drivers/char/hw_random/omap3-rom-rng.c
+++ b/drivers/char/hw_random/omap3-rom-rng.c
@@ -88,6 +88,7 @@ static int omap3_rom_rng_read(struct hwrng *rng, void *data, size_t max, bool w)
 
 static struct hwrng omap3_rom_rng_ops = {
 	.name		= "omap3-rom",
+	.quality	= 900,
 };
 
 static int omap3_rom_rng_probe(struct platform_device *pdev)
-- 
2.23.0

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 5/6] hwrng: omap3-rom - Update to use standard driver data
  2019-09-13 22:09 [PATCH 0/6] Non-urgent fixes and improvments for omap3-rom-rng Tony Lindgren
                   ` (3 preceding siblings ...)
  2019-09-13 22:09 ` [PATCH 4/6] hwrng: omap3-rom - Initialize default quality to get data Tony Lindgren
@ 2019-09-13 22:09 ` Tony Lindgren
  2019-09-13 22:09 ` [PATCH 6/6] hwrng: omap3-rom - Use runtime PM instead of custom functions Tony Lindgren
  2019-09-14 13:05 ` [PATCH 0/6] Non-urgent fixes and improvments for omap3-rom-rng Sebastian Reichel
  6 siblings, 0 replies; 11+ messages in thread
From: Tony Lindgren @ 2019-09-13 22:09 UTC (permalink / raw)
  To: Matt Mackall, Herbert Xu, linux-kernel, linux-omap
  Cc: linux-crypto, Aaro Koskinen, Adam Ford, Pali Rohár,
	Rob Herring, Tero Kristo, devicetree

Let's update omap3-rom-rng to use standard driver data to make it easier
to add runtime PM support in the following patch. Just use it for the
clock for now, but still keep also old rng_clk still around. We will
remove delayed work and rng_clk with runtime PM in the next patch.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/char/hw_random/omap3-rom-rng.c | 51 +++++++++++++++++---------
 1 file changed, 33 insertions(+), 18 deletions(-)

diff --git a/drivers/char/hw_random/omap3-rom-rng.c b/drivers/char/hw_random/omap3-rom-rng.c
--- a/drivers/char/hw_random/omap3-rom-rng.c
+++ b/drivers/char/hw_random/omap3-rom-rng.c
@@ -31,6 +31,12 @@
 /* param1: ptr, param2: count, param3: flag */
 static u32 (*omap3_rom_rng_call)(u32, u32, u32);
 
+struct omap_rom_rng {
+	struct clk *clk;
+	struct device *dev;
+	struct hwrng ops;
+};
+
 static struct delayed_work idle_work;
 static int rng_idle;
 static struct clk *rng_clk;
@@ -86,60 +92,69 @@ static int omap3_rom_rng_read(struct hwrng *rng, void *data, size_t max, bool w)
 	return 4;
 }
 
-static struct hwrng omap3_rom_rng_ops = {
-	.name		= "omap3-rom",
-	.quality	= 900,
-};
-
 static int omap3_rom_rng_probe(struct platform_device *pdev)
 {
+	struct omap_rom_rng *ddata;
 	int ret = 0;
 
-	omap3_rom_rng_ops.read = of_device_get_match_data(&pdev->dev);
-	if (!omap3_rom_rng_ops.read) {
+	ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
+	if (!ddata)
+		return -ENOMEM;
+
+	ddata->dev = &pdev->dev;
+	ddata->ops.priv = (unsigned long)ddata;
+	ddata->ops.name = "omap3-rom";
+	ddata->ops.read = of_device_get_match_data(&pdev->dev);
+	ddata->ops.quality = 900;
+	if (!ddata->ops.read) {
 		dev_err(&pdev->dev, "missing rom code handler\n");
 
 		return -ENODEV;
 	}
+	dev_set_drvdata(ddata->dev, ddata);
 
 	omap3_rom_rng_call = pdev->dev.platform_data;
 	if (!omap3_rom_rng_call) {
-		pr_err("omap3_rom_rng_call is NULL\n");
+		dev_err(ddata->dev, "rom_rng_call is NULL\n");
 		return -EINVAL;
 	}
 
 	INIT_DELAYED_WORK(&idle_work, omap3_rom_rng_idle);
-	rng_clk = devm_clk_get(&pdev->dev, "ick");
-	if (IS_ERR(rng_clk)) {
-		pr_err("unable to get RNG clock\n");
-		return PTR_ERR(rng_clk);
+	ddata->clk = devm_clk_get(ddata->dev, "ick");
+	if (IS_ERR(ddata->clk)) {
+		dev_err(ddata->dev, "unable to get RNG clock\n");
+		return PTR_ERR(ddata->clk);
 	}
+	rng_clk = ddata->clk;
 
-	ret = clk_prepare(rng_clk);
+	ret = clk_prepare(ddata->clk);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "clk_prepare failed: %i\n", ret);
 		return ret;
 	}
 
 	/* Leave the RNG in reset state. */
-	ret = clk_enable(rng_clk);
+	ret = clk_enable(ddata->clk);
 	if (ret)
 		goto err_unprepare;
 	omap3_rom_rng_idle(0);
 
-	return hwrng_register(&omap3_rom_rng_ops);
+	return hwrng_register(&ddata->ops);
 
 err_unprepare:
-	clk_unprepare(rng_clk);
+	clk_unprepare(ddata->clk);
 
 	return ret;
 }
 
 static int omap3_rom_rng_remove(struct platform_device *pdev)
 {
+	struct omap_rom_rng *ddata;
+
+	ddata = dev_get_drvdata(&pdev->dev);
 	cancel_delayed_work_sync(&idle_work);
-	hwrng_unregister(&omap3_rom_rng_ops);
-	clk_unprepare(rng_clk);
+	hwrng_unregister(&ddata->ops);
+	clk_unprepare(ddata->clk);
 
 	return 0;
 }
-- 
2.23.0

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 6/6] hwrng: omap3-rom - Use runtime PM instead of custom functions
  2019-09-13 22:09 [PATCH 0/6] Non-urgent fixes and improvments for omap3-rom-rng Tony Lindgren
                   ` (4 preceding siblings ...)
  2019-09-13 22:09 ` [PATCH 5/6] hwrng: omap3-rom - Update to use standard driver data Tony Lindgren
@ 2019-09-13 22:09 ` Tony Lindgren
  2019-09-14 13:05 ` [PATCH 0/6] Non-urgent fixes and improvments for omap3-rom-rng Sebastian Reichel
  6 siblings, 0 replies; 11+ messages in thread
From: Tony Lindgren @ 2019-09-13 22:09 UTC (permalink / raw)
  To: Matt Mackall, Herbert Xu, linux-kernel, linux-omap
  Cc: linux-crypto, Aaro Koskinen, Adam Ford, Pali Rohár,
	Rob Herring, Tero Kristo, devicetree

Nowadays we have runtime PM, and we can use it with autosuspend_timeout
to idle things automatically. This allows us to get rid of the custom
PM implementation.

We enable clocks and init RNG in runtime_resume, and reset RNG and
disable clocks in runtime_suspend. And then omap3_rom_rng_read()
becomes very simple and we don't need the old functions for
omap3_rom_rng_idle() and omap3_rom_rng_get_random().

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/char/hw_random/omap3-rom-rng.c | 127 +++++++++++++++----------
 1 file changed, 77 insertions(+), 50 deletions(-)

diff --git a/drivers/char/hw_random/omap3-rom-rng.c b/drivers/char/hw_random/omap3-rom-rng.c
--- a/drivers/char/hw_random/omap3-rom-rng.c
+++ b/drivers/char/hw_random/omap3-rom-rng.c
@@ -23,73 +23,83 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 
 #define RNG_RESET			0x01
 #define RNG_GEN_PRNG_HW_INIT		0x02
 #define RNG_GEN_HW			0x08
 
-/* param1: ptr, param2: count, param3: flag */
-static u32 (*omap3_rom_rng_call)(u32, u32, u32);
-
 struct omap_rom_rng {
 	struct clk *clk;
 	struct device *dev;
 	struct hwrng ops;
+	u32 (*rom_rng_call)(u32 ptr, u32 count, u32 flag);
 };
 
-static struct delayed_work idle_work;
-static int rng_idle;
-static struct clk *rng_clk;
-
-static void omap3_rom_rng_idle(struct work_struct *work)
+static int omap3_rom_rng_read(struct hwrng *rng, void *data, size_t max, bool w)
 {
+	struct omap_rom_rng *ddata;
+	u32 ptr;
 	int r;
 
-	r = omap3_rom_rng_call(0, 0, RNG_RESET);
-	if (r != 0) {
-		pr_err("reset failed: %d\n", r);
-		return;
+	ddata = (struct omap_rom_rng *)rng->priv;
+
+	r = pm_runtime_get_sync(ddata->dev);
+	if (r < 0) {
+		pm_runtime_put_noidle(ddata->dev);
+
+		return r;
 	}
-	clk_disable(rng_clk);
-	rng_idle = 1;
+
+	ptr = virt_to_phys(data);
+	r = ddata->rom_rng_call(ptr, 4, RNG_GEN_HW);
+	if (r != 0)
+		r = -EINVAL;
+	else
+		r = 4;
+
+	pm_runtime_mark_last_busy(ddata->dev);
+	pm_runtime_put_autosuspend(ddata->dev);
+
+	return r;
 }
 
-static int omap3_rom_rng_get_random(void *buf, unsigned int count)
+static int omap_rom_rng_runtime_suspend(struct device *dev)
 {
-	u32 r;
-	u32 ptr;
+	struct omap_rom_rng *ddata;
+	int r;
 
-	cancel_delayed_work_sync(&idle_work);
-	if (rng_idle) {
-		r = clk_enable(rng_clk);
-		if (r)
-			return r;
-
-		r = omap3_rom_rng_call(0, 0, RNG_GEN_PRNG_HW_INIT);
-		if (r != 0) {
-			clk_disable(rng_clk);
-			pr_err("HW init failed: %d\n", r);
-			return -EIO;
-		}
-		rng_idle = 0;
-	}
+	ddata = dev_get_drvdata(dev);
 
-	ptr = virt_to_phys(buf);
-	r = omap3_rom_rng_call(ptr, count, RNG_GEN_HW);
-	schedule_delayed_work(&idle_work, msecs_to_jiffies(500));
+	r = ddata->rom_rng_call(0, 0, RNG_RESET);
 	if (r != 0)
-		return -EINVAL;
+		pr_err("reset failed: %d\n", r);
+
+	clk_disable(ddata->clk);
+
 	return 0;
 }
 
-static int omap3_rom_rng_read(struct hwrng *rng, void *data, size_t max, bool w)
+static int omap_rom_rng_runtime_resume(struct device *dev)
 {
+	struct omap_rom_rng *ddata;
 	int r;
 
-	r = omap3_rom_rng_get_random(data, 4);
+	ddata = dev_get_drvdata(dev);
+
+	r = clk_enable(ddata->clk);
 	if (r < 0)
 		return r;
-	return 4;
+
+	r = ddata->rom_rng_call(0, 0, RNG_GEN_PRNG_HW_INIT);
+	if (r != 0) {
+		clk_disable(ddata->clk);
+		dev_err(ddata->dev, "HW init failed: %d\n", r);
+
+		return -EIO;
+	}
+
+	return 0;
 }
 
 static int omap3_rom_rng_probe(struct platform_device *pdev)
@@ -113,19 +123,17 @@ static int omap3_rom_rng_probe(struct platform_device *pdev)
 	}
 	dev_set_drvdata(ddata->dev, ddata);
 
-	omap3_rom_rng_call = pdev->dev.platform_data;
-	if (!omap3_rom_rng_call) {
+	ddata->rom_rng_call = pdev->dev.platform_data;
+	if (!ddata->rom_rng_call) {
 		dev_err(ddata->dev, "rom_rng_call is NULL\n");
 		return -EINVAL;
 	}
 
-	INIT_DELAYED_WORK(&idle_work, omap3_rom_rng_idle);
 	ddata->clk = devm_clk_get(ddata->dev, "ick");
 	if (IS_ERR(ddata->clk)) {
 		dev_err(ddata->dev, "unable to get RNG clock\n");
 		return PTR_ERR(ddata->clk);
 	}
-	rng_clk = ddata->clk;
 
 	ret = clk_prepare(ddata->clk);
 	if (ret < 0) {
@@ -133,15 +141,27 @@ static int omap3_rom_rng_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	/* Leave the RNG in reset state. */
-	ret = clk_enable(ddata->clk);
-	if (ret)
-		goto err_unprepare;
-	omap3_rom_rng_idle(0);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, 500);
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+	ret = pm_runtime_get_sync(&pdev->dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(&pdev->dev);
+		goto err_disable;
 
-	return hwrng_register(&ddata->ops);
+		return ret;
+	}
 
-err_unprepare:
+	pm_runtime_mark_last_busy(&pdev->dev);
+	pm_runtime_put_autosuspend(&pdev->dev);
+
+	ret = hwrng_register(&ddata->ops);
+	if (!ret)
+		return 0;
+
+err_disable:
+	pm_runtime_dont_use_autosuspend(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
 	clk_unprepare(ddata->clk);
 
 	return ret;
@@ -152,8 +172,9 @@ static int omap3_rom_rng_remove(struct platform_device *pdev)
 	struct omap_rom_rng *ddata;
 
 	ddata = dev_get_drvdata(&pdev->dev);
-	cancel_delayed_work_sync(&idle_work);
 	hwrng_unregister(&ddata->ops);
+	pm_runtime_dont_use_autosuspend(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
 	clk_unprepare(ddata->clk);
 
 	return 0;
@@ -165,10 +186,16 @@ static const struct of_device_id omap_rom_rng_match[] = {
 };
 MODULE_DEVICE_TABLE(of, omap_rom_rng_match);
 
+static const struct dev_pm_ops omap_rom_rng_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(omap_rom_rng_runtime_suspend,
+				omap_rom_rng_runtime_resume)
+};
+
 static struct platform_driver omap3_rom_rng_driver = {
 	.driver = {
 		.name		= "omap3-rom-rng",
 		.of_match_table = omap_rom_rng_match,
+		.pm = &omap_rom_rng_pm_ops,
 	},
 	.probe		= omap3_rom_rng_probe,
 	.remove		= omap3_rom_rng_remove,
-- 
2.23.0

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/6] hwrng: omap3-rom - Call clk_prepare() on init and exit only
  2019-09-13 22:09 ` [PATCH 3/6] hwrng: omap3-rom - Call clk_prepare() on init and exit only Tony Lindgren
@ 2019-09-14 12:54   ` Sebastian Reichel
  2019-09-14 17:57     ` Tony Lindgren
  0 siblings, 1 reply; 11+ messages in thread
From: Sebastian Reichel @ 2019-09-14 12:54 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Matt Mackall, Herbert Xu, linux-kernel, linux-omap, linux-crypto,
	Aaro Koskinen, Adam Ford, Pali Rohár, Tero Kristo,
	Rob Herring, devicetree

[-- Attachment #1: Type: text/plain, Size: 373 bytes --]

Hi,

On Fri, Sep 13, 2019 at 03:09:19PM -0700, Tony Lindgren wrote:
> Also, we should not call prepare and unprepare except during init, and
> only call enable and disable during use.

Why? Usually clk_(un)prepare() is the part saving most power, so I
would expect the runtime resume handlers to call clk_prepare_enable
and vice versa in the suspend handler.

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 0/6] Non-urgent fixes and improvments for omap3-rom-rng
  2019-09-13 22:09 [PATCH 0/6] Non-urgent fixes and improvments for omap3-rom-rng Tony Lindgren
                   ` (5 preceding siblings ...)
  2019-09-13 22:09 ` [PATCH 6/6] hwrng: omap3-rom - Use runtime PM instead of custom functions Tony Lindgren
@ 2019-09-14 13:05 ` Sebastian Reichel
  2019-09-14 17:59   ` Tony Lindgren
  6 siblings, 1 reply; 11+ messages in thread
From: Sebastian Reichel @ 2019-09-14 13:05 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Matt Mackall, Herbert Xu, linux-kernel, linux-omap, linux-crypto,
	Aaro Koskinen, Adam Ford, Pali Rohár, Rob Herring,
	Tero Kristo, devicetree

[-- Attachment #1: Type: text/plain, Size: 647 bytes --]

Hi,

On Fri, Sep 13, 2019 at 03:09:16PM -0700, Tony Lindgren wrote:
> Here are fixes and improvments for omap3-rom-rng that's been broken for
> a while.
> 
> The first four patches get it working, and then the last two patches add
> support for runtime PM.

Nice cleanups, the series is

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

Assuming you use clk_prepare_enable() in the runtime PM handler, I
suggest to add another patch and go all the way to managed resources:
devm_add_action() can be used for disabling runtime PM and
devm_hwrng_register() can be used to register the hwrng device.

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/6] hwrng: omap3-rom - Call clk_prepare() on init and exit only
  2019-09-14 12:54   ` Sebastian Reichel
@ 2019-09-14 17:57     ` Tony Lindgren
  0 siblings, 0 replies; 11+ messages in thread
From: Tony Lindgren @ 2019-09-14 17:57 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Matt Mackall, Herbert Xu, linux-kernel, linux-omap, linux-crypto,
	Aaro Koskinen, Adam Ford, Pali Rohár, Tero Kristo,
	Rob Herring, devicetree

* Sebastian Reichel <sre@kernel.org> [190914 13:01]:
> Hi,
> 
> On Fri, Sep 13, 2019 at 03:09:19PM -0700, Tony Lindgren wrote:
> > Also, we should not call prepare and unprepare except during init, and
> > only call enable and disable during use.
> 
> Why? Usually clk_(un)prepare() is the part saving most power, so I
> would expect the runtime resume handlers to call clk_prepare_enable
> and vice versa in the suspend handler.

Sure yeah fine with me, clk_prepare_enable() is more generic at the
cost of some extra calls to toggle a clock gate bit :) Let's also
forget the probe changes, those will get cleared with the runtime
PM changes anyways.

Regards,

Tony

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 0/6] Non-urgent fixes and improvments for omap3-rom-rng
  2019-09-14 13:05 ` [PATCH 0/6] Non-urgent fixes and improvments for omap3-rom-rng Sebastian Reichel
@ 2019-09-14 17:59   ` Tony Lindgren
  0 siblings, 0 replies; 11+ messages in thread
From: Tony Lindgren @ 2019-09-14 17:59 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Matt Mackall, Herbert Xu, linux-kernel, linux-omap, linux-crypto,
	Aaro Koskinen, Adam Ford, Pali Rohár, Rob Herring,
	Tero Kristo, devicetree

* Sebastian Reichel <sre@kernel.org> [190914 13:06]:
> Hi,
> 
> On Fri, Sep 13, 2019 at 03:09:16PM -0700, Tony Lindgren wrote:
> > Here are fixes and improvments for omap3-rom-rng that's been broken for
> > a while.
> > 
> > The first four patches get it working, and then the last two patches add
> > support for runtime PM.
> 
> Nice cleanups, the series is
> 
> Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> 
> Assuming you use clk_prepare_enable() in the runtime PM handler, I
> suggest to add another patch and go all the way to managed resources:
> devm_add_action() can be used for disabling runtime PM and
> devm_hwrng_register() can be used to register the hwrng device.

Sure good idea. I'll post a patch for that when I post v2 of
this set.

Regards,

Tony



^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2019-09-14 17:59 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-13 22:09 [PATCH 0/6] Non-urgent fixes and improvments for omap3-rom-rng Tony Lindgren
2019-09-13 22:09 ` [PATCH 1/6] ARM: OMAP2+: Check omap3-rom-rng for GP device instead of HS device Tony Lindgren
2019-09-13 22:09 ` [PATCH 2/6] hwrng: omap3-rom - Fix missing clock by probing with device tree Tony Lindgren
2019-09-13 22:09 ` [PATCH 3/6] hwrng: omap3-rom - Call clk_prepare() on init and exit only Tony Lindgren
2019-09-14 12:54   ` Sebastian Reichel
2019-09-14 17:57     ` Tony Lindgren
2019-09-13 22:09 ` [PATCH 4/6] hwrng: omap3-rom - Initialize default quality to get data Tony Lindgren
2019-09-13 22:09 ` [PATCH 5/6] hwrng: omap3-rom - Update to use standard driver data Tony Lindgren
2019-09-13 22:09 ` [PATCH 6/6] hwrng: omap3-rom - Use runtime PM instead of custom functions Tony Lindgren
2019-09-14 13:05 ` [PATCH 0/6] Non-urgent fixes and improvments for omap3-rom-rng Sebastian Reichel
2019-09-14 17:59   ` Tony Lindgren

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).