[U-Boot,v2,3/5] test: clk: Update tests to also check the managed API
diff mbox series

Message ID 20191022120007.23288-4-jjhiblot@ti.com
State Accepted
Delegated to: Lukasz Majewski
Headers show
Series
  • clk: Add a managed API and fix clock self-assignment
Related show

Commit Message

Jean-Jacques Hiblot Oct. 22, 2019, noon UTC
Add a few more clocks the clk_sandbox clock provider and get them using
the managed API.
Make sure they are released when the device is removed.

Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
---

Changes in v2: None

 arch/sandbox/dts/test.dts      |  6 ++--
 arch/sandbox/include/asm/clk.h | 33 +++++++++++++++++
 drivers/clk/clk_sandbox.c      | 34 ++++++++++++++++++
 drivers/clk/clk_sandbox_test.c | 66 +++++++++++++++++++++++++++++-----
 test/dm/clk.c                  | 36 ++++++++++++++++++-
 5 files changed, 163 insertions(+), 12 deletions(-)

Patch
diff mbox series

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 5d9ab3724f..0ee86a74ed 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -232,8 +232,10 @@ 
 		compatible = "sandbox,clk-test";
 		clocks = <&clk_fixed>,
 			 <&clk_sandbox 1>,
-			 <&clk_sandbox 0>;
-		clock-names = "fixed", "i2c", "spi";
+			 <&clk_sandbox 0>,
+			 <&clk_sandbox 3>,
+			 <&clk_sandbox 2>;
+		clock-names = "fixed", "i2c", "spi", "uart2", "uart1";
 	};
 
 	ccf: clk-ccf {
diff --git a/arch/sandbox/include/asm/clk.h b/arch/sandbox/include/asm/clk.h
index 2b1c49f783..1573e4a134 100644
--- a/arch/sandbox/include/asm/clk.h
+++ b/arch/sandbox/include/asm/clk.h
@@ -19,6 +19,8 @@  struct udevice;
 enum sandbox_clk_id {
 	SANDBOX_CLK_ID_SPI,
 	SANDBOX_CLK_ID_I2C,
+	SANDBOX_CLK_ID_UART1,
+	SANDBOX_CLK_ID_UART2,
 
 	SANDBOX_CLK_ID_COUNT,
 };
@@ -33,10 +35,15 @@  enum sandbox_clk_test_id {
 	SANDBOX_CLK_TEST_ID_FIXED,
 	SANDBOX_CLK_TEST_ID_SPI,
 	SANDBOX_CLK_TEST_ID_I2C,
+	SANDBOX_CLK_TEST_ID_DEVM1,
+	SANDBOX_CLK_TEST_ID_DEVM2,
+	SANDBOX_CLK_TEST_ID_DEVM_NULL,
 
 	SANDBOX_CLK_TEST_ID_COUNT,
 };
 
+#define SANDBOX_CLK_TEST_NON_DEVM_COUNT SANDBOX_CLK_TEST_ID_DEVM1
+
 /**
  * sandbox_clk_query_rate - Query the current rate of a sandbox clock.
  *
@@ -53,6 +60,14 @@  ulong sandbox_clk_query_rate(struct udevice *dev, int id);
  * @return:	The rate of the clock.
  */
 int sandbox_clk_query_enable(struct udevice *dev, int id);
+/**
+ * sandbox_clk_query_requested - Query the requested state of a sandbox clock.
+ *
+ * @dev:	The sandbox clock provider device.
+ * @id:		The clock to query.
+ * @return:	The rate of the clock.
+ */
+int sandbox_clk_query_requested(struct udevice *dev, int id);
 
 /**
  * sandbox_clk_test_get - Ask the sandbox clock test device to request its
@@ -62,6 +77,16 @@  int sandbox_clk_query_enable(struct udevice *dev, int id);
  * @return:	0 if OK, or a negative error code.
  */
 int sandbox_clk_test_get(struct udevice *dev);
+
+/**
+ * sandbox_clk_test_devm_get - Ask the sandbox clock test device to request its
+ * clocks using the managed API.
+ *
+ * @dev:	The sandbox clock test (client) devivce.
+ * @return:	0 if OK, or a negative error code.
+ */
+int sandbox_clk_test_devm_get(struct udevice *dev);
+
 /**
  * sandbox_clk_test_get_bulk - Ask the sandbox clock test device to request its
  * clocks with the bulk clk API.
@@ -146,5 +171,13 @@  int sandbox_clk_test_release_bulk(struct udevice *dev);
  * @return:	0 if OK, or a negative error code.
  */
 int sandbox_clk_test_valid(struct udevice *dev);
+/**
+ * sandbox_clk_test_valid - Ask the sandbox clock test device to check its
+ * clocks are valid.
+ *
+ * @dev:	The sandbox clock test (client) devivce.
+ * @return:	0 if OK, or a negative error code.
+ */
+struct clk *sandbox_clk_test_get_devm_clk(struct udevice *dev, int id);
 
 #endif
diff --git a/drivers/clk/clk_sandbox.c b/drivers/clk/clk_sandbox.c
index 1d5cbb589a..d152fd7e5b 100644
--- a/drivers/clk/clk_sandbox.c
+++ b/drivers/clk/clk_sandbox.c
@@ -12,6 +12,7 @@ 
 struct sandbox_clk_priv {
 	ulong rate[SANDBOX_CLK_ID_COUNT];
 	bool enabled[SANDBOX_CLK_ID_COUNT];
+	bool requested[SANDBOX_CLK_ID_COUNT];
 };
 
 static ulong sandbox_clk_get_rate(struct clk *clk)
@@ -65,11 +66,35 @@  static int sandbox_clk_disable(struct clk *clk)
 	return 0;
 }
 
