Browse Source

syscon: dm: Add a new method to get a regmap from DTS

syscon_regmap_lookup_by_phandle() can be used to get the regmap of a syscon
device from a reference in the DTS. It operates similarly to the linux
version of the namesake function.

Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Jean-Jacques Hiblot 5 years ago
parent
commit
6c3af1f24e
4 changed files with 69 additions and 2 deletions
  1. 4 2
      arch/sandbox/dts/test.dts
  2. 23 0
      drivers/core/syscon-uclass.c
  3. 13 0
      include/syscon.h
  4. 29 0
      test/dm/syscon.c

+ 4 - 2
arch/sandbox/dts/test.dts

@@ -460,6 +460,8 @@
 
 		test4 {
 			compatible = "denx,u-boot-probe-test";
+			first-syscon = <&syscon0>;
+			second-sys-ctrl = <&another_system_controller>;
 		};
 	};
 
@@ -540,12 +542,12 @@
 		};
 	};
 
-	syscon@0 {
+	syscon0: syscon@0 {
 		compatible = "sandbox,syscon0";
 		reg = <0x10 16>;
 	};
 
-	syscon@1 {
+	another_system_controller: syscon@1 {
 		compatible = "sandbox,syscon1";
 		reg = <0x20 5
 			0x28 6

+ 23 - 0
drivers/core/syscon-uclass.c

@@ -53,6 +53,29 @@ static int syscon_pre_probe(struct udevice *dev)
 #endif
 }
 
+struct regmap *syscon_regmap_lookup_by_phandle(struct udevice *dev,
+					       const char *name)
+{
+	struct udevice *syscon;
+	struct regmap *r;
+	int err;
+
+	err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
+					   name, &syscon);
+	if (err) {
+		dev_dbg(dev, "unable to find syscon device\n");
+		return ERR_PTR(err);
+	}
+
+	r = syscon_get_regmap(syscon);
+	if (!r) {
+		dev_dbg(dev, "unable to find regmap\n");
+		return ERR_PTR(-ENODEV);
+	}
+
+	return r;
+}
+
 int syscon_get_by_driver_data(ulong driver_data, struct udevice **devp)
 {
 	struct udevice *dev;

+ 13 - 0
include/syscon.h

@@ -73,6 +73,19 @@ int syscon_get_by_driver_data(ulong driver_data, struct udevice **devp);
  */
 struct regmap *syscon_get_regmap_by_driver_data(ulong driver_data);
 
+/**
+ * syscon_regmap_lookup_by_phandle() - Look up a controller by a phandle
+ *
+ * This operates by looking up the given name in the device (device
+ * tree property) of the device using the system controller.
+ *
+ * @dev:	Device using the system controller
+ * @name:	Name of property referring to the system controller
+ * @return	A pointer to the regmap if found, ERR_PTR(-ve) on error
+ */
+struct regmap *syscon_regmap_lookup_by_phandle(struct udevice *dev,
+					       const char *name);
+
 /**
  * syscon_get_first_range() - get the first memory range from a syscon regmap
  *

+ 29 - 0
test/dm/syscon.c

@@ -6,6 +6,7 @@
 #include <common.h>
 #include <dm.h>
 #include <syscon.h>
+#include <regmap.h>
 #include <asm/test.h>
 #include <dm/test.h>
 #include <test/ut.h>
@@ -43,3 +44,31 @@ static int dm_test_syscon_by_driver_data(struct unit_test_state *uts)
 	return 0;
 }
 DM_TEST(dm_test_syscon_by_driver_data, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test system controller by phandle */
+static int dm_test_syscon_by_phandle(struct unit_test_state *uts)
+{
+	struct udevice *dev;
+	struct regmap *map;
+
+	ut_assertok(uclass_get_device_by_name(UCLASS_TEST_PROBE, "test4",
+					      &dev));
+
+	ut_assertok_ptr(syscon_regmap_lookup_by_phandle(dev, "first-syscon"));
+	map = syscon_regmap_lookup_by_phandle(dev, "first-syscon");
+	ut_assert(map);
+	ut_assert(!IS_ERR(map));
+	ut_asserteq(1, map->range_count);
+
+	ut_assertok_ptr(syscon_regmap_lookup_by_phandle(dev,
+							"second-sys-ctrl"));
+	map = syscon_regmap_lookup_by_phandle(dev, "second-sys-ctrl");
+	ut_assert(map);
+	ut_assert(!IS_ERR(map));
+	ut_asserteq(4, map->range_count);
+
+	ut_assert(IS_ERR(syscon_regmap_lookup_by_phandle(dev, "not-present")));
+
+	return 0;
+}
+DM_TEST(dm_test_syscon_by_phandle, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);