ENOSYS clean-up

Minor dtoc improvements
 Convert CONFIG_MISC_INIT_F to Kconfig
 Allow unit tests to run on any board
 pylibfdt build-rule fix
 -----BEGIN PGP SIGNATURE-----
 
 iQFFBAABCgAvFiEEslwAIq+Gp8wWVbYnfxc6PpAIreYFAmBr+AgRHHNqZ0BjaHJv
 bWl1bS5vcmcACgkQfxc6PpAIrebnqQf/dZUk4cpj4q29icFJhAhG3wUkzKdKywWu
 wOwHPIaUIetytpjwKTbkv0cUdel5Jhp9mvnJ2O5cRUZlVdgCH+lEQmFiq1O74Jf5
 IwYBN74xZuP7+rno3ZxuKhjj2ixbpeg2A5R/o7gaevIgtu4vCK71qrj3y+unjnnt
 Rd5BGaVzouMya0lS9cdkrzE1vmuLXs7ZJBvKdppaNda0VScJj+JP3NqooFKRKPU+
 OeyblmtfL5lGOXFdY7Wfjg0pzv5L8fJxDaYDxf6iRWWG/X6RO6zV26MWAo28Ga+J
 E3fuvl0mBqr1eAg3Cf17j4s9gRZv1tMtS6Mol1scIcBrldalVFA44g==
 =x75X
 -----END PGP SIGNATURE-----

Merge tag 'dm-pull-6apr21' of https://source.denx.de/u-boot/custodians/u-boot-dm

ENOSYS clean-up
Minor dtoc improvements
Convert CONFIG_MISC_INIT_F to Kconfig
Allow unit tests to run on any board
pylibfdt build-rule fix
This commit is contained in:
Tom Rini 2021-04-06 08:36:11 -04:00
commit 779786dac3
45 changed files with 336 additions and 92 deletions

View file

@ -527,6 +527,12 @@ config LAST_STAGE_INIT
U-Boot calls last_stage_init() before the command-line interpreter is
started.
config MISC_INIT_F
bool "Execute pre-relocation misc init"
help
Enabling this option calls the 'misc_init_f' function in the init
sequence just before DRAM is inited.
config MISC_INIT_R
bool "Execute Misc Init"
default y if ARCH_KEYSTONE || ARCH_SUNXI || MPC85xx

View file

@ -154,6 +154,7 @@ CONFIG_SYS_EXTRA_OPTIONS="SYS_TEXT_BASE=0xFE000000"
CONFIG_BOOTDELAY=6
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="root=/dev/nfs rw nfsroot=:/nfsroot/rootfs ip=::::mpc8349emitxgp:eth0:off console=ttyS0,115200"
CONFIG_MISC_INIT_F=y
CONFIG_MISC_INIT_R=y
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="MPC8349E-mITX-GP> "

View file

@ -153,6 +153,7 @@ CONFIG_OF_STDOUT_VIA_ALIAS=y
CONFIG_BOOTDELAY=6
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="root=/dev/nfs rw nfsroot=:/nfsroot/rootfs ip=::::mpc8349emitx:eth0:off console=ttyS0,115200"
CONFIG_MISC_INIT_F=y
CONFIG_MISC_INIT_R=y
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="MPC8349E-mITX> "

View file

@ -152,6 +152,7 @@ CONFIG_OF_STDOUT_VIA_ALIAS=y
CONFIG_BOOTDELAY=6
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="root=/dev/nfs rw nfsroot=:/nfsroot/rootfs ip=::::mpc8349emitx:eth0:off console=ttyS0,115200"
CONFIG_MISC_INIT_F=y
CONFIG_MISC_INIT_R=y
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="MPC8349E-mITX> "

View file

@ -20,6 +20,7 @@ CONFIG_AUTOBOOT_STOP_STR=" "
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_LAST_STAGE_INIT=y
CONFIG_MISC_INIT_F=y
CONFIG_HUSH_PARSER=y
CONFIG_CMD_ASKENV=y
CONFIG_CMD_GREPENV=y

View file

@ -20,8 +20,8 @@ CONFIG_BOOTSTAGE_STASH_SIZE=0x4096
CONFIG_CONSOLE_RECORD=y
CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
CONFIG_PRE_CONSOLE_BUFFER=y
CONFIG_LOG_SYSLOG=y
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_MISC_INIT_F=y
CONFIG_CMD_CPU=y
CONFIG_CMD_LICENSE=y
CONFIG_CMD_BOOTZ=y

View file

@ -24,6 +24,7 @@ CONFIG_PRE_CONSOLE_BUFFER=y
CONFIG_LOG_SYSLOG=y
CONFIG_LOG_ERROR_RETURN=y
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_MISC_INIT_F=y
CONFIG_ANDROID_AB=y
CONFIG_CMD_CPU=y
CONFIG_CMD_LICENSE=y

View file

@ -17,8 +17,8 @@ CONFIG_BOOTSTAGE_STASH=y
CONFIG_BOOTSTAGE_STASH_SIZE=0x4096
CONFIG_CONSOLE_RECORD=y
CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
CONFIG_LOG_SYSLOG=y
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_MISC_INIT_F=y
CONFIG_CMD_CPU=y
CONFIG_CMD_LICENSE=y
CONFIG_CMD_BOOTZ=y

View file

@ -11,6 +11,7 @@ CONFIG_SPL_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL=y
CONFIG_BOOTSTAGE_STASH_ADDR=0x0
CONFIG_DEFAULT_DEVICE_TREE="sandbox"
CONFIG_TARGET_SANDBOX_SPL=y
CONFIG_SANDBOX_SPL=y
CONFIG_DEBUG_UART=y
CONFIG_DISTRO_DEFAULTS=y
@ -27,6 +28,7 @@ CONFIG_BOOTSTAGE_STASH_SIZE=0x4096
CONFIG_CONSOLE_RECORD=y
CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_MISC_INIT_F=y
CONFIG_HANDOFF=y
CONFIG_SPL_BOARD_INIT=y
CONFIG_SPL_ENV_SUPPORT=y

View file

@ -4,6 +4,7 @@ CONFIG_DEFAULT_DEVICE_TREE="sandbox"
CONFIG_ANDROID_BOOT_IMAGE=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_MISC_INIT_F=y
# CONFIG_CMD_BOOTD is not set
# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_ELF is not set

View file

@ -900,6 +900,139 @@ Some special flags are used to determine whether to remove the device:
The dm_remove_devices_flags() function can be used to remove devices based on
their driver flags.
Error codes
-----------
Driver model tries to use errors codes in a consistent way, as follows:
\-EAGAIN
Try later, e.g. dependencies not ready
\-EINVAL
Invalid argument, such as `dev_read_...()` failed or any other
devicetree-related access. Also used when a driver method is passed an
argument it considers invalid or does not support.
\-EIO
Failed to perform an I/O operation. This is used when a local device
(i.e. part of the SOC) does not work as expected. Use -EREMOTEIO for
failures to talk to a separate device, e.g. over an I2C or SPI
channel.
\-ENODEV
Do not bind the device. This should not be used to indicate an
error probing the device or for any other purpose, lest driver model get
confused. Using `-ENODEV` inside a driver method makes no sense, since
clearly there is a device.
\-ENOENT
Entry or object not found. This is used when a device, file or directory
cannot be found (e.g. when looked up by name), It can also indicate a
missing devicetree subnode.
\-ENOMEM
Out of memory
\-ENOSPC
Ran out of space (e.g. in a buffer or limited-size array)
\-ENOSYS
Function not implemented. This is returned by uclasses where the driver does
not implement a particular method. It can also be returned by drivers when
a particular sub-method is not implemented. This is widely checked in the
wider code base, where a feature may or may not be compiled into U-Boot. It
indicates that the feature is not available, but this is often just normal
operation. Please do not use -ENOSUPP. If an incorrect or unknown argument
is provided to a method (e.g. an unknown clock ID), return -EINVAL.
\-ENXIO
Couldn't find device/address. This is used when a device or address
could not be obtained or is not valid. It is often used to indicate a
different type of problem, if -ENOENT is already used for something else in
the driver.
\-EPERM
This is -1 so some older code may use it as a generic error. This indicates
that an operation is not permitted, e.g. a security violation or policy
constraint. It is returned internally when binding devices before relocation,
if the device is not marked for pre-relocation use.
\-EPFNOSUPPORT
Missing uclass. This is deliberately an uncommon error code so that it can
easily be distinguished. If you see this very early in U-Boot, it means that
a device exists with a particular uclass but the uclass does not (mostly
likely because it is not compiled in). Enable DEBUG in uclass.c or lists.c
to see which uclass ID or driver is causing the problem.
\-EREMOTEIO
This indicates an error in talking to a peripheral over a comms link, such
as I2C or SPI. It might indicate that the device is not present or is not
responding as expected.
\-ETIMEDOUT
Hardware access or some other operation has timed out. This is used where
there is an expected time of response and that was exceeded by enough of
a margin that there is probably something wrong.
Less common ones:
\-ECOMM
Not widely used, but similar to -EREMOTEIO. Can be useful as a secondary
error to distinguish the problem from -EREMOTEIO.
\-EKEYREJECTED
Attempt to remove a device which does not match the removal flags. See
device_remove().
\-EILSEQ
Devicetree read failure, specifically trying to read a string index which
does not exist, in a string-listg property
\-ENOEXEC
Attempt to use a uclass method on a device not in that uclass. This is
seldom checked at present, since it is generally a programming error and a
waste of code space. A DEBUG-only check would be useful here.
\-ENODATA
Devicetree read error, where a property exists but has no data associated
with it
\-EOVERFLOW
Devicetree read error, where the property is longer than expected
\-EPROBE_DEFER
Attempt to remove a non-vital device when the removal flags indicate that
only vital devices should be removed
\-ERANGE
Returned by regmap functions when arguments are out of range. This can be
useful for disinguishing regmap errors from other errors obtained while
probing devices.
Drivers should use the same conventions so that things function as expected.
In particular, if a driver fails to probe, or a uclass operation fails, the
error code is the primary way to indicate what actually happened.
Printing error messages in drivers is discouraged due to code size bloat and
since it can result in messages appearing in normal operation. For example, if
a command tries two different devices and uses whichever one probes correctly,
we don't want an error message displayed, even if the command itself might show
a warning or informational message. Ideally, messages in drivers should only be
displayed when debugging, e.g. by using log_debug() although in extreme cases
log_warning() or log_error() may be used.
Error messages can be logged using `log_msg_ret()`, so that enabling
`CONFIG_LOG` and `CONFIG_LOG_ERROR_RETURN` shows a trace of error codes returned
through the call stack. That can be a handy way of quickly figuring out where
an error occurred. Get into the habit of return errors with
`return log_msg_ret("here", ret)` instead of just `return ret`. The string
just needs to be long enough to find in a single function, since a log record
stores (and can print with `CONFIG_LOGF_FUNC`) the function where it was
generated.
Data Structures
---------------

