summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/core/Kconfig14
-rw-r--r--drivers/core/fdtaddr.c6
-rw-r--r--drivers/core/of_access.c65
-rw-r--r--drivers/core/ofnode.c183
-rw-r--r--drivers/core/read.c6
-rw-r--r--drivers/core/util.c2
-rw-r--r--drivers/misc/cros_ec_sandbox.c9
-rw-r--r--drivers/pci/pci-uclass.c2
-rw-r--r--drivers/pci/pci_mvebu.c3
-rw-r--r--drivers/pci/pci_tegra.c2
-rw-r--r--drivers/pci/pcie_mediatek.c4
-rw-r--r--drivers/serial/Kconfig2
-rw-r--r--drivers/serial/ns16550.c21
13 files changed, 282 insertions, 37 deletions
diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
index f0d848f45d8..fe5c41d57ec 100644
--- a/drivers/core/Kconfig
+++ b/drivers/core/Kconfig
@@ -14,7 +14,7 @@ config SPL_DM
help
Enable driver model in SPL. You will need to provide a
suitable malloc() implementation. If you are not using the
- full malloc() enabled by CFG_SYS_SPL_MALLOC_START,
+ full malloc() enabled by CFG_SPL_SYS_MALLOC_START,
consider using CONFIG_SPL_SYS_MALLOC_SIMPLE. In that case you
must provide CONFIG_SPL_SYS_MALLOC_F_LEN to set the size.
In most cases driver model will only allocate a few uclasses
@@ -27,12 +27,12 @@ config TPL_DM
help
Enable driver model in TPL. You will need to provide a
suitable malloc() implementation. If you are not using the
- full malloc() enabled by CFG_SYS_SPL_MALLOC_START,
+ full malloc() enabled by CFG_TPL_SYS_MALLOC_START,
consider using CONFIG_TPL_SYS_MALLOC_SIMPLE. In that case you
- must provide CONFIG_SPL_SYS_MALLOC_F_LEN to set the size.
+ must provide CONFIG_TPL_SYS_MALLOC_F_LEN to set the size.
In most cases driver model will only allocate a few uclasses
- and devices in SPL, so 1KB should be enough. See
- CONFIG_SPL_SYS_MALLOC_F_LEN for more details on how to enable it.
+ and devices in TPL, so 1KB should be enough. See
+ CONFIG_TPL_SYS_MALLOC_F_LEN for more details on how to enable it.
Disable this for very small implementations.
config VPL_DM
@@ -42,8 +42,8 @@ config VPL_DM
help
Enable driver model in VPL. You will need to provide a
suitable malloc() implementation. If you are not using the
- full malloc() enabled by CFG_SYS_SPL_MALLOC_START,
- consider using CONFIG_SPL_SYS_MALLOC_SIMPLE.
+ full malloc() enabled by CFG_TPL_SYS_MALLOC_START,
+ consider using CONFIG_TPL_SYS_MALLOC_SIMPLE.
config DM_WARN
bool "Enable warnings in driver model"
diff --git a/drivers/core/fdtaddr.c b/drivers/core/fdtaddr.c
index 546db675aaf..b79d138c419 100644
--- a/drivers/core/fdtaddr.c
+++ b/drivers/core/fdtaddr.c
@@ -215,7 +215,7 @@ void *devfdt_map_physmem(const struct udevice *dev, unsigned long size)
return map_physmem(addr, size, MAP_NOCACHE);
}
-fdt_addr_t devfdt_get_addr_pci(const struct udevice *dev)
+fdt_addr_t devfdt_get_addr_pci(const struct udevice *dev, fdt_size_t *sizep)
{
ulong addr;
@@ -226,12 +226,12 @@ fdt_addr_t devfdt_get_addr_pci(const struct udevice *dev)
int ret;
ret = ofnode_read_pci_addr(dev_ofnode(dev), FDT_PCI_SPACE_MEM32,
- "reg", &pci_addr);
+ "reg", &pci_addr, sizep);
if (ret) {
/* try if there is any i/o-mapped register */
ret = ofnode_read_pci_addr(dev_ofnode(dev),
FDT_PCI_SPACE_IO, "reg",
- &pci_addr);
+ &pci_addr, sizep);
if (ret)
return FDT_ADDR_T_NONE;
}
diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c
index 1bb4d8eab70..c8db743f529 100644
--- a/drivers/core/of_access.c
+++ b/drivers/core/of_access.c
@@ -1040,3 +1040,68 @@ int of_add_subnode(struct device_node *parent, const char *name, int len,
return 0;
}
+
+int __of_remove_property(struct device_node *np, struct property *prop)
+{
+ struct property **next;
+
+ for (next = &np->properties; *next; next = &(*next)->next) {
+ if (*next == prop)
+ break;
+ }
+ if (!*next)
+ return -ENODEV;
+
+ /* found the node */
+ *next = prop->next;
+
+ return 0;
+}
+
+int of_remove_property(struct device_node *np, struct property *prop)
+{
+ int rc;
+
+ mutex_lock(&of_mutex);
+
+ rc = __of_remove_property(np, prop);
+
+ mutex_unlock(&of_mutex);
+
+ return rc;
+}
+
+int of_remove_node(struct device_node *to_remove)
+{
+ struct device_node *parent = to_remove->parent;
+ struct device_node *np, *prev;
+
+ if (!parent)
+ return -EPERM;
+ prev = NULL;
+ __for_each_child_of_node(parent, np) {
+ if (np == to_remove)
+ break;
+ prev = np;
+ }
+ if (!np)
+ return -EFAULT;
+
+ /* if there is a previous node, link it to this one's sibling */
+ if (prev)
+ prev->sibling = np->sibling;
+ else
+ parent->child = np->sibling;
+
+ /*
+ * don't free it, since if this is an unflattened tree, all the memory
+ * was alloced in one block; this pointer will be somewhere in the
+ * middle of that
+ *
+ * TODO(sjg@chromium.org): Consider marking nodes as 'allocated'?
+ *
+ * free(np);
+ */
+
+ return 0;
+}
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index 2cafa7bca5b..29a42945102 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -47,6 +47,17 @@ static int oftree_find(const void *fdt)
return -1;
}
+static int check_tree_count(void)
+{
+ if (oftree_count == CONFIG_OFNODE_MULTI_TREE_MAX) {
+ log_warning("Too many registered device trees (max %d)\n",
+ CONFIG_OFNODE_MULTI_TREE_MAX);
+ return -E2BIG;
+ }
+
+ return 0;
+}
+
static oftree oftree_ensure(void *fdt)
{
oftree tree;
@@ -69,11 +80,8 @@ static oftree oftree_ensure(void *fdt)
if (gd->flags & GD_FLG_RELOC) {
i = oftree_find(fdt);
if (i == -1) {
- if (oftree_count == CONFIG_OFNODE_MULTI_TREE_MAX) {
- log_warning("Too many registered device trees (max %d)\n",
- CONFIG_OFNODE_MULTI_TREE_MAX);
+ if (check_tree_count())
return oftree_null();
- }
/* register the new tree */
i = oftree_count++;
@@ -92,6 +100,41 @@ static oftree oftree_ensure(void *fdt)
return tree;
}
+int oftree_new(oftree *treep)
+{
+ oftree tree = oftree_null();
+ int ret;
+
+ if (of_live_active()) {
+ struct device_node *root;
+
+ ret = of_live_create_empty(&root);
+ if (ret)
+ return log_msg_ret("liv", ret);
+ tree = oftree_from_np(root);
+ } else {
+ const int size = 1024;
+ void *fdt;
+
+ ret = check_tree_count();
+ if (ret)
+ return log_msg_ret("fla", ret);
+
+ /* register the new tree with a small size */
+ fdt = malloc(size);
+ if (!fdt)
+ return log_msg_ret("fla", -ENOMEM);
+ ret = fdt_create_empty_tree(fdt, size);
+ if (ret)
+ return log_msg_ret("fla", -EINVAL);
+ oftree_list[oftree_count++] = fdt;
+ tree.fdt = fdt;
+ }
+ *treep = tree;
+
+ return 0;
+}
+
void oftree_dispose(oftree tree)
{
if (of_live_active())
@@ -193,8 +236,31 @@ static inline int oftree_find(const void *fdt)
return 0;
}
+int oftree_new(oftree *treep)
+{
+ return -ENOSYS;
+}
+
#endif /* OFNODE_MULTI_TREE */
+int oftree_to_fdt(oftree tree, struct abuf *buf)
+{
+ int ret;
+
+ if (of_live_active()) {
+ ret = of_live_flatten(ofnode_to_np(oftree_root(tree)), buf);
+ if (ret)
+ return log_msg_ret("flt", ret);
+ } else {
+ void *fdt = oftree_lookup_fdt(tree);
+
+ abuf_init(buf);
+ abuf_set(buf, fdt, fdt_totalsize(fdt));
+ }
+
+ return 0;
+}
+
/**
* ofnode_from_tree_offset() - get an ofnode from a tree offset (flat tree)
*
@@ -425,12 +491,12 @@ u64 ofnode_read_u64_default(ofnode node, const char *propname, u64 def)
bool ofnode_read_bool(ofnode node, const char *propname)
{
- const void *prop;
+ bool prop;
assert(ofnode_valid(node));
debug("%s: %s: ", __func__, propname);
- prop = ofnode_get_property(node, propname, NULL);
+ prop = ofnode_has_property(node, propname);
debug("%s\n", prop ? "true" : "false");
@@ -1102,6 +1168,14 @@ const void *ofnode_get_property(ofnode node, const char *propname, int *lenp)
propname, lenp);
}
+bool ofnode_has_property(ofnode node, const char *propname)
+{
+ if (ofnode_is_np(node))
+ return of_find_property(ofnode_to_np(node), propname, NULL);
+ else
+ return ofnode_get_property(node, propname, NULL);
+}
+
int ofnode_first_property(ofnode node, struct ofprop *prop)
{
prop->node = node;
@@ -1196,7 +1270,8 @@ const uint8_t *ofnode_read_u8_array_ptr(ofnode node, const char *propname,
}
int ofnode_read_pci_addr(ofnode node, enum fdt_pci_space type,
- const char *propname, struct fdt_pci_addr *addr)
+ const char *propname, struct fdt_pci_addr *addr,
+ fdt_size_t *size)
{
const fdt32_t *cell;
int len;
@@ -1224,14 +1299,18 @@ int ofnode_read_pci_addr(ofnode node, enum fdt_pci_space type,
(ulong)fdt32_to_cpu(cell[1]),
(ulong)fdt32_to_cpu(cell[2]));
if ((fdt32_to_cpu(*cell) & type) == type) {
+ const unaligned_fdt64_t *ptr;
+
addr->phys_hi = fdt32_to_cpu(cell[0]);
addr->phys_mid = fdt32_to_cpu(cell[1]);
addr->phys_lo = fdt32_to_cpu(cell[2]);
+ ptr = (const unaligned_fdt64_t *)(cell + 3);
+ if (size)
+ *size = fdt64_to_cpu(*ptr);
break;
}
- cell += (FDT_PCI_ADDR_CELLS +
- FDT_PCI_SIZE_CELLS);
+ cell += FDT_PCI_ADDR_CELLS + FDT_PCI_SIZE_CELLS;
}
if (i == num) {
@@ -1547,7 +1626,46 @@ int ofnode_write_u32(ofnode node, const char *propname, u32 value)
return -ENOMEM;
*val = cpu_to_fdt32(value);
- return ofnode_write_prop(node, propname, val, sizeof(value), false);
+ return ofnode_write_prop(node, propname, val, sizeof(value), true);
+}
+
+int ofnode_write_u64(ofnode node, const char *propname, u64 value)
+{
+ fdt64_t *val;
+
+ assert(ofnode_valid(node));
+
+ log_debug("%s = %llx", propname, (unsigned long long)value);
+ val = malloc(sizeof(*val));
+ if (!val)
+ return -ENOMEM;
+ *val = cpu_to_fdt64(value);
+
+ return ofnode_write_prop(node, propname, val, sizeof(value), true);
+}
+
+int ofnode_write_bool(ofnode node, const char *propname, bool value)
+{
+ if (value)
+ return ofnode_write_prop(node, propname, NULL, 0, false);
+ else
+ return ofnode_delete_prop(node, propname);
+}
+
+int ofnode_delete_prop(ofnode node, const char *propname)
+{
+ if (ofnode_is_np(node)) {
+ struct property *prop;
+ int len;
+
+ prop = of_find_property(ofnode_to_np(node), propname, &len);
+ if (prop)
+ return of_remove_property(ofnode_to_np(node), prop);
+ return 0;
+ } else {
+ return fdt_delprop(ofnode_to_fdt(node), ofnode_to_offset(node),
+ propname);
+ }
}
int ofnode_set_enabled(ofnode node, bool value)
@@ -1731,7 +1849,30 @@ int ofnode_add_subnode(ofnode node, const char *name, ofnode *subnodep)
return ret; /* 0 or -EEXIST */
}
-int ofnode_copy_props(ofnode src, ofnode dst)
+int ofnode_delete(ofnode *nodep)
+{
+ ofnode node = *nodep;
+ int ret;
+
+ assert(ofnode_valid(node));
+ if (ofnode_is_np(node)) {
+ ret = of_remove_node(ofnode_to_np(node));
+ } else {
+ void *fdt = ofnode_to_fdt(node);
+ int offset = ofnode_to_offset(node);
+
+ ret = fdt_del_node(fdt, offset);
+ if (ret)
+ ret = -EFAULT;
+ }
+ if (ret)
+ return ret;
+ *nodep = ofnode_null();
+
+ return 0;
+}
+
+int ofnode_copy_props(ofnode dst, ofnode src)
{
struct ofprop prop;
@@ -1754,3 +1895,23 @@ int ofnode_copy_props(ofnode src, ofnode dst)
return 0;
}
+
+int ofnode_copy_node(ofnode dst_parent, const char *name, ofnode src,
+ ofnode *nodep)
+{
+ ofnode node;
+ int ret;
+
+ ret = ofnode_add_subnode(dst_parent, name, &node);
+ if (ret) {
+ if (ret == -EEXIST)
+ *nodep = node;
+ return log_msg_ret("add", ret);
+ }
+ ret = ofnode_copy_props(node, src);
+ if (ret)
+ return log_msg_ret("cpy", ret);
+ *nodep = node;
+
+ return 0;
+}
diff --git a/drivers/core/read.c b/drivers/core/read.c
index 49066b59cda..419013451f0 100644
--- a/drivers/core/read.c
+++ b/drivers/core/read.c
@@ -405,13 +405,15 @@ int dev_read_alias_highest_id(const char *stem)
return fdtdec_get_alias_highest_id(gd->fdt_blob, stem);
}
-fdt_addr_t dev_read_addr_pci(const struct udevice *dev)
+fdt_addr_t dev_read_addr_pci(const struct udevice *dev, fdt_size_t *sizep)
{
ulong addr;
addr = dev_read_addr(dev);
+ if (sizep)
+ *sizep = 0;
if (addr == FDT_ADDR_T_NONE && !of_live_active())
- addr = devfdt_get_addr_pci(dev);
+ addr = devfdt_get_addr_pci(dev, sizep);
return addr;
}
diff --git a/drivers/core/util.c b/drivers/core/util.c
index aa60fdd15bc..81497df85ff 100644
--- a/drivers/core/util.c
+++ b/drivers/core/util.c
@@ -30,7 +30,7 @@ int pci_get_devfn(struct udevice *dev)
/* Extract the devfn from fdt_pci_addr */
ret = ofnode_read_pci_addr(dev_ofnode(dev), FDT_PCI_SPACE_CONFIG,
- "reg", &addr);
+ "reg", &addr, NULL);
if (ret) {
if (ret != -ENOENT)
return -EINVAL;
diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c
index 8dbe0b188a4..1201535f4af 100644
--- a/drivers/misc/cros_ec_sandbox.c
+++ b/drivers/misc/cros_ec_sandbox.c
@@ -81,6 +81,7 @@ struct ec_pwm_channel {
/**
* struct ec_state - Information about the EC state
*
+ * @valid: true if this struct contains valid state data
* @vbnv_context: Vboot context data stored by EC
* @ec_config: FDT config information about the EC (e.g. flashmap)
* @flash_data: Contents of flash memory
@@ -95,6 +96,7 @@ struct ec_pwm_channel {
* @pwm: Information per PWM channel
*/
struct ec_state {
+ bool valid;
u8 vbnv_context[EC_VBNV_BLOCK_SIZE_V2];
struct fdt_cros_ec ec_config;
uint8_t *flash_data;
@@ -145,6 +147,7 @@ static int cros_ec_read_state(const void *blob, int node)
memcpy(ec->flash_data, prop, len);
debug("%s: Loaded EC flash data size %#x\n", __func__, len);
}
+ ec->valid = true;
return 0;
}
@@ -589,6 +592,7 @@ static int process_cmd(struct ec_state *ec,
printf(" ** Unknown EC command %#02x\n", req_hdr->command);
return -1;
}
+ debug(" - EC command %#0x, result %d\n", req_hdr->command, len);
return len;
}
@@ -675,7 +679,10 @@ int cros_ec_probe(struct udevice *dev)
ofnode node;
int err;
- memcpy(ec, &s_state, sizeof(*ec));
+ if (s_state.valid)
+ memcpy(ec, &s_state, sizeof(*ec));
+ else
+ ec->current_image = EC_IMAGE_RO;
err = cros_ec_decode_ec_flash(dev, &ec->ec_config);
if (err) {
debug("%s: Cannot device EC flash\n", __func__);
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index ae7350aaff9..e0d01f6a85d 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -123,7 +123,7 @@ static void pci_dev_find_ofnode(struct udevice *bus, phys_addr_t bdf,
dev_for_each_subnode(node, bus) {
ret = ofnode_read_pci_addr(node, FDT_PCI_SPACE_CONFIG, "reg",
- &addr);
+ &addr, NULL);
if (ret)
continue;
diff --git a/drivers/pci/pci_mvebu.c b/drivers/pci/pci_mvebu.c
index 3697cd8d652..83559550e6f 100644
--- a/drivers/pci/pci_mvebu.c
+++ b/drivers/pci/pci_mvebu.c
@@ -641,7 +641,8 @@ static int mvebu_pcie_port_parse_dt(ofnode node, ofnode parent, struct mvebu_pci
pcie->is_x4 = true;
/* devfn is in bits [15:8], see PCI_DEV usage */
- ret = ofnode_read_pci_addr(node, FDT_PCI_SPACE_CONFIG, "reg", &pci_addr);
+ ret = ofnode_read_pci_addr(node, FDT_PCI_SPACE_CONFIG, "reg", &pci_addr,
+ NULL);
if (ret < 0) {
printf("%s: property \"reg\" is invalid\n", pcie->name);
goto err;
diff --git a/drivers/pci/pci_tegra.c b/drivers/pci/pci_tegra.c
index 131c21b7684..d6374a58e33 100644
--- a/drivers/pci/pci_tegra.c
+++ b/drivers/pci/pci_tegra.c
@@ -462,7 +462,7 @@ static int tegra_pcie_parse_port_info(ofnode node, uint *index, uint *lanes)
*lanes = err;
- err = ofnode_read_pci_addr(node, 0, "reg", &addr);
+ err = ofnode_read_pci_addr(node, 0, "reg", &addr, NULL);
if (err < 0) {
pr_err("failed to parse \"reg\" property\n");
return err;
diff --git a/drivers/pci/pcie_mediatek.c b/drivers/pci/pcie_mediatek.c
index ed25a10bcf0..f0f34b5d119 100644
--- a/drivers/pci/pcie_mediatek.c
+++ b/drivers/pci/pcie_mediatek.c
@@ -661,7 +661,7 @@ static int mtk_pcie_probe(struct udevice *dev)
if (!ofnode_is_enabled(subnode))
continue;
- err = ofnode_read_pci_addr(subnode, 0, "reg", &addr);
+ err = ofnode_read_pci_addr(subnode, 0, "reg", &addr, NULL);
if (err)
return err;
@@ -700,7 +700,7 @@ static int mtk_pcie_probe_v2(struct udevice *dev)
if (!ofnode_is_enabled(subnode))
continue;
- err = ofnode_read_pci_addr(subnode, 0, "reg", &addr);
+ err = ofnode_read_pci_addr(subnode, 0, "reg", &addr, NULL);
if (err)
return err;
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 6cb6598f3d2..9f0f84c9b42 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -160,7 +160,6 @@ config SERIAL_PROBE_ALL
config SPL_DM_SERIAL
bool "Enable Driver Model for serial drivers in SPL"
depends on DM_SERIAL && SPL_DM
- select SYS_SPL_MALLOC_F
default y
help
Enable driver model for serial in SPL. This replaces
@@ -171,7 +170,6 @@ config SPL_DM_SERIAL
config TPL_DM_SERIAL
bool "Enable Driver Model for serial drivers in TPL"
depends on DM_SERIAL && TPL_DM
- select SYS_TPL_MALLOC_F
default y if TPL && DM_SERIAL
help
Enable driver model for serial in TPL. This replaces
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index eab9537fbae..6deb1d8ddc5 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -13,6 +13,7 @@
#include <ns16550.h>
#include <reset.h>
#include <serial.h>
+#include <spl.h>
#include <watchdog.h>
#include <asm/global_data.h>
#include <linux/err.h>
@@ -472,6 +473,10 @@ static int ns16550_serial_getinfo(struct udevice *dev,
struct ns16550 *const com_port = dev_get_priv(dev);
struct ns16550_plat *plat = com_port->plat;
+ /* save code size */
+ if (!spl_in_proper())
+ return -ENOSYS;
+
info->type = SERIAL_CHIP_16550_COMPATIBLE;
#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
info->addr_space = SERIAL_ADDRESS_SPACE_IO;
@@ -479,6 +484,7 @@ static int ns16550_serial_getinfo(struct udevice *dev,
info->addr_space = SERIAL_ADDRESS_SPACE_MEMORY;
#endif
info->addr = plat->base;
+ info->size = plat->size;
info->reg_width = plat->reg_width;
info->reg_shift = plat->reg_shift;
info->reg_offset = plat->reg_offset;
@@ -487,7 +493,8 @@ static int ns16550_serial_getinfo(struct udevice *dev,
return 0;
}
-static int ns16550_serial_assign_base(struct ns16550_plat *plat, fdt_addr_t base)
+static int ns16550_serial_assign_base(struct ns16550_plat *plat,
+ fdt_addr_t base, fdt_size_t size)
{
if (base == FDT_ADDR_T_NONE)
return -EINVAL;
@@ -497,6 +504,7 @@ static int ns16550_serial_assign_base(struct ns16550_plat *plat, fdt_addr_t base
#else
plat->base = (unsigned long)map_physmem(base, 0, MAP_NOCACHE);
#endif
+ plat->size = size;
return 0;
}
@@ -507,6 +515,7 @@ int ns16550_serial_probe(struct udevice *dev)
struct ns16550 *const com_port = dev_get_priv(dev);
struct reset_ctl_bulk reset_bulk;
fdt_addr_t addr;
+ fdt_addr_t size;
int ret;
/*
@@ -514,8 +523,8 @@ int ns16550_serial_probe(struct udevice *dev)
* or via a PCI bridge, assign plat->base before probing hardware.
*/
if (device_is_on_pci_bus(dev)) {
- addr = devfdt_get_addr_pci(dev);
- ret = ns16550_serial_assign_base(plat, addr);
+ addr = devfdt_get_addr_pci(dev, &size);
+ ret = ns16550_serial_assign_base(plat, addr, size);
if (ret)
return ret;
}
@@ -542,12 +551,14 @@ int ns16550_serial_of_to_plat(struct udevice *dev)
{
struct ns16550_plat *plat = dev_get_plat(dev);
const u32 port_type = dev_get_driver_data(dev);
+ fdt_size_t size = 0;
fdt_addr_t addr;
struct clk clk;
int err;
- addr = dev_read_addr(dev);
- err = ns16550_serial_assign_base(plat, addr);
+ addr = spl_in_proper() ? dev_read_addr_size(dev, &size) :
+ dev_read_addr(dev);
+ err = ns16550_serial_assign_base(plat, addr, size);
if (err && !device_is_on_pci_bus(dev))
return err;