mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-21 06:31:31 +00:00
Merge branch 'master' of git://git.denx.de/u-boot-dm
This commit is contained in:
commit
5f757cdcc6
36 changed files with 814 additions and 216 deletions
|
@ -2,6 +2,8 @@
|
|||
* U-Boot additions to enable a generic Exynos GPIO driver
|
||||
*
|
||||
* Copyright (c) 2014 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/{
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* U-Boot additions to enable a generic Exynos GPIO driver
|
||||
*
|
||||
* Copyright (c) 2014 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/{
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* U-Boot additions to enable a generic Exynos GPIO driver
|
||||
*
|
||||
* Copyright (c) 2014 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/{
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* U-Boot additions to enable a generic Exynos GPIO driver
|
||||
*
|
||||
* Copyright (c) 2014 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/{
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* U-Boot additions to enable a generic Exynos GPIO driver
|
||||
*
|
||||
* Copyright (c) 2014 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/ {
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* U-Boot additions to enable a generic Exynos GPIO driver
|
||||
*
|
||||
* Copyright (c) 2014 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/ {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <common.h>
|
||||
#include <dm/root.h>
|
||||
#include <os.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/state.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
@ -97,3 +98,43 @@ phys_addr_t map_to_sysmem(const void *ptr)
|
|||
void flush_dcache_range(unsigned long start, unsigned long stop)
|
||||
{
|
||||
}
|
||||
|
||||
int sandbox_read_fdt_from_file(void)
|
||||
{
|
||||
struct sandbox_state *state = state_get_current();
|
||||
const char *fname = state->fdt_fname;
|
||||
void *blob;
|
||||
loff_t size;
|
||||
int err;
|
||||
int fd;
|
||||
|
||||
blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0);
|
||||
if (!state->fdt_fname) {
|
||||
err = fdt_create_empty_tree(blob, 256);
|
||||
if (!err)
|
||||
goto done;
|
||||
printf("Unable to create empty FDT: %s\n", fdt_strerror(err));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = os_get_filesize(fname, &size);
|
||||
if (err < 0) {
|
||||
printf("Failed to file FDT file '%s'\n", fname);
|
||||
return err;
|
||||
}
|
||||
fd = os_open(fname, OS_O_RDONLY);
|
||||
if (fd < 0) {
|
||||
printf("Failed to open FDT file '%s'\n", fname);
|
||||
return -EACCES;
|
||||
}
|
||||
if (os_read(fd, blob, size) != size) {
|
||||
os_close(fd);
|
||||
return -EIO;
|
||||
}
|
||||
os_close(fd);
|
||||
|
||||
done:
|
||||
gd->fdt_blob = blob;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
/*
|
||||
* Copyright (c) 2011 The Chromium OS Authors.
|
||||
*
|
||||
* Modified from Linux arch/arm/include/asm/bitops.h
|
||||
*
|
||||
* Copyright 1995, Russell King.
|
||||
* Various bits and pieces copyrights include:
|
||||
* Linus Torvalds (test_bit).
|
||||
|
|
|
@ -75,4 +75,12 @@ int pci_unmap_physmem(const void *addr, unsigned long len,
|
|||
*/
|
||||
void sandbox_set_enable_pci_map(int enable);
|
||||
|
||||
/**
|
||||
* sandbox_read_fdt_from_file() - Read a device tree from a file
|
||||
*
|
||||
* Read a device tree file from a host file and set it up for use as the
|
||||
* control FDT.
|
||||
*/
|
||||
int sandbox_read_fdt_from_file(void);
|
||||
|
||||
#endif /* _U_BOOT_SANDBOX_H_ */
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <i2c.h>
|
||||
#include <initcall.h>
|
||||
#include <logbuff.h>
|
||||
#include <malloc.h>
|
||||
#include <mapmem.h>
|
||||
|
||||
/* TODO: Can we move these into arch/ headers? */
|
||||
|
@ -282,49 +283,6 @@ __weak int arch_cpu_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF_HOSTFILE
|
||||
|
||||
static int read_fdt_from_file(void)
|
||||
{
|
||||
struct sandbox_state *state = state_get_current();
|
||||
const char *fname = state->fdt_fname;
|
||||
void *blob;
|
||||
loff_t size;
|
||||
int err;
|
||||
int fd;
|
||||
|
||||
blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0);
|
||||
if (!state->fdt_fname) {
|
||||
err = fdt_create_empty_tree(blob, 256);
|
||||
if (!err)
|
||||
goto done;
|
||||
printf("Unable to create empty FDT: %s\n", fdt_strerror(err));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = os_get_filesize(fname, &size);
|
||||
if (err < 0) {
|
||||
printf("Failed to file FDT file '%s'\n", fname);
|
||||
return err;
|
||||
}
|
||||
fd = os_open(fname, OS_O_RDONLY);
|
||||
if (fd < 0) {
|
||||
printf("Failed to open FDT file '%s'\n", fname);
|
||||
return -EACCES;
|
||||
}
|
||||
if (os_read(fd, blob, size) != size) {
|
||||
os_close(fd);
|
||||
return -EIO;
|
||||
}
|
||||
os_close(fd);
|
||||
|
||||
done:
|
||||
gd->fdt_blob = blob;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SANDBOX
|
||||
static int setup_ram_buf(void)
|
||||
{
|
||||
|
@ -337,28 +295,6 @@ static int setup_ram_buf(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
static int setup_fdt(void)
|
||||
{
|
||||
#ifdef CONFIG_OF_CONTROL
|
||||
# ifdef CONFIG_OF_EMBED
|
||||
/* Get a pointer to the FDT */
|
||||
gd->fdt_blob = __dtb_dt_begin;
|
||||
# elif defined CONFIG_OF_SEPARATE
|
||||
/* FDT is at end of image */
|
||||
gd->fdt_blob = (ulong *)&_end;
|
||||
# elif defined(CONFIG_OF_HOSTFILE)
|
||||
if (read_fdt_from_file()) {
|
||||
puts("Failed to read control FDT\n");
|
||||
return -1;
|
||||
}
|
||||
# endif
|
||||
/* Allow the early environment to override the fdt address */
|
||||
gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16,
|
||||
(uintptr_t)gd->fdt_blob);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the top of usable RAM */
|
||||
__weak ulong board_get_usable_ram_top(ulong total_size)
|
||||
{
|
||||
|
@ -786,17 +722,6 @@ static int mark_bootstage(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int initf_malloc(void)
|
||||
{
|
||||
#ifdef CONFIG_SYS_MALLOC_F_LEN
|
||||
assert(gd->malloc_base); /* Set up by crt0.S */
|
||||
gd->malloc_limit = gd->malloc_base + CONFIG_SYS_MALLOC_F_LEN;
|
||||
gd->malloc_ptr = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int initf_dm(void)
|
||||
{
|
||||
#if defined(CONFIG_DM) && defined(CONFIG_SYS_MALLOC_F_LEN)
|
||||
|
@ -826,7 +751,9 @@ static init_fnc_t init_sequence_f[] = {
|
|||
setup_ram_buf,
|
||||
#endif
|
||||
setup_mon_len,
|
||||
setup_fdt,
|
||||
#ifdef CONFIG_OF_CONTROL
|
||||
fdtdec_setup,
|
||||
#endif
|
||||
#ifdef CONFIG_TRACE
|
||||
trace_early_init,
|
||||
#endif
|
||||
|
@ -837,9 +764,6 @@ static init_fnc_t init_sequence_f[] = {
|
|||
#endif
|
||||
arch_cpu_init, /* basic arch cpu dependent setup */
|
||||
mark_bootstage,
|
||||
#ifdef CONFIG_OF_CONTROL
|
||||
fdtdec_check_fdt,
|
||||
#endif
|
||||
initf_dm,
|
||||
arch_cpu_init_dm,
|
||||
#if defined(CONFIG_BOARD_EARLY_INIT_F)
|
||||
|
|
|
@ -3261,6 +3261,17 @@ int mALLOPt(param_number, value) int param_number; int value;
|
|||
}
|
||||
}
|
||||
|
||||
int initf_malloc(void)
|
||||
{
|
||||
#ifdef CONFIG_SYS_MALLOC_F_LEN
|
||||
assert(gd->malloc_base); /* Set up by crt0.S */
|
||||
gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN;
|
||||
gd->malloc_ptr = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
History:
|
||||
|
|
|
@ -151,6 +151,8 @@ static void spl_ram_load_image(void)
|
|||
void board_init_r(gd_t *dummy1, ulong dummy2)
|
||||
{
|
||||
u32 boot_device;
|
||||
int ret;
|
||||
|
||||
debug(">>spl:board_init_r()\n");
|
||||
|
||||
#if defined(CONFIG_SYS_SPL_MALLOC_START)
|
||||
|
@ -158,12 +160,24 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
|
|||
CONFIG_SYS_SPL_MALLOC_SIZE);
|
||||
gd->flags |= GD_FLG_FULL_MALLOC_INIT;
|
||||
#elif defined(CONFIG_SYS_MALLOC_F_LEN)
|
||||
gd->malloc_limit = gd->malloc_base + CONFIG_SYS_MALLOC_F_LEN;
|
||||
gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN;
|
||||
gd->malloc_ptr = 0;
|
||||
#endif
|
||||
#ifdef CONFIG_SPL_DM
|
||||
dm_init_and_scan(true);
|
||||
#endif
|
||||
if (IS_ENABLED(CONFIG_OF_CONTROL) &&
|
||||
!IS_ENABLED(CONFIG_SPL_DISABLE_OF_CONTROL)) {
|
||||
ret = fdtdec_setup();
|
||||
if (ret) {
|
||||
debug("fdtdec_setup() returned error %d\n", ret);
|
||||
hang();
|
||||
}
|
||||
}
|
||||
if (IS_ENABLED(CONFIG_SPL_DM)) {
|
||||
ret = dm_init_and_scan(true);
|
||||
if (ret) {
|
||||
debug("dm_init_and_scan() returned error %d\n", ret);
|
||||
hang();
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CONFIG_PPC
|
||||
/*
|
||||
|
|
|
@ -95,43 +95,82 @@ are provided in test/dm. To run them, try:
|
|||
You should see something like this:
|
||||
|
||||
<...U-Boot banner...>
|
||||
Running 29 driver model tests
|
||||
Running 53 driver model tests
|
||||
Test: dm_test_autobind
|
||||
Test: dm_test_autoprobe
|
||||
Test: dm_test_bus_child_post_bind
|
||||
Test: dm_test_bus_child_post_bind_uclass
|
||||
Test: dm_test_bus_child_pre_probe_uclass
|
||||
Test: dm_test_bus_children
|
||||
Device 'd-test': seq 3 is in use by 'b-test'
|
||||
Device 'c-test@0': seq 0 is in use by 'a-test'
|
||||
Device 'c-test@1': seq 1 is in use by 'd-test'
|
||||
Device 'c-test@0': seq 0 is in use by 'd-test'
|
||||
Device 'c-test@1': seq 1 is in use by 'f-test'
|
||||
Test: dm_test_bus_children_funcs
|
||||
Test: dm_test_bus_children_iterators
|
||||
Test: dm_test_bus_parent_data
|
||||
Test: dm_test_bus_parent_data_uclass
|
||||
Test: dm_test_bus_parent_ops
|
||||
Test: dm_test_bus_parent_platdata
|
||||
Test: dm_test_bus_parent_platdata_uclass
|
||||
Test: dm_test_children
|
||||
Test: dm_test_device_get_uclass_id
|
||||
Test: dm_test_eth
|
||||
Using eth@10002000 device
|
||||
Using eth@10003000 device
|
||||
Using eth@10004000 device
|
||||
Test: dm_test_eth_alias
|
||||
Using eth@10002000 device
|
||||
Using eth@10004000 device
|
||||
Using eth@10002000 device
|
||||
Using eth@10003000 device
|
||||
Test: dm_test_eth_prime
|
||||
Using eth@10003000 device
|
||||
Using eth@10002000 device
|
||||
Test: dm_test_eth_rotate
|
||||
|
||||
Error: eth@10004000 address not set.
|
||||
|
||||
Error: eth@10004000 address not set.
|
||||
Using eth@10002000 device
|
||||
|
||||
Error: eth@10004000 address not set.
|
||||
|
||||
Error: eth@10004000 address not set.
|
||||
Using eth@10004000 device
|
||||
Test: dm_test_fdt
|
||||
Device 'd-test': seq 3 is in use by 'b-test'
|
||||
Test: dm_test_fdt_offset
|
||||
Test: dm_test_fdt_pre_reloc
|
||||
Test: dm_test_fdt_uclass_seq
|
||||
Device 'd-test': seq 3 is in use by 'b-test'
|
||||
Device 'a-test': seq 0 is in use by 'd-test'
|
||||
Test: dm_test_gpio
|
||||
extra-gpios: get_value: error: gpio b5 not reserved
|
||||
Test: dm_test_gpio_anon
|
||||
Test: dm_test_gpio_copy
|
||||
Test: dm_test_gpio_leak
|
||||
extra-gpios: get_value: error: gpio b5 not reserved
|
||||
Test: dm_test_gpio_phandles
|
||||
Test: dm_test_gpio_requestf
|
||||
Test: dm_test_i2c_bytewise
|
||||
Test: dm_test_i2c_find
|
||||
Test: dm_test_i2c_offset
|
||||
Test: dm_test_i2c_offset_len
|
||||
Test: dm_test_i2c_probe_empty
|
||||
Test: dm_test_i2c_read_write
|
||||
Test: dm_test_i2c_speed
|
||||
Test: dm_test_leak
|
||||
Test: dm_test_lifecycle
|
||||
Test: dm_test_net_retry
|
||||
Using eth@10004000 device
|
||||
Using eth@10002000 device
|
||||
Using eth@10004000 device
|
||||
Test: dm_test_operations
|
||||
Test: dm_test_ordering
|
||||
Test: dm_test_pci_base
|
||||
Test: dm_test_pci_swapcase
|
||||
Test: dm_test_platdata
|
||||
Test: dm_test_pre_reloc
|
||||
Test: dm_test_remove
|
||||
Test: dm_test_spi_find
|
||||
Invalid chip select 0:0 (err=-19)
|
||||
SF: Failed to get idcodes
|
||||
Device 'name-emul': seq 0 is in use by 'name-emul'
|
||||
SF: Detected M25P16 with page size 256 Bytes, erase size 64 KiB, total 2 MiB
|
||||
Test: dm_test_spi_flash
|
||||
2097152 bytes written in 0 ms
|
||||
|
@ -150,6 +189,9 @@ You should see something like this:
|
|||
SF: Detected M25P16 with page size 256 Bytes, erase size 64 KiB, total 2 MiB
|
||||
Test: dm_test_uclass
|
||||
Test: dm_test_uclass_before_ready
|
||||
Test: dm_test_usb_base
|
||||
Test: dm_test_usb_flash
|
||||
USB-1: scanning bus 1 for devices... 2 USB Device(s) found
|
||||
Failures: 0
|
||||
|
||||
|
||||
|
|
|
@ -46,3 +46,12 @@ config DM_STDIO
|
|||
Normally serial drivers register with stdio so that they can be used
|
||||
as normal output devices. In SPL we don't normally use stdio, so
|
||||
we can omit this feature.
|
||||
|
||||
config DM_SEQ_ALIAS
|
||||
bool "Support numbered aliases in device tree"
|
||||
depends on DM
|
||||
default y
|
||||
help
|
||||
Most boards will have a '/aliases' node containing the path to
|
||||
numbered devices (e.g. serial0 = &serial0). This feature can be
|
||||
disabled if it is not required, to save code space in SPL.
|
||||
|
|
|
@ -92,6 +92,10 @@ int device_unbind(struct udevice *dev)
|
|||
free(dev->platdata);
|
||||
dev->platdata = NULL;
|
||||
}
|
||||
if (dev->flags & DM_FLAG_ALLOC_UCLASS_PDATA) {
|
||||
free(dev->uclass_platdata);
|
||||
dev->uclass_platdata = NULL;
|
||||
}
|
||||
if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) {
|
||||
free(dev->parent_platdata);
|
||||
dev->parent_platdata = NULL;
|
||||
|
|
|
@ -30,7 +30,7 @@ int device_bind(struct udevice *parent, const struct driver *drv,
|
|||
{
|
||||
struct udevice *dev;
|
||||
struct uclass *uc;
|
||||
int ret = 0;
|
||||
int size, ret = 0;
|
||||
|
||||
*devp = NULL;
|
||||
if (!name)
|
||||
|
@ -56,21 +56,23 @@ int device_bind(struct udevice *parent, const struct driver *drv,
|
|||
|
||||
dev->seq = -1;
|
||||
dev->req_seq = -1;
|
||||
#ifdef CONFIG_OF_CONTROL
|
||||
/*
|
||||
* Some devices, such as a SPI bus, I2C bus and serial ports are
|
||||
* numbered using aliases.
|
||||
*
|
||||
* 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 && of_offset != -1) {
|
||||
fdtdec_get_alias_seq(gd->fdt_blob, uc->uc_drv->name,
|
||||
of_offset, &dev->req_seq);
|
||||
if (IS_ENABLED(CONFIG_OF_CONTROL) && IS_ENABLED(CONFIG_DM_SEQ_ALIAS)) {
|
||||
/*
|
||||
* Some devices, such as a SPI bus, I2C bus and serial ports
|
||||
* are numbered using aliases.
|
||||
*
|
||||
* 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 && of_offset != -1) {
|
||||
fdtdec_get_alias_seq(gd->fdt_blob,
|
||||
uc->uc_drv->name, of_offset,
|
||||
&dev->req_seq);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!dev->platdata && drv->platdata_auto_alloc_size) {
|
||||
dev->flags |= DM_FLAG_ALLOC_PDATA;
|
||||
dev->platdata = calloc(1, drv->platdata_auto_alloc_size);
|
||||
|
@ -79,9 +81,19 @@ int device_bind(struct udevice *parent, const struct driver *drv,
|
|||
goto fail_alloc1;
|
||||
}
|
||||
}
|
||||
if (parent) {
|
||||
int size = parent->driver->per_child_platdata_auto_alloc_size;
|
||||
|
||||
size = uc->uc_drv->per_device_platdata_auto_alloc_size;
|
||||
if (size) {
|
||||
dev->flags |= DM_FLAG_ALLOC_UCLASS_PDATA;
|
||||
dev->uclass_platdata = calloc(1, size);
|
||||
if (!dev->uclass_platdata) {
|
||||
ret = -ENOMEM;
|
||||
goto fail_alloc2;
|
||||
}
|
||||
}
|
||||
|
||||
if (parent) {
|
||||
size = parent->driver->per_child_platdata_auto_alloc_size;
|
||||
if (!size) {
|
||||
size = parent->uclass->uc_drv->
|
||||
per_child_platdata_auto_alloc_size;
|
||||
|
@ -91,7 +103,7 @@ int device_bind(struct udevice *parent, const struct driver *drv,
|
|||
dev->parent_platdata = calloc(1, size);
|
||||
if (!dev->parent_platdata) {
|
||||
ret = -ENOMEM;
|
||||
goto fail_alloc2;
|
||||
goto fail_alloc3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -123,21 +135,32 @@ int device_bind(struct udevice *parent, const struct driver *drv,
|
|||
return 0;
|
||||
|
||||
fail_child_post_bind:
|
||||
if (drv->unbind && drv->unbind(dev)) {
|
||||
dm_warn("unbind() method failed on dev '%s' on error path\n",
|
||||
dev->name);
|
||||
if (IS_ENABLED(DM_DEVICE_REMOVE)) {
|
||||
if (drv->unbind && drv->unbind(dev)) {
|
||||
dm_warn("unbind() method failed on dev '%s' on error path\n",
|
||||
dev->name);
|
||||
}
|
||||
}
|
||||
|
||||
fail_bind:
|
||||
if (uclass_unbind_device(dev)) {
|
||||
dm_warn("Failed to unbind dev '%s' on error path\n",
|
||||
dev->name);
|
||||
if (IS_ENABLED(DM_DEVICE_REMOVE)) {
|
||||
if (uclass_unbind_device(dev)) {
|
||||
dm_warn("Failed to unbind dev '%s' on error path\n",
|
||||
dev->name);
|
||||
}
|
||||
}
|
||||
fail_uclass_bind:
|
||||
list_del(&dev->sibling_node);
|
||||
if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) {
|
||||
free(dev->parent_platdata);
|
||||
dev->parent_platdata = NULL;
|
||||
if (IS_ENABLED(DM_DEVICE_REMOVE)) {
|
||||
list_del(&dev->sibling_node);
|
||||
if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) {
|
||||
free(dev->parent_platdata);
|
||||
dev->parent_platdata = NULL;
|
||||
}
|
||||
}
|
||||
fail_alloc3:
|
||||
if (dev->flags & DM_FLAG_ALLOC_UCLASS_PDATA) {
|
||||
free(dev->uclass_platdata);
|
||||
dev->uclass_platdata = NULL;
|
||||
}
|
||||
fail_alloc2:
|
||||
if (dev->flags & DM_FLAG_ALLOC_PDATA) {
|
||||
|
@ -314,6 +337,16 @@ void *dev_get_parent_platdata(struct udevice *dev)
|
|||
return dev->parent_platdata;
|
||||
}
|
||||
|
||||
void *dev_get_uclass_platdata(struct udevice *dev)
|
||||
{
|
||||
if (!dev) {
|
||||
dm_warn("%s: null device", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dev->uclass_platdata;
|
||||
}
|
||||
|
||||
void *dev_get_priv(struct udevice *dev)
|
||||
{
|
||||
if (!dev) {
|
||||
|
@ -474,11 +507,27 @@ ulong dev_get_driver_data(struct udevice *dev)
|
|||
return dev->driver_data;
|
||||
}
|
||||
|
||||
const void *dev_get_driver_ops(struct udevice *dev)
|
||||
{
|
||||
if (!dev || !dev->driver->ops)
|
||||
return NULL;
|
||||
|
||||
return dev->driver->ops;
|
||||
}
|
||||
|
||||
enum uclass_id device_get_uclass_id(struct udevice *dev)
|
||||
{
|
||||
return dev->uclass->uc_drv->id;
|
||||
}
|
||||
|
||||
const char *dev_get_uclass_name(struct udevice *dev)
|
||||
{
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
return dev->uclass->uc_drv->name;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF_CONTROL
|
||||
fdt_addr_t dev_get_addr(struct udevice *dev)
|
||||
{
|
||||
|
|
|
@ -197,13 +197,15 @@ int dm_init_and_scan(bool pre_reloc_only)
|
|||
debug("dm_scan_platdata() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
#ifdef CONFIG_OF_CONTROL
|
||||
ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only);
|
||||
if (ret) {
|
||||
debug("dm_scan_fdt() failed: %d\n", ret);
|
||||
return ret;
|
||||
|
||||
if (OF_CONTROL) {
|
||||
ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only);
|
||||
if (ret) {
|
||||
debug("dm_scan_fdt() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = dm_scan_other(pre_reloc_only);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -99,10 +99,18 @@ fail_mem:
|
|||
int uclass_destroy(struct uclass *uc)
|
||||
{
|
||||
struct uclass_driver *uc_drv;
|
||||
struct udevice *dev, *tmp;
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
list_for_each_entry_safe(dev, tmp, &uc->dev_head, uclass_node) {
|
||||
/*
|
||||
* We cannot use list_for_each_entry_safe() here. If a device in this
|
||||
* uclass has a child device also in this uclass, it will be also be
|
||||
* unbound (by the recursion in the call to device_unbind() below).
|
||||
* We can loop until the list is empty.
|
||||
*/
|
||||
while (!list_empty(&uc->dev_head)) {
|
||||
dev = list_first_entry(&uc->dev_head, struct udevice,
|
||||
uclass_node);
|
||||
ret = device_remove(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -156,6 +164,60 @@ int uclass_find_device(enum uclass_id id, int index, struct udevice **devp)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
int uclass_find_first_device(enum uclass_id id, struct udevice **devp)
|
||||
{
|
||||
struct uclass *uc;
|
||||
int ret;
|
||||
|
||||
*devp = NULL;
|
||||
ret = uclass_get(id, &uc);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (list_empty(&uc->dev_head))
|
||||
return 0;
|
||||
|
||||
*devp = list_first_entry(&uc->dev_head, struct udevice, uclass_node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uclass_find_next_device(struct udevice **devp)
|
||||
{
|
||||
struct udevice *dev = *devp;
|
||||
|
||||
*devp = NULL;
|
||||
if (list_is_last(&dev->uclass_node, &dev->uclass->dev_head))
|
||||
return 0;
|
||||
|
||||
*devp = list_entry(dev->uclass_node.next, struct udevice, uclass_node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uclass_find_device_by_name(enum uclass_id id, const char *name,
|
||||
struct udevice **devp)
|
||||
{
|
||||
struct uclass *uc;
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
*devp = NULL;
|
||||
if (!name)
|
||||
return -EINVAL;
|
||||
ret = uclass_get(id, &uc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
list_for_each_entry(dev, &uc->dev_head, uclass_node) {
|
||||
if (!strncmp(dev->name, name, strlen(name))) {
|
||||
*devp = dev;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq,
|
||||
bool find_req_seq, struct udevice **devp)
|
||||
{
|
||||
|
@ -209,17 +271,7 @@ static int uclass_find_device_by_of_offset(enum uclass_id id, int node,
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
/**
|
||||
* uclass_get_device_tail() - handle the end of a get_device call
|
||||
*
|
||||
* This handles returning an error or probing a device as needed.
|
||||
*
|
||||
* @dev: Device that needs to be probed
|
||||
* @ret: Error to return. If non-zero then the device is not probed
|
||||
* @devp: Returns the value of 'dev' if there is no error
|
||||
* @return ret, if non-zero, else the result of the device_probe() call
|
||||
*/
|
||||
static int uclass_get_device_tail(struct udevice *dev, int ret,
|
||||
int uclass_get_device_tail(struct udevice *dev, int ret,
|
||||
struct udevice **devp)
|
||||
{
|
||||
if (ret)
|
||||
|
@ -244,6 +296,17 @@ int uclass_get_device(enum uclass_id id, int index, struct udevice **devp)
|
|||
return uclass_get_device_tail(dev, ret, devp);
|
||||
}
|
||||
|
||||
int uclass_get_device_by_name(enum uclass_id id, const char *name,
|
||||
struct udevice **devp)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
*devp = NULL;
|
||||
ret = uclass_find_device_by_name(id, name, &dev);
|
||||
return uclass_get_device_tail(dev, ret, devp);
|
||||
}
|
||||
|
||||
int uclass_get_device_by_seq(enum uclass_id id, int seq, struct udevice **devp)
|
||||
{
|
||||
struct udevice *dev;
|
||||
|
@ -274,24 +337,12 @@ int uclass_get_device_by_of_offset(enum uclass_id id, int node,
|
|||
|
||||
int uclass_first_device(enum uclass_id id, struct udevice **devp)
|
||||
{
|
||||
struct uclass *uc;
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
*devp = NULL;
|
||||
ret = uclass_get(id, &uc);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (list_empty(&uc->dev_head))
|
||||
return 0;
|
||||
|
||||
dev = list_first_entry(&uc->dev_head, struct udevice, uclass_node);
|
||||
ret = device_probe(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
*devp = dev;
|
||||
|
||||
return 0;
|
||||
ret = uclass_find_first_device(id, &dev);
|
||||
return uclass_get_device_tail(dev, ret, devp);
|
||||
}
|
||||
|
||||
int uclass_next_device(struct udevice **devp)
|
||||
|
@ -300,17 +351,8 @@ int uclass_next_device(struct udevice **devp)
|
|||
int ret;
|
||||
|
||||
*devp = NULL;
|
||||
if (list_is_last(&dev->uclass_node, &dev->uclass->dev_head))
|
||||
return 0;
|
||||
|
||||
dev = list_entry(dev->uclass_node.next, struct udevice,
|
||||
uclass_node);
|
||||
ret = device_probe(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
*devp = dev;
|
||||
|
||||
return 0;
|
||||
ret = uclass_find_next_device(&dev);
|
||||
return uclass_get_device_tail(dev, ret, devp);
|
||||
}
|
||||
|
||||
int uclass_bind_device(struct udevice *dev)
|
||||
|
@ -344,6 +386,7 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DM_DEVICE_REMOVE
|
||||
int uclass_unbind_device(struct udevice *dev)
|
||||
{
|
||||
struct uclass *uc;
|
||||
|
@ -359,6 +402,7 @@ int uclass_unbind_device(struct udevice *dev)
|
|||
list_del(&dev->uclass_node);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int uclass_resolve_seq(struct udevice *dev)
|
||||
{
|
||||
|
@ -422,6 +466,7 @@ int uclass_post_probe_device(struct udevice *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DM_DEVICE_REMOVE
|
||||
int uclass_pre_remove_device(struct udevice *dev)
|
||||
{
|
||||
struct uclass_driver *uc_drv;
|
||||
|
@ -443,3 +488,4 @@ int uclass_pre_remove_device(struct udevice *dev)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -66,6 +66,16 @@ config DEBUG_UART_CLOCK
|
|||
A default should be provided by your board, but if not you will need
|
||||
to use the correct value here.
|
||||
|
||||
config DEBUG_UART_SHIFT
|
||||
int "UART register shift"
|
||||
depends on DEBUG_UART
|
||||
default 0 if DEBUG_UART
|
||||
help
|
||||
Some UARTs (notably ns16550) support different register layouts
|
||||
where the registers are spaced either as bytes, words or some other
|
||||
value. Use this value to specify the shift to use, where 0=byte
|
||||
registers, 2=32-bit word registers, etc.
|
||||
|
||||
config UNIPHIER_SERIAL
|
||||
bool "UniPhier on-chip UART support"
|
||||
depends on ARCH_UNIPHIER && DM_SERIAL
|
||||
|
|
|
@ -57,7 +57,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||
|
||||
#ifdef CONFIG_DM_SERIAL
|
||||
|
||||
static inline void serial_out_shift(unsigned char *addr, int shift, int value)
|
||||
static inline void serial_out_shift(void *addr, int shift, int value)
|
||||
{
|
||||
#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
|
||||
outb(value, (ulong)addr);
|
||||
|
@ -72,7 +72,7 @@ static inline void serial_out_shift(unsigned char *addr, int shift, int value)
|
|||
#endif
|
||||
}
|
||||
|
||||
static inline int serial_in_shift(unsigned char *addr, int shift)
|
||||
static inline int serial_in_shift(void *addr, int shift)
|
||||
{
|
||||
#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
|
||||
return inb((ulong)addr);
|
||||
|
@ -114,9 +114,11 @@ static int ns16550_readb(NS16550_t port, int offset)
|
|||
|
||||
/* We can clean these up once everything is moved to driver model */
|
||||
#define serial_out(value, addr) \
|
||||
ns16550_writeb(com_port, addr - (unsigned char *)com_port, value)
|
||||
ns16550_writeb(com_port, \
|
||||
(unsigned char *)addr - (unsigned char *)com_port, value)
|
||||
#define serial_in(addr) \
|
||||
ns16550_readb(com_port, addr - (unsigned char *)com_port)
|
||||
ns16550_readb(com_port, \
|
||||
(unsigned char *)addr - (unsigned char *)com_port)
|
||||
#endif
|
||||
|
||||
static inline int calc_divisor(NS16550_t port, int clock, int baudrate)
|
||||
|
@ -173,7 +175,6 @@ void NS16550_init(NS16550_t com_port, int baud_divisor)
|
|||
defined(CONFIG_TI81XX) || defined(CONFIG_AM43XX)
|
||||
serial_out(0x7, &com_port->mdr1); /* mode select reset TL16C750*/
|
||||
#endif
|
||||
NS16550_setbrg(com_port, 0);
|
||||
serial_out(UART_MCRVAL, &com_port->mcr);
|
||||
serial_out(UART_FCRVAL, &com_port->fcr);
|
||||
if (baud_divisor != -1)
|
||||
|
@ -254,15 +255,20 @@ void debug_uart_init(void)
|
|||
*/
|
||||
baud_divisor = calc_divisor(com_port, CONFIG_DEBUG_UART_CLOCK,
|
||||
CONFIG_BAUDRATE);
|
||||
baud_divisor = 13;
|
||||
serial_out_shift(&com_port->ier, CONFIG_DEBUG_UART_SHIFT,
|
||||
CONFIG_SYS_NS16550_IER);
|
||||
serial_out_shift(&com_port->mcr, CONFIG_DEBUG_UART_SHIFT, UART_MCRVAL);
|
||||
serial_out_shift(&com_port->fcr, CONFIG_DEBUG_UART_SHIFT, UART_FCRVAL);
|
||||
|
||||
serial_out_shift(&com_port->ier, 0, CONFIG_SYS_NS16550_IER);
|
||||
serial_out_shift(&com_port->mcr, 0, UART_MCRVAL);
|
||||
serial_out_shift(&com_port->fcr, 0, UART_FCRVAL);
|
||||
|
||||
serial_out_shift(&com_port->lcr, 0, UART_LCR_BKSE | UART_LCRVAL);
|
||||
serial_out_shift(&com_port->dll, 0, baud_divisor & 0xff);
|
||||
serial_out_shift(&com_port->dlm, 0, (baud_divisor >> 8) & 0xff);
|
||||
serial_out_shift(&com_port->lcr, 0, UART_LCRVAL);
|
||||
serial_out_shift(&com_port->lcr, CONFIG_DEBUG_UART_SHIFT,
|
||||
UART_LCR_BKSE | UART_LCRVAL);
|
||||
serial_out_shift(&com_port->dll, CONFIG_DEBUG_UART_SHIFT,
|
||||
baud_divisor & 0xff);
|
||||
serial_out_shift(&com_port->dlm, CONFIG_DEBUG_UART_SHIFT,
|
||||
(baud_divisor >> 8) & 0xff);
|
||||
serial_out_shift(&com_port->lcr, CONFIG_DEBUG_UART_SHIFT,
|
||||
UART_LCRVAL);
|
||||
}
|
||||
|
||||
static inline void _debug_uart_putc(int ch)
|
||||
|
@ -271,7 +277,7 @@ static inline void _debug_uart_putc(int ch)
|
|||
|
||||
while (!(serial_in_shift(&com_port->lsr, 0) & UART_LSR_THRE))
|
||||
;
|
||||
serial_out_shift(&com_port->thr, 0, ch);
|
||||
serial_out_shift(&com_port->thr, CONFIG_DEBUG_UART_SHIFT, ch);
|
||||
}
|
||||
|
||||
DEBUG_UART_FUNCS
|
||||
|
|
|
@ -70,7 +70,7 @@ static void serial_find_console_or_panic(void)
|
|||
if (uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &dev) &&
|
||||
uclass_get_device(UCLASS_SERIAL, INDEX, &dev) &&
|
||||
(uclass_first_device(UCLASS_SERIAL, &dev) || !dev))
|
||||
panic("No serial driver found");
|
||||
panic_str("No serial driver found");
|
||||
#undef INDEX
|
||||
gd->cur_serial_dev = dev;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ static struct usb_string hub_strings[] = {
|
|||
{STRING_MANUFACTURER, "sandbox"},
|
||||
{STRING_PRODUCT, "hub"},
|
||||
{STRING_SERIAL, "2345"},
|
||||
{},
|
||||
};
|
||||
|
||||
static struct usb_device_descriptor hub_device_desc = {
|
||||
|
|
11
dts/Kconfig
11
dts/Kconfig
|
@ -1,9 +1,6 @@
|
|||
#
|
||||
# Device Tree Control
|
||||
#
|
||||
# TODO:
|
||||
# This feature is not currently supported for SPL,
|
||||
# but this restriction should be removed in the future.
|
||||
|
||||
config SUPPORT_OF_CONTROL
|
||||
bool
|
||||
|
@ -17,6 +14,14 @@ config OF_CONTROL
|
|||
This feature provides for run-time configuration of U-Boot
|
||||
via a flattened device tree.
|
||||
|
||||
config SPL_DISABLE_OF_CONTROL
|
||||
bool "Disable run-time configuration via Device Tree in SPL"
|
||||
depends on OF_CONTROL
|
||||
help
|
||||
Some boards use device tree in U-Boot but only have 4KB of SRAM
|
||||
which is not enough to support device tree. Enable this option to
|
||||
allow such boards to be supported by U-Boot SPL.
|
||||
|
||||
choice
|
||||
prompt "Provider of DTB for DT control"
|
||||
depends on OF_CONTROL
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#undef CONFIG_DM_WARN
|
||||
#undef CONFIG_DM_DEVICE_REMOVE
|
||||
#undef CONFIG_DM_SEQ_ALIAS
|
||||
#undef CONFIG_DM_STDIO
|
||||
|
||||
#endif /* CONFIG_SPL_BUILD */
|
||||
|
|
|
@ -30,8 +30,11 @@ struct driver_info;
|
|||
/* DM is responsible for allocating and freeing parent_platdata */
|
||||
#define DM_FLAG_ALLOC_PARENT_PDATA (1 << 3)
|
||||
|
||||
/* DM is responsible for allocating and freeing uclass_platdata */
|
||||
#define DM_FLAG_ALLOC_UCLASS_PDATA (1 << 4)
|
||||
|
||||
/* Allocate driver private data on a DMA boundary */
|
||||
#define DM_FLAG_ALLOC_PRIV_DMA (1 << 4)
|
||||
#define DM_FLAG_ALLOC_PRIV_DMA (1 << 5)
|
||||
|
||||
/**
|
||||
* struct udevice - An instance of a driver
|
||||
|
@ -54,6 +57,7 @@ struct driver_info;
|
|||
* @name: Name of device, typically the FDT node name
|
||||
* @platdata: Configuration data for this device
|
||||
* @parent_platdata: The parent bus's configuration data for this device
|
||||
* @uclass_platdata: The uclass's configuration data for this device
|
||||
* @of_offset: Device tree node offset for this device (- for none)
|
||||
* @driver_data: Driver data word for the entry that matched this device with
|
||||
* its driver
|
||||
|
@ -75,6 +79,7 @@ struct udevice {
|
|||
const char *name;
|
||||
void *platdata;
|
||||
void *parent_platdata;
|
||||
void *uclass_platdata;
|
||||
int of_offset;
|
||||
ulong driver_data;
|
||||
struct udevice *parent;
|
||||
|
@ -209,6 +214,16 @@ void *dev_get_platdata(struct udevice *dev);
|
|||
*/
|
||||
void *dev_get_parent_platdata(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* dev_get_uclass_platdata() - Get the uclass platform data for a device
|
||||
*
|
||||
* This checks that dev is not NULL, but no other checks for now
|
||||
*
|
||||
* @dev Device to check
|
||||
* @return uclass's platform data, or NULL if none
|
||||
*/
|
||||
void *dev_get_uclass_platdata(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* dev_get_parentdata() - Get the parent data for a device
|
||||
*
|
||||
|
@ -265,6 +280,17 @@ void *dev_get_uclass_priv(struct udevice *dev);
|
|||
*/
|
||||
ulong dev_get_driver_data(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* dev_get_driver_ops() - get the device's driver's operations
|
||||
*
|
||||
* This checks that dev is not NULL, and returns the pointer to device's
|
||||
* driver's operations.
|
||||
*
|
||||
* @dev: Device to check
|
||||
* @return void pointer to driver's operations or NULL for NULL-dev or NULL-ops
|
||||
*/
|
||||
const void *dev_get_driver_ops(struct udevice *dev);
|
||||
|
||||
/*
|
||||
* device_get_uclass_id() - return the uclass ID of a device
|
||||
*
|
||||
|
@ -273,6 +299,16 @@ ulong dev_get_driver_data(struct udevice *dev);
|
|||
*/
|
||||
enum uclass_id device_get_uclass_id(struct udevice *dev);
|
||||
|
||||
/*
|
||||
* dev_get_uclass_name() - return the uclass name of a device
|
||||
*
|
||||
* This checks that dev is not NULL.
|
||||
*
|
||||
* @dev: Device to check
|
||||
* @return pointer to the uclass name for the device
|
||||
*/
|
||||
const char *dev_get_uclass_name(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* device_get_child() - Get the child of a device by index
|
||||
*
|
||||
|
|
|
@ -98,6 +98,26 @@ struct dm_test_parent_data {
|
|||
int flag;
|
||||
};
|
||||
|
||||
/* Test values for test device's uclass platform data */
|
||||
enum {
|
||||
TEST_UC_PDATA_INTVAL1 = 2,
|
||||
TEST_UC_PDATA_INTVAL2 = 334,
|
||||
TEST_UC_PDATA_INTVAL3 = 789452,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dm_test_uclass_platda - uclass's information on each device
|
||||
*
|
||||
* @intval1: set to TEST_UC_PDATA_INTVAL1 in .post_bind method of test uclass
|
||||
* @intval2: set to TEST_UC_PDATA_INTVAL2 in .post_bind method of test uclass
|
||||
* @intval3: set to TEST_UC_PDATA_INTVAL3 in .post_bind method of test uclass
|
||||
*/
|
||||
struct dm_test_perdev_uc_pdata {
|
||||
int intval1;
|
||||
int intval2;
|
||||
int intval3;
|
||||
};
|
||||
|
||||
/*
|
||||
* Operation counts for the test driver, used to check that each method is
|
||||
* called correctly
|
||||
|
|
|
@ -10,19 +10,94 @@
|
|||
#ifndef _DM_UCLASS_INTERNAL_H
|
||||
#define _DM_UCLASS_INTERNAL_H
|
||||
|
||||
/**
|
||||
* uclass_get_device_tail() - handle the end of a get_device call
|
||||
*
|
||||
* This handles returning an error or probing a device as needed.
|
||||
*
|
||||
* @dev: Device that needs to be probed
|
||||
* @ret: Error to return. If non-zero then the device is not probed
|
||||
* @devp: Returns the value of 'dev' if there is no error
|
||||
* @return ret, if non-zero, else the result of the device_probe() call
|
||||
*/
|
||||
int uclass_get_device_tail(struct udevice *dev, int ret, struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_find_device() - Return n-th child of uclass
|
||||
* @id: Id number of the uclass
|
||||
* @index: Position of the child in uclass's list
|
||||
* #devp: Returns pointer to device, or NULL on error
|
||||
*
|
||||
* The device is not prepared for use - this is an internal function
|
||||
* The device is not prepared for use - this is an internal function.
|
||||
* The function uclass_get_device_tail() can be used to probe the device.
|
||||
*
|
||||
* @return the uclass pointer of a child at the given index or
|
||||
* return NULL on error.
|
||||
*/
|
||||
int uclass_find_device(enum uclass_id id, int index, struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_find_first_device() - Return the first device in a uclass
|
||||
* @id: Id number of the uclass
|
||||
* #devp: Returns pointer to device, or NULL on error
|
||||
*
|
||||
* The device is not prepared for use - this is an internal function.
|
||||
* The function uclass_get_device_tail() can be used to probe the device.
|
||||
*
|
||||
* @return 0 if OK (found or not found), -1 on error
|
||||
*/
|
||||
int uclass_find_first_device(enum uclass_id id, struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_find_next_device() - Return the next device in a uclass
|
||||
* @devp: On entry, pointer to device to lookup. On exit, returns pointer
|
||||
* to the next device in the same uclass, or NULL if none
|
||||
*
|
||||
* The device is not prepared for use - this is an internal function.
|
||||
* The function uclass_get_device_tail() can be used to probe the device.
|
||||
*
|
||||
* @return 0 if OK (found or not found), -1 on error
|
||||
*/
|
||||
int uclass_find_next_device(struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_find_device_by_name() - Find uclass device based on ID and name
|
||||
*
|
||||
* This searches for a device with the exactly given name.
|
||||
*
|
||||
* The device is NOT probed, it is merely returned.
|
||||
*
|
||||
* @id: ID to look up
|
||||
* @name: name of a device to find
|
||||
* @devp: Returns pointer to device (the first one with the name)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int uclass_find_device_by_name(enum uclass_id id, const char *name,
|
||||
struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_find_device_by_seq() - Find uclass device based on ID and sequence
|
||||
*
|
||||
* This searches for a device with the given seq or req_seq.
|
||||
*
|
||||
* For seq, if an active device has this sequence it will be returned.
|
||||
* If there is no such device then this will return -ENODEV.
|
||||
*
|
||||
* For req_seq, if a device (whether activated or not) has this req_seq
|
||||
* value, that device will be returned. This is a strong indication that
|
||||
* the device will receive that sequence when activated.
|
||||
*
|
||||
* The device is NOT probed, it is merely returned.
|
||||
*
|
||||
* @id: ID to look up
|
||||
* @seq_or_req_seq: Sequence number to find (0=first)
|
||||
* @find_req_seq: true to find req_seq, false to find seq
|
||||
* @devp: Returns pointer to device (there is only one per for each seq)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq,
|
||||
bool find_req_seq, struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_bind_device() - Associate device with a uclass
|
||||
*
|
||||
|
@ -41,7 +116,11 @@ int uclass_bind_device(struct udevice *dev);
|
|||
* @dev: Pointer to the device
|
||||
* #return 0 on success, -ve on error
|
||||
*/
|
||||
#ifdef CONFIG_DM_DEVICE_REMOVE
|
||||
int uclass_unbind_device(struct udevice *dev);
|
||||
#else
|
||||
static inline int uclass_unbind_device(struct udevice *dev) { return 0; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* uclass_pre_probe_device() - Deal with a device that is about to be probed
|
||||
|
@ -74,7 +153,11 @@ int uclass_post_probe_device(struct udevice *dev);
|
|||
* @dev: Pointer to the device
|
||||
* #return 0 on success, -ve on error
|
||||
*/
|
||||
#ifdef CONFIG_DM_DEVICE_REMOVE
|
||||
int uclass_pre_remove_device(struct udevice *dev);
|
||||
#else
|
||||
static inline int uclass_pre_remove_device(struct udevice *dev) { return 0; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* uclass_find() - Find uclass by its id
|
||||
|
@ -94,27 +177,4 @@ struct uclass *uclass_find(enum uclass_id key);
|
|||
*/
|
||||
int uclass_destroy(struct uclass *uc);
|
||||
|
||||
/**
|
||||
* uclass_find_device_by_seq() - Find uclass device based on ID and sequence
|
||||
*
|
||||
* This searches for a device with the given seq or req_seq.
|
||||
*
|
||||
* For seq, if an active device has this sequence it will be returned.
|
||||
* If there is no such device then this will return -ENODEV.
|
||||
*
|
||||
* For req_seq, if a device (whether activated or not) has this req_seq
|
||||
* value, that device will be returned. This is a strong indication that
|
||||
* the device will receive that sequence when activated.
|
||||
*
|
||||
* The device is NOT probed, it is merely returned.
|
||||
*
|
||||
* @id: ID to look up
|
||||
* @seq_or_req_seq: Sequence number to find (0=first)
|
||||
* @find_req_seq: true to find req_seq, false to find seq
|
||||
* @devp: Returns pointer to device (there is only one per for each seq)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq,
|
||||
bool find_req_seq, struct udevice **devp);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -65,6 +65,9 @@ struct udevice;
|
|||
* @per_device_auto_alloc_size: Each device can hold private data owned
|
||||
* by the uclass. If required this will be automatically allocated if this
|
||||
* value is non-zero.
|
||||
* @per_device_platdata_auto_alloc_size: Each device can hold platform data
|
||||
* owned by the uclass as 'dev->uclass_platdata'. If the value is non-zero,
|
||||
* then this will be automatically allocated.
|
||||
* @per_child_auto_alloc_size: Each child device (of a parent in this
|
||||
* uclass) can hold parent data for the device/uclass. This value is only
|
||||
* used as a falback if this member is 0 in the driver.
|
||||
|
@ -90,6 +93,7 @@ struct uclass_driver {
|
|||
int (*destroy)(struct uclass *class);
|
||||
int priv_auto_alloc_size;
|
||||
int per_device_auto_alloc_size;
|
||||
int per_device_platdata_auto_alloc_size;
|
||||
int per_child_auto_alloc_size;
|
||||
int per_child_platdata_auto_alloc_size;
|
||||
const void *ops;
|
||||
|
@ -125,6 +129,21 @@ int uclass_get(enum uclass_id key, struct uclass **ucp);
|
|||
*/
|
||||
int uclass_get_device(enum uclass_id id, int index, struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_get_device_by_name() - Get a uclass device by it's name
|
||||
*
|
||||
* This searches the devices in the uclass for one with the exactly given name.
|
||||
*
|
||||
* The device is probed to activate it ready for use.
|
||||
*
|
||||
* @id: ID to look up
|
||||
* @name: name of a device to get
|
||||
* @devp: Returns pointer to device (the first one with the name)
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int uclass_get_device_by_name(enum uclass_id id, const char *name,
|
||||
struct udevice **devp);
|
||||
|
||||
/**
|
||||
* uclass_get_device_by_seq() - Get a uclass device based on an ID and sequence
|
||||
*
|
||||
|
|
|
@ -41,6 +41,16 @@ struct fdt_memory {
|
|||
fdt_addr_t end;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF_CONTROL
|
||||
# if defined(CONFIG_SPL_BUILD) && defined(SPL_DISABLE_OF_CONTROL)
|
||||
# define OF_CONTROL 0
|
||||
# else
|
||||
# define OF_CONTROL 1
|
||||
# endif
|
||||
#else
|
||||
# define OF_CONTROL 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Information about a resource. start is the first address of the resource
|
||||
* and end is the last address (inclusive). The length of the resource will
|
||||
|
@ -793,4 +803,10 @@ int fdt_get_named_resource(const void *fdt, int node, const char *property,
|
|||
int fdtdec_decode_memory_region(const void *blob, int node,
|
||||
const char *mem_type, const char *suffix,
|
||||
fdt_addr_t *basep, fdt_size_t *sizep);
|
||||
|
||||
/**
|
||||
* Set up the device tree ready for use
|
||||
*/
|
||||
int fdtdec_setup(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -906,6 +906,9 @@ void *realloc_simple(void *ptr, size_t size);
|
|||
|
||||
#endif
|
||||
|
||||
/* Set up pre-relocation malloc() ready for use */
|
||||
int initf_malloc(void);
|
||||
|
||||
/* Public routines */
|
||||
|
||||
/* Simple versions which can be used when space is tight */
|
||||
|
|
|
@ -39,9 +39,32 @@ int strict_strtoul(const char *cp, unsigned int base, unsigned long *res);
|
|||
unsigned long long simple_strtoull(const char *cp, char **endp,
|
||||
unsigned int base);
|
||||
long simple_strtol(const char *cp, char **endp, unsigned int base);
|
||||
|
||||
/**
|
||||
* panic() - Print a message and reset/hang
|
||||
*
|
||||
* Prints a message on the console(s) and then resets. If CONFIG_PANIC_HANG is
|
||||
* defined, then it will hang instead of reseting.
|
||||
*
|
||||
* @param fmt: printf() format string for message, which should not include
|
||||
* \n, followed by arguments
|
||||
*/
|
||||
void panic(const char *fmt, ...)
|
||||
__attribute__ ((format (__printf__, 1, 2), noreturn));
|
||||
|
||||
/**
|
||||
* panic_str() - Print a message and reset/hang
|
||||
*
|
||||
* Prints a message on the console(s) and then resets. If CONFIG_PANIC_HANG is
|
||||
* defined, then it will hang instead of reseting.
|
||||
*
|
||||
* This function can be used instead of panic() when your board does not
|
||||
* already use printf(), * to keep code size small.
|
||||
*
|
||||
* @param fmt: string to display, which should not include \n
|
||||
*/
|
||||
void panic_str(const char *str) __attribute__ ((noreturn));
|
||||
|
||||
/**
|
||||
* Format a string and place it in a buffer
|
||||
*
|
||||
|
|
|
@ -44,6 +44,12 @@ obj-$(CONFIG_BITREVERSE) += bitrev.o
|
|||
obj-y += list_sort.o
|
||||
endif
|
||||
|
||||
ifndef CONFIG_SPL_DISABLE_OF_CONTROL
|
||||
obj-$(CONFIG_OF_LIBFDT) += libfdt/
|
||||
obj-$(CONFIG_OF_CONTROL) += fdtdec_common.o
|
||||
obj-$(CONFIG_OF_CONTROL) += fdtdec.o
|
||||
endif
|
||||
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
obj-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o
|
||||
obj-$(CONFIG_SPL_NET_SUPPORT) += net_utils.o
|
||||
|
|
39
lib/fdtdec.c
39
lib/fdtdec.c
|
@ -9,6 +9,7 @@
|
|||
#include <serial.h>
|
||||
#include <libfdt.h>
|
||||
#include <fdtdec.h>
|
||||
#include <asm/sections.h>
|
||||
#include <linux/ctype.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
@ -565,9 +566,11 @@ int fdtdec_prepare_fdt(void)
|
|||
{
|
||||
if (!gd->fdt_blob || ((uintptr_t)gd->fdt_blob & 3) ||
|
||||
fdt_check_header(gd->fdt_blob)) {
|
||||
printf("No valid FDT found - please append one to U-Boot "
|
||||
"binary, use u-boot-dtb.bin or define "
|
||||
"CONFIG_OF_EMBED. For sandbox, use -d <file.dtb>\n");
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
puts("Missing DTB\n");
|
||||
#else
|
||||
puts("No valid device tree binary found - please append one to U-Boot binary, use u-boot-dtb.bin or define CONFIG_OF_EMBED. For sandbox, use -d <file.dtb>\n");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -1035,4 +1038,34 @@ int fdtdec_decode_memory_region(const void *blob, int config_node,
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdtdec_setup(void)
|
||||
{
|
||||
#ifdef CONFIG_OF_CONTROL
|
||||
# ifdef CONFIG_OF_EMBED
|
||||
/* Get a pointer to the FDT */
|
||||
gd->fdt_blob = __dtb_dt_begin;
|
||||
# elif defined CONFIG_OF_SEPARATE
|
||||
# ifdef CONFIG_SPL_BUILD
|
||||
/* FDT is at end of BSS */
|
||||
gd->fdt_blob = (ulong *)&__bss_end;
|
||||
# else
|
||||
/* FDT is at end of image */
|
||||
gd->fdt_blob = (ulong *)&_end;
|
||||
#endif
|
||||
# elif defined(CONFIG_OF_HOSTFILE)
|
||||
if (sandbox_read_fdt_from_file()) {
|
||||
puts("Failed to read control FDT\n");
|
||||
return -1;
|
||||
}
|
||||
# endif
|
||||
# ifndef CONFIG_SPL_BUILD
|
||||
/* Allow the early environment to override the fdt address */
|
||||
gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16,
|
||||
(uintptr_t)gd->fdt_blob);
|
||||
# endif
|
||||
#endif
|
||||
return fdtdec_prepare_fdt();
|
||||
}
|
||||
|
||||
#endif /* !USE_HOSTCC */
|
||||
|
|
|
@ -842,13 +842,11 @@ int sprintf(char *buf, const char *fmt, ...)
|
|||
return i;
|
||||
}
|
||||
|
||||
void panic(const char *fmt, ...)
|
||||
static void panic_finish(void) __attribute__ ((noreturn));
|
||||
|
||||
static void panic_finish(void)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vprintf(fmt, args);
|
||||
putc('\n');
|
||||
va_end(args);
|
||||
#if defined(CONFIG_PANIC_HANG)
|
||||
hang();
|
||||
#else
|
||||
|
@ -859,6 +857,21 @@ void panic(const char *fmt, ...)
|
|||
;
|
||||
}
|
||||
|
||||
void panic_str(const char *str)
|
||||
{
|
||||
puts(str);
|
||||
panic_finish();
|
||||
}
|
||||
|
||||
void panic(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vprintf(fmt, args);
|
||||
va_end(args);
|
||||
panic_finish();
|
||||
}
|
||||
|
||||
void __assert_fail(const char *assertion, const char *file, unsigned line,
|
||||
const char *function)
|
||||
{
|
||||
|
|
175
test/dm/core.c
175
test/dm/core.c
|
@ -129,6 +129,61 @@ static int dm_test_autobind(struct dm_test_state *dms)
|
|||
}
|
||||
DM_TEST(dm_test_autobind, 0);
|
||||
|
||||
/* Test that binding with uclass platdata allocation occurs correctly */
|
||||
static int dm_test_autobind_uclass_pdata_alloc(struct dm_test_state *dms)
|
||||
{
|
||||
struct dm_test_perdev_uc_pdata *uc_pdata;
|
||||
struct udevice *dev;
|
||||
struct uclass *uc;
|
||||
|
||||
ut_assertok(uclass_get(UCLASS_TEST, &uc));
|
||||
ut_assert(uc);
|
||||
|
||||
/**
|
||||
* Test if test uclass driver requires allocation for the uclass
|
||||
* platform data and then check the dev->uclass_platdata pointer.
|
||||
*/
|
||||
ut_assert(uc->uc_drv->per_device_platdata_auto_alloc_size);
|
||||
|
||||
for (uclass_find_first_device(UCLASS_TEST, &dev);
|
||||
dev;
|
||||
uclass_find_next_device(&dev)) {
|
||||
ut_assert(dev);
|
||||
|
||||
uc_pdata = dev_get_uclass_platdata(dev);
|
||||
ut_assert(uc_pdata);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_autobind_uclass_pdata_alloc, DM_TESTF_SCAN_PDATA);
|
||||
|
||||
/* Test that binding with uclass platdata setting occurs correctly */
|
||||
static int dm_test_autobind_uclass_pdata_valid(struct dm_test_state *dms)
|
||||
{
|
||||
struct dm_test_perdev_uc_pdata *uc_pdata;
|
||||
struct udevice *dev;
|
||||
|
||||
/**
|
||||
* In the test_postbind() method of test uclass driver, the uclass
|
||||
* platform data should be set to three test int values - test it.
|
||||
*/
|
||||
for (uclass_find_first_device(UCLASS_TEST, &dev);
|
||||
dev;
|
||||
uclass_find_next_device(&dev)) {
|
||||
ut_assert(dev);
|
||||
|
||||
uc_pdata = dev_get_uclass_platdata(dev);
|
||||
ut_assert(uc_pdata);
|
||||
ut_assert(uc_pdata->intval1 == TEST_UC_PDATA_INTVAL1);
|
||||
ut_assert(uc_pdata->intval2 == TEST_UC_PDATA_INTVAL2);
|
||||
ut_assert(uc_pdata->intval3 == TEST_UC_PDATA_INTVAL3);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_autobind_uclass_pdata_valid, DM_TESTF_SCAN_PDATA);
|
||||
|
||||
/* Test that autoprobe finds all the expected devices */
|
||||
static int dm_test_autoprobe(struct dm_test_state *dms)
|
||||
{
|
||||
|
@ -596,14 +651,130 @@ static int dm_test_uclass_before_ready(struct dm_test_state *dms)
|
|||
|
||||
ut_assertok(uclass_get(UCLASS_TEST, &uc));
|
||||
|
||||
memset(gd, '\0', sizeof(*gd));
|
||||
gd->dm_root = NULL;
|
||||
gd->dm_root_f = NULL;
|
||||
memset(&gd->uclass_root, '\0', sizeof(gd->uclass_root));
|
||||
|
||||
ut_asserteq_ptr(NULL, uclass_find(UCLASS_TEST));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DM_TEST(dm_test_uclass_before_ready, 0);
|
||||
|
||||
static int dm_test_uclass_devices_find(struct dm_test_state *dms)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
|
||||
dev;
|
||||
ret = uclass_find_next_device(&dev)) {
|
||||
ut_assert(!ret);
|
||||
ut_assert(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_uclass_devices_find, DM_TESTF_SCAN_PDATA);
|
||||
|
||||
static int dm_test_uclass_devices_find_by_name(struct dm_test_state *dms)
|
||||
{
|
||||
struct udevice *finddev;
|
||||
struct udevice *testdev;
|
||||
int findret, ret;
|
||||
|
||||
/*
|
||||
* For each test device found in fdt like: "a-test", "b-test", etc.,
|
||||
* use its name and try to find it by uclass_find_device_by_name().
|
||||
* Then, on success check if:
|
||||
* - current 'testdev' name is equal to the returned 'finddev' name
|
||||
* - current 'testdev' pointer is equal to the returned 'finddev'
|
||||
*
|
||||
* We assume that, each uclass's device name is unique, so if not, then
|
||||
* this will fail on checking condition: testdev == finddev, since the
|
||||
* uclass_find_device_by_name(), returns the first device by given name.
|
||||
*/
|
||||
for (ret = uclass_find_first_device(UCLASS_TEST_FDT, &testdev);
|
||||
testdev;
|
||||
ret = uclass_find_next_device(&testdev)) {
|
||||
ut_assertok(ret);
|
||||
ut_assert(testdev);
|
||||
|
||||
findret = uclass_find_device_by_name(UCLASS_TEST_FDT,
|
||||
testdev->name,
|
||||
&finddev);
|
||||
|
||||
ut_assertok(findret);
|
||||
ut_assert(testdev);
|
||||
ut_asserteq_str(testdev->name, finddev->name);
|
||||
ut_asserteq_ptr(testdev, finddev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_uclass_devices_find_by_name, DM_TESTF_SCAN_FDT);
|
||||
|
||||
static int dm_test_uclass_devices_get(struct dm_test_state *dms)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
for (ret = uclass_first_device(UCLASS_TEST, &dev);
|
||||
dev;
|
||||
ret = uclass_next_device(&dev)) {
|
||||
ut_assert(!ret);
|
||||
ut_assert(dev);
|
||||
ut_assert(device_active(dev));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_uclass_devices_get, DM_TESTF_SCAN_PDATA);
|
||||
|
||||
static int dm_test_uclass_devices_get_by_name(struct dm_test_state *dms)
|
||||
{
|
||||
struct udevice *finddev;
|
||||
struct udevice *testdev;
|
||||
int ret, findret;
|
||||
|
||||
/*
|
||||
* For each test device found in fdt like: "a-test", "b-test", etc.,
|
||||
* use its name and try to get it by uclass_get_device_by_name().
|
||||
* On success check if:
|
||||
* - returned finddev' is active
|
||||
* - current 'testdev' name is equal to the returned 'finddev' name
|
||||
* - current 'testdev' pointer is equal to the returned 'finddev'
|
||||
*
|
||||
* We asserts that the 'testdev' is active on each loop entry, so we
|
||||
* could be sure that the 'finddev' is activated too, but for sure
|
||||
* we check it again.
|
||||
*
|
||||
* We assume that, each uclass's device name is unique, so if not, then
|
||||
* this will fail on checking condition: testdev == finddev, since the
|
||||
* uclass_get_device_by_name(), returns the first device by given name.
|
||||
*/
|
||||
for (ret = uclass_first_device(UCLASS_TEST_FDT, &testdev);
|
||||
testdev;
|
||||
ret = uclass_next_device(&testdev)) {
|
||||
ut_assertok(ret);
|
||||
ut_assert(testdev);
|
||||
ut_assert(device_active(testdev));
|
||||
|
||||
findret = uclass_get_device_by_name(UCLASS_TEST_FDT,
|
||||
testdev->name,
|
||||
&finddev);
|
||||
|
||||
ut_assertok(findret);
|
||||
ut_assert(finddev);
|
||||
ut_assert(device_active(finddev));
|
||||
ut_asserteq_str(testdev->name, finddev->name);
|
||||
ut_asserteq_ptr(testdev, finddev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_uclass_devices_get_by_name, DM_TESTF_SCAN_FDT);
|
||||
|
||||
static int dm_test_device_get_uclass_id(struct dm_test_state *dms)
|
||||
{
|
||||
struct udevice *dev;
|
||||
|
|
|
@ -30,9 +30,18 @@ int test_ping(struct udevice *dev, int pingval, int *pingret)
|
|||
|
||||
static int test_post_bind(struct udevice *dev)
|
||||
{
|
||||
struct dm_test_perdev_uc_pdata *uc_pdata;
|
||||
|
||||
dm_testdrv_op_count[DM_TEST_OP_POST_BIND]++;
|
||||
ut_assert(!device_active(dev));
|
||||
|
||||
uc_pdata = dev_get_uclass_platdata(dev);
|
||||
ut_assert(uc_pdata);
|
||||
|
||||
uc_pdata->intval1 = TEST_UC_PDATA_INTVAL1;
|
||||
uc_pdata->intval2 = TEST_UC_PDATA_INTVAL2;
|
||||
uc_pdata->intval3 = TEST_UC_PDATA_INTVAL3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -115,4 +124,6 @@ UCLASS_DRIVER(test) = {
|
|||
.destroy = test_destroy,
|
||||
.priv_auto_alloc_size = sizeof(struct dm_test_uclass_priv),
|
||||
.per_device_auto_alloc_size = sizeof(struct dm_test_uclass_perdev_priv),
|
||||
.per_device_platdata_auto_alloc_size =
|
||||
sizeof(struct dm_test_perdev_uc_pdata),
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue