of-platdata and dtoc improvements
sandbox SPL tests
binman support for compressed sections
This commit is contained in:
Tom Rini
2020-10-30 15:24:30 -04:00
89 changed files with 1861 additions and 502 deletions

View File

@@ -38,8 +38,7 @@ int clk_get_by_driver_info(struct udevice *dev, struct phandle_1_arg *cells,
{
int ret;
ret = device_get_by_driver_info((struct driver_info *)cells->node,
&clk->dev);
ret = device_get_by_driver_info_idx(cells->idx, &clk->dev);
if (ret)
return ret;
clk->id = cells->arg[0];

View File

@@ -46,8 +46,8 @@ static const struct udevice_id clk_fixed_rate_match[] = {
{ /* sentinel */ }
};
U_BOOT_DRIVER(clk_fixed_rate) = {
.name = "fixed_rate_clock",
U_BOOT_DRIVER(fixed_clock) = {
.name = "fixed_clock",
.id = UCLASS_CLK,
.of_match = clk_fixed_rate_match,
.ofdata_to_platdata = clk_fixed_rate_ofdata_to_platdata,

View File

@@ -124,8 +124,8 @@ static const struct udevice_id sandbox_clk_ids[] = {
{ }
};
U_BOOT_DRIVER(clk_sandbox) = {
.name = "clk_sandbox",
U_BOOT_DRIVER(sandbox_clk) = {
.name = "sandbox_clk",
.id = UCLASS_CLK,
.of_match = sandbox_clk_ids,
.ops = &sandbox_clk_ops,

View File

@@ -40,10 +40,24 @@ config DM_WARN
depends on DM
default y
help
Enable this to see warnings related to driver model.
Warnings may help with debugging, such as when expected devices do
not bind correctly. If the option is disabled, dm_warn() is compiled
out - it will do nothing when called.
config SPL_DM_WARN
bool "Enable warnings in driver model wuth SPL"
depends on SPL_DM
help
Enable this to see warnings related to driver model in SPL
The dm_warn() function can use up quite a bit of space for its
strings. By default this is disabled for SPL builds to save space.
This will cause dm_warn() to be compiled out - it will do nothing
when called.
Warnings may help with debugging, such as when expected devices do
not bind correctly. If the option is disabled, dm_warn() is compiled
out - it will do nothing when called.
config DM_DEBUG
bool "Enable debug messages in driver model core"

View File

@@ -11,7 +11,7 @@ obj-$(CONFIG_SIMPLE_PM_BUS) += simple-pm-bus.o
obj-$(CONFIG_DM) += dump.o
obj-$(CONFIG_$(SPL_TPL_)REGMAP) += regmap.o
obj-$(CONFIG_$(SPL_TPL_)SYSCON) += syscon-uclass.o
obj-$(CONFIG_OF_LIVE) += of_access.o of_addr.o
obj-$(CONFIG_$(SPL_)OF_LIVE) += of_access.o of_addr.o
ifndef CONFIG_DM_DEV_READ_INLINE
obj-$(CONFIG_OF_CONTROL) += read.o
endif

View File

@@ -249,7 +249,7 @@ int device_bind_ofnode(struct udevice *parent, const struct driver *drv,
}
int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
struct driver_info *info, struct udevice **devp)
const struct driver_info *info, struct udevice **devp)
{
struct driver *drv;
uint platdata_size = 0;
@@ -269,9 +269,6 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
platdata_size, devp);
if (ret)
return ret;
#if CONFIG_IS_ENABLED(OF_PLATDATA)
info->dev = *devp;
#endif
return ret;
}
@@ -764,9 +761,25 @@ int device_get_global_by_ofnode(ofnode ofnode, struct udevice **devp)
int device_get_by_driver_info(const struct driver_info *info,
struct udevice **devp)
{
struct driver_info *info_base =
ll_entry_start(struct driver_info, driver_info);
int idx = info - info_base;
struct driver_rt *drt = gd_dm_driver_rt() + idx;
struct udevice *dev;
dev = info->dev;
dev = drt->dev;
*devp = NULL;
return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp);
}
int device_get_by_driver_info_idx(uint idx, struct udevice **devp)
{
struct driver_rt *drt = gd_dm_driver_rt() + idx;
struct udevice *dev;
dev = drt->dev;
*devp = NULL;
return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp);
}

View File

@@ -51,25 +51,81 @@ struct uclass_driver *lists_uclass_lookup(enum uclass_id id)
return NULL;
}
int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only)
static int bind_drivers_pass(struct udevice *parent, bool pre_reloc_only)
{
struct driver_info *info =
ll_entry_start(struct driver_info, driver_info);
const int n_ents = ll_entry_count(struct driver_info, driver_info);
struct driver_info *entry;
struct udevice *dev;
bool missing_parent = false;
int result = 0;
int ret;
uint idx;
for (entry = info; entry != info + n_ents; entry++) {
ret = device_bind_by_name(parent, pre_reloc_only, entry, &dev);
if (ret && ret != -EPERM) {
/*
* Do one iteration through the driver_info records. For of-platdata,
* bind only devices whose parent is already bound. If we find any
* device we can't bind, set missing_parent to true, which will cause
* this function to be called again.
*/
for (idx = 0; idx < n_ents; idx++) {
struct udevice *par = parent;
const struct driver_info *entry = info + idx;
struct driver_rt *drt = gd_dm_driver_rt() + idx;
struct udevice *dev;
int ret;
if (CONFIG_IS_ENABLED(OF_PLATDATA)) {
int parent_idx = driver_info_parent_id(entry);
if (drt->dev)
continue;
if (CONFIG_IS_ENABLED(OF_PLATDATA_PARENT) &&
parent_idx != -1) {
struct driver_rt *parent_drt;
parent_drt = gd_dm_driver_rt() + parent_idx;
if (!parent_drt->dev) {
missing_parent = true;
continue;
}
par = parent_drt->dev;
}
}
ret = device_bind_by_name(par, pre_reloc_only, entry, &dev);
if (!ret) {
if (CONFIG_IS_ENABLED(OF_PLATDATA))
drt->dev = dev;
} else if (ret != -EPERM) {
dm_warn("No match for driver '%s'\n", entry->name);
if (!result || ret != -ENOENT)
result = ret;
}
}
return result ? result : missing_parent ? -EAGAIN : 0;
}
int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only)
{
int result = 0;
int pass;
/*
* 10 passes is 10 levels deep in the devicetree, which is plenty. If
* OF_PLATDATA_PARENT is not enabled, then bind_drivers_pass() will
* always succeed on the first pass.
*/
for (pass = 0; pass < 10; pass++) {
int ret;
ret = bind_drivers_pass(parent, pre_reloc_only);
if (!ret)
break;
if (ret != -EAGAIN && !result)
result = ret;
}
return result;
}

View File

@@ -50,7 +50,6 @@ void dm_fixup_for_gd_move(struct global_data *new_gd)
}
}
#if defined(CONFIG_NEEDS_MANUAL_RELOC)
void fix_drivers(void)
{
struct driver *drv =
@@ -61,7 +60,7 @@ void fix_drivers(void)
for (entry = drv; entry != drv + n_ents; entry++) {
if (entry->of_match)
entry->of_match = (const struct udevice_id *)
((u32)entry->of_match + gd->reloc_off);
((ulong)entry->of_match + gd->reloc_off);
if (entry->bind)
entry->bind += gd->reloc_off;
if (entry->probe)
@@ -129,8 +128,6 @@ void fix_devices(void)
}
}
#endif
int dm_init(bool of_live)
{
int ret;
@@ -141,21 +138,19 @@ int dm_init(bool of_live)
}
INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST);
#if defined(CONFIG_NEEDS_MANUAL_RELOC)
fix_drivers();
fix_uclass();
fix_devices();
#endif
if (IS_ENABLED(CONFIG_NEEDS_MANUAL_RELOC)) {
fix_drivers();
fix_uclass();
fix_devices();
}
ret = device_bind_by_name(NULL, false, &root_info, &DM_ROOT_NON_CONST);
if (ret)
return ret;
#if CONFIG_IS_ENABLED(OF_CONTROL)
# if CONFIG_IS_ENABLED(OF_LIVE)
if (of_live)
DM_ROOT_NON_CONST->node = np_to_ofnode(gd->of_root);
if (CONFIG_IS_ENABLED(OF_LIVE) && of_live)
DM_ROOT_NON_CONST->node = np_to_ofnode(gd_of_root());
else
#endif
DM_ROOT_NON_CONST->node = offset_to_ofnode(0);
#endif
ret = device_probe(DM_ROOT_NON_CONST);
@@ -187,6 +182,17 @@ int dm_scan_platdata(bool pre_reloc_only)
{
int ret;
if (CONFIG_IS_ENABLED(OF_PLATDATA)) {
struct driver_rt *dyn;
int n_ents;
n_ents = ll_entry_count(struct driver_info, driver_info);
dyn = calloc(n_ents, sizeof(struct driver_rt));
if (!dyn)
return -ENOMEM;
gd_set_dm_driver_rt(dyn);
}
ret = lists_bind_drivers(DM_ROOT_NON_CONST, pre_reloc_only);
if (ret == -ENOENT) {
dm_warn("Some drivers were not found\n");
@@ -196,7 +202,7 @@ int dm_scan_platdata(bool pre_reloc_only)
return ret;
}
#if CONFIG_IS_ENABLED(OF_LIVE)
#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
static int dm_scan_fdt_live(struct udevice *parent,
const struct device_node *node_parent,
bool pre_reloc_only)
@@ -223,9 +229,7 @@ static int dm_scan_fdt_live(struct udevice *parent,
return ret;
}
#endif /* CONFIG_IS_ENABLED(OF_LIVE) */
#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
/**
* dm_scan_fdt_node() - Scan the device tree and bind drivers for a node
*
@@ -272,24 +276,20 @@ int dm_scan_fdt_dev(struct udevice *dev)
if (!dev_of_valid(dev))
return 0;
#if CONFIG_IS_ENABLED(OF_LIVE)
if (of_live_active())
return dm_scan_fdt_live(dev, dev_np(dev),
gd->flags & GD_FLG_RELOC ? false : true);
else
#endif
return dm_scan_fdt_node(dev, gd->fdt_blob, dev_of_offset(dev),
gd->flags & GD_FLG_RELOC ? false : true);
}
int dm_scan_fdt(const void *blob, bool pre_reloc_only)
{
#if CONFIG_IS_ENABLED(OF_LIVE)
if (of_live_active())
return dm_scan_fdt_live(gd->dm_root, gd->of_root,
return dm_scan_fdt_live(gd->dm_root, gd_of_root(),
pre_reloc_only);
else
#endif
return dm_scan_fdt_node(gd->dm_root, blob, 0, pre_reloc_only);
}
@@ -302,10 +302,9 @@ static int dm_scan_fdt_ofnode_path(const void *blob, const char *path,
if (!ofnode_valid(node))
return 0;
#if CONFIG_IS_ENABLED(OF_LIVE)
if (of_live_active())
return dm_scan_fdt_live(gd->dm_root, node.np, pre_reloc_only);
#endif
return dm_scan_fdt_node(gd->dm_root, blob, node.of_offset,
pre_reloc_only);
}
@@ -348,11 +347,10 @@ int dm_init_and_scan(bool pre_reloc_only)
{
int ret;
#if CONFIG_IS_ENABLED(OF_PLATDATA)
dm_populate_phandle_data();
#endif
if (CONFIG_IS_ENABLED(OF_PLATDATA))
dm_populate_phandle_data();
ret = dm_init(IS_ENABLED(CONFIG_OF_LIVE));
ret = dm_init(CONFIG_IS_ENABLED(OF_LIVE));
if (ret) {
debug("dm_init() failed: %d\n", ret);
return ret;

View File

@@ -11,7 +11,7 @@
#include <linux/libfdt.h>
#include <vsprintf.h>
#ifdef CONFIG_DM_WARN
#if CONFIG_IS_ENABLED(DM_WARN)
void dm_warn(const char *fmt, ...)
{
va_list args;

View File

@@ -6,7 +6,7 @@ obj-$(CONFIG_DM_I2C) += i2c-uclass.o
ifdef CONFIG_ACPIGEN
obj-$(CONFIG_DM_I2C) += acpi_i2c.o
endif
obj-$(CONFIG_DM_I2C_GPIO) += i2c-gpio.o
obj-$(CONFIG_$(SPL_)DM_I2C_GPIO) += i2c-gpio.o
obj-$(CONFIG_$(SPL_)I2C_CROS_EC_TUNNEL) += cros_ec_tunnel.o
obj-$(CONFIG_$(SPL_)I2C_CROS_EC_LDO) += cros_ec_ldo.o

View File

@@ -76,7 +76,9 @@ UCLASS_DRIVER(i2c_emul) = {
UCLASS_DRIVER(i2c_emul_parent) = {
.id = UCLASS_I2C_EMUL_PARENT,
.name = "i2c_emul_parent",
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
.post_bind = dm_scan_fdt_dev,
#endif
};
static const struct udevice_id i2c_emul_parent_ids[] = {

View File

@@ -93,8 +93,8 @@ static const struct udevice_id sandbox_i2c_ids[] = {
{ }
};
U_BOOT_DRIVER(i2c_sandbox) = {
.name = "i2c_sandbox",
U_BOOT_DRIVER(sandbox_i2c) = {
.name = "sandbox_i2c",
.id = UCLASS_I2C,
.of_match = sandbox_i2c_ids,
.ops = &sandbox_i2c_ops,

View File

@@ -69,7 +69,7 @@ int irq_get_by_driver_info(struct udevice *dev,
{
int ret;
ret = device_get_by_driver_info(cells->node, &irq->dev);
ret = device_get_by_driver_info_idx(cells->idx, &irq->dev);
if (ret)
return ret;
irq->id = cells->arg[0];

View File

@@ -174,19 +174,20 @@ int p2sb_set_port_id(struct udevice *dev, int portid)
if (!CONFIG_IS_ENABLED(OF_PLATDATA))
return -ENOSYS;
uclass_find_first_device(UCLASS_P2SB, &ps2b);
if (!ps2b)
return -EDEADLK;
dev->parent = ps2b;
if (!CONFIG_IS_ENABLED(OF_PLATDATA_PARENT)) {
uclass_find_first_device(UCLASS_P2SB, &ps2b);
if (!ps2b)
return -EDEADLK;
dev->parent = ps2b;
/*
* We must allocate this, since when the device was bound it did not
* have a parent.
* TODO(sjg@chromium.org): Add a parent pointer to child devices in dtoc
*/
dev->parent_platdata = malloc(sizeof(*pplat));
if (!dev->parent_platdata)
return -ENOMEM;
/*
* We must allocate this, since when the device was bound it did
* not have a parent.
*/
dev->parent_platdata = malloc(sizeof(*pplat));
if (!dev->parent_platdata)
return -ENOMEM;
}
pplat = dev_get_parent_platdata(dev);
pplat->pid = portid;

View File

@@ -8,43 +8,8 @@
#include <dm.h>
#include <dt-structs.h>
static int sandbox_spl_probe(struct udevice *dev)
{
struct dtd_sandbox_spl_test *plat = dev_get_platdata(dev);
int i;
printf("of-platdata probe:\n");
printf("bool %d\n", plat->boolval);
printf("byte %02x\n", plat->byteval);
printf("bytearray");
for (i = 0; i < sizeof(plat->bytearray); i++)
printf(" %02x", plat->bytearray[i]);
printf("\n");
printf("int %d\n", plat->intval);
printf("intarray");
for (i = 0; i < ARRAY_SIZE(plat->intarray); i++)
printf(" %d", plat->intarray[i]);
printf("\n");
printf("longbytearray");
for (i = 0; i < sizeof(plat->longbytearray); i++)
printf(" %02x", plat->longbytearray[i]);
printf("\n");
printf("string %s\n", plat->stringval);
printf("stringarray");
for (i = 0; i < ARRAY_SIZE(plat->stringarray); i++)
printf(" \"%s\"", plat->stringarray[i]);
printf("\n");
return 0;
}
U_BOOT_DRIVER(sandbox_spl_test) = {
.name = "sandbox_spl_test",
.id = UCLASS_MISC,
.flags = DM_FLAG_PRE_RELOC,
.probe = sandbox_spl_probe,
};

View File

@@ -1504,12 +1504,9 @@ static int fsl_esdhc_probe(struct udevice *dev)
if (CONFIG_IS_ENABLED(DM_GPIO) && !priv->non_removable) {
struct udevice *gpiodev;
struct driver_info *info;
info = (struct driver_info *)dtplat->cd_gpios->node;
ret = device_get_by_driver_info(info, &gpiodev);
ret = device_get_by_driver_info_idx(dtplat->cd_gpios->idx,
&gpiodev);
if (ret)
return ret;

View File

@@ -174,5 +174,7 @@ int rtc_write32(struct udevice *dev, unsigned int reg, u32 value)
UCLASS_DRIVER(rtc) = {
.name = "rtc",
.id = UCLASS_RTC,
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
.post_bind = dm_scan_fdt_dev,
#endif
};

View File

@@ -92,8 +92,8 @@ static const struct udevice_id sandbox_rtc_ids[] = {
{ }
};
U_BOOT_DRIVER(rtc_sandbox) = {
.name = "rtc-sandbox",
U_BOOT_DRIVER(sandbox_rtc) = {
.name = "sandbox_rtc",
.id = UCLASS_RTC,
.of_match = sandbox_rtc_ids,
.ops = &sandbox_rtc_ops,

View File

@@ -267,6 +267,7 @@ U_BOOT_DRIVER(sandbox_serial) = {
.flags = DM_FLAG_PRE_RELOC,
};
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
static const struct sandbox_serial_platdata platdata_non_fdt = {
.colour = -1,
};
@@ -275,4 +276,6 @@ U_BOOT_DEVICE(serial_sandbox_non_fdt) = {
.name = "sandbox_serial",
.platdata = &platdata_non_fdt,
};
#endif
#endif /* CONFIG_IS_ENABLED(OF_CONTROL) */

View File

@@ -615,6 +615,7 @@ static int ich_spi_exec_op(struct spi_slave *slave, const struct spi_mem_op *op)
return ret;
}
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
/**
* ich_spi_get_basics() - Get basic information about the ICH device
*
@@ -657,6 +658,7 @@ static int ich_spi_get_basics(struct udevice *bus, bool can_probe,
return ret;
}
#endif
/**
* ich_get_mmap_bus() - Handle the get_mmap() method for a bus
@@ -946,10 +948,10 @@ static int ich_spi_child_pre_probe(struct udevice *dev)
static int ich_spi_ofdata_to_platdata(struct udevice *dev)
{
struct ich_spi_platdata *plat = dev_get_platdata(dev);
int ret;
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct ich_spi_priv *priv = dev_get_priv(dev);
int ret;
ret = ich_spi_get_basics(dev, true, &priv->pch, &plat->ich_version,
&plat->mmio_base);

View File

@@ -130,7 +130,9 @@ U_BOOT_DRIVER(warm_sysreset_sandbox) = {
.ops = &sandbox_warm_sysreset_ops,
};
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
/* This is here in case we don't have a device tree */
U_BOOT_DEVICE(sysreset_sandbox_non_fdt) = {
.name = "sysreset_sandbox",
};
#endif