+static int sandbox_clk_request(struct clk *clk)
+{
+	struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
+
+	if (clk->id >= SANDBOX_CLK_ID_COUNT)
+		return -EINVAL;
+
+	priv->requested[clk->id] = true;
+	return 0;
+}
+
+static int sandbox_clk_free(struct clk *clk)
+{
+	struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
+
+	if (clk->id >= SANDBOX_CLK_ID_COUNT)
+		return -EINVAL;
+
+	priv->requested[clk->id] = false;
+	return 0;
+}
+
 static struct clk_ops sandbox_clk_ops = {
 	.get_rate	= sandbox_clk_get_rate,
 	.set_rate	= sandbox_clk_set_rate,
 	.enable		= sandbox_clk_enable,
 	.disable	= sandbox_clk_disable,
+	.request	= sandbox_clk_request,
+	.free		= sandbox_clk_free,
 };
 
 static const struct udevice_id sandbox_clk_ids[] = {
@@ -104,3 +129,12 @@  int sandbox_clk_query_enable(struct udevice *dev, int id)
 
 	return priv->enabled[id];
 }
+
+int sandbox_clk_query_requested(struct udevice *dev, int id)
+{
+	struct sandbox_clk_priv *priv = dev_get_priv(dev);
+
+	if (id < 0 || id >= SANDBOX_CLK_ID_COUNT)
+		return -EINVAL;
+	return priv->requested[id];
+}
diff --git a/drivers/clk/clk_sandbox_test.c b/drivers/clk/clk_sandbox_test.c
index e8465dbfad..41954660ea 100644
--- a/drivers/clk/clk_sandbox_test.c
+++ b/drivers/clk/clk_sandbox_test.c
@@ -9,7 +9,8 @@ 
 #include <asm/clk.h>
 
 struct sandbox_clk_test {
-	struct clk clks[SANDBOX_CLK_TEST_ID_COUNT];
+	struct clk clks[SANDBOX_CLK_TEST_NON_DEVM_COUNT];
+	struct clk *clkps[SANDBOX_CLK_TEST_ID_COUNT];
 	struct clk_bulk bulk;
 };
 
@@ -24,7 +25,7 @@  int sandbox_clk_test_get(struct udevice *dev)
 	struct sandbox_clk_test *sbct = dev_get_priv(dev);
 	int i, ret;
 
