Merge branch '2022-06-09-add-support-for-nvmem-api' into next

To quote the author:
This adds support for the nvmem-cells properties cropping up in manyb
device trees. This is an easy way to load configuration, version
information, or calibration data from a non-volatile memory source. For
more information, refer to patch 6 ("misc: Add support for nvmem
cells").

For the moment I have only added some integration tests using the
ethernet addresses. This hits the main code paths (looking up nvmem
cells) but doesn't test writing. I can add a few stand-alone tests if
desired.
This commit is contained in:
Tom Rini 2022-06-09 15:20:11 -04:00
commit e5028bb227
26 changed files with 436 additions and 29 deletions

View file

@ -1091,6 +1091,13 @@ F: cmd/nvme.c
F: include/nvme.h
F: doc/develop/driver-model/nvme.rst
NVMEM
M: Sean Anderson <seanga2@gmail.com>
S: Maintained
F: doc/api/nvmem.rst
F: drivers/misc/nvmem.c
F: include/nvmem.h
NXP C45 TJA11XX PHY DRIVER
M: Radu Pirea <radu-nicolae.pirea@oss.nxp.com>
S: Maintained

View file

@ -63,7 +63,6 @@
eth@10002000 {
compatible = "sandbox,eth";
reg = <0x10002000 0x1000>;
fake-host-hwaddr = [00 00 66 44 22 00];
};
host-fs {

View file

@ -58,7 +58,6 @@
eth@10002000 {
compatible = "sandbox,eth";
reg = <0x0 0x10002000 0x0 0x1000>;
fake-host-hwaddr = [00 00 66 44 22 00];
};
i2c_0: i2c@0 {

View file

@ -28,6 +28,9 @@
ethernet3 = &eth_3;
ethernet4 = &dsa_eth0;
ethernet5 = &eth_5;
ethernet6 = "/eth@10004000";
ethernet7 = &swp_1;
ethernet8 = &phy_eth0;
gpio1 = &gpio_a;
gpio2 = &gpio_b;
gpio3 = &gpio_c;
@ -524,31 +527,31 @@
eth@10002000 {
compatible = "sandbox,eth";
reg = <0x10002000 0x1000>;
fake-host-hwaddr = [00 00 66 44 22 00];
};
eth_5: eth@10003000 {
compatible = "sandbox,eth";
reg = <0x10003000 0x1000>;
fake-host-hwaddr = [00 00 66 44 22 11];
nvmem-cells = <&eth5_addr>;
nvmem-cell-names = "mac-address";
};
eth_3: sbe5 {
compatible = "sandbox,eth";
reg = <0x10005000 0x1000>;
fake-host-hwaddr = [00 00 66 44 22 33];
nvmem-cells = <&eth3_addr>;
nvmem-cell-names = "mac-address";
};
eth@10004000 {
compatible = "sandbox,eth";
reg = <0x10004000 0x1000>;
fake-host-hwaddr = [00 00 66 44 22 22];
};
phy_eth0: phy-test-eth {
compatible = "sandbox,eth";
reg = <0x10007000 0x1000>;
fake-host-hwaddr = [00 00 66 44 22 77];
mac-address = [ 02 00 11 22 33 49 ];
phy-handle = <&ethphy1>;
phy-mode = "2500base-x";
};
@ -556,7 +559,8 @@
dsa_eth0: dsa-test-eth {
compatible = "sandbox,eth";
reg = <0x10006000 0x1000>;
fake-host-hwaddr = [00 00 66 44 22 66];
nvmem-cells = <&eth4_addr>;
nvmem-cell-names = "mac-address";
};
dsa-test {
@ -700,6 +704,8 @@
pinctrl-0 = <&pinmux_i2c0_pins>;
eeprom@2c {
#address-cells = <1>;
#size-cells = <1>;
reg = <0x2c>;
compatible = "i2c-eeprom";
sandbox,emul = <&emul_eeprom>;
@ -711,12 +717,22 @@
reg = <10 2>;
};
};
eth3_addr: mac-address@24 {
reg = <24 6>;
};
};
rtc_0: rtc@43 {
#address-cells = <1>;
#size-cells = <1>;
reg = <0x43>;
compatible = "sandbox-rtc";
sandbox,emul = <&emul0>;
eth4_addr: mac-address@40 {
reg = <0x40 6>;
};
};
rtc_1: rtc@61 {
@ -898,7 +914,13 @@
};
misc-test {
#address-cells = <1>;
#size-cells = <1>;
compatible = "sandbox,misc_sandbox";
eth5_addr: mac-address@10 {
reg = <0x10 6>;
};
};
mmc2 {

View file

@ -6,10 +6,6 @@ stdout=serial,vidconsole
stderr=serial,vidconsole
ethaddr=02:00:11:22:33:44
eth2addr=02:00:11:22:33:48
eth3addr=02:00:11:22:33:45
eth4addr=02:00:11:22:33:48
eth5addr=02:00:11:22:33:46
eth6addr=02:00:11:22:33:47
ipaddr=192.0.2.1

View file

@ -144,6 +144,7 @@ CONFIG_LED_GPIO=y
CONFIG_DM_MAILBOX=y
CONFIG_SANDBOX_MBOX=y
CONFIG_MISC=y
CONFIG_NVMEM=y
CONFIG_CROS_EC=y
CONFIG_CROS_EC_I2C=y
CONFIG_CROS_EC_LPC=y

View file

@ -188,6 +188,7 @@ CONFIG_LED_GPIO=y
CONFIG_DM_MAILBOX=y
CONFIG_SANDBOX_MBOX=y
CONFIG_MISC=y
CONFIG_NVMEM=y
CONFIG_CROS_EC=y
CONFIG_CROS_EC_I2C=y
CONFIG_CROS_EC_LPC=y

View file

@ -117,6 +117,7 @@ CONFIG_LED_GPIO=y
CONFIG_DM_MAILBOX=y
CONFIG_SANDBOX_MBOX=y
CONFIG_MISC=y
CONFIG_NVMEM=y
CONFIG_CROS_EC=y
CONFIG_CROS_EC_I2C=y
CONFIG_CROS_EC_LPC=y

View file

@ -144,6 +144,7 @@ CONFIG_LED_GPIO=y
CONFIG_DM_MAILBOX=y
CONFIG_SANDBOX_MBOX=y
CONFIG_MISC=y
CONFIG_NVMEM=y
CONFIG_CROS_EC=y
CONFIG_CROS_EC_I2C=y
CONFIG_CROS_EC_LPC=y

View file

@ -145,6 +145,8 @@ CONFIG_LED_GPIO=y
CONFIG_DM_MAILBOX=y
CONFIG_SANDBOX_MBOX=y
CONFIG_MISC=y
CONFIG_NVMEM=y
CONFIG_SPL_NVMEM=y
CONFIG_CROS_EC=y
CONFIG_CROS_EC_I2C=y
CONFIG_CROS_EC_LPC=y
@ -153,6 +155,7 @@ CONFIG_CROS_EC_SPI=y
CONFIG_P2SB=y
CONFIG_PWRSEQ=y
CONFIG_SPL_PWRSEQ=y
CONFIG_I2C_EEPROM=y
CONFIG_MMC_SANDBOX=y
CONFIG_SPI_FLASH_SANDBOX=y
CONFIG_SPI_FLASH_ATMEL=y

View file

@ -14,6 +14,7 @@ U-Boot API documentation
linker_lists
lmb
logging
nvmem
pinctrl
rng
sandbox

10
doc/api/nvmem.rst Normal file
View file

@ -0,0 +1,10 @@
.. SPDX-License-Identifier: GPL-2.0+
NVMEM API
=========
.. kernel-doc:: include/nvmem.h
:doc: Design
.. kernel-doc:: include/nvmem.h
:internal:

View file

@ -43,6 +43,22 @@ config VPL_MISC
set of generic read, write and ioctl methods may be used to
access the device.
config NVMEM
bool "NVMEM support"
help
This adds support for a common interface to different types of
non-volatile memory. Consumers can use nvmem-cells properties to look
up hardware configuration data such as MAC addresses and calibration
settings.
config SPL_NVMEM
bool "NVMEM support in SPL"
help
This adds support for a common interface to different types of
non-volatile memory. Consumers can use nvmem-cells properties to look
up hardware configuration data such as MAC addresses and calibration
settings.
config ALTERA_SYSID
bool "Altera Sysid support"
depends on MISC

View file

@ -4,6 +4,7 @@
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
obj-$(CONFIG_$(SPL_TPL_)MISC) += misc-uclass.o
obj-$(CONFIG_$(SPL_TPL_)NVMEM) += nvmem.o
obj-$(CONFIG_$(SPL_TPL_)CROS_EC) += cros_ec.o
obj-$(CONFIG_$(SPL_TPL_)CROS_EC_SANDBOX) += cros_ec_sandbox.o

View file

@ -33,7 +33,8 @@ int i2c_eeprom_read(struct udevice *dev, int offset, uint8_t *buf, int size)
return ops->read(dev, offset, buf, size);
}
int i2c_eeprom_write(struct udevice *dev, int offset, uint8_t *buf, int size)
int i2c_eeprom_write(struct udevice *dev, int offset, const uint8_t *buf,
int size)
{
const struct i2c_eeprom_ops *ops = device_get_ops(dev);

View file

@ -171,11 +171,15 @@ static int sandbox_i2c_eeprom_probe(struct udevice *dev)
{
struct sandbox_i2c_flash_plat_data *plat = dev_get_plat(dev);
struct sandbox_i2c_flash *priv = dev_get_priv(dev);
/* For eth3 */
const u8 mac[] = { 0x02, 0x00, 0x11, 0x22, 0x33, 0x45 };
priv->data = calloc(1, plat->size);
if (!priv->data)
return -ENOMEM;
memcpy(&priv->data[24], mac, sizeof(mac));
return 0;
}

View file

@ -112,8 +112,11 @@ static const struct misc_ops misc_sandbox_ops = {
int misc_sandbox_probe(struct udevice *dev)
{
struct misc_sandbox_priv *priv = dev_get_priv(dev);
/* For eth5 */
const u8 mac[] = { 0x02, 0x00, 0x11, 0x22, 0x33, 0x46 };
priv->enabled = true;
memcpy(&priv->mem[16], mac, sizeof(mac));
return 0;
}

142
drivers/misc/nvmem.c Normal file
View file

@ -0,0 +1,142 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2022 Sean Anderson <sean.anderson@seco.com>
*/
#include <common.h>
#include <i2c_eeprom.h>
#include <linker_lists.h>
#include <misc.h>
#include <nvmem.h>
#include <rtc.h>
#include <dm/device_compat.h>
#include <dm/ofnode.h>
#include <dm/read.h>
#include <dm/uclass.h>
int nvmem_cell_read(struct nvmem_cell *cell, void *buf, size_t size)
{
dev_dbg(cell->nvmem, "%s: off=%u size=%zu\n", __func__, cell->offset, size);
if (size != cell->size)
return -EINVAL;
switch (cell->nvmem->driver->id) {
case UCLASS_I2C_EEPROM:
return i2c_eeprom_read(cell->nvmem, cell->offset, buf, size);
case UCLASS_MISC: {
int ret = misc_read(cell->nvmem, cell->offset, buf, size);
if (ret < 0)
return ret;
if (ret != size)
return -EIO;
return 0;
}
case UCLASS_RTC:
return dm_rtc_read(cell->nvmem, cell->offset, buf, size);
default:
return -ENOSYS;
}
}
int nvmem_cell_write(struct nvmem_cell *cell, const void *buf, size_t size)
{
dev_dbg(cell->nvmem, "%s: off=%u size=%zu\n", __func__, cell->offset, size);
if (size != cell->size)
return -EINVAL;
switch (cell->nvmem->driver->id) {
case UCLASS_I2C_EEPROM:
return i2c_eeprom_write(cell->nvmem, cell->offset, buf, size);
case UCLASS_MISC: {
int ret = misc_write(cell->nvmem, cell->offset, buf, size);
if (ret < 0)
return ret;
if (ret != size)
return -EIO;
return 0;
}
case UCLASS_RTC:
return dm_rtc_write(cell->nvmem, cell->offset, buf, size);
default:
return -ENOSYS;
}
}
/**
* nvmem_get_device() - Get an nvmem device for a cell
* @node: ofnode of the nvmem device
* @cell: Cell to look up
*
* Try to find a nvmem-compatible device by going through the nvmem interfaces.
*
* Return:
* * 0 on success
* * -ENODEV if we didn't find anything
* * A negative error if there was a problem looking up the device
*/
static int nvmem_get_device(ofnode node, struct nvmem_cell *cell)
{
int i, ret;
enum uclass_id ids[] = {
UCLASS_I2C_EEPROM,
UCLASS_MISC,
UCLASS_RTC,
};
for (i = 0; i < ARRAY_SIZE(ids); i++) {
ret = uclass_get_device_by_ofnode(ids[i], node, &cell->nvmem);
if (!ret)
return 0;
if (ret != -ENODEV && ret != -EPFNOSUPPORT)
return ret;
}
return -ENODEV;
}
int nvmem_cell_get_by_index(struct udevice *dev, int index,
struct nvmem_cell *cell)
{
fdt_addr_t offset;
fdt_size_t size = FDT_SIZE_T_NONE;
int ret;
struct ofnode_phandle_args args;
dev_dbg(dev, "%s: index=%d\n", __func__, index);
ret = dev_read_phandle_with_args(dev, "nvmem-cells", NULL, 0, index,
&args);
if (ret)
return ret;
ret = nvmem_get_device(ofnode_get_parent(args.node), cell);
if (ret)
return ret;
offset = ofnode_get_addr_size_index_notrans(args.node, 0, &size);
if (offset == FDT_ADDR_T_NONE || size == FDT_SIZE_T_NONE) {
dev_dbg(cell->nvmem, "missing address or size for %s\n",
ofnode_get_name(args.node));
return -EINVAL;
}
cell->offset = offset;
cell->size = size;
return 0;
}
int nvmem_cell_get_by_name(struct udevice *dev, const char *name,
struct nvmem_cell *cell)
{
int index;
dev_dbg(dev, "%s, name=%s\n", __func__, name);
index = dev_read_stringlist_search(dev, "nvmem-cell-names", name);
if (index < 0)
return index;
return nvmem_cell_get_by_index(dev, index, cell);
}

View file

@ -395,9 +395,11 @@ static void sb_eth_stop(struct udevice *dev)
static int sb_eth_write_hwaddr(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_plat(dev);
struct eth_sandbox_priv *priv = dev_get_priv(dev);
debug("eth_sandbox %s: Write HW ADDR - %pM\n", dev->name,
pdata->enetaddr);
memcpy(priv->fake_host_hwaddr, pdata->enetaddr, ARP_HLEN);
return 0;
}
@ -419,16 +421,8 @@ static int sb_eth_of_to_plat(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_plat(dev);
struct eth_sandbox_priv *priv = dev_get_priv(dev);
const u8 *mac;
pdata->iobase = dev_read_addr(dev);
mac = dev_read_u8_array_ptr(dev, "fake-host-hwaddr", ARP_HLEN);
if (!mac) {
printf("'fake-host-hwaddr' is missing from the DT\n");
return -EINVAL;
}
memcpy(priv->fake_host_hwaddr, mac, ARP_HLEN);
priv->disabled = false;
priv->tx_handler = sb_default_handler;

View file

@ -203,6 +203,15 @@ static int sandbox_i2c_rtc_bind(struct udevice *dev)
return 0;
}
static int sandbox_i2c_rtc_probe(struct udevice *dev)
{
const u8 mac[] = { 0x02, 0x00, 0x11, 0x22, 0x33, 0x48 };
struct sandbox_i2c_rtc_plat_data *plat = dev_get_plat(dev);
memcpy(&plat->reg[0x40], mac, sizeof(mac));
return 0;
}
static const struct udevice_id sandbox_i2c_rtc_ids[] = {
{ .compatible = "sandbox,i2c-rtc-emul" },
{ }
@ -213,6 +222,7 @@ U_BOOT_DRIVER(sandbox_i2c_rtc_emul) = {
.id = UCLASS_I2C_EMUL,
.of_match = sandbox_i2c_rtc_ids,
.bind = sandbox_i2c_rtc_bind,
.probe = sandbox_i2c_rtc_probe,
.priv_auto = sizeof(struct sandbox_i2c_rtc),
.plat_auto = sizeof(struct sandbox_i2c_rtc_plat_data),
.ops = &sandbox_i2c_rtc_emul_ops,

View file

@ -6,6 +6,8 @@
#ifndef __I2C_EEPROM
#define __I2C_EEPROM
struct udevice;
struct i2c_eeprom_ops {
int (*read)(struct udevice *dev, int offset, uint8_t *buf, int size);
int (*write)(struct udevice *dev, int offset, const uint8_t *buf,
@ -20,6 +22,7 @@ struct i2c_eeprom {
unsigned long size;
};
#if CONFIG_IS_ENABLED(I2C_EEPROM)
/*
* i2c_eeprom_read() - read bytes from an I2C EEPROM chip
*
@ -42,7 +45,8 @@ int i2c_eeprom_read(struct udevice *dev, int offset, uint8_t *buf, int size);
*
* Return: 0 on success, -ve on failure
*/
int i2c_eeprom_write(struct udevice *dev, int offset, uint8_t *buf, int size);
int i2c_eeprom_write(struct udevice *dev, int offset, const uint8_t *buf,
int size);
/*
* i2c_eeprom_size() - get size of I2C EEPROM chip
@ -53,4 +57,25 @@ int i2c_eeprom_write(struct udevice *dev, int offset, uint8_t *buf, int size);
*/
int i2c_eeprom_size(struct udevice *dev);
#else /* !I2C_EEPROM */
static inline int i2c_eeprom_read(struct udevice *dev, int offset, uint8_t *buf,
int size)
{
return -ENOSYS;
}
static inline int i2c_eeprom_write(struct udevice *dev, int offset,
const uint8_t *buf, int size)
{
return -ENOSYS;
}
static inline int i2c_eeprom_size(struct udevice *dev)
{
return -ENOSYS;
}
#endif /* I2C_EEPROM */
#endif

134
include/nvmem.h Normal file
View file

@ -0,0 +1,134 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2022 Sean Anderson <sean.anderson@seco.com>
*/
#ifndef NVMEM_H
#define NVMEM_H
/**
* DOC: Design
*
* The NVMEM subsystem is a "meta-uclass" in that it abstracts over several
* different uclasses all with read/write APIs. One approach to implementing
* this could be to add a new sub-device for each nvmem-style device of
* UCLASS_NVMEM. This subsystem has taken the approach of using the existing
* access methods (i2c_eeprom_write, misc_write, etc.) directly. This has the
* advantage of not requiring an extra device/driver, saving on binary size and
* runtime memory usage. On the other hand, it is not idiomatic. Similar
* efforts should generally use a new uclass.
*/
/**
* struct nvmem_cell - One datum within non-volatile memory
* @nvmem: The backing storage device
* @offset: The offset of the cell from the start of @nvmem
* @size: The size of the cell, in bytes
*/
struct nvmem_cell {
struct udevice *nvmem;
unsigned int offset;
size_t size;
};
struct udevice;
#if CONFIG_IS_ENABLED(NVMEM)
/**
* nvmem_cell_read() - Read the value of an nvmem cell
* @cell: The nvmem cell to read
* @buf: The buffer to read into
* @size: The size of @buf
*
* Return:
* * 0 on success
* * -EINVAL if @buf is not the same size as @cell.
* * -ENOSYS if CONFIG_NVMEM is disabled
* * A negative error if there was a problem reading the underlying storage
*/
int nvmem_cell_read(struct nvmem_cell *cell, void *buf, size_t size);
/**
* nvmem_cell_write() - Write a value to an nvmem cell
* @cell: The nvmem cell to write
* @buf: The buffer to write from
* @size: The size of @buf
*
* Return:
* * 0 on success
* * -EINVAL if @buf is not the same size as @cell
* * -ENOSYS if @cell is read-only, or if CONFIG_NVMEM is disabled
* * A negative error if there was a problem writing the underlying storage
*/
int nvmem_cell_write(struct nvmem_cell *cell, const void *buf, size_t size);
/**
* nvmem_cell_get_by_index() - Get an nvmem cell from a given device and index
* @dev: The device that uses the nvmem cell
* @index: The index of the cell in nvmem-cells
* @cell: The cell to initialize
*
* Look up the nvmem cell referenced by the phandle at @index in nvmem-cells in
* @dev.
*
* Return:
* * 0 on success
* * -EINVAL if the regs property is missing, empty, or undersized
* * -ENODEV if the nvmem device is missing or unimplemented
* * -ENOSYS if CONFIG_NVMEM is disabled
* * A negative error if there was a problem reading nvmem-cells or getting the
* device
*/
int nvmem_cell_get_by_index(struct udevice *dev, int index,
struct nvmem_cell *cell);
/**
* nvmem_cell_get_by_name() - Get an nvmem cell from a given device and name
* @dev: The device that uses the nvmem cell
* @name: The name of the nvmem cell
* @cell: The cell to initialize
*
* Look up the nvmem cell referenced by @name in the nvmem-cell-names property
* of @dev.
*
* Return:
* * 0 on success
* * -EINVAL if the regs property is missing, empty, or undersized
* * -ENODEV if the nvmem device is missing or unimplemented
* * -ENODATA if @name is not in nvmem-cell-names
* * -ENOSYS if CONFIG_NVMEM is disabled
* * A negative error if there was a problem reading nvmem-cell-names,
* nvmem-cells, or getting the device
*/
int nvmem_cell_get_by_name(struct udevice *dev, const char *name,
struct nvmem_cell *cell);
#else /* CONFIG_NVMEM */
static inline int nvmem_cell_read(struct nvmem_cell *cell, void *buf, int size)
{
return -ENOSYS;
}
static inline int nvmem_cell_write(struct nvmem_cell *cell, const void *buf,
int size)
{
return -ENOSYS;
}
static inline int nvmem_cell_get_by_index(struct udevice *dev, int index,
struct nvmem_cell *cell)
{
return -ENOSYS;
}
static inline int nvmem_cell_get_by_name(struct udevice *dev, const char *name,
struct nvmem_cell *cell)
{
return -ENOSYS;
}
#endif /* CONFIG_NVMEM */
#endif /* NVMEM_H */

View file

@ -477,8 +477,10 @@ static int dsa_pre_probe(struct udevice *dev)
return -ENODEV;
}
uclass_find_device_by_ofnode(UCLASS_ETH, pdata->master_node,
&priv->master_dev);
err = uclass_get_device_by_ofnode(UCLASS_ETH, pdata->master_node,
&priv->master_dev);
if (err)
return err;
/* Simulate a probing event for the CPU port */
if (ops->port_probe) {

View file

@ -14,6 +14,7 @@
#include <env.h>
#include <log.h>
#include <net.h>
#include <nvmem.h>
#include <asm/global_data.h>
#include <dm/device-internal.h>
#include <dm/uclass-internal.h>
@ -507,17 +508,21 @@ static bool eth_dev_get_mac_address(struct udevice *dev, u8 mac[ARP_HLEN])
{
#if CONFIG_IS_ENABLED(OF_CONTROL)
const uint8_t *p;
struct nvmem_cell mac_cell;
p = dev_read_u8_array_ptr(dev, "mac-address", ARP_HLEN);
if (!p)
p = dev_read_u8_array_ptr(dev, "local-mac-address", ARP_HLEN);
if (!p)
if (p) {
memcpy(mac, p, ARP_HLEN);
return true;
}
if (nvmem_cell_get_by_name(dev, "mac-address", &mac_cell))
return false;
memcpy(mac, p, ARP_HLEN);
return true;
return !nvmem_cell_read(&mac_cell, mac, ARP_HLEN);
#else
return false;
#endif

View file

@ -147,6 +147,35 @@ static int dm_test_eth_act(struct unit_test_state *uts)
}
DM_TEST(dm_test_eth_act, UT_TESTF_SCAN_FDT);
/* Ensure that all addresses are loaded properly */
static int dm_test_ethaddr(struct unit_test_state *uts)
{
static const char *const addr[] = {
"02:00:11:22:33:44",
"02:00:11:22:33:48", /* dsa slave */
"02:00:11:22:33:45",
"02:00:11:22:33:48", /* dsa master */
"02:00:11:22:33:46",
"02:00:11:22:33:47",
"02:00:11:22:33:48", /* dsa slave */
"02:00:11:22:33:49",
};
int i;
for (i = 0; i < ARRAY_SIZE(addr); i++) {
char addrname[10];
if (i)
snprintf(addrname, sizeof(addrname), "eth%daddr", i + 1);
else
strcpy(addrname, "ethaddr");
ut_asserteq_str(addr[i], env_get(addrname));
}
return 0;
}
DM_TEST(dm_test_ethaddr, UT_TESTF_SCAN_FDT);
/* The asserts include a return on fail; cleanup in the caller */
static int _dm_test_eth_rotate1(struct unit_test_state *uts)
{

View file

@ -184,7 +184,7 @@ static int dm_test_alias_highest_id(struct unit_test_state *uts)
int ret;
ret = dev_read_alias_highest_id("ethernet");
ut_asserteq(5, ret);
ut_asserteq(8, ret);
ret = dev_read_alias_highest_id("gpio");
ut_asserteq(3, ret);