summaryrefslogtreecommitdiff
path: root/drivers/core
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/core')
-rw-r--r--drivers/core/Kconfig12
-rw-r--r--drivers/core/device.c10
-rw-r--r--drivers/core/fdtaddr.c10
-rw-r--r--drivers/core/read.c20
-rw-r--r--drivers/core/root.c1
-rw-r--r--drivers/core/syscon-uclass.c23
-rw-r--r--drivers/core/uclass.c24
7 files changed, 94 insertions, 6 deletions
diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
index e8ba20ca82d..046b87a3337 100644
--- a/drivers/core/Kconfig
+++ b/drivers/core/Kconfig
@@ -57,13 +57,21 @@ config DM_DEVICE_REMOVE
default y
help
We can save some code space by dropping support for removing a
- device. This is not normally required in SPL, so by default this
- option is disabled for SPL.
+ device.
Note that this may have undesirable results in the USB subsystem as
it causes unplugged devices to linger around in the dm-tree, and it
causes USB host controllers to not be stopped when booting the OS.
+config SPL_DM_DEVICE_REMOVE
+ bool "Support device removal in SPL"
+ depends on SPL_DM
+ default n
+ help
+ We can save some code space by dropping support for removing a
+ device. This is not normally required in SPL, so by default this
+ option is disabled for SPL.
+
config DM_STDIO
bool "Support stdio registration"
depends on DM
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 836bcadced5..0d15e5062b6 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -70,7 +70,8 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
dev->seq = -1;
dev->req_seq = -1;
- if (CONFIG_IS_ENABLED(OF_CONTROL) && CONFIG_IS_ENABLED(DM_SEQ_ALIAS)) {
+ if (CONFIG_IS_ENABLED(DM_SEQ_ALIAS) &&
+ (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS)) {
/*
* Some devices, such as a SPI bus, I2C bus and serial ports
* are numbered using aliases.
@@ -78,10 +79,11 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
* This is just a 'requested' sequence, and will be
* resolved (and ->seq updated) when the device is probed.
*/
- if (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS) {
- if (uc->uc_drv->name && ofnode_valid(node)) {
+ if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) {
+ if (uc->uc_drv->name && ofnode_valid(node))
dev_read_alias_seq(dev, &dev->req_seq);
- }
+ } else {
+ dev->req_seq = uclass_find_next_free_req_seq(drv->id);
}
}
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/drivers/core/root.c b/drivers/core/root.c
index 4ce55f9cc89..e6ec7faf379 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -187,6 +187,7 @@ int dm_uninit(void)
{
device_remove(dm_root(), DM_REMOVE_NORMAL);
device_unbind(dm_root());
+ gd->dm_root = NULL;
return 0;
}
diff --git a/drivers/core/syscon-uclass.c b/drivers/core/syscon-uclass.c
index 303e166a69c..661cf61d62a 100644
--- a/drivers/core/syscon-uclass.c
+++ b/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;
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 9766aeabd19..a622f079410 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -269,6 +269,30 @@ int uclass_find_device_by_name(enum uclass_id id, const char *name,
return -ENODEV;
}
+#if !CONFIG_IS_ENABLED(OF_CONTROL) || CONFIG_IS_ENABLED(OF_PLATDATA)
+int uclass_find_next_free_req_seq(enum uclass_id id)
+{
+ struct uclass *uc;
+ struct udevice *dev;
+ int ret;
+ int max = -1;
+
+ ret = uclass_get(id, &uc);
+ if (ret)
+ return ret;
+
+ list_for_each_entry(dev, &uc->dev_head, uclass_node) {
+ if ((dev->req_seq != -1) && (dev->req_seq > max))
+ max = dev->req_seq;
+ }
+
+ if (max == -1)
+ return 0;
+
+ return max + 1;
+}
+#endif
+
int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq,
bool find_req_seq, struct udevice **devp)
{