-	for (i = 0; i < SANDBOX_CLK_TEST_ID_COUNT; i++) {
+	for (i = 0; i < SANDBOX_CLK_TEST_NON_DEVM_COUNT; i++) {
 		ret = clk_get_by_name(dev, sandbox_clk_test_names[i],
 				      &sbct->clks[i]);
 		if (ret)
@@ -34,6 +35,37 @@  int sandbox_clk_test_get(struct udevice *dev)
 	return 0;
 }
 
+int sandbox_clk_test_devm_get(struct udevice *dev)
+{
+	struct sandbox_clk_test *sbct = dev_get_priv(dev);
+	struct clk *clk;
+
+	clk = devm_clk_get(dev, "no-an-existing-clock");
+	if (!IS_ERR(clk)) {
+		dev_err(dev, "devm_clk_get() should have failed\n");
+		return -EINVAL;
+	}
+
+	clk = devm_clk_get(dev, "uart2");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+	sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM1] = clk;
+
+	clk = devm_clk_get_optional(dev, "uart1");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+	sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM2] = clk;
+
+	sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM_NULL] = NULL;
+	clk = devm_clk_get_optional(dev, "not_an_existing_clock");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+	if (clk)
+		return -EINVAL;
+
+	return 0;
+}
+
 int sandbox_clk_test_get_bulk(struct udevice *dev)
 {
 	struct sandbox_clk_test *sbct = dev_get_priv(dev);
@@ -48,7 +80,7 @@  ulong sandbox_clk_test_get_rate(struct udevice *dev, int id)
 	if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
 		return -EINVAL;
 
-	return clk_get_rate(&sbct->clks[id]);
+	return clk_get_rate(sbct->clkps[id]);
 }
 
 ulong sandbox_clk_test_set_rate(struct udevice *dev, int id, ulong rate)
@@ -58,7 +90,7 @@  ulong sandbox_clk_test_set_rate(struct udevice *dev, int id, ulong rate)
 	if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
 		return -EINVAL;
 
-	return clk_set_rate(&sbct->clks[id], rate);
+	return clk_set_rate(sbct->clkps[id], rate);
 }
 
 int sandbox_clk_test_enable(struct udevice *dev, int id)
@@ -68,7 +100,7 @@  int sandbox_clk_test_enable(struct udevice *dev, int id)
 	if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
 		return -EINVAL;
 
-	return clk_enable(&sbct->clks[id]);
+	return clk_enable(sbct->clkps[id]);
 }
 
 int sandbox_clk_test_enable_bulk(struct udevice *dev)
@@ -85,7 +117,7 @@  int sandbox_clk_test_disable(struct udevice *dev, int id)
 	if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
 		return -EINVAL;
 
-	return clk_disable(&sbct->clks[id]);
+	return clk_disable(sbct->clkps[id]);
 }
 
 int sandbox_clk_test_disable_bulk(struct udevice *dev)
@@ -100,7 +132,8 @@  int sandbox_clk_test_free(struct udevice *dev)
 	struct sandbox_clk_test *sbct = dev_get_priv(dev);
 	int i, ret;
 
-	for (i = 0; i < SANDBOX_CLK_TEST_ID_COUNT; i++) {
+	devm_clk_put(dev, sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM1]);
+	for (i = 0; i < SANDBOX_CLK_TEST_NON_DEVM_COUNT; i++) {
 		ret = clk_free(&sbct->clks[i]);
 		if (ret)
 			return ret;
@@ -122,13 +155,27 @@  int sandbox_clk_test_valid(struct udevice *dev)
 	int i;
 
 	for (i = 0; i < SANDBOX_CLK_TEST_ID_COUNT; i++) {
-		if (!clk_valid(&sbct->clks[i]))
-			return -EINVAL;
+		if (!clk_valid(sbct->clkps[i]))
+			if (i != SANDBOX_CLK_TEST_ID_DEVM_NULL)
+				return -EINVAL;
 	}
 
 	return 0;
 }
 
+static int sandbox_clk_test_probe(struct udevice *dev)
+{
+	struct sandbox_clk_test *sbct = dev_get_priv(dev);
+	int i;
+
+	for (i = 0; i < SANDBOX_CLK_TEST_ID_DEVM1; i++)
+		sbct->clkps[i] = &sbct->clks[i];
+	for (i = SANDBOX_CLK_TEST_ID_DEVM1; i < SANDBOX_CLK_TEST_ID_COUNT; i++)
+		sbct->clkps[i] = NULL;
+
+	return 0;
+}
+
 static const struct udevice_id sandbox_clk_test_ids[] = {
 	{ .compatible = "sandbox,clk-test" },
 	{ }
@@ -138,5 +185,6 @@  U_BOOT_DRIVER(sandbox_clk_test) = {
 	.name = "sandbox_clk_test",
 	.id = UCLASS_MISC,
 	.of_match = sandbox_clk_test_ids,
+	.probe = sandbox_clk_test_probe,
 	.priv_auto_alloc_size = sizeof(struct sandbox_clk_test),
 };
diff --git a/test/dm/clk.c b/test/dm/clk.c
index 676ef217f0..3ad0ad8ca3 100644
--- a/test/dm/clk.c
+++ b/test/dm/clk.c
@@ -8,6 +8,7 @@ 
 #include <dm.h>
 #include <asm/clk.h>
 #include <dm/test.h>
+#include <dm/device-internal.h>
 #include <linux/err.h>
 #include <test/ut.h>
 
@@ -53,8 +54,19 @@  static int dm_test_clk(struct unit_test_state *uts)
 	ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "clk-test",
 					      &dev_test));
 	ut_assertok(sandbox_clk_test_get(dev_test));
