aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÁlvaro Fernández Rojas2018-12-03 19:37:09 +0100
committerSimon Glass2018-12-05 06:06:44 -0700
commit7959882049a9b389c131eff9a128437ee8ebe08e (patch)
treea0b31f0e5dbf3d95ae731918a675c075614db3be
parentbb48470df21c0ce4ebed47f5dc3ea25ff02fd4dd (diff)
dm: core: add functions to get/remap I/O addresses by name
This functions allow us to get and remap I/O addresses by name, which is useful when there are multiple reg addresses indexed by reg-names property. This is needed in bmips dma/eth patch series, but can also be used on many other drivers. Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
-rw-r--r--arch/sandbox/dts/test.dts1
-rw-r--r--drivers/core/fdtaddr.c10
-rw-r--r--drivers/core/read.c20
-rw-r--r--include/dm/fdtaddr.h13
-rw-r--r--include/dm/read.h36
-rw-r--r--test/dm/test-fdt.c82
6 files changed, 160 insertions, 2 deletions
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 252aa7b6b63..6722e18bc39 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -690,6 +690,7 @@
dev@0,0 {
compatible = "denx,u-boot-fdt-dummy";
reg = <0 0x0 0x1000>;
+ reg-names = "sandbox-dummy-0";
};
dev@1,100 {
diff --git a/drivers/core/fdtaddr.c b/drivers/core/fdtaddr.c
index bfd9580050c..e113f1dd39c 100644
--- a/drivers/core/fdtaddr.c
+++ b/drivers/core/fdtaddr.c
@@ -146,6 +146,16 @@ void *devfdt_remap_addr_index(struct udevice *dev, int index)
return map_physmem(addr, 0, MAP_NOCACHE);
}
+void *devfdt_remap_addr_name(struct udevice *dev, const char *name)
+{
+ fdt_addr_t addr = devfdt_get_addr_name(dev, name);
+
+ if (addr == FDT_ADDR_T_NONE)
+ return NULL;
+
+ return map_physmem(addr, 0, MAP_NOCACHE);
+}
+
void *devfdt_remap_addr(struct udevice *dev)
{
return devfdt_remap_addr_index(dev, 0);
diff --git a/drivers/core/read.c b/drivers/core/read.c
index 96766c7876a..cdd78be03e2 100644
--- a/drivers/core/read.c
+++ b/drivers/core/read.c
@@ -69,6 +69,26 @@ void *dev_remap_addr_index(struct udevice *dev, int index)
return map_physmem(addr, 0, MAP_NOCACHE);
}
+fdt_addr_t dev_read_addr_name(struct udevice *dev, const char *name)
+{
+ int index = dev_read_stringlist_search(dev, "reg-names", name);
+
+ if (index < 0)
+ return FDT_ADDR_T_NONE;
+ else
+ return dev_read_addr_index(dev, index);
+}
+
+void *dev_remap_addr_name(struct udevice *dev, const char *name)
+{
+ fdt_addr_t addr = dev_read_addr_name(dev, name);
+
+ if (addr == FDT_ADDR_T_NONE)
+ return NULL;
+
+ return map_physmem(addr, 0, MAP_NOCACHE);
+}
+
fdt_addr_t dev_read_addr(struct udevice *dev)
{
return dev_read_addr_index(dev, 0);
diff --git a/include/dm/fdtaddr.h b/include/dm/fdtaddr.h
index 49a6ffd5f83..c171d9bc2f4 100644
--- a/include/dm/fdtaddr.h
+++ b/include/dm/fdtaddr.h
@@ -56,6 +56,19 @@ void *devfdt_remap_addr(struct udevice *dev);
void *devfdt_remap_addr_index(struct udevice *dev, int index);
/**
+ * devfdt_remap_addr_name() - Get the reg property of a device, indexed by
+ * name, as a memory-mapped I/O pointer
+ * @name: the 'reg' property can hold a list of <addr, size> pairs, with the
+ * 'reg-names' property providing named-based identification. @index
+ * indicates the value to search for in 'reg-names'.
+ *
+ * @dev: Pointer to a device
+ *
+ * @return Pointer to addr, or NULL if there is no such property
+ */
+void *devfdt_remap_addr_name(struct udevice *dev, const char *name);
+
+/**
* devfdt_map_physmem() - Read device address from reg property of the
* device node and map the address into CPU address
* space.
diff --git a/include/dm/read.h b/include/dm/read.h
index a27b8554fb1..efcbee15eca 100644
--- a/include/dm/read.h
+++ b/include/dm/read.h
@@ -125,6 +125,31 @@ fdt_addr_t dev_read_addr_index(struct udevice *dev, int index);
void *dev_remap_addr_index(struct udevice *dev, int index);
/**
+ * dev_read_addr_name() - Get the reg property of a device, indexed by name
+ *
+ * @dev: Device to read from
+ * @name: the 'reg' property can hold a list of <addr, size> pairs, with the
+ * 'reg-names' property providing named-based identification. @index
+ * indicates the value to search for in 'reg-names'.
+ *
+ * @return address or FDT_ADDR_T_NONE if not found
+ */
+fdt_addr_t dev_read_addr_name(struct udevice *dev, const char* name);
+
+/**
+ * dev_remap_addr_name() - Get the reg property of a device, indexed by name,
+ * as a memory-mapped I/O pointer
+ *
+ * @dev: Device to read from
+ * @name: the 'reg' property can hold a list of <addr, size> pairs, with the
+ * 'reg-names' property providing named-based identification. @index
+ * indicates the value to search for in 'reg-names'.
+ *
+ * @return pointer or NULL if not found
+ */
+void *dev_remap_addr_name(struct udevice *dev, const char* name);
+
+/**
* dev_read_addr() - Get the reg property of a device
*
* @dev: Device to read from
@@ -494,6 +519,12 @@ static inline fdt_addr_t dev_read_addr_index(struct udevice *dev, int index)
return devfdt_get_addr_index(dev, index);
}
+static inline fdt_addr_t dev_read_addr_name(struct udevice *dev,
+ const char *name)
+{
+ return devfdt_get_addr_name(dev, name);
+}
+
static inline fdt_addr_t dev_read_addr(struct udevice *dev)
{
return devfdt_get_addr(dev);
@@ -514,6 +545,11 @@ static inline void *dev_remap_addr_index(struct udevice *dev, int index)
return devfdt_remap_addr_index(dev, index);
}
+static inline void *dev_remap_addr_name(struct udevice *dev, const char *name)
+{
+ return devfdt_remap_addr_name(dev, name);
+}
+
static inline fdt_addr_t dev_read_addr_size(struct udevice *dev,
const char *propname,
fdt_size_t *sizep)
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index 0fbd9be765a..96d2528accb 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -490,7 +490,6 @@ static int dm_test_fdt_translation(struct unit_test_state *uts)
}
DM_TEST(dm_test_fdt_translation, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
-/* Test devfdt_remap_addr_index() */
static int dm_test_fdt_remap_addr_flat(struct unit_test_state *uts)
{
struct udevice *dev;
@@ -511,7 +510,46 @@ static int dm_test_fdt_remap_addr_flat(struct unit_test_state *uts)
DM_TEST(dm_test_fdt_remap_addr_flat,
DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE);
-/* Test dev_remap_addr_index() */
+static int dm_test_fdt_remap_addr_index_flat(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+ fdt_addr_t addr;
+ void *paddr;
+
+ ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev));
+
+ addr = devfdt_get_addr_index(dev, 0);
+ ut_asserteq(0x8000, addr);
+
+ paddr = map_physmem(addr, 0, MAP_NOCACHE);
+ ut_assertnonnull(paddr);
+ ut_asserteq_ptr(paddr, devfdt_remap_addr_index(dev, 0));
+
+ return 0;
+}
+DM_TEST(dm_test_fdt_remap_addr_index_flat,
+ DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE);
+
+static int dm_test_fdt_remap_addr_name_flat(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+ fdt_addr_t addr;
+ void *paddr;
+
+ ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev));
+
+ addr = devfdt_get_addr_name(dev, "sandbox-dummy-0");
+ ut_asserteq(0x8000, addr);
+
+ paddr = map_physmem(addr, 0, MAP_NOCACHE);
+ ut_assertnonnull(paddr);
+ ut_asserteq_ptr(paddr, devfdt_remap_addr_name(dev, "sandbox-dummy-0"));
+
+ return 0;
+}
+DM_TEST(dm_test_fdt_remap_addr_name_flat,
+ DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE);
+
static int dm_test_fdt_remap_addr_live(struct unit_test_state *uts)
{
struct udevice *dev;
@@ -532,6 +570,46 @@ static int dm_test_fdt_remap_addr_live(struct unit_test_state *uts)
DM_TEST(dm_test_fdt_remap_addr_live,
DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+static int dm_test_fdt_remap_addr_index_live(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+ fdt_addr_t addr;
+ void *paddr;
+
+ ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev));
+
+ addr = dev_read_addr_index(dev, 0);
+ ut_asserteq(0x8000, addr);
+
+ paddr = map_physmem(addr, 0, MAP_NOCACHE);
+ ut_assertnonnull(paddr);
+ ut_asserteq_ptr(paddr, dev_remap_addr_index(dev, 0));
+
+ return 0;
+}
+DM_TEST(dm_test_fdt_remap_addr_index_live,
+ DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+static int dm_test_fdt_remap_addr_name_live(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+ fdt_addr_t addr;
+ void *paddr;
+
+ ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev));
+
+ addr = dev_read_addr_name(dev, "sandbox-dummy-0");
+ ut_asserteq(0x8000, addr);
+
+ paddr = map_physmem(addr, 0, MAP_NOCACHE);
+ ut_assertnonnull(paddr);
+ ut_asserteq_ptr(paddr, dev_remap_addr_name(dev, "sandbox-dummy-0"));
+
+ return 0;
+}
+DM_TEST(dm_test_fdt_remap_addr_name_live,
+ DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
static int dm_test_fdt_livetree_writing(struct unit_test_state *uts)
{
struct udevice *dev;