View file

@ -1140,7 +1140,7 @@ int soc_clk_dump(void)
clk_free(&clk);
if (ret == -ENOTSUPP) {
if (ret == -EINVAL) {
printf("clk ID %lu not supported yet\n",
aspeed_clk_names[i].id);
continue;

View file

@ -37,10 +37,10 @@ static int clk_composite_set_parent(struct clk *clk, struct clk *parent)
const struct clk_ops *mux_ops = composite->mux_ops;
struct clk *mux = composite->mux;
if (mux && mux_ops)
return mux_ops->set_parent(mux, parent);
else
return -ENOTSUPP;
if (!mux || !mux_ops)
return -ENOSYS;
return mux_ops->set_parent(mux, parent);
}
static unsigned long clk_composite_recalc_rate(struct clk *clk)

View file

@ -718,7 +718,7 @@ static ulong hsdk_cgu_set_rate(struct clk *sclk, ulong rate)
if (clk->map[sclk->id].set_rate)
return clk->map[sclk->id].set_rate(sclk, rate);
return -ENOTSUPP;
return -EINVAL;
}
static int hsdk_cgu_disable(struct clk *sclk)
@ -731,7 +731,7 @@ static int hsdk_cgu_disable(struct clk *sclk)
if (clk->map[sclk->id].disable)
return clk->map[sclk->id].disable(sclk);
return -ENOTSUPP;
return -EINVAL;
}
static const struct clk_ops hsdk_cgu_ops = {

View file

@ -29,7 +29,7 @@ __weak ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
__weak int __imx8_clk_enable(struct clk *clk, bool enable)
{
return -ENOTSUPP;
return -EINVAL;
}
static int imx8_clk_disable(struct clk *clk)
@ -70,7 +70,7 @@ int soc_clk_dump(void)
clk_free(&clk);
if (ret == -ENOTSUPP) {
if (ret == -EINVAL) {
printf("clk ID %lu not supported yet\n",
imx8_clk_names[i].id);
continue;

View file

@ -133,7 +133,7 @@ ulong imx8_clk_get_rate(struct clk *clk)
__func__, clk->id);
return -EINVAL;
}
return -ENOTSUPP;
return -EINVAL;
};
ret = sc_pm_get_clock_rate(-1, resource, pm_clk,
@ -237,7 +237,7 @@ ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
__func__, clk->id);
return -EINVAL;
}
return -ENOTSUPP;
return -EINVAL;
};
ret = sc_pm_set_clock_rate(-1, resource, pm_clk, &new_rate);
@ -337,7 +337,7 @@ int __imx8_clk_enable(struct clk *clk, bool enable)
__func__, clk->id);
return -EINVAL;
}
return -ENOTSUPP;
return -EINVAL;
}
ret = sc_pm_clock_enable(-1, resource, pm_clk, enable, 0);

View file

@ -126,7 +126,7 @@ ulong imx8_clk_get_rate(struct clk *clk)
__func__, clk->id);
return -EINVAL;
}
return -ENOTSUPP;
return -EINVAL;
};
ret = sc_pm_get_clock_rate(-1, resource, pm_clk,
@ -221,7 +221,7 @@ ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
__func__, clk->id);
return -EINVAL;
}
return -ENOTSUPP;
return -EINVAL;
};
ret = sc_pm_set_clock_rate(-1, resource, pm_clk, &new_rate);
@ -311,7 +311,7 @@ int __imx8_clk_enable(struct clk *clk, bool enable)
__func__, clk->id);
return -EINVAL;
}
return -ENOTSUPP;
return -EINVAL;
}
ret = sc_pm_clock_enable(-1, resource, pm_clk, enable, 0);

View file

@ -290,7 +290,7 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
break;
default:
kfree(pll);
return ERR_PTR(-ENOTSUPP);
return ERR_PTR(-EINVAL);
}
pll->base = base;

View file

@ -157,7 +157,7 @@ static int k210_bypass_set_parent(struct clk *clk, struct clk *parent)
if (ops->set_parent)
return ops->set_parent(bypass->bypassee, parent);
else
return -ENOTSUPP;
return -EINVAL;
}
/*

View file

@ -495,7 +495,7 @@ static int k210_clk_probe(struct udevice *dev)
* could fix this, but it's Probably Not Worth It (TM).
*/
if (probed)
return -ENOTSUPP;
return -EINVAL;
base = dev_read_addr_ptr(dev_get_parent(dev));
if (!base)

View file

@ -340,7 +340,7 @@ static int periph_clk_enable(struct clk *clk, int enable)
return -EINVAL;
if (!periph_clk->can_gate)
return -ENOTSUPP;
return -EINVAL;
if (enable)
clrbits_le32(priv->reg + CLK_DIS, periph_clk->disable_bit);
@ -408,7 +408,7 @@ static ulong armada_37xx_periph_clk_set_rate(struct clk *clk, ulong req_rate)
return old_rate;
if (!periph_clk->can_gate || !periph_clk->dividers)
return -ENOTSUPP;
return -EINVAL;
parent_rate = get_parent_rate(priv, clk->id);
if (parent_rate == -EINVAL)
@ -445,7 +445,7 @@ static int armada_37xx_periph_clk_set_parent(struct clk *clk,
return -EINVAL;
if (!periph_clk->can_mux || !periph_clk->can_gate)
return -ENOTSUPP;
return -EINVAL;
ret = clk_get_by_index(clk->dev, 0, &check_parent);
if (ret < 0)

View file

@ -91,7 +91,7 @@ int acpi_get_path(const struct udevice *dev, char *out_path, int maxlen)
path = dev_read_string(dev, "acpi,path");
if (path) {
if (strlen(path) >= maxlen)
return -E2BIG;
return -ENOSPC;
strcpy(out_path, path);
return 0;
}

View file

@ -21,7 +21,7 @@ static int simple_pm_bus_probe(struct udevice *dev)
return ret;
ret = clk_enable_bulk(bulk);
if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
if (ret && ret != -ENOSYS) {
clk_release_bulk(bulk);
return ret;
}
@ -34,7 +34,7 @@ static int simple_pm_bus_remove(struct udevice *dev)
struct clk_bulk *bulk = dev_get_priv(dev);
ret = clk_release_bulk(bulk);
if (ret && ret != -ENOSYS && ret != -ENOTSUPP)
if (ret && ret != -ENOSYS)
return ret;
else
return 0;

View file

@ -235,8 +235,9 @@ int pinctrl_gpio_request(struct udevice *dev, unsigned offset)
return ret;
ops = pinctrl_get_ops(pctldev);
if (!ops || !ops->gpio_request_enable)
return -ENOTSUPP;
assert(ops);
if (!ops->gpio_request_enable)
return -ENOSYS;
return ops->gpio_request_enable(pctldev, pin_selector);
}
@ -261,8 +262,9 @@ int pinctrl_gpio_free(struct udevice *dev, unsigned offset)
return ret;
ops = pinctrl_get_ops(pctldev);
if (!ops || !ops->gpio_disable_free)
return -ENOTSUPP;
assert(ops);
if (!ops->gpio_disable_free)
return -ENOSYS;
return ops->gpio_disable_free(pctldev, pin_selector);
}

View file

@ -45,7 +45,7 @@ int usb_gadget_release(int index)
dev_array[index] = NULL;
return ret;
#else
return -ENOTSUPP;
return -ENOSYS;
#endif
}

View file

@ -39,8 +39,6 @@
#ifndef __CONFIG_H
#define __CONFIG_H
#define CONFIG_MISC_INIT_F
/*
* On-board devices
*/

View file

@ -177,8 +177,6 @@ unsigned long get_board_sys_clk(unsigned long dummy);
#define CONFIG_SYS_BR1_PRELIM CONFIG_SYS_QRIO_BR_PRELIM /* QRIO Base Address */
#define CONFIG_SYS_OR1_PRELIM CONFIG_SYS_QRIO_OR_PRELIM /* QRIO Options */
#define CONFIG_MISC_INIT_F
#define CONFIG_HWCONFIG
/* define to use L1 as initial stack */

View file

@ -130,6 +130,4 @@
#define CONFIG_SYS_SATA_MAX_DEVICE 2
#define CONFIG_MISC_INIT_F
#endif

View file

@ -222,11 +222,14 @@ static inline int _log_nop(enum log_category_t cat, enum log_level_t level,
#define _SPL_BUILD 0
#endif
#if !_DEBUG && CONFIG_IS_ENABLED(LOG)
#if CONFIG_IS_ENABLED(LOG)
#define debug_cond(cond, fmt, args...) \
({ \
log(LOG_CATEGORY, LOGL_DEBUG, fmt, ##args); \
#define debug_cond(cond, fmt, args...) \
({ \
if (cond) \
log(LOG_CATEGORY, \
(enum log_level_t)(LOGL_FORCE_DEBUG | _LOG_DEBUG), \
fmt, ##args); \
})
#else /* _DEBUG */

View file

@ -134,7 +134,9 @@ void os_free(void *ptr);
* This follows the semantics of realloc(), so can perform an os_malloc() or
* os_free() depending on @ptr and @length.
*
* Return: Pointer to reallocated memory or NULL if @length is 0
* @ptr: pointer to previously allocated memory of NULL
* @length: number of bytes to allocate
* Return: pointer to reallocated memory or NULL if @length is 0
*/
void *os_realloc(void *ptr, size_t length);

View file

@ -222,7 +222,7 @@ spi_controller_dma_map_mem_op_data(struct spi_controller *ctlr,
const struct spi_mem_op *op,
struct sg_table *sg)
{
return -ENOTSUPP;
return -ENOSYS;
}
static inline void

View file

@ -124,4 +124,13 @@ enum {
*/
struct udevice *testbus_get_clear_removed(void);
static inline void arch_reset_for_test(void)
{
#ifdef CONFIG_SANDBOX
#include <asm/state.h>
state_reset_for_test(state_get_current());
#endif
}
#endif /* __TEST_TEST_H */

View file

@ -114,19 +114,19 @@ int read_tlvinfo_tlv_eeprom(void *eeprom, struct tlvinfo_header **hdr,
static inline int read_tlv_eeprom(void *eeprom, int offset, int len, int dev)
{
return -ENOTSUPP;
return -ENOSYS;
}
static inline int write_tlv_eeprom(void *eeprom, int len)
{
return -ENOTSUPP;
return -ENOSYS;
}
static inline int
read_tlvinfo_tlv_eeprom(void *eeprom, struct tlvinfo_header **hdr,
struct tlvinfo_tlv **first_entry, int dev)
{
return -ENOTSUPP;
return -ENOSYS;
}
#endif /* CONFIG_IS_ENABLED(CMD_TLV_EEPROM) */

View file

@ -1030,7 +1030,6 @@ CONFIG_MIPS_HUGE_TLB_SUPPORT
CONFIG_MIPS_MT_FPAFF
CONFIG_MIRQ_EN
CONFIG_MISC_COMMON
CONFIG_MISC_INIT_F
CONFIG_MIU_1BIT_INTERLEAVED
CONFIG_MIU_2BIT_21_7_INTERLEAVED
CONFIG_MIU_2BIT_INTERLEAVED

View file

@ -34,6 +34,7 @@ rebuild: $(src)/setup.py $(PYLIBFDT_srcs)
fi
$(obj)/_libfdt.so $(obj)/libfdt.py &: rebuild
@:
always += _libfdt.so libfdt.py

View file

@ -7,7 +7,6 @@
#include <common.h>
#include <console.h>
#include <dm.h>
#include <asm/state.h>
#include <dm/root.h>
#include <dm/test.h>
#include <dm/uclass-internal.h>
@ -46,9 +45,9 @@ static int dm_test_pre_run(struct unit_test_state *uts)
uts->force_fail_alloc = false;
uts->skip_post_probe = false;
gd->dm_root = NULL;
if (!CONFIG_IS_ENABLED(OF_PLATDATA))
if (IS_ENABLED(CONFIG_UT_DM) && !CONFIG_IS_ENABLED(OF_PLATDATA))
memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count));
state_reset_for_test(state_get_current());
arch_reset_for_test();
/* Determine whether to make the live tree available */
gd_set_of_root(of_live ? uts->of_root : NULL);

View file

@ -344,7 +344,8 @@ class BuilderThread(threading.Thread):
# Write out the image and function size information and an objdump
env = result.toolchain.MakeEnvironment(self.builder.full_path)
with open(os.path.join(build_dir, 'out-env'), 'w') as fd:
with open(os.path.join(build_dir, 'out-env'), 'w',
encoding='utf-8') as fd:
for var in sorted(env.keys()):
print('%s="%s"' % (var, env[var]), file=fd)
lines = []

View file

@ -440,6 +440,9 @@ class DtbPlatdata():
Number of size cells for this node
"""
parent = node.parent
if parent and not parent.props:
raise ValueError("Parent node '%s' has no properties - do you need u-boot,dm-spl or similar?" %
parent.path)
num_addr, num_size = 2, 2
if parent:
addr_prop = parent.props.get('#address-cells')
@ -467,20 +470,21 @@ class DtbPlatdata():
if reg.type != fdt.Type.INT:
raise ValueError("Node '%s' reg property is not an int" %
node.name)
if not isinstance(reg.value, list):
reg.value = [reg.value]
if len(reg.value) % total:
raise ValueError(
"Node '%s' reg property has %d cells "
"Node '%s' (parent '%s') reg property has %d cells "
'which is not a multiple of na + ns = %d + %d)' %
(node.name, len(reg.value), num_addr, num_size))
(node.name, node.parent.name, len(reg.value), num_addr,
num_size))
reg.num_addr = num_addr
reg.num_size = num_size
if num_addr != 1 or num_size != 1:
if num_addr > 1 or num_size > 1:
reg.type = fdt.Type.INT64
i = 0
new_value = []
val = reg.value
if not isinstance(val, list):
val = [val]
while i < len(val):
addr = fdt_util.fdt_cells_to_cpu(val[i:], reg.num_addr)
i += num_addr
@ -1194,8 +1198,7 @@ def run_steps(args, dtb_file, include_disabled, output, output_dirs, phase,
raise ValueError('Must specify either output or output_dirs, not both')
if not scan:
scan = src_scan.Scanner(basedir, warning_disabled, drivers_additional,
phase)
scan = src_scan.Scanner(basedir, drivers_additional, phase)
scan.scan_drivers()
do_process = True
else:
@ -1232,4 +1235,7 @@ def run_steps(args, dtb_file, include_disabled, output, output_dirs, phase,
plat.out_header(outfile)
outfile.method(plat)
plat.finish_output()
if not warning_disabled:
scan.show_warnings()
return plat

View file

@ -188,7 +188,6 @@ class Scanner:
key: Driver alias declared with
DM_DRIVER_ALIAS(driver_alias, driver_name)
value: Driver name declared with U_BOOT_DRIVER(driver_name)
_warning_disabled: true to disable warnings about driver names not found
_drivers_additional (list or str): List of additional drivers to use
during scanning
_of_match: Dict holding information about compatible strings
@ -206,7 +205,7 @@ class Scanner:
_phase: The phase of U-Boot that we are generating data for, e.g. 'spl'
or 'tpl'. None if not known
"""
def __init__(self, basedir, warning_disabled, drivers_additional, phase=''):
def __init__(self, basedir, drivers_additional, phase=''):
"""Set up a new Scanner
"""
if not basedir:
@ -217,7 +216,7 @@ class Scanner:
self._drivers = {}
self._driver_aliases = {}
self._drivers_additional = drivers_additional or []
self._warning_disabled = warning_disabled
self._missing_drivers = set()
self._of_match = {}
self._compat_to_driver = {}
self._uclass = {}
@ -268,9 +267,7 @@ class Scanner:
aliases_c.remove(compat_c)
return compat_c, aliases_c
if not self._warning_disabled:
print('WARNING: the driver %s was not found in the driver list'
% (compat_list_c[0]))
self._missing_drivers.add(compat_list_c[0])
return compat_list_c[0], compat_list_c[1:]
@ -578,6 +575,12 @@ class Scanner:
self._drivers[driver.name] = driver
self._of_match.update(of_match)
def show_warnings(self):
"""Show any warnings that have been collected"""
for name in sorted(list(self._missing_drivers)):
print('WARNING: the driver %s was not found in the driver list'
% name)
def scan_driver(self, fname):
"""Scan a driver file to build a list of driver names and aliases

View file

@ -0,0 +1,21 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Test device tree file for dtoc
*
* Copyright 2017 Google, Inc
*/
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
i2c@0 {
pmic@9 {
compatible = "sandbox,pmic";
u-boot,dm-pre-reloc;
reg = <9>;
low-power;
};
};
};

View file

@ -0,0 +1,30 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Test device tree file for dtoc
*
* Copyright 2017 Google, Inc
*/
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
i2c@0 {
compatible = "sandbox,i2c";
u-boot,dm-pre-reloc;
#address-cells = <1>;
#size-cells = <0>;
pmic@9 {
compatible = "sandbox,pmic";
u-boot,dm-pre-reloc;
reg = <9>;
low-power;
gpio {
compatible = "sandbox,gpio";
};
};
};
};

View file

@ -104,7 +104,7 @@ def setup():
# Disable warnings so that calls to get_normalized_compat_name() will not
# output things.
saved_scan = src_scan.Scanner(None, True, False)
saved_scan = src_scan.Scanner(None, False)
saved_scan.scan_drivers()
def copy_scan():
@ -293,7 +293,7 @@ struct dtd_sandbox_i2c {
};
struct dtd_sandbox_pmic {
\tbool\t\tlow_power;
\tfdt64_t\t\treg[2];
\tfdt32_t\t\treg[1];
};
struct dtd_sandbox_spl_test {
\tconst char * acpi_name;
@ -341,7 +341,7 @@ U_BOOT_DRVINFO(i2c_at_0) = {
*/
static struct dtd_sandbox_pmic dtv_pmic_at_9 = {
\t.low_power\t\t= true,
\t.reg\t\t\t= {0x9, 0x0},
\t.reg\t\t\t= {0x9},
};
U_BOOT_DRVINFO(pmic_at_9) = {
\t.name\t\t= "sandbox_pmic",
@ -721,7 +721,7 @@ struct dm_test_pdata __attribute__ ((section (".priv_data")))
\t.dtplat = {
\t\t.ping_add\t\t= 0x5,
\t\t.ping_expect\t\t= 0x5,
\t\t.reg\t\t\t= {0x5, 0x0},
\t\t.reg\t\t\t= {0x5},
\t},
};
#include <dm/test.h>
@ -1462,7 +1462,7 @@ U_BOOT_DRVINFO(test3) = {
with self.assertRaises(ValueError) as exc:
self.run_test(['struct'], dtb_file, output)
self.assertIn(
"Node 'spl-test' reg property has 3 cells which is not a multiple of na + ns = 1 + 1)",
"Node 'spl-test' (parent '/') reg property has 3 cells which is not a multiple of na + ns = 1 + 1)",
str(exc.exception))
def test_add_prop(self):
@ -1824,3 +1824,18 @@ U_BOOT_DRVINFO(spl_test2) = {
self.assertEqual(
'Warning: Cannot find header file for struct dm_test_uc_priv',
stdout.getvalue().strip())
def test_missing_props(self):
"""Test detection of a parent node with no properties"""
dtb_file = get_dtb_file('dtoc_test_noprops.dts', capture_stderr=True)
output = tools.GetOutputFilename('output')
with self.assertRaises(ValueError) as exc:
self.run_test(['struct'], dtb_file, output)
self.assertIn("Parent node '/i2c@0' has no properties - do you need",
str(exc.exception))
def test_single_reg(self):
"""Test detection of a parent node with no properties"""
dtb_file = get_dtb_file('dtoc_test_single_reg.dts')
output = tools.GetOutputFilename('output')
self.run_test(['struct'], dtb_file, output)

View file

@ -48,7 +48,7 @@ class TestSrcScan(unittest.TestCase):
def test_simple(self):
"""Simple test of scanning drivers"""
scan = src_scan.Scanner(None, True, None)
scan = src_scan.Scanner(None, None)
scan.scan_drivers()
self.assertIn('sandbox_gpio', scan._drivers)
self.assertIn('sandbox_gpio_alias', scan._driver_aliases)
@ -59,8 +59,7 @@ class TestSrcScan(unittest.TestCase):
def test_additional(self):
"""Test with additional drivers to scan"""
scan = src_scan.Scanner(
None, True,
[None, '', 'tools/dtoc/test/dtoc_test_scan_drivers.cxx'])
None, [None, '', 'tools/dtoc/test/dtoc_test_scan_drivers.cxx'])
scan.scan_drivers()
self.assertIn('sandbox_gpio_alias2', scan._driver_aliases)
self.assertEqual('sandbox_gpio',
@ -77,7 +76,7 @@ class TestSrcScan(unittest.TestCase):
with open(driver_fn, 'wb+') as fout:
fout.write(b'\x81')
scan = src_scan.Scanner(None, True, [driver_fn])
scan = src_scan.Scanner(None, [driver_fn])
with test_util.capture_sys_output() as (stdout, _):
scan.scan_drivers()
self.assertRegex(stdout.getvalue(),
@ -126,7 +125,7 @@ class TestSrcScan(unittest.TestCase):
# Mock out scan_driver and check that it is called with the
# expected files
with mock.patch.object(src_scan.Scanner, "scan_driver") as mocked:
scan = src_scan.Scanner(indir, True, None)
scan = src_scan.Scanner(indir, None)
scan.scan_drivers()
self.assertEqual(2, len(mocked.mock_calls))
self.assertEqual(mock.call(fname_list[0]),
@ -141,7 +140,7 @@ class TestSrcScan(unittest.TestCase):
"""Test scanning of a driver"""
fname = os.path.join(OUR_PATH, '..', '..', 'drivers/i2c/tegra_i2c.c')
buff = tools.ReadFile(fname, False)
scan = src_scan.Scanner(None, False, None)
scan = src_scan.Scanner(None, None)
scan._parse_driver(fname, buff)
self.assertIn('i2c_tegra', scan._drivers)
drv = scan._drivers['i2c_tegra']
@ -165,14 +164,15 @@ class TestSrcScan(unittest.TestCase):
# get_normalized_compat_name() uses this to check for root node
node.parent = FakeNode()
scan = src_scan.Scanner(None, False, None)
scan = src_scan.Scanner(None, None)
with test_util.capture_sys_output() as (stdout, _):
name, aliases = scan.get_normalized_compat_name(node)
self.assertEqual('rockchip_rk3288_grf', name)
self.assertEqual([], aliases)
self.assertEqual(
'WARNING: the driver rockchip_rk3288_grf was not found in the driver list',
stdout.getvalue().strip())
self.assertEqual(1, len(scan._missing_drivers))
self.assertEqual({'rockchip_rk3288_grf'}, scan._missing_drivers)
#'WARNING: the driver rockchip_rk3288_grf was not found in the driver list',
#stdout.getvalue().strip())
i2c = 'I2C_UCLASS'
compat = {'rockchip,rk3288-grf': 'ROCKCHIP_SYSCON_GRF',
@ -211,7 +211,7 @@ U_BOOT_DRIVER(i2c_tegra) = {
.of_match = tegra_i2c_ids,
};
'''
scan = src_scan.Scanner(None, False, None)
scan = src_scan.Scanner(None, None)
with self.assertRaises(ValueError) as exc:
scan._parse_driver('file.c', buff)
self.assertIn(
@ -232,7 +232,7 @@ U_BOOT_DRIVER(i2c_tegra) = {
.of_match = of_match_ptr(tegra_i2c_ids),
};
'''
scan = src_scan.Scanner(None, False, None)
scan = src_scan.Scanner(None, None)
scan._parse_driver('file.c', buff)
self.assertIn('i2c_tegra', scan._drivers)
drv = scan._drivers['i2c_tegra']
@ -261,7 +261,7 @@ U_BOOT_DRIVER(testing) = {
DM_HEADER(<asm/clk.h>)
};
'''
scan = src_scan.Scanner(None, False, None)
scan = src_scan.Scanner(None, None)
scan._parse_driver('file.c', buff)
self.assertIn('testing', scan._drivers)
drv = scan._drivers['testing']
@ -293,7 +293,7 @@ UCLASS_DRIVER(i2c) = {
};
'''
scan = src_scan.Scanner(None, False, None)
scan = src_scan.Scanner(None, None)
scan._parse_uclass_driver('file.c', buff)
self.assertIn('UCLASS_I2C', scan._uclass)
drv = scan._uclass['UCLASS_I2C']
@ -325,7 +325,7 @@ UCLASS_DRIVER(i2c) = {
};
'''
scan = src_scan.Scanner(None, False, None)
scan = src_scan.Scanner(None, None)
with self.assertRaises(ValueError) as exc:
scan._parse_uclass_driver('file.c', buff)
self.assertIn("file.c: Cannot parse uclass ID in driver 'i2c'",
@ -340,7 +340,7 @@ struct some_struct1 {
uint nmsgs;
};
'''
scan = src_scan.Scanner(None, False, None)
scan = src_scan.Scanner(None, None)
scan._basedir = os.path.join(OUR_PATH, '..', '..')
scan._parse_structs('arch/arm/include/asm/file.h', buff)
self.assertIn('some_struct1', scan._structs)
@ -371,7 +371,7 @@ struct another_struct {
output = tools.GetOutputFilename('output.h')
tools.WriteFile(output, b'struct this is a test \x81 of bad unicode')
scan = src_scan.Scanner(None, False, None)
scan = src_scan.Scanner(None, None)
with test_util.capture_sys_output() as (stdout, _):
scan.scan_header(output)
self.assertIn('due to unicode error', stdout.getvalue())
@ -411,7 +411,7 @@ U_BOOT_DRIVER(%s) = {
.of_match = test_ids,
};
''' % name
scan = src_scan.Scanner(None, False, None, phase)
scan = src_scan.Scanner(None, None, phase)
scan._parse_driver('file1.c', driver1)
self.assertIn(name, scan._drivers)
drv1 = scan._drivers[name]
@ -476,7 +476,7 @@ U_BOOT_DRIVER(%s) = {
def test_sequence(self):
"""Test assignment of sequence numnbers"""
scan = src_scan.Scanner(None, False, None, '')
scan = src_scan.Scanner(None, None, '')
node = FakeNode()
uc = src_scan.UclassDriver('UCLASS_I2C')
node.uclass = uc

View file

@ -12,6 +12,10 @@ config options from headers to Kconfig (defconfig).
This tool intends to help this tremendous work.
Installing
----------
You may need to install 'python3-asteval' for the 'asteval' module.
Usage
-----
@ -573,7 +577,11 @@ def cleanup_empty_blocks(header_path, options):
"""
pattern = re.compile(r'^\s*#\s*if.*$\n^\s*#\s*endif.*$\n*', flags=re.M)
with open(header_path) as f:
data = f.read()
try:
data = f.read()
except UnicodeDecodeError as e:
print("Failed on file %s': %s" % (header_path, e))
return
new_data = pattern.sub('\n', data)
@ -596,7 +604,11 @@ def cleanup_one_header(header_path, patterns, options):
options: option flags.
"""
with open(header_path) as f:
lines = f.readlines()
try:
lines = f.readlines()
except UnicodeDecodeError as e:
print("Failed on file %s': %s" % (header_path, e))
return
matched = []
for i, line in enumerate(lines):

View file

@ -133,8 +133,8 @@ class PatchStream:
ValueError: Warning is generated with no commit associated
"""
if not self.commit:
raise ValueError('Warning outside commit: %s' % warn)
if warn not in self.commit.warn:
print('Warning outside commit: %s' % warn)
elif warn not in self.commit.warn:
self.commit.warn.append(warn)
def _add_to_series(self, line, name, value):