diff options
Diffstat (limited to 'drivers/core')
-rw-r--r-- | drivers/core/Kconfig | 12 | ||||
-rw-r--r-- | drivers/core/device.c | 10 | ||||
-rw-r--r-- | drivers/core/fdtaddr.c | 10 | ||||
-rw-r--r-- | drivers/core/read.c | 20 | ||||
-rw-r--r-- | drivers/core/root.c | 1 | ||||
-rw-r--r-- | drivers/core/syscon-uclass.c | 23 | ||||
-rw-r--r-- | drivers/core/uclass.c | 24 |
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) { |