+	ut_assertok(sandbox_clk_test_devm_get(dev_test));
 	ut_assertok(sandbox_clk_test_valid(dev_test));
 
+	ut_asserteq(0, sandbox_clk_test_get_rate(dev_test,
+						 SANDBOX_CLK_TEST_ID_DEVM_NULL));
+	ut_asserteq(0, sandbox_clk_test_set_rate(dev_test,
+						 SANDBOX_CLK_TEST_ID_DEVM_NULL,
+						 0));
+	ut_asserteq(0, sandbox_clk_test_enable(dev_test,
+					       SANDBOX_CLK_TEST_ID_DEVM_NULL));
+	ut_asserteq(0, sandbox_clk_test_disable(dev_test,
+						SANDBOX_CLK_TEST_ID_DEVM_NULL));
+
 	ut_asserteq(1234,
 		    sandbox_clk_test_get_rate(dev_test,
 					      SANDBOX_CLK_TEST_ID_FIXED));
@@ -62,6 +74,10 @@  static int dm_test_clk(struct unit_test_state *uts)
 						 SANDBOX_CLK_TEST_ID_SPI));
 	ut_asserteq(0, sandbox_clk_test_get_rate(dev_test,
 						 SANDBOX_CLK_TEST_ID_I2C));
+	ut_asserteq(0, sandbox_clk_test_get_rate(dev_test,
+						 SANDBOX_CLK_TEST_ID_DEVM1));
+	ut_asserteq(0, sandbox_clk_test_get_rate(dev_test,
+						 SANDBOX_CLK_TEST_ID_DEVM2));
 
 	rate = sandbox_clk_test_set_rate(dev_test, SANDBOX_CLK_TEST_ID_FIXED,
 					 12345);
@@ -121,8 +137,25 @@  static int dm_test_clk(struct unit_test_state *uts)
 	ut_asserteq(0, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_SPI));
 	ut_asserteq(0, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_I2C));
 
+	ut_asserteq(1, sandbox_clk_query_requested(dev_clk,
+						   SANDBOX_CLK_ID_SPI));
+	ut_asserteq(1, sandbox_clk_query_requested(dev_clk,
+						   SANDBOX_CLK_ID_I2C));
+	ut_asserteq(1, sandbox_clk_query_requested(dev_clk,
+						   SANDBOX_CLK_ID_UART2));
 	ut_assertok(sandbox_clk_test_free(dev_test));
-
+	ut_asserteq(0, sandbox_clk_query_requested(dev_clk,
+						   SANDBOX_CLK_ID_SPI));
+	ut_asserteq(0, sandbox_clk_query_requested(dev_clk,
+						   SANDBOX_CLK_ID_I2C));
+	ut_asserteq(0, sandbox_clk_query_requested(dev_clk,
+						   SANDBOX_CLK_ID_UART2));
+
+	ut_asserteq(1, sandbox_clk_query_requested(dev_clk,
+						   SANDBOX_CLK_ID_UART1));
+	ut_assertok(device_remove(dev_test, DM_REMOVE_NORMAL));
+	ut_asserteq(0, sandbox_clk_query_requested(dev_clk,
+						   SANDBOX_CLK_ID_UART1));
 	return 0;
 }
 DM_TEST(dm_test_clk, DM_TESTF_SCAN_FDT);
@@ -159,6 +192,7 @@  static int dm_test_clk_bulk(struct unit_test_state *uts)
 	ut_assertok(sandbox_clk_test_release_bulk(dev_test));
 	ut_asserteq(0, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_SPI));
 	ut_asserteq(0, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_I2C));
+	ut_assertok(device_remove(dev_test, DM_REMOVE_NORMAL));
 
 	return 0;
 }