Преглед изворни кода

Merge tag 'dm-pull-10jul20' of https://gitlab.denx.de/u-boot/custodians/u-boot-dm

of-platdata: better phandle and compatible-string support
patman support for Python3 on Ubuntu 14.04
new checkpatch check to avoid #ifdefs
Tom Rini пре 3 година
родитељ
комит
4a9146c295
95 измењених фајлова са 1030 додато и 313 уклоњено
  1. 4 0
      arch/arm/dts/da850-evm-u-boot.dtsi
  2. 4 0
      arch/arm/dts/da850-lcdk-u-boot.dtsi
  3. 4 0
      arch/arm/dts/rk3288-u-boot.dtsi
  4. 1 1
      arch/arm/dts/rk3288-veyron-speedy-u-boot.dtsi
  5. 11 0
      arch/arm/dts/rk3288-veyron-u-boot.dtsi
  6. 3 3
      arch/arm/mach-at91/arm926ejs/at91sam9260_devices.c
  7. 5 5
      arch/arm/mach-at91/arm926ejs/at91sam9m10g45_devices.c
  8. 2 2
      arch/arm/mach-rockchip/rk3328/syscon_rk3328.c
  9. 10 0
      arch/sandbox/Kconfig
  10. 4 1
      arch/sandbox/cpu/state.c
  11. 1 1
      arch/sandbox/cpu/u-boot-spl.lds
  12. 1 1
      arch/sandbox/include/asm/state.h
  13. 1 1
      board/davinci/da8xxevm/omapl138_lcdk.c
  14. 1 1
      board/sandbox/sandbox.c
  15. 8 3
      cmd/fdt.c
  16. 2 2
      cmd/log.c
  17. 18 0
      common/Kconfig
  18. 5 1
      common/log.c
  19. 7 7
      common/log_console.c
  20. 7 7
      common/log_syslog.c
  21. 29 9
      doc/driver-model/of-plat.rst
  22. 2 2
      drivers/clk/at91/clk-master.c
  23. 2 2
      drivers/clk/at91/clk-peripheral.c
  24. 4 2
      drivers/clk/at91/pmc.c
  25. 5 6
      drivers/clk/clk-uclass.c
  26. 24 4
      drivers/core/device.c
  27. 5 1
      drivers/core/root.c
  28. 2 2
      drivers/core/simple-bus.c
  29. 2 2
      drivers/gpio/at91_gpio.c
  30. 2 2
      drivers/gpio/da8xx_gpio.c
  31. 3 5
      drivers/gpio/mxs_gpio.c
  32. 2 2
      drivers/gpio/rk_gpio.c
  33. 4 2
      drivers/gpio/sandbox.c
  34. 4 2
      drivers/i2c/rk_i2c.c
  35. 2 2
      drivers/input/cros_ec_keyb.c
  36. 2 2
      drivers/misc/cros_ec_sandbox.c
  37. 4 6
      drivers/misc/irq-uclass.c
  38. 1 1
      drivers/mmc/davinci_mmc.c
  39. 1 1
      drivers/mmc/ftsdc010_mci.c
  40. 2 5
      drivers/mmc/mxsmmc.c
  41. 5 2
      drivers/mmc/rockchip_dw_mmc.c
  42. 1 1
      drivers/mmc/rockchip_sdhci.c
  43. 0 2
      drivers/mtd/spi/sandbox.c
  44. 1 1
      drivers/mtd/spi/sf-uclass.c
  45. 4 2
      drivers/mtd/spi/sf_probe.c
  46. 4 2
      drivers/pinctrl/nxp/pinctrl-mxs.c
  47. 4 2
      drivers/pinctrl/pinctrl-at91.c
  48. 1 1
      drivers/pinctrl/rockchip/pinctrl-rk3188.c
  49. 1 1
      drivers/pinctrl/rockchip/pinctrl-rk3288.c
  50. 1 1
      drivers/pinctrl/rockchip/pinctrl-rk3328.c
  51. 1 1
      drivers/pinctrl/rockchip/pinctrl-rk3368.c
  52. 4 2
      drivers/power/pmic/rk8xx.c
  53. 2 2
      drivers/power/regulator/fixed.c
  54. 1 1
      drivers/ram/rockchip/dmc-rk3368.c
  55. 1 1
      drivers/ram/rockchip/sdram_rk3188.c
  56. 1 1
      drivers/ram/rockchip/sdram_rk3288.c
  57. 1 1
      drivers/ram/rockchip/sdram_rk3328.c
  58. 1 1
      drivers/ram/rockchip/sdram_rk3399.c
  59. 4 0
      drivers/serial/ns16550.c
  60. 6 4
      drivers/serial/sandbox.c
  61. 3 5
      drivers/spi/mxs_spi.c
  62. 4 6
      drivers/spi/rk_spi.c
  63. 2 2
      drivers/spi/sandbox_spi.c
  64. 2 2
      drivers/tpm/tpm_tis_sandbox.c
  65. 2 2
      drivers/video/rockchip/rk3288_vop.c
  66. 2 2
      drivers/video/sandbox_sdl.c
  67. 2 2
      drivers/watchdog/at91sam9_wdt.c
  68. 2 2
      include/clk.h
  69. 4 1
      include/configs/sandbox.h
  70. 1 1
      include/dm/device-internal.h
  71. 22 0
      include/dm/device.h
  72. 14 0
      include/dm/platdata.h
  73. 1 1
      include/dm/uclass.h
  74. 17 1
      include/log.h
  75. 1 1
      scripts/checkpatch.pl
  76. 72 1
      test/dm/fdtdec.c
  77. 1 1
      test/dm/gpio.c
  78. 3 3
      test/dm/spi.c
  79. 14 6
      test/log/syslog_test.c
  80. 27 27
      test/py/tests/test_bind.py
  81. 2 0
      test/py/tests/test_log.py
  82. 133 15
      tools/dtoc/dtb_platdata.py
  83. 20 0
      tools/dtoc/dtoc_test_driver_alias.dts
  84. 15 0
      tools/dtoc/dtoc_test_invalid_driver.dts
  85. 42 0
      tools/dtoc/dtoc_test_phandle_cd_gpios.dts
  86. 219 68
      tools/dtoc/test_dtoc.py
  87. 15 9
      tools/patman/checkpatch.py
  88. 3 4
      tools/patman/command.py
  89. 7 7
      tools/patman/get_maintainer.py
  90. 4 6
      tools/patman/gitutil.py
  91. 3 3
      tools/patman/main.py
  92. 2 1
      tools/patman/series.py
  93. 3 4
      tools/patman/settings.py
  94. 121 4
      tools/patman/test_checkpatch.py
  95. 0 1
      tools/patman/test_util.py

+ 4 - 0
arch/arm/dts/da850-evm-u-boot.dtsi

@@ -39,3 +39,7 @@
 &spi1 {
 	u-boot,dm-spl;
 };
+
+&gpio {
+	u-boot,dm-spl;
+};

+ 4 - 0
arch/arm/dts/da850-lcdk-u-boot.dtsi

@@ -28,3 +28,7 @@
 &serial2 {
 	u-boot,dm-spl;
 };
+
+&gpio {
+	u-boot,dm-spl;
+};

+ 4 - 0
arch/arm/dts/rk3288-u-boot.dtsi

@@ -43,3 +43,7 @@
 &noc {
 	u-boot,dm-pre-reloc;
 };
+
+&gpio7 {
+	u-boot,dm-pre-reloc;
+};

+ 1 - 1
arch/arm/dts/rk3288-veyron-speedy-u-boot.dtsi

@@ -3,7 +3,7 @@
  * Copyright 2015 Google, Inc
  */
 
-#include "rk3288-u-boot.dtsi"
+#include "rk3288-veyron-u-boot.dtsi"
 
 &dmc {
 	rockchip,pctl-timing = <0x215 0xc8 0x0 0x35 0x26 0x2 0x70 0x2000d

+ 11 - 0
arch/arm/dts/rk3288-veyron-u-boot.dtsi

@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2015 Google, Inc
+ */
+
+#include "rk3288-u-boot.dtsi"
+
+&gpio7 {
+	u-boot,dm-pre-reloc;
+};
+

+ 3 - 3
arch/arm/mach-at91/arm926ejs/at91sam9260_devices.c

@@ -220,7 +220,7 @@ static const struct at91_port_platdata at91sam9260_plat[] = {
 };
 
 U_BOOT_DEVICES(at91sam9260_gpios) = {
-	{ "gpio_at91", &at91sam9260_plat[0] },
-	{ "gpio_at91", &at91sam9260_plat[1] },
-	{ "gpio_at91", &at91sam9260_plat[2] },
+	{ "atmel_at91rm9200_gpio", &at91sam9260_plat[0] },
+	{ "atmel_at91rm9200_gpio", &at91sam9260_plat[1] },
+	{ "atmel_at91rm9200_gpio", &at91sam9260_plat[2] },
 };

+ 5 - 5
arch/arm/mach-at91/arm926ejs/at91sam9m10g45_devices.c

@@ -176,9 +176,9 @@ static const struct at91_port_platdata at91sam9260_plat[] = {
 };
 
 U_BOOT_DEVICES(at91sam9260_gpios) = {
-	{ "gpio_at91", &at91sam9260_plat[0] },
-	{ "gpio_at91", &at91sam9260_plat[1] },
-	{ "gpio_at91", &at91sam9260_plat[2] },
-	{ "gpio_at91", &at91sam9260_plat[3] },
-	{ "gpio_at91", &at91sam9260_plat[4] },
+	{ "atmel_at91rm9200_gpio", &at91sam9260_plat[0] },
+	{ "atmel_at91rm9200_gpio", &at91sam9260_plat[1] },
+	{ "atmel_at91rm9200_gpio", &at91sam9260_plat[2] },
+	{ "atmel_at91rm9200_gpio", &at91sam9260_plat[3] },
+	{ "atmel_at91rm9200_gpio", &at91sam9260_plat[4] },
 };

+ 2 - 2
arch/arm/mach-rockchip/rk3328/syscon_rk3328.c

@@ -13,8 +13,8 @@ static const struct udevice_id rk3328_syscon_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(syscon_rk3328) = {
-	.name = "rk3328_syscon",
+U_BOOT_DRIVER(rockchip_rk3328_grf) = {
+	.name = "rockchip_rk3328_grf",
 	.id = UCLASS_SYSCON,
 	.of_match = rk3328_syscon_ids,
 };

+ 10 - 0
arch/sandbox/Kconfig

@@ -15,6 +15,16 @@ config SANDBOX64
 	select PHYS_64BIT
 	select HOST_64BIT
 
+config SANDBOX_RAM_SIZE_MB
+	int "RAM size in MiB"
+	default 128
+	range 64 4095 if !SANDBOX64
+	range 64 268435456 if SANDBOX64
+	help
+	  Memory size of the sandbox in MiB. The default value is 128 MiB.
+	  The minimum value is 64 MiB. The maximum value is 4095 MiB for the
+	  32bit sandbox.
+
 config SANDBOX_SPL
 	bool "Enable SPL for sandbox"
 	select SUPPORT_SPL

+ 4 - 1
arch/sandbox/cpu/state.c

@@ -378,7 +378,10 @@ int state_init(void)
 
 	state->ram_size = CONFIG_SYS_SDRAM_SIZE;
 	state->ram_buf = os_malloc(state->ram_size);
-	assert(state->ram_buf);
+	if (!state->ram_buf) {
+		printf("Out of memory\n");
+		os_exit(1);
+	}
 
 	state_reset_for_test(state);
 	/*

+ 1 - 1
arch/sandbox/cpu/u-boot-spl.lds

@@ -20,4 +20,4 @@ SECTIONS
 	__bss_start = .;
 }
 
-INSERT BEFORE .data;
+INSERT AFTER .data;

+ 1 - 1
arch/sandbox/include/asm/state.h

@@ -73,7 +73,7 @@ struct sandbox_state {
 	char **argv;			/* Command line arguments */
 	const char *jumped_fname;	/* Jumped from previous U_Boot */
 	uint8_t *ram_buf;		/* Emulated RAM buffer */
-	unsigned int ram_size;		/* Size of RAM buffer */
+	unsigned long ram_size;		/* Size of RAM buffer */
 	const char *ram_buf_fname;	/* Filename to use for RAM buffer */
 	bool ram_buf_rm;		/* Remove RAM buffer file after read */
 	bool write_ram_buf;		/* Write RAM buffer on exit */

+ 1 - 1
board/davinci/da8xxevm/omapl138_lcdk.c

@@ -380,7 +380,7 @@ static const struct davinci_mmc_plat mmc_platdata = {
 	},
 };
 U_BOOT_DEVICE(omapl138_mmc) = {
-	.name = "davinci_mmc",
+	.name = "ti_da830_mmc",
 	.platdata = &mmc_platdata,
 };
 

+ 1 - 1
board/sandbox/sandbox.c

@@ -22,7 +22,7 @@ gd_t *gd;
 
 /* Add a simple GPIO device */
 U_BOOT_DEVICE(gpio_sandbox) = {
-	.name = "gpio_sandbox",
+	.name = "sandbox_gpio",
 };
 
 void flush_cache(unsigned long start, unsigned long size)

+ 8 - 3
cmd/fdt.c

@@ -21,7 +21,6 @@
 
 #define MAX_LEVEL	32		/* how deeply nested we will go */
 #define SCRATCHPAD	1024		/* bytes of scratchpad memory */
-#define CMD_FDT_MAX_DUMP 64
 
 /*
  * Global data (for the gd->bd)
@@ -934,11 +933,17 @@ static int is_printable_string(const void *data, int len)
 static void print_data(const void *data, int len)
 {
 	int j;
+	const char *env_max_dump;
+	ulong max_dump = ULONG_MAX;
 
 	/* no data, don't print */
 	if (len == 0)
 		return;
 
+	env_max_dump = env_get("fdt_max_dump");
+	if (env_max_dump)
+		max_dump = simple_strtoul(env_max_dump, NULL, 16);
+
 	/*
 	 * It is a string, but it may have multiple strings (embedded '\0's).
 	 */
@@ -957,7 +962,7 @@ static void print_data(const void *data, int len)
 	}
 
 	if ((len %4) == 0) {
-		if (len > CMD_FDT_MAX_DUMP)
+		if (len > max_dump)
 			printf("* 0x%p [0x%08x]", data, len);
 		else {
 			const __be32 *p;
@@ -969,7 +974,7 @@ static void print_data(const void *data, int len)
 			printf(">");
 		}
 	} else { /* anything else... hexdump */
-		if (len > CMD_FDT_MAX_DUMP)
+		if (len > max_dump)
 			printf("* 0x%p [0x%08x]", data, len);
 		else {
 			const u8 *s;

+ 2 - 2
cmd/log.c

@@ -39,7 +39,7 @@ static int do_log_format(struct cmd_tbl *cmdtp, int flag, int argc,
 		const char *str = argv[1];
 
 		if (!strcmp(str, "default")) {
-			gd->log_fmt = LOGF_DEFAULT;
+			gd->log_fmt = log_get_default_format();
 		} else if (!strcmp(str, "all")) {
 			gd->log_fmt = LOGF_ALL;
 		} else {
@@ -139,7 +139,7 @@ static char log_help_text[] =
 	"log format <fmt> - set log output format. <fmt> is a string where\n"
 	"\teach letter indicates something that should be displayed:\n"
 	"\tc=category, l=level, F=file, L=line number, f=function, m=msg\n"
-	"\tor 'default', equivalent to 'fm', or 'all' for all\n"
+	"\tor 'default', or 'all' for all\n"
 	"log rec <category> <level> <file> <line> <func> <message> - "
 		"output a log record"
 	;

+ 18 - 0
common/Kconfig

@@ -699,6 +699,24 @@ config LOG_CONSOLE
 	  log message is shown - other details like level, category, file and
 	  line number are omitted.
 
+config LOGF_FILE
+	bool "Show source file name in log messages by default"
+	help
+	  Show the source file name in log messages by default. This value
+	  can be overridden using the 'log format' command.
+
+config LOGF_LINE
+	bool "Show source line number in log messages by default"
+	help
+	  Show the source line number in log messages by default. This value
+	  can be overridden using the 'log format' command.
+
+config LOGF_FUNC
+	bool "Show function name in log messages by default"
+	help
+	  Show the function name in log messages by default. This value can
+	  be overridden using the 'log format' command.
+
 config LOG_SYSLOG
 	bool "Log output to syslog server"
 	depends on NET

+ 5 - 1
common/log.c

@@ -45,7 +45,11 @@ const char *log_get_cat_name(enum log_category_t cat)
 	if (cat >= LOGC_NONE)
 		return log_cat_name[cat - LOGC_NONE];
 
+#if CONFIG_IS_ENABLED(DM)
 	name = uclass_get_name((enum uclass_id)cat);
+#else
+	name = NULL;
+#endif
 
 	return name ? name : "<missing>";
 }
@@ -317,7 +321,7 @@ int log_init(void)
 	gd->flags |= GD_FLG_LOG_READY;
 	if (!gd->default_log_level)
 		gd->default_log_level = CONFIG_LOG_DEFAULT_LEVEL;
-	gd->log_fmt = LOGF_DEFAULT;
+	gd->log_fmt = log_get_default_format();
 
 	return 0;
 }

+ 7 - 7
common/log_console.c

@@ -25,18 +25,18 @@ static int log_console_emit(struct log_device *ldev, struct log_rec *rec)
 	 *    - function is an identifier and ends with ()
 	 *    - message has a space before it unless it is on its own
 	 */
-	if (fmt & (1 << LOGF_LEVEL))
+	if (fmt & BIT(LOGF_LEVEL))
 		printf("%s.", log_get_level_name(rec->level));
-	if (fmt & (1 << LOGF_CAT))
+	if (fmt & BIT(LOGF_CAT))
 		printf("%s,", log_get_cat_name(rec->cat));
-	if (fmt & (1 << LOGF_FILE))
+	if (fmt & BIT(LOGF_FILE))
 		printf("%s:", rec->file);
-	if (fmt & (1 << LOGF_LINE))
+	if (fmt & BIT(LOGF_LINE))
 		printf("%d-", rec->line);
-	if (fmt & (1 << LOGF_FUNC))
+	if (fmt & BIT(LOGF_FUNC))
 		printf("%s()", rec->func);
-	if (fmt & (1 << LOGF_MSG))
-		printf("%s%s", fmt != (1 << LOGF_MSG) ? " " : "", rec->msg);
+	if (fmt & BIT(LOGF_MSG))
+		printf("%s%s", fmt != BIT(LOGF_MSG) ? " " : "", rec->msg);
 
 	return 0;
 }

+ 7 - 7
common/log_syslog.c

@@ -82,21 +82,21 @@ static int log_syslog_emit(struct log_device *ldev, struct log_rec *rec)
 	if (log_hostname)
 		append(&ptr, msg_end, "%s ", log_hostname);
 	append(&ptr, msg_end, "uboot: ");
-	if (fmt & (1 << LOGF_LEVEL))
+	if (fmt & BIT(LOGF_LEVEL))
 		append(&ptr, msg_end, "%s.",
 		       log_get_level_name(rec->level));
-	if (fmt & (1 << LOGF_CAT))
+	if (fmt & BIT(LOGF_CAT))
 		append(&ptr, msg_end, "%s,",
 		       log_get_cat_name(rec->cat));
-	if (fmt & (1 << LOGF_FILE))
+	if (fmt & BIT(LOGF_FILE))
 		append(&ptr, msg_end, "%s:", rec->file);
-	if (fmt & (1 << LOGF_LINE))
+	if (fmt & BIT(LOGF_LINE))
 		append(&ptr, msg_end, "%d-", rec->line);
-	if (fmt & (1 << LOGF_FUNC))
+	if (fmt & BIT(LOGF_FUNC))
 		append(&ptr, msg_end, "%s()", rec->func);
-	if (fmt & (1 << LOGF_MSG))
+	if (fmt & BIT(LOGF_MSG))
 		append(&ptr, msg_end, "%s%s",
-		       fmt != (1 << LOGF_MSG) ? " " : "", rec->msg);
+		       fmt != BIT(LOGF_MSG) ? " " : "", rec->msg);
 	/* Consider trailing 0x00 */
 	ptr++;
 

+ 29 - 9
doc/driver-model/of-plat.rst

@@ -69,9 +69,8 @@ strictly necessary. Notable problems include:
    - Correct relations between nodes are not implemented. This means that
      parent/child relations (like bus device iteration) do not work yet.
      Some phandles (those that are recognised as such) are converted into
-     a pointer to platform data. This pointer can potentially be used to
-     access the referenced device (by searching for the pointer value).
-     This feature is not yet implemented, however.
+     a pointer to struct driver_info. This pointer can be used to access
+     the referenced device.
 
 
 How it works
@@ -146,10 +145,10 @@ and the following device declaration:
             .clock_freq_min_max     = {0x61a80, 0x8f0d180},
             .vmmc_supply            = 0xb,
             .num_slots              = 0x1,
-            .clocks                 = {{&dtv_clock_controller_at_ff760000, 456},
-                                       {&dtv_clock_controller_at_ff760000, 68},
-                                       {&dtv_clock_controller_at_ff760000, 114},
-                                       {&dtv_clock_controller_at_ff760000, 118}},
+            .clocks                 = {{NULL, 456},
+                                       {NULL, 68},
+                                       {NULL, 114},
+                                       {NULL, 118}},
             .cap_mmc_highspeed      = true,
             .disable_wp             = true,
             .bus_width              = 0x4,
@@ -164,6 +163,13 @@ and the following device declaration:
             .platdata_size  = sizeof(dtv_dwmmc_at_ff0c0000),
     };
 
+    void dm_populate_phandle_data(void) {
+            dtv_dwmmc_at_ff0c0000.clocks[0].node = DM_GET_DEVICE(clock_controller_at_ff760000);
+            dtv_dwmmc_at_ff0c0000.clocks[1].node = DM_GET_DEVICE(clock_controller_at_ff760000);
+            dtv_dwmmc_at_ff0c0000.clocks[2].node = DM_GET_DEVICE(clock_controller_at_ff760000);
+            dtv_dwmmc_at_ff0c0000.clocks[3].node = DM_GET_DEVICE(clock_controller_at_ff760000);
+    }
+
 The device is then instantiated at run-time and the platform data can be
 accessed using:
 
@@ -183,6 +189,17 @@ via U_BOOT_DRIVER(). This effectively means that a U_BOOT_DRIVER() with a
 it to a valid name for C) is needed, so a dedicated driver is required for
 each 'compatible' string.
 
+In order to make this a bit more flexible U_BOOT_DRIVER_ALIAS macro can be
+used to declare an alias for a driver name, typically a 'compatible' string.
+This macro produces no code, but it is by dtoc tool.
+
+During the build process dtoc parses both U_BOOT_DRIVER and U_BOOT_DRIVER_ALIAS
+to build a list of valid driver names and driver aliases. If the 'compatible'
+string used for a device does not not match a valid driver name, it will be
+checked against the list of driver aliases in order to get the right driver
+name to use. If in this step there is no match found a warning is issued to
+avoid run-time failures.
+
 Where a node has multiple compatible strings, a #define is used to make them
 equivalent, e.g.:
 
@@ -269,7 +286,7 @@ For example:
     };
 
     U_BOOT_DRIVER(mmc_drv) = {
-            .name           = "vendor_mmc",  /* matches compatible string */
+            .name           = "mmc_drv",
             .id             = UCLASS_MMC,
             .of_match       = mmc_ids,
             .ofdata_to_platdata = mmc_ofdata_to_platdata,
@@ -278,6 +295,7 @@ For example:
             .platdata_auto_alloc_size = sizeof(struct mmc_platdata),
     };
 
+    U_BOOT_DRIVER_ALIAS(mmc_drv, vendor_mmc) /* matches compatible string */
 
 Note that struct mmc_platdata is defined in the C file, not in a header. This
 is to avoid needing to include dt-structs.h in a header file. The idea is to
@@ -317,7 +335,9 @@ prevents them being used inadvertently. All usage must be bracketed with
 #if CONFIG_IS_ENABLED(OF_PLATDATA).
 
 The dt-platdata.c file contains the device declarations and is is built in
-spl/dt-platdata.c.
+spl/dt-platdata.c. It additionally contains the definition of
+dm_populate_phandle_data() which is responsible of filling the phandle
+information by adding references to U_BOOT_DEVICE by using DM_GET_DEVICE
 
 The beginnings of a libfdt Python module are provided. So far this only
 implements a subset of the features.

+ 2 - 2
drivers/clk/at91/clk-master.c

@@ -25,8 +25,8 @@ static const struct udevice_id at91_master_clk_match[] = {
 	{}
 };
 
-U_BOOT_DRIVER(at91_master_clk) = {
-	.name = "at91-master-clk",
+U_BOOT_DRIVER(atmel_at91rm9200_clk_master) = {
+	.name = "atmel_at91rm9200_clk_master",
 	.id = UCLASS_CLK,
 	.of_match = at91_master_clk_match,
 	.ops = &at91_master_clk_ops,

+ 2 - 2
drivers/clk/at91/clk-peripheral.c

@@ -43,8 +43,8 @@ static const struct udevice_id sam9x5_periph_clk_match[] = {
 	{}
 };
 
-U_BOOT_DRIVER(sam9x5_periph_clk) = {
-	.name = "sam9x5-periph-clk",
+U_BOOT_DRIVER(atmel_at91rm9200_clk_peripheral) = {
+	.name = "atmel_at91rm9200_clk_peripheral",
 	.id = UCLASS_MISC,
 	.of_match = sam9x5_periph_clk_match,
 	.bind = sam9x5_periph_clk_bind,

+ 4 - 2
drivers/clk/at91/pmc.c

@@ -25,12 +25,14 @@ static const struct udevice_id at91_pmc_match[] = {
 	{}
 };
 
-U_BOOT_DRIVER(at91_pmc) = {
-	.name = "at91-pmc",
+U_BOOT_DRIVER(atmel_at91rm9200_pmc) = {
+	.name = "atmel_at91rm9200_pmc",
 	.id = UCLASS_SIMPLE_BUS,
 	.of_match = at91_pmc_match,
 };
 
+U_BOOT_DRIVER_ALIAS(atmel_at91rm9200_pmc, atmel_at91sam9260_pmc)
+
 /*---------------------------------------------------------*/
 
 int at91_pmc_core_probe(struct udevice *dev)

+ 5 - 6
drivers/clk/clk-uclass.c

@@ -27,17 +27,16 @@ static inline const struct clk_ops *clk_dev_ops(struct udevice *dev)
 
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 # if CONFIG_IS_ENABLED(OF_PLATDATA)
-int clk_get_by_index_platdata(struct udevice *dev, int index,
-			      struct phandle_1_arg *cells, struct clk *clk)
+int clk_get_by_driver_info(struct udevice *dev, struct phandle_1_arg *cells,
+			   struct clk *clk)
 {
 	int ret;
 
-	if (index != 0)
-		return -ENOSYS;
-	ret = uclass_get_device(UCLASS_CLK, 0, &clk->dev);
+	ret = device_get_by_driver_info((struct driver_info *)cells->node,
+					&clk->dev);
 	if (ret)
 		return ret;
-	clk->id = cells[0].arg[0];
+	clk->id = cells->arg[0];
 
 	return 0;
 }

+ 24 - 4
drivers/core/device.c

@@ -248,10 +248,11 @@ int device_bind_ofnode(struct udevice *parent, const struct driver *drv,
 }
 
 int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
-			const struct driver_info *info, struct udevice **devp)
+			struct driver_info *info, struct udevice **devp)
 {
 	struct driver *drv;
 	uint platdata_size = 0;
+	int ret;
 
 	drv = lists_driver_lookup_name(info->name);
 	if (!drv)
@@ -262,9 +263,16 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
 #if CONFIG_IS_ENABLED(OF_PLATDATA)
 	platdata_size = info->platdata_size;
 #endif
-	return device_bind_common(parent, drv, info->name,
-			(void *)info->platdata, 0, ofnode_null(), platdata_size,
-			devp);
+	ret = device_bind_common(parent, drv, info->name,
+				 (void *)info->platdata, 0, ofnode_null(),
+				 platdata_size, devp);
+	if (ret)
+		return ret;
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	info->dev = *devp;
+#endif
+
+	return ret;
 }
 
 static void *alloc_priv(int size, uint flags)
@@ -729,6 +737,18 @@ int device_get_global_by_ofnode(ofnode ofnode, struct udevice **devp)
 	return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp);
 }
 
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+int device_get_by_driver_info(const struct driver_info *info,
+			      struct udevice **devp)
+{
+	struct udevice *dev;
+
+	dev = info->dev;
+
+	return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp);
+}
+#endif
+
 int device_find_first_child(const struct udevice *parent, struct udevice **devp)
 {
 	if (list_empty(&parent->child_head)) {

+ 5 - 1
drivers/core/root.c

@@ -26,7 +26,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static const struct driver_info root_info = {
+static struct driver_info root_info = {
 	.name		= "root_driver",
 };
 
@@ -347,6 +347,10 @@ int dm_init_and_scan(bool pre_reloc_only)
 {
 	int ret;
 
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	dm_populate_phandle_data();
+#endif
+
 	ret = dm_init(IS_ENABLED(CONFIG_OF_LIVE));
 	if (ret) {
 		debug("dm_init() failed: %d\n", ret);

+ 2 - 2
drivers/core/simple-bus.c

@@ -56,8 +56,8 @@ static const struct udevice_id generic_simple_bus_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(simple_bus_drv) = {
-	.name	= "generic_simple_bus",
+U_BOOT_DRIVER(simple_bus) = {
+	.name	= "simple_bus",
 	.id	= UCLASS_SIMPLE_BUS,
 	.of_match = generic_simple_bus_ids,
 	.flags	= DM_FLAG_PRE_RELOC,

+ 2 - 2
drivers/gpio/at91_gpio.c

@@ -624,8 +624,8 @@ static const struct udevice_id at91_gpio_ids[] = {
 };
 #endif
 
-U_BOOT_DRIVER(gpio_at91) = {
-	.name	= "gpio_at91",
+U_BOOT_DRIVER(atmel_at91rm9200_gpio) = {
+	.name	= "atmel_at91rm9200_gpio",
 	.id	= UCLASS_GPIO,
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 	.of_match = at91_gpio_ids,

+ 2 - 2
drivers/gpio/da8xx_gpio.c

@@ -553,8 +553,8 @@ static int davinci_gpio_ofdata_to_platdata(struct udevice *dev)
 	return 0;
 }
 
-U_BOOT_DRIVER(gpio_davinci) = {
-	.name	= "gpio_davinci",
+U_BOOT_DRIVER(ti_dm6441_gpio) = {
+	.name	= "ti_dm6441_gpio",
 	.id	= UCLASS_GPIO,
 	.ops	= &gpio_davinci_ops,
 	.ofdata_to_platdata = of_match_ptr(davinci_gpio_ofdata_to_platdata),

+ 3 - 5
drivers/gpio/mxs_gpio.c

@@ -299,12 +299,8 @@ static const struct udevice_id mxs_gpio_ids[] = {
 };
 #endif
 
-U_BOOT_DRIVER(gpio_mxs) = {
-#ifdef CONFIG_MX28
-	.name = "fsl_imx28_gpio",
-#else /* CONFIG_MX23 */
+U_BOOT_DRIVER(fsl_imx23_gpio) = {
 	.name = "fsl_imx23_gpio",
-#endif
 	.id	= UCLASS_GPIO,
 	.ops	= &gpio_mxs_ops,
 	.probe	= mxs_gpio_probe,
@@ -315,4 +311,6 @@ U_BOOT_DRIVER(gpio_mxs) = {
 	.ofdata_to_platdata = mxs_ofdata_to_platdata,
 #endif
 };
+
+U_BOOT_DRIVER_ALIAS(fsl_imx23_gpio, fsl_imx28_gpio)
 #endif /* DM_GPIO */

+ 2 - 2
drivers/gpio/rk_gpio.c

@@ -172,8 +172,8 @@ static const struct udevice_id rockchip_gpio_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(gpio_rockchip) = {
-	.name	= "gpio_rockchip",
+U_BOOT_DRIVER(rockchip_gpio_bank) = {
+	.name	= "rockchip_gpio_bank",
 	.id	= UCLASS_GPIO,
 	.of_match = rockchip_gpio_ids,
 	.ops	= &gpio_rockchip_ops,

+ 4 - 2
drivers/gpio/sandbox.c

@@ -244,8 +244,8 @@ static const struct udevice_id sandbox_gpio_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(gpio_sandbox) = {
-	.name	= "gpio_sandbox",
+U_BOOT_DRIVER(sandbox_gpio) = {
+	.name	= "sandbox_gpio",
 	.id	= UCLASS_GPIO,
 	.of_match = sandbox_gpio_ids,
 	.ofdata_to_platdata = sandbox_gpio_ofdata_to_platdata,
@@ -254,6 +254,8 @@ U_BOOT_DRIVER(gpio_sandbox) = {
 	.ops	= &gpio_sandbox_ops,
 };
 
+U_BOOT_DRIVER_ALIAS(sandbox_gpio, sandbox_gpio_alias)
+
 /* pincontrol: used only to check GPIO pin configuration (pinmux command) */
 
 struct sb_pinctrl_priv {

+ 4 - 2
drivers/i2c/rk_i2c.c

@@ -485,8 +485,8 @@ static const struct udevice_id rockchip_i2c_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(i2c_rockchip) = {
-	.name	= "i2c_rockchip",
+U_BOOT_DRIVER(rockchip_rk3066_i2c) = {
+	.name	= "rockchip_rk3066_i2c",
 	.id	= UCLASS_I2C,
 	.of_match = rockchip_i2c_ids,
 	.ofdata_to_platdata = rockchip_i2c_ofdata_to_platdata,
@@ -494,3 +494,5 @@ U_BOOT_DRIVER(i2c_rockchip) = {
 	.priv_auto_alloc_size = sizeof(struct rk_i2c),
 	.ops	= &rockchip_i2c_ops,
 };
+
+U_BOOT_DRIVER_ALIAS(rockchip_rk3066_i2c, rockchip_rk3288_i2c)

+ 2 - 2
drivers/input/cros_ec_keyb.c

@@ -225,8 +225,8 @@ static const struct udevice_id cros_ec_kbd_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(cros_ec_kbd) = {
-	.name	= "cros_ec_kbd",
+U_BOOT_DRIVER(google_cros_ec_keyb) = {
+	.name	= "google_cros_ec_keyb",
 	.id	= UCLASS_KEYBOARD,
 	.of_match = cros_ec_kbd_ids,
 	.probe = cros_ec_kbd_probe,

+ 2 - 2
drivers/misc/cros_ec_sandbox.c

@@ -572,8 +572,8 @@ static const struct udevice_id cros_ec_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(cros_ec_sandbox) = {
-	.name		= "cros_ec_sandbox",
+U_BOOT_DRIVER(google_cros_ec_sandbox) = {
+	.name		= "google_cros_ec_sandbox",
 	.id		= UCLASS_CROS_EC,
 	.of_match	= cros_ec_ids,
 	.probe		= cros_ec_probe,

+ 4 - 6
drivers/misc/irq-uclass.c

@@ -64,17 +64,15 @@ int irq_read_and_clear(struct irq *irq)
 }
 
 #if CONFIG_IS_ENABLED(OF_PLATDATA)
-int irq_get_by_index_platdata(struct udevice *dev, int index,
-			      struct phandle_1_arg *cells, struct irq *irq)
+int irq_get_by_driver_info(struct udevice *dev,
+			   struct phandle_1_arg *cells, struct irq *irq)
 {
 	int ret;
 
-	if (index != 0)
-		return -ENOSYS;
-	ret = uclass_get_device(UCLASS_IRQ, 0, &irq->dev);
+	ret = device_get_by_driver_info(cells->node, &irq->dev);
 	if (ret)
 		return ret;
-	irq->id = cells[0].arg[0];
+	irq->id = cells->arg[0];
 
 	return 0;
 }

+ 1 - 1
drivers/mmc/davinci_mmc.c

@@ -522,7 +522,7 @@ static const struct udevice_id davinci_mmc_ids[] = {
 	{},
 };
 #endif
-U_BOOT_DRIVER(davinci_mmc_drv) = {
+U_BOOT_DRIVER(ti_da830_mmc) = {
 	.name = "davinci_mmc",
 	.id		= UCLASS_MMC,
 #if CONFIG_IS_ENABLED(OF_CONTROL)

+ 1 - 1
drivers/mmc/ftsdc010_mci.c

@@ -439,7 +439,7 @@ static int ftsdc010_mmc_probe(struct udevice *dev)
 	chip->priv = dev;
 	chip->dev_index = 1;
 	memcpy(priv->minmax, dtplat->clock_freq_min_max, sizeof(priv->minmax));
-	ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->clk);
+	ret = clk_get_by_driver_info(dev, dtplat->clocks, &priv->clk);
 	if (ret < 0)
 		return ret;
 #endif

+ 2 - 5
drivers/mmc/mxsmmc.c

@@ -711,12 +711,8 @@ static const struct udevice_id mxsmmc_ids[] = {
 };
 #endif
 
-U_BOOT_DRIVER(mxsmmc) = {
-#ifdef CONFIG_MX28
-	.name = "fsl_imx28_mmc",
-#else /* CONFIG_MX23 */
+U_BOOT_DRIVER(fsl_imx23_mmc) = {
 	.name = "fsl_imx23_mmc",
-#endif
 	.id	= UCLASS_MMC,
 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
 	.of_match = mxsmmc_ids,
@@ -731,4 +727,5 @@ U_BOOT_DRIVER(mxsmmc) = {
 	.platdata_auto_alloc_size = sizeof(struct mxsmmc_platdata),
 };
 
+U_BOOT_DRIVER_ALIAS(fsl_imx23_mmc, fsl_imx28_mmc)
 #endif /* CONFIG_DM_MMC */

+ 5 - 2
drivers/mmc/rockchip_dw_mmc.c

@@ -122,7 +122,7 @@ static int rockchip_dwmmc_probe(struct udevice *dev)
 	priv->minmax[0] = 400000;  /*  400 kHz */
 	priv->minmax[1] = dtplat->max_frequency;
 
-	ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->clk);
+	ret = clk_get_by_driver_info(dev, dtplat->clocks, &priv->clk);
 	if (ret < 0)
 		return ret;
 #else
@@ -168,7 +168,7 @@ static const struct udevice_id rockchip_dwmmc_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(rockchip_dwmmc_drv) = {
+U_BOOT_DRIVER(rockchip_rk3288_dw_mshc) = {
 	.name		= "rockchip_rk3288_dw_mshc",
 	.id		= UCLASS_MMC,
 	.of_match	= rockchip_dwmmc_ids,
@@ -180,6 +180,9 @@ U_BOOT_DRIVER(rockchip_dwmmc_drv) = {
 	.platdata_auto_alloc_size = sizeof(struct rockchip_mmc_plat),
 };
 
+U_BOOT_DRIVER_ALIAS(rockchip_rk3288_dw_mshc, rockchip_rk3328_dw_mshc)
+U_BOOT_DRIVER_ALIAS(rockchip_rk3288_dw_mshc, rockchip_rk3368_dw_mshc)
+
 #ifdef CONFIG_PWRSEQ
 static int rockchip_dwmmc_pwrseq_set_power(struct udevice *dev, bool enable)
 {

+ 1 - 1
drivers/mmc/rockchip_sdhci.c

@@ -46,7 +46,7 @@ static int arasan_sdhci_probe(struct udevice *dev)
 	host->name = dev->name;
 	host->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]);
 	max_frequency = dtplat->max_frequency;
-	ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &clk);
+	ret = clk_get_by_driver_info(dev, dtplat->clocks, &clk);
 #else
 	max_frequency = dev_read_u32_default(dev, "max-frequency", 0);
 	ret = clk_get_by_index(dev, 0, &clk);

+ 0 - 2
drivers/mtd/spi/sandbox.c

@@ -44,7 +44,6 @@ enum sandbox_sf_state {
 	SF_WRITE_STATUS, /* write the flash's status register */
 };
 
-#if CONFIG_IS_ENABLED(LOG)
 static const char *sandbox_sf_state_name(enum sandbox_sf_state state)
 {
 	static const char * const states[] = {
@@ -53,7 +52,6 @@ static const char *sandbox_sf_state_name(enum sandbox_sf_state state)
 	};
 	return states[state];
 }
-#endif /* LOG */
 
 /* Bits for the status register */
 #define STAT_WIP	(1 << 0)

+ 1 - 1
drivers/mtd/spi/sf-uclass.c

@@ -68,7 +68,7 @@ int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs,
 	str = strdup(name);
 #endif
 	ret = spi_get_bus_and_cs(busnum, cs, max_hz, spi_mode,
-				  "spi_flash_std", str, &bus, &slave);
+				  "jedec_spi_nor", str, &bus, &slave);
 	if (ret)
 		return ret;
 

+ 4 - 2
drivers/mtd/spi/sf_probe.c

@@ -160,8 +160,8 @@ static const struct udevice_id spi_flash_std_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(spi_flash_std) = {
-	.name		= "spi_flash_std",
+U_BOOT_DRIVER(jedec_spi_nor) = {
+	.name		= "jedec_spi_nor",
 	.id		= UCLASS_SPI_FLASH,
 	.of_match	= spi_flash_std_ids,
 	.probe		= spi_flash_std_probe,
@@ -170,4 +170,6 @@ U_BOOT_DRIVER(spi_flash_std) = {
 	.ops		= &spi_flash_std_ops,
 };
 
+U_BOOT_DRIVER_ALIAS(jedec_spi_nor, spansion_m25p16)
+
 #endif /* CONFIG_DM_SPI_FLASH */

+ 4 - 2
drivers/pinctrl/nxp/pinctrl-mxs.c

@@ -180,8 +180,8 @@ static const struct udevice_id mxs_pinctrl_match[] = {
 	{ /* sentinel */ }
 };
 
-U_BOOT_DRIVER(mxs_pinctrl) = {
-	.name = "mxs-pinctrl",
+U_BOOT_DRIVER(fsl_imx23_pinctrl) = {
+	.name = "fsl_imx23_pinctrl",
 	.id = UCLASS_PINCTRL,
 	.of_match = of_match_ptr(mxs_pinctrl_match),
 	.probe = mxs_pinctrl_probe,
@@ -191,3 +191,5 @@ U_BOOT_DRIVER(mxs_pinctrl) = {
 	.priv_auto_alloc_size = sizeof(struct mxs_pinctrl_priv),
 	.ops = &mxs_pinctrl_ops,
 };
+
+U_BOOT_DRIVER_ALIAS(fsl_imx23_pinctrl, fsl_imx28_pinctrl)

+ 4 - 2
drivers/pinctrl/pinctrl-at91.c

@@ -519,11 +519,13 @@ static const struct udevice_id at91_pinctrl_match[] = {
 	{}
 };
 
-U_BOOT_DRIVER(at91_pinctrl) = {
-	.name = "pinctrl_at91",
+U_BOOT_DRIVER(atmel_sama5d3_pinctrl) = {
+	.name = "atmel_sama5d3_pinctrl",
 	.id = UCLASS_PINCTRL,
 	.of_match = at91_pinctrl_match,
 	.probe = at91_pinctrl_probe,
 	.priv_auto_alloc_size = sizeof(struct at91_pinctrl_priv),
 	.ops = &at91_pinctrl_ops,
 };
+
+U_BOOT_DRIVER_ALIAS(atmel_sama5d3_pinctrl, atmel_at91rm9200_pinctrl)

+ 1 - 1
drivers/pinctrl/rockchip/pinctrl-rk3188.c

@@ -120,7 +120,7 @@ static const struct udevice_id rk3188_pinctrl_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(pinctrl_rk3188) = {
+U_BOOT_DRIVER(rockchip_rk3188_pinctrl) = {
 	.name		= "rockchip_rk3188_pinctrl",
 	.id		= UCLASS_PINCTRL,
 	.of_match	= rk3188_pinctrl_ids,

+ 1 - 1
drivers/pinctrl/rockchip/pinctrl-rk3288.c

@@ -242,7 +242,7 @@ static const struct udevice_id rk3288_pinctrl_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(pinctrl_rk3288) = {
+U_BOOT_DRIVER(rockchip_rk3288_pinctrl) = {
 	.name		= "rockchip_rk3288_pinctrl",
 	.id		= UCLASS_PINCTRL,
 	.of_match	= rk3288_pinctrl_ids,

+ 1 - 1
drivers/pinctrl/rockchip/pinctrl-rk3328.c

@@ -317,7 +317,7 @@ static const struct udevice_id rk3328_pinctrl_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(pinctrl_rk3328) = {
+U_BOOT_DRIVER(rockchip_rk3328_pinctrl) = {
 	.name		= "rockchip_rk3328_pinctrl",
 	.id		= UCLASS_PINCTRL,
 	.of_match	= rk3328_pinctrl_ids,

+ 1 - 1
drivers/pinctrl/rockchip/pinctrl-rk3368.c

@@ -171,7 +171,7 @@ static const struct udevice_id rk3368_pinctrl_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(pinctrl_rk3368) = {
+U_BOOT_DRIVER(rockchip_rk3368_pinctrl) = {
 	.name		= "rockchip_rk3368_pinctrl",
 	.id		= UCLASS_PINCTRL,
 	.of_match	= rk3368_pinctrl_ids,

+ 4 - 2
drivers/power/pmic/rk8xx.c

@@ -183,8 +183,8 @@ static const struct udevice_id rk8xx_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(pmic_rk8xx) = {
-	.name = "rk8xx pmic",
+U_BOOT_DRIVER(rockchip_rk805) = {
+	.name = "rockchip_rk805",
 	.id = UCLASS_PMIC,
 	.of_match = rk8xx_ids,
 #if CONFIG_IS_ENABLED(PMIC_CHILDREN)
@@ -194,3 +194,5 @@ U_BOOT_DRIVER(pmic_rk8xx) = {
 	.probe = rk8xx_probe,
 	.ops = &rk8xx_ops,
 };
+
+U_BOOT_DRIVER_ALIAS(rockchip_rk805, rockchip_rk808)

+ 2 - 2
drivers/power/regulator/fixed.c

@@ -82,8 +82,8 @@ static const struct udevice_id fixed_regulator_ids[] = {
 	{ },
 };
 
-U_BOOT_DRIVER(fixed_regulator) = {
-	.name = "fixed regulator",
+U_BOOT_DRIVER(regulator_fixed) = {
+	.name = "regulator_fixed",
 	.id = UCLASS_REGULATOR,
 	.ops = &fixed_regulator_ops,
 	.of_match = fixed_regulator_ids,

+ 1 - 1
drivers/ram/rockchip/dmc-rk3368.c

@@ -992,7 +992,7 @@ static const struct udevice_id rk3368_dmc_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(dmc_rk3368) = {
+U_BOOT_DRIVER(rockchip_rk3368_dmc) = {
 	.name = "rockchip_rk3368_dmc",
 	.id = UCLASS_RAM,
 	.of_match = rk3368_dmc_ids,

+ 1 - 1
drivers/ram/rockchip/sdram_rk3188.c

@@ -945,7 +945,7 @@ static const struct udevice_id rk3188_dmc_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(dmc_rk3188) = {
+U_BOOT_DRIVER(rockchip_rk3188_dmc) = {
 	.name = "rockchip_rk3188_dmc",
 	.id = UCLASS_RAM,
 	.of_match = rk3188_dmc_ids,

+ 1 - 1
drivers/ram/rockchip/sdram_rk3288.c

@@ -1113,7 +1113,7 @@ static const struct udevice_id rk3288_dmc_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(dmc_rk3288) = {
+U_BOOT_DRIVER(rockchip_rk3288_dmc) = {
 	.name = "rockchip_rk3288_dmc",
 	.id = UCLASS_RAM,
 	.of_match = rk3288_dmc_ids,

+ 1 - 1
drivers/ram/rockchip/sdram_rk3328.c

@@ -606,7 +606,7 @@ static const struct udevice_id rk3328_dmc_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(dmc_rk3328) = {
+U_BOOT_DRIVER(rockchip_rk3328_dmc) = {
 	.name = "rockchip_rk3328_dmc",
 	.id = UCLASS_RAM,
 	.of_match = rk3328_dmc_ids,

+ 1 - 1
drivers/ram/rockchip/sdram_rk3399.c

@@ -3128,7 +3128,7 @@ static int rk3399_dmc_init(struct udevice *dev)
 	      priv->cic, priv->pmugrf, priv->pmusgrf, priv->pmucru, priv->pmu);
 
 #if CONFIG_IS_ENABLED(OF_PLATDATA)
-	ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->ddr_clk);
+	ret = clk_get_by_driver_info(dev, dtplat->clocks, &priv->ddr_clk);
 #else
 	ret = clk_get_by_index(dev, 0, &priv->ddr_clk);
 #endif

+ 4 - 0
drivers/serial/ns16550.c

@@ -620,6 +620,10 @@ U_BOOT_DRIVER(ns16550_serial) = {
 	.flags	= DM_FLAG_PRE_RELOC,
 #endif
 };
+
+U_BOOT_DRIVER_ALIAS(ns16550_serial, rockchip_rk3328_uart)
+U_BOOT_DRIVER_ALIAS(ns16550_serial, rockchip_rk3368_uart)
+U_BOOT_DRIVER_ALIAS(ns16550_serial, ti_da830_uart)
 #endif
 #endif /* SERIAL_PRESENT */
 

+ 6 - 4
drivers/serial/sandbox.c

@@ -93,7 +93,9 @@ static int sandbox_serial_putc(struct udevice *dev, const char ch)
 	struct sandbox_serial_priv *priv = dev_get_priv(dev);
 	struct sandbox_serial_platdata *plat = dev->platdata;
 
-	if (priv->start_of_line && plat->colour != -1) {
+	/* With of-platdata we don't real the colour correctly, so disable it */
+	if (!CONFIG_IS_ENABLED(OF_PLATDATA) && priv->start_of_line &&
+	    plat->colour != -1) {
 		priv->start_of_line = false;
 		output_ansi_colour(plat->colour);
 	}
@@ -252,8 +254,8 @@ static const struct udevice_id sandbox_serial_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(serial_sandbox) = {
-	.name	= "serial_sandbox",
+U_BOOT_DRIVER(sandbox_serial) = {
+	.name	= "sandbox_serial",
 	.id	= UCLASS_SERIAL,
 	.of_match = sandbox_serial_ids,
 	.ofdata_to_platdata = sandbox_serial_ofdata_to_platdata,
@@ -270,7 +272,7 @@ static const struct sandbox_serial_platdata platdata_non_fdt = {
 };
 
 U_BOOT_DEVICE(serial_sandbox_non_fdt) = {
-	.name = "serial_sandbox",
+	.name = "sandbox_serial",
 	.platdata = &platdata_non_fdt,
 };
 #endif /* CONFIG_IS_ENABLED(OF_CONTROL) */

+ 3 - 5
drivers/spi/mxs_spi.c

@@ -486,12 +486,8 @@ static const struct udevice_id mxs_spi_ids[] = {
 };
 #endif
 
-U_BOOT_DRIVER(mxs_spi) = {
-#ifdef CONFIG_MX28
-	.name = "fsl_imx28_spi",
-#else /* CONFIG_MX23 */
+U_BOOT_DRIVER(fsl_imx23_spi) = {
 	.name = "fsl_imx23_spi",
-#endif
 	.id	= UCLASS_SPI,
 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
 	.of_match = mxs_spi_ids,
@@ -502,3 +498,5 @@ U_BOOT_DRIVER(mxs_spi) = {
 	.priv_auto_alloc_size = sizeof(struct mxs_spi_priv),
 	.probe	= mxs_spi_probe,
 };
+
+U_BOOT_DRIVER_ALIAS(fsl_imx23_spi, fsl_imx28_spi)

+ 4 - 6
drivers/spi/rk_spi.c

@@ -183,7 +183,7 @@ static int conv_of_platdata(struct udevice *dev)
 
 	plat->base = dtplat->reg[0];
 	plat->frequency = 20000000;
-	ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->clk);
+	ret = clk_get_by_driver_info(dev, dtplat->clocks, &priv->clk);
 	if (ret < 0)
 		return ret;
 	dev->req_seq = 0;
@@ -553,12 +553,8 @@ static const struct udevice_id rockchip_spi_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(rockchip_spi) = {
-#if CONFIG_IS_ENABLED(OF_PLATDATA)
+U_BOOT_DRIVER(rockchip_rk3288_spi) = {
 	.name	= "rockchip_rk3288_spi",
-#else
-	.name	= "rockchip_spi",
-#endif
 	.id	= UCLASS_SPI,
 	.of_match = rockchip_spi_ids,
 	.ops	= &rockchip_spi_ops,
@@ -567,3 +563,5 @@ U_BOOT_DRIVER(rockchip_spi) = {
 	.priv_auto_alloc_size = sizeof(struct rockchip_spi_priv),
 	.probe	= rockchip_spi_probe,
 };
+
+U_BOOT_DRIVER_ALIAS(rockchip_rk3288_spi, rockchip_rk3368_spi)

+ 2 - 2
drivers/spi/sandbox_spi.c

@@ -146,8 +146,8 @@ static const struct udevice_id sandbox_spi_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(spi_sandbox) = {
-	.name	= "spi_sandbox",
+U_BOOT_DRIVER(sandbox_spi) = {
+	.name	= "sandbox_spi",
 	.id	= UCLASS_SPI,
 	.of_match = sandbox_spi_ids,
 	.ops	= &sandbox_spi_ops,

+ 2 - 2
drivers/tpm/tpm_tis_sandbox.c

@@ -355,8 +355,8 @@ static const struct udevice_id sandbox_tpm_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(sandbox_tpm) = {
-	.name   = "sandbox_tpm",
+U_BOOT_DRIVER(google_sandbox_tpm) = {
+	.name   = "google_sandbox_tpm",
 	.id     = UCLASS_TPM,
 	.of_match = sandbox_tpm_ids,
 	.ops    = &sandbox_tpm_ops,

+ 2 - 2
drivers/video/rockchip/rk3288_vop.c

@@ -97,8 +97,8 @@ static const struct udevice_id rk3288_vop_ids[] = {
 static const struct video_ops rk3288_vop_ops = {
 };
 
-U_BOOT_DRIVER(rk_vop) = {
-	.name	= "rk3288_vop",
+U_BOOT_DRIVER(rockchip_rk3288_vop) = {
+	.name	= "rockchip_rk3288_vop",
 	.id	= UCLASS_VIDEO,
 	.of_match = rk3288_vop_ids,
 	.ops	= &rk3288_vop_ops,

+ 2 - 2
drivers/video/sandbox_sdl.c

@@ -72,8 +72,8 @@ static const struct udevice_id sandbox_sdl_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(sdl_sandbox) = {
-	.name	= "sdl_sandbox",
+U_BOOT_DRIVER(sandbox_lcd_sdl) = {
+	.name	= "sandbox_lcd_sdl",
 	.id	= UCLASS_VIDEO,
 	.of_match = sandbox_sdl_ids,
 	.bind	= sandbox_sdl_bind,

+ 2 - 2
drivers/watchdog/at91sam9_wdt.c

@@ -113,8 +113,8 @@ static int at91_wdt_probe(struct udevice *dev)
 	return 0;
 }
 
-U_BOOT_DRIVER(at91_wdt) = {
-	.name = "at91_wdt",
+U_BOOT_DRIVER(atmel_at91sam9260_wdt) = {
+	.name = "atmel_at91sam9260_wdt",
 	.id = UCLASS_WDT,
 	.of_match = at91_wdt_ids,
 	.priv_auto_alloc_size = sizeof(struct at91_wdt_priv),

+ 2 - 2
include/clk.h

@@ -89,8 +89,8 @@ struct clk_bulk {
 
 #if CONFIG_IS_ENABLED(OF_CONTROL) && CONFIG_IS_ENABLED(CLK)
 struct phandle_1_arg;
-int clk_get_by_index_platdata(struct udevice *dev, int index,
-			      struct phandle_1_arg *cells, struct clk *clk);
+int clk_get_by_driver_info(struct udevice *dev,
+			   struct phandle_1_arg *cells, struct clk *clk);
 
 /**
  * clk_get_by_index - Get/request a clock by integer index.

+ 4 - 1
include/configs/sandbox.h

@@ -47,8 +47,11 @@
 #define CONFIG_PHYSMEM
 
 /* Size of our emulated memory */
+#define SB_CONCAT(x, y) x ## y
+#define SB_TO_UL(s) SB_CONCAT(s, UL)
 #define CONFIG_SYS_SDRAM_BASE		0
-#define CONFIG_SYS_SDRAM_SIZE		(128 << 20)
+#define CONFIG_SYS_SDRAM_SIZE \
+		(SB_TO_UL(CONFIG_SANDBOX_RAM_SIZE_MB) << 20)
 #define CONFIG_SYS_MONITOR_BASE	0
 
 #define CONFIG_SYS_BAUDRATE_TABLE	{4800, 9600, 19200, 38400, 57600,\

+ 1 - 1
include/dm/device-internal.h

@@ -81,7 +81,7 @@ int device_bind_with_driver_data(struct udevice *parent,
  * @return 0 if OK, -ve on error
  */
 int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
-			const struct driver_info *info, struct udevice **devp);
+			struct driver_info *info, struct udevice **devp);
 
 /**
  * device_ofdata_to_platdata() - Read platform data for a device

+ 22 - 0
include/dm/device.h

@@ -282,6 +282,13 @@ struct driver {
 #define DM_GET_DRIVER(__name)						\
 	ll_entry_get(struct driver, __name, driver)
 
+/**
+ * Declare a macro to state a alias for a driver name. This macro will
+ * produce no code but its information will be parsed by tools like
+ * dtoc
+ */
+#define U_BOOT_DRIVER_ALIAS(__name, __alias)
+
 /**
  * dev_get_platdata() - Get the platform data for a device
  *
@@ -531,6 +538,21 @@ int device_find_global_by_ofnode(ofnode node, struct udevice **devp);
  */
 int device_get_global_by_ofnode(ofnode node, struct udevice **devp);
 
+/**
+ * device_get_by_driver_info() - Get a device based on driver_info
+ *
+ * Locates a device by its struct driver_info, by using its reference which
+ * is updated during the bind process.
+ *
+ * The device is probed to activate it ready for use.
+ *
+ * @info: Struct driver_info
+ * @devp: Returns pointer to device if found, otherwise this is set to NULL
+ * @return 0 if OK, -ve on error
+ */
+int device_get_by_driver_info(const struct driver_info *info,
+			      struct udevice **devp);
+
 /**
  * device_find_first_child() - Find the first child of a device
  *

+ 14 - 0
include/dm/platdata.h

@@ -22,12 +22,14 @@
  * @name:	Driver name
  * @platdata:	Driver-specific platform data
  * @platdata_size: Size of platform data structure
+ * @dev:	Device created from this structure data
  */
 struct driver_info {
 	const char *name;
 	const void *platdata;
 #if CONFIG_IS_ENABLED(OF_PLATDATA)
 	uint platdata_size;
+	struct udevice *dev;
 #endif
 };
 
@@ -43,4 +45,16 @@ struct driver_info {
 #define U_BOOT_DEVICES(__name)						\
 	ll_entry_declare_list(struct driver_info, __name, driver_info)
 
+/* Get a pointer to a given driver */
+#define DM_GET_DEVICE(__name)						\
+	ll_entry_get(struct driver_info, __name, driver_info)
+
+/**
+ * dm_populate_phandle_data() - Populates phandle data in platda
+ *
+ * This populates phandle data with an U_BOOT_DEVICE entry get by
+ * DM_GET_DEVICE. The implementation of this function will be done
+ * by dtoc when parsing dtb.
+ */
+void dm_populate_phandle_data(void);
 #endif

+ 1 - 1
include/dm/uclass.h

@@ -390,7 +390,7 @@ int uclass_resolve_seq(struct udevice *dev);
  * @id: enum uclass_id ID to use
  * @pos: struct udevice * to hold the current device. Set to NULL when there
  * are no more devices.
- * @uc: temporary uclass variable (struct udevice *)
+ * @uc: temporary uclass variable (struct uclass *)
  */
 #define uclass_id_foreach_dev(id, pos, uc) \
 	if (!uclass_get(id, &uc)) \

+ 17 - 1
include/log.h

@@ -12,6 +12,7 @@
 #include <stdio.h>
 #include <linker_lists.h>
 #include <dm/uclass-id.h>
+#include <linux/bitops.h>
 #include <linux/list.h>
 
 struct cmd_tbl;
@@ -411,7 +412,6 @@ enum log_fmt {
 	LOGF_MSG,
 
 	LOGF_COUNT,
-	LOGF_DEFAULT = (1 << LOGF_FUNC) | (1 << LOGF_MSG),
 	LOGF_ALL = 0x3f,
 };
 
@@ -460,4 +460,20 @@ static inline int log_init(void)
 }
 #endif
 
+/**
+ * log_get_default_format() - get default log format
+ *
+ * The default log format is configurable via
+ * CONFIG_LOGF_FILE, CONFIG_LOGF_LINE, CONFIG_LOGF_FUNC.
+ *
+ * Return:	default log format
+ */
+static inline int log_get_default_format(void)
+{
+	return BIT(LOGF_MSG) |
+	       (IS_ENABLED(CONFIG_LOGF_FILE) ? BIT(LOGF_FILE) : 0) |
+	       (IS_ENABLED(CONFIG_LOGF_LINE) ? BIT(LOGF_LINE) : 0) |
+	       (IS_ENABLED(CONFIG_LOGF_FUNC) ? BIT(LOGF_FUNC) : 0);
+}
+
 #endif

+ 1 - 1
scripts/checkpatch.pl

@@ -2343,7 +2343,7 @@ sub u_boot_line {
 	}
 
 	# use if instead of #if
-	if ($line =~ /^\+#if.*CONFIG.*/) {
+	if ($realfile =~ /\.c$/ && $line =~ /^\+#if.*CONFIG.*/) {
 		WARN("PREFER_IF",
 		     "Use 'if (IS_ENABLED(CONFIG...))' instead of '#if or #ifdef' where possible\n" . $herecurr);
 	}

+ 72 - 1
test/dm/fdtdec.c

@@ -9,6 +9,8 @@
 #include <dm/test.h>
 #include <test/ut.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 static int dm_test_fdtdec_set_carveout(struct unit_test_state *uts)
 {
 	struct fdt_memory resv;
@@ -20,7 +22,7 @@ static int dm_test_fdtdec_set_carveout(struct unit_test_state *uts)
 	blob = malloc(blob_sz);
 	ut_assertnonnull(blob);
 
-	/* Make a writtable copy of the fdt blob */
+	/* Make a writable copy of the fdt blob */
 	ut_assertok(fdt_open_into(gd->fdt_blob, blob, blob_sz));
 
 	resv.start = 0x1000;
@@ -57,3 +59,72 @@ static int dm_test_fdtdec_set_carveout(struct unit_test_state *uts)
 }
 DM_TEST(dm_test_fdtdec_set_carveout,
 	DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE);
+
+static int dm_test_fdtdec_add_reserved_memory(struct unit_test_state *uts)
+{
+	struct fdt_memory resv;
+	fdt_addr_t addr;
+	fdt_size_t size;
+	void *blob;
+	int blob_sz, parent, subnode;
+	uint32_t phandle, phandle1;
+
+	blob_sz = fdt_totalsize(gd->fdt_blob) + 128;
+	blob = malloc(blob_sz);
+	ut_assertnonnull(blob);
+
+	/* Make a writable copy of the fdt blob */
+	ut_assertok(fdt_open_into(gd->fdt_blob, blob, blob_sz));
+
+	/* Insert a memory region in /reserved-memory node */
+	resv.start = 0x1000;
+	resv.end = 0x1fff;
+	ut_assertok(fdtdec_add_reserved_memory(blob, "rsvd_region",
+					       &resv, &phandle));
+
+	/* Test /reserve-memory and its subnode should exist */
+	parent = fdt_path_offset(blob, "/reserved-memory");
+	ut_assert(parent > 0);
+	subnode = fdt_path_offset(blob, "/reserved-memory/rsvd_region");
+	ut_assert(subnode > 0);
+
+	/* Test reg property of /reserved-memory/rsvd_region node */
+	addr = fdtdec_get_addr_size_auto_parent(blob, parent, subnode,
+						"reg", 0, &size, false);
+	ut_assert(addr == resv.start);
+	ut_assert(size == resv.end -  resv.start + 1);
+
+	/* Insert another memory region in /reserved-memory node */
+	subnode = fdt_path_offset(blob, "/reserved-memory/rsvd_region1");
+	ut_assert(subnode < 0);
+
+	resv.start = 0x2000;
+	resv.end = 0x2fff;
+	ut_assertok(fdtdec_add_reserved_memory(blob, "rsvd_region1",
+					       &resv, &phandle1));
+	subnode = fdt_path_offset(blob, "/reserved-memory/rsvd_region1");
+	ut_assert(subnode > 0);
+
+	/* phandles must be different */
+	ut_assert(phandle != phandle1);
+
+	/*
+	 * Insert a 3rd memory region with the same addr/size as the 1st one,
+	 * but a new node should not be inserted due to the same addr/size.
+	 */
+	resv.start = 0x1000;
+	resv.end = 0x1fff;
+	ut_assertok(fdtdec_add_reserved_memory(blob, "rsvd_region2",
+					       &resv, &phandle1));
+	subnode = fdt_path_offset(blob, "/reserved-memory/rsvd_region2");
+	ut_assert(subnode < 0);
+
+	/* phandle must be same as the 1st one */
+	ut_assert(phandle == phandle1);
+
+	free(blob);
+
+	return 0;
+}
+DM_TEST(dm_test_fdtdec_add_reserved_memory,
+	DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE);

+ 1 - 1
test/dm/gpio.c

@@ -244,7 +244,7 @@ static int dm_test_gpio_anon(struct unit_test_state *uts)
 
 	/* And the anonymous bank */
 	ut_assertok(gpio_lookup_name("14", &dev, &offset, &gpio));
-	ut_asserteq_str(dev->name, "gpio_sandbox");
+	ut_asserteq_str(dev->name, "sandbox_gpio");
 	ut_asserteq(14, offset);
 	ut_asserteq(14, gpio);
 

+ 3 - 3
test/dm/spi.c

@@ -58,7 +58,7 @@ static int dm_test_spi_find(struct unit_test_state *uts)
 	 */
 	ut_asserteq(-ENODEV, spi_find_bus_and_cs(busnum, cs, &bus, &dev));
 	ut_asserteq(-ENOENT, spi_get_bus_and_cs(busnum, cs, speed, mode,
-						"spi_flash_std", "name", &bus,
+						"jedec_spi_nor", "name", &bus,
 						&slave));
 	sandbox_sf_unbind_emul(state_get_current(), busnum, cs);
 	ut_assertok(spi_cs_info(bus, cs, &info));
@@ -69,7 +69,7 @@ static int dm_test_spi_find(struct unit_test_state *uts)
 					 "name"));
 	ut_assertok(spi_find_bus_and_cs(busnum, cs, &bus, &dev));
 	ut_assertok(spi_get_bus_and_cs(busnum, cs, speed, mode,
-				       "spi_flash_std", "name", &bus, &slave));
+				       "jedec_spi_nor", "name", &bus, &slave));
 
 	ut_assertok(spi_cs_info(bus, cs, &info));
 	ut_asserteq_ptr(info.dev, slave->dev);
@@ -78,7 +78,7 @@ static int dm_test_spi_find(struct unit_test_state *uts)
 	ut_assertok(sandbox_sf_bind_emul(state, busnum, cs_b, bus, node,
 					 "name"));
 	ut_asserteq(-EINVAL, spi_get_bus_and_cs(busnum, cs_b, speed, mode,
-				       "spi_flash_std", "name", &bus, &slave));
+				       "jedec_spi_nor", "name", &bus, &slave));
 	ut_asserteq(-EINVAL, spi_cs_info(bus, cs_b, &info));
 	ut_asserteq_ptr(NULL, info.dev);
 

+ 14 - 6
test/log/syslog_test.c

@@ -21,6 +21,8 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#define LOGF_TEST (BIT(LOGF_FUNC) | BIT(LOGF_MSG))
+
 /**
  * struct sb_log_env - private data for sandbox ethernet driver
  *
@@ -102,7 +104,7 @@ static int log_test_syslog_err(struct unit_test_state *uts)
 	int old_log_level = gd->default_log_level;
 	struct sb_log_env env;
 
-	gd->log_fmt = LOGF_DEFAULT;
+	gd->log_fmt = LOGF_TEST;
 	gd->default_log_level = LOGL_INFO;
 	env_set("ethact", "eth@10002000");
 	env_set("log_hostname", "sandbox");
@@ -116,6 +118,7 @@ static int log_test_syslog_err(struct unit_test_state *uts)
 	/* Check that the callback function was called */
 	sandbox_eth_set_tx_handler(0, NULL);
 	gd->default_log_level = old_log_level;
+	gd->log_fmt = log_get_default_format();
 
 	return 0;
 }
@@ -132,7 +135,7 @@ static int log_test_syslog_warning(struct unit_test_state *uts)
 	int old_log_level = gd->default_log_level;
 	struct sb_log_env env;
 
-	gd->log_fmt = LOGF_DEFAULT;
+	gd->log_fmt = LOGF_TEST;
 	gd->default_log_level = LOGL_INFO;
 	env_set("ethact", "eth@10002000");
 	env_set("log_hostname", "sandbox");
@@ -147,6 +150,7 @@ static int log_test_syslog_warning(struct unit_test_state *uts)
 	/* Check that the callback function was called */
 	ut_assertnull(env.expected);
 	gd->default_log_level = old_log_level;
+	gd->log_fmt = log_get_default_format();
 
 	return 0;
 }
@@ -163,7 +167,7 @@ static int log_test_syslog_notice(struct unit_test_state *uts)
 	int old_log_level = gd->default_log_level;
 	struct sb_log_env env;
 
-	gd->log_fmt = LOGF_DEFAULT;
+	gd->log_fmt = LOGF_TEST;
 	gd->default_log_level = LOGL_INFO;
 	env_set("ethact", "eth@10002000");
 	env_set("log_hostname", "sandbox");
@@ -178,6 +182,7 @@ static int log_test_syslog_notice(struct unit_test_state *uts)
 	/* Check that the callback function was called */
 	ut_assertnull(env.expected);
 	gd->default_log_level = old_log_level;
+	gd->log_fmt = log_get_default_format();
 
 	return 0;
 }
@@ -194,7 +199,7 @@ static int log_test_syslog_info(struct unit_test_state *uts)
 	int old_log_level = gd->default_log_level;
 	struct sb_log_env env;
 
-	gd->log_fmt = LOGF_DEFAULT;
+	gd->log_fmt = LOGF_TEST;
 	gd->default_log_level = LOGL_INFO;
 	env_set("ethact", "eth@10002000");
 	env_set("log_hostname", "sandbox");
@@ -209,6 +214,7 @@ static int log_test_syslog_info(struct unit_test_state *uts)
 	/* Check that the callback function was called */
 	ut_assertnull(env.expected);
 	gd->default_log_level = old_log_level;
+	gd->log_fmt = log_get_default_format();
 
 	return 0;
 }
@@ -225,7 +231,7 @@ static int log_test_syslog_debug(struct unit_test_state *uts)
 	int old_log_level = gd->default_log_level;
 	struct sb_log_env env;
 
-	gd->log_fmt = LOGF_DEFAULT;
+	gd->log_fmt = LOGF_TEST;
 	gd->default_log_level = LOGL_DEBUG;
 	env_set("ethact", "eth@10002000");
 	env_set("log_hostname", "sandbox");
@@ -240,6 +246,7 @@ static int log_test_syslog_debug(struct unit_test_state *uts)
 	/* Check that the callback function was called */
 	ut_assertnull(env.expected);
 	gd->default_log_level = old_log_level;
+	gd->log_fmt = log_get_default_format();
 
 	return 0;
 }
@@ -259,7 +266,7 @@ static int log_test_syslog_nodebug(struct unit_test_state *uts)
 	int old_log_level = gd->default_log_level;
 	struct sb_log_env env;
 
-	gd->log_fmt = LOGF_DEFAULT;
+	gd->log_fmt = LOGF_TEST;
 	gd->default_log_level = LOGL_INFO;
 	env_set("ethact", "eth@10002000");
 	env_set("log_hostname", "sandbox");
@@ -274,6 +281,7 @@ static int log_test_syslog_nodebug(struct unit_test_state *uts)
 	/* Check that the callback function was not called */
 	ut_assertnonnull(env.expected);
 	gd->default_log_level = old_log_level;
+	gd->log_fmt = log_get_default_format();
 
 	return 0;
 }

+ 27 - 27
test/py/tests/test_bind.py

@@ -26,45 +26,45 @@ def in_tree(response, name, uclass, drv, depth, last_child):
 def test_bind_unbind_with_node(u_boot_console):
 
 	#bind /bind-test. Device should come up as well as its children
-	response = u_boot_console.run_command('bind  /bind-test generic_simple_bus')
+	response = u_boot_console.run_command('bind  /bind-test simple_bus')
 	assert response == ''
 	tree = u_boot_console.run_command('dm tree')
-	assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
+	assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True)
 	assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, False)
-	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
+	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True)
 
 	#Unbind child #1. No error expected and all devices should be there except for bind-test-child1
 	response = u_boot_console.run_command('unbind  /bind-test/bind-test-child1')
 	assert response == ''
 	tree = u_boot_console.run_command('dm tree')
-	assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
+	assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True)
 	assert 'bind-test-child1' not in tree
-	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
+	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True)
 
 	#bind child #1. No error expected and all devices should be there
 	response = u_boot_console.run_command('bind  /bind-test/bind-test-child1 phy_sandbox')
 	assert response == ''
 	tree = u_boot_console.run_command('dm tree')
-	assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
+	assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True)
 	assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, True)
-	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, False)
+	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, False)
 
 	#Unbind child #2. No error expected and all devices should be there except for bind-test-child2
 	response = u_boot_console.run_command('unbind  /bind-test/bind-test-child2')
 	assert response == ''
 	tree = u_boot_console.run_command('dm tree')
-	assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
+	assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True)
 	assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, True)
 	assert 'bind-test-child2' not in tree
 
 
 	#Bind child #2. No error expected and all devices should be there
-	response = u_boot_console.run_command('bind /bind-test/bind-test-child2 generic_simple_bus')
+	response = u_boot_console.run_command('bind /bind-test/bind-test-child2 simple_bus')
 	assert response == ''
 	tree = u_boot_console.run_command('dm tree')
-	assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
+	assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True)
 	assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, False)
-	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
+	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True)
 
 	#Unbind parent. No error expected. All devices should be removed and unbound
 	response = u_boot_console.run_command('unbind  /bind-test')
@@ -75,7 +75,7 @@ def test_bind_unbind_with_node(u_boot_console):
 	assert 'bind-test-child2' not in tree
 
 	#try binding invalid node with valid driver
-	response = u_boot_console.run_command('bind  /not-a-valid-node generic_simple_bus')
+	response = u_boot_console.run_command('bind  /not-a-valid-node simple_bus')
 	assert response != ''
 	tree = u_boot_console.run_command('dm tree')
 	assert 'not-a-valid-node' not in tree
@@ -87,12 +87,12 @@ def test_bind_unbind_with_node(u_boot_console):
 	assert 'bind-test' not in tree
 
 	#bind /bind-test. Device should come up as well as its children
-	response = u_boot_console.run_command('bind  /bind-test generic_simple_bus')
+	response = u_boot_console.run_command('bind  /bind-test simple_bus')
 	assert response == ''
 	tree = u_boot_console.run_command('dm tree')
-	assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
+	assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True)
 	assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, False)
-	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
+	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True)
 
 	response = u_boot_console.run_command('unbind  /bind-test')
 	assert response == ''
@@ -112,7 +112,7 @@ def get_next_line(tree, name):
 @pytest.mark.buildconfigspec('cmd_bind')
 def test_bind_unbind_with_uclass(u_boot_console):
 	#bind /bind-test
-	response = u_boot_console.run_command('bind  /bind-test generic_simple_bus')
+	response = u_boot_console.run_command('bind  /bind-test simple_bus')
 	assert response == ''
 
 	#make sure bind-test-child2 is there and get its uclass/index pair
@@ -123,8 +123,8 @@ def test_bind_unbind_with_uclass(u_boot_console):
 	child2_uclass = child2_line[0].split()[0]
 	child2_index = int(child2_line[0].split()[1])
 
-	#bind generic_simple_bus as a child of bind-test-child2
-	response = u_boot_console.run_command('bind  {} {} generic_simple_bus'.format(child2_uclass, child2_index, 'generic_simple_bus'))
+	#bind simple_bus as a child of bind-test-child2
+	response = u_boot_console.run_command('bind  {} {} simple_bus'.format(child2_uclass, child2_index, 'simple_bus'))
 
 	#check that the child is there and its uclass/index pair is right
 	tree = u_boot_console.run_command('dm tree')
@@ -132,20 +132,20 @@ def test_bind_unbind_with_uclass(u_boot_console):
 	child_of_child2_line = get_next_line(tree, 'bind-test-child2')
 	assert child_of_child2_line
 	child_of_child2_index = int(child_of_child2_line.split()[1])
-	assert in_tree(tree, 'generic_simple_bus', 'simple_bus', 'generic_simple_bus', 2, True)
+	assert in_tree(tree, 'simple_bus', 'simple_bus', 'simple_bus', 2, True)
 	assert child_of_child2_index == child2_index + 1
 
 	#unbind the child and check it has been removed
 	response = u_boot_console.run_command('unbind  simple_bus {}'.format(child_of_child2_index))
 	assert response == ''
 	tree = u_boot_console.run_command('dm tree')
-	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
-	assert not in_tree(tree, 'generic_simple_bus', 'simple_bus', 'generic_simple_bus', 2, True)
+	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True)
+	assert not in_tree(tree, 'simple_bus', 'simple_bus', 'simple_bus', 2, True)
 	child_of_child2_line = get_next_line(tree, 'bind-test-child2')
 	assert child_of_child2_line == ''
 
-	#bind generic_simple_bus as a child of bind-test-child2
-	response = u_boot_console.run_command('bind  {} {} generic_simple_bus'.format(child2_uclass, child2_index, 'generic_simple_bus'))
+	#bind simple_bus as a child of bind-test-child2
+	response = u_boot_console.run_command('bind  {} {} simple_bus'.format(child2_uclass, child2_index, 'simple_bus'))
 
 	#check that the child is there and its uclass/index pair is right
 	tree = u_boot_console.run_command('dm tree')
@@ -154,22 +154,22 @@ def test_bind_unbind_with_uclass(u_boot_console):
 	child_of_child2_line = get_next_line(tree, 'bind-test-child2')
 	assert child_of_child2_line
 	child_of_child2_index = int(child_of_child2_line.split()[1])
-	assert in_tree(tree, 'generic_simple_bus', 'simple_bus', 'generic_simple_bus', 2, True)
+	assert in_tree(tree, 'simple_bus', 'simple_bus', 'simple_bus', 2, True)
 	assert child_of_child2_index == child2_index + 1
 
 	#unbind the child and check it has been removed
-	response = u_boot_console.run_command('unbind  {} {} generic_simple_bus'.format(child2_uclass, child2_index, 'generic_simple_bus'))
+	response = u_boot_console.run_command('unbind  {} {} simple_bus'.format(child2_uclass, child2_index, 'simple_bus'))
 	assert response == ''
 
 	tree = u_boot_console.run_command('dm tree')
-	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
+	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True)
 
 	child_of_child2_line = get_next_line(tree, 'bind-test-child2')
 	assert child_of_child2_line == ''
 
 	#unbind the child again and check it doesn't change the tree
 	tree_old = u_boot_console.run_command('dm tree')
-	response = u_boot_console.run_command('unbind  {} {} generic_simple_bus'.format(child2_uclass, child2_index, 'generic_simple_bus'))
+	response = u_boot_console.run_command('unbind  {} {} simple_bus'.format(child2_uclass, child2_index, 'simple_bus'))
 	tree_new = u_boot_console.run_command('dm tree')
 
 	assert response == ''

+ 2 - 0
test/py/tests/test_log.py

@@ -39,6 +39,8 @@ def test_log(u_boot_console):
         Returns:
             iterator containing the lines output from the command
         """
+        output = u_boot_console.run_command('log format fm')
+        assert output == ''
         with cons.log.section('basic'):
            output = u_boot_console.run_command('log test %d' % testnum)
         split = output.replace('\r', '').splitlines()

+ 133 - 15
tools/dtoc/dtb_platdata.py

@@ -13,6 +13,8 @@ static data.
 
 import collections
 import copy
+import os
+import re
 import sys
 
 from dtoc import fdt
@@ -139,16 +141,61 @@ class DtbPlatdata(object):
         _valid_nodes: A list of Node object with compatible strings
         _include_disabled: true to include nodes marked status = "disabled"
         _outfile: The current output file (sys.stdout or a real file)
+        _warning_disabled: true to disable warnings about driver names not found
         _lines: Stashed list of output lines for outputting in the future
+        _aliases: Dict that hold aliases for compatible strings
+            key: First compatible string declared in a node
+            value: List of additional compatible strings declared in a node
+        _drivers: List of valid driver names found in drivers/
+        _driver_aliases: Dict that holds aliases for driver names
+            key: Driver alias declared with
+                U_BOOT_DRIVER_ALIAS(driver_alias, driver_name)
+            value: Driver name declared with U_BOOT_DRIVER(driver_name)
+        _links: List of links to be included in dm_populate_phandle_data()
     """
-    def __init__(self, dtb_fname, include_disabled):
+    def __init__(self, dtb_fname, include_disabled, warning_disabled):
         self._fdt = None
         self._dtb_fname = dtb_fname
         self._valid_nodes = None
         self._include_disabled = include_disabled
         self._outfile = None
+        self._warning_disabled = warning_disabled
         self._lines = []
         self._aliases = {}
+        self._drivers = []
+        self._driver_aliases = {}
+        self._links = []
+
+    def get_normalized_compat_name(self, node):
+        """Get a node's normalized compat name
+
+        Returns a valid driver name by retrieving node's first compatible
+        string as a C identifier and performing a check against _drivers
+        and a lookup in driver_aliases printing a warning in case of failure.
+
+        Args:
+            node: Node object to check
+        Return:
+            Tuple:
+                Driver name associated with the first compatible string
+                List of C identifiers for all the other compatible strings
+                    (possibly empty)
+                In case of no match found, the return will be the same as
+                get_compat_name()
+        """
+        compat_c, aliases_c = get_compat_name(node)
+        if compat_c not in self._drivers:
+            compat_c_old = compat_c
+            compat_c = self._driver_aliases.get(compat_c)
+            if not compat_c:
+                if not self._warning_disabled:
+                    print('WARNING: the driver %s was not found in the driver list'
+                          % (compat_c_old))
+                compat_c = compat_c_old
+            else:
+                aliases_c = [compat_c_old] + aliases_c
+
+        return compat_c, aliases_c
 
     def setup_output(self, fname):
         """Set up the output destination
@@ -211,7 +258,7 @@ class DtbPlatdata(object):
         Return:
             Number of argument cells is this is a phandle, else None
         """
-        if prop.name in ['clocks']:
+        if prop.name in ['clocks', 'cd-gpios']:
             if not isinstance(prop.value, list):
                 prop.value = [prop.value]
             val = prop.value
@@ -231,11 +278,14 @@ class DtbPlatdata(object):
                 if not target:
                     raise ValueError("Cannot parse '%s' in node '%s'" %
                                      (prop.name, node_name))
-                prop_name = '#clock-cells'
-                cells = target.props.get(prop_name)
+                cells = None
+                for prop_name in ['#clock-cells', '#gpio-cells']:
+                    cells = target.props.get(prop_name)
+                    if cells:
+                        break
                 if not cells:
-                    raise ValueError("Node '%s' has no '%s' property" %
-                            (target.name, prop_name))
+                    raise ValueError("Node '%s' has no cells property" %
+                            (target.name))
                 num_args = fdt_util.fdt32_to_cpu(cells.value)
                 max_args = max(max_args, num_args)
                 args.append(num_args)
@@ -243,6 +293,54 @@ class DtbPlatdata(object):
             return PhandleInfo(max_args, args)
         return None
 
+    def scan_driver(self, fn):
+        """Scan a driver file to build a list of driver names and aliases
+
+        This procedure will populate self._drivers and self._driver_aliases
+
+        Args
+            fn: Driver filename to scan
+        """
+        with open(fn, encoding='utf-8') as fd:
+            try:
+                buff = fd.read()
+            except UnicodeDecodeError:
+                # This seems to happen on older Python versions
+                print("Skipping file '%s' due to unicode error" % fn)
+                return
+
+            # The following re will search for driver names declared as
+            # U_BOOT_DRIVER(driver_name)
+            drivers = re.findall('U_BOOT_DRIVER\((.*)\)', buff)
+
+            for driver in drivers:
+                self._drivers.append(driver)
+
+            # The following re will search for driver aliases declared as
+            # U_BOOT_DRIVER_ALIAS(alias, driver_name)
+            driver_aliases = re.findall('U_BOOT_DRIVER_ALIAS\(\s*(\w+)\s*,\s*(\w+)\s*\)',
+                                        buff)
+
+            for alias in driver_aliases: # pragma: no cover
+                if len(alias) != 2:
+                    continue
+                self._driver_aliases[alias[1]] = alias[0]
+
+    def scan_drivers(self):
+        """Scan the driver folders to build a list of driver names and aliases
+
+        This procedure will populate self._drivers and self._driver_aliases
+
+        """
+        basedir = sys.argv[0].replace('tools/dtoc/dtoc', '')
+        if basedir == '':
+            basedir = './'
+        for (dirpath, dirnames, filenames) in os.walk(basedir):
+            for fn in filenames:
+                if not fn.endswith('.c'):
+                    continue
+                self.scan_driver(dirpath + '/' + fn)
+
     def scan_dtb(self):
         """Scan the device tree to obtain a tree of nodes and properties
 
@@ -353,7 +451,7 @@ class DtbPlatdata(object):
         """
         structs = {}
         for node in self._valid_nodes:
-            node_name, _ = get_compat_name(node)
+            node_name, _ = self.get_normalized_compat_name(node)
             fields = {}
 
             # Get a list of all the valid properties in this node.
@@ -377,14 +475,14 @@ class DtbPlatdata(object):
 
         upto = 0
         for node in self._valid_nodes:
-            node_name, _ = get_compat_name(node)
+            node_name, _ = self.get_normalized_compat_name(node)
             struct = structs[node_name]
             for name, prop in node.props.items():
                 if name not in PROP_IGNORE_LIST and name[0] != '#':
                     prop.Widen(struct[name])
             upto += 1
 
-            struct_name, aliases = get_compat_name(node)
+            struct_name, aliases = self.get_normalized_compat_name(node)
             for alias in aliases:
                 self._aliases[alias] = struct_name
 
@@ -461,9 +559,9 @@ class DtbPlatdata(object):
         Args:
             node: node to output
         """
-        struct_name, _ = get_compat_name(node)
+        struct_name, _ = self.get_normalized_compat_name(node)
         var_name = conv_name_to_c(node.name)
-        self.buf('static const struct %s%s %s%s = {\n' %
+        self.buf('static struct %s%s %s%s = {\n' %
                  (STRUCT_PREFIX, struct_name, VAL_PREFIX, var_name))
         for pname in sorted(node.props):
             prop = node.props[pname]
@@ -482,6 +580,7 @@ class DtbPlatdata(object):
                 if info:
                     # Process the list as pairs of (phandle, id)
                     pos = 0
+                    item = 0
                     for args in info.args:
                         phandle_cell = prop.value[pos]
                         phandle = fdt_util.fdt32_to_cpu(phandle_cell)
@@ -491,8 +590,16 @@ class DtbPlatdata(object):
                         for i in range(args):
                             arg_values.append(str(fdt_util.fdt32_to_cpu(prop.value[pos + 1 + i])))
                         pos += 1 + args
-                        vals.append('\t{&%s%s, {%s}}' % (VAL_PREFIX, name,
-                                                     ', '.join(arg_values)))
+                        # node member is filled with NULL as the real value
+                        # will be update at run-time during dm_init_and_scan()
+                        # by dm_populate_phandle_data()
+                        vals.append('\t{NULL, {%s}}' % (', '.join(arg_values)))
+                        var_node = '%s%s.%s[%d].node' % \
+                                    (VAL_PREFIX, var_name, member_name, item)
+                        # Save the the link information to be use to define
+                        # dm_populate_phandle_data()
+                        self._links.append({'var_node': var_node, 'dev_name': name})
+                        item += 1
                     for val in vals:
                         self.buf('\n\t\t%s,' % val)
                 else:
@@ -548,8 +655,18 @@ class DtbPlatdata(object):
             self.output_node(node)
             nodes_to_output.remove(node)
 
+        # Define dm_populate_phandle_data() which will add the linking between
+        # nodes using DM_GET_DEVICE
+        # dtv_dmc_at_xxx.clocks[0].node = DM_GET_DEVICE(clock_controller_at_xxx)
+        self.buf('void dm_populate_phandle_data(void) {\n')
+        for l in self._links:
+            self.buf('\t%s = DM_GET_DEVICE(%s);\n' %
+                     (l['var_node'], l['dev_name']))
+        self.buf('}\n')
+
+        self.out(''.join(self.get_buf()))
 
-def run_steps(args, dtb_file, include_disabled, output):
+def run_steps(args, dtb_file, include_disabled, output, warning_disabled=False):
     """Run all the steps of the dtoc tool
 
     Args:
@@ -561,7 +678,8 @@ def run_steps(args, dtb_file, include_disabled, output):
     if not args:
         raise ValueError('Please specify a command: struct, platdata')
 
-    plat = DtbPlatdata(dtb_file, include_disabled)
+    plat = DtbPlatdata(dtb_file, include_disabled, warning_disabled)
+    plat.scan_drivers()
     plat.scan_dtb()
     plat.scan_tree()
     plat.scan_reg_sizes()

+ 20 - 0
tools/dtoc/dtoc_test_driver_alias.dts

@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test device tree file for dtoc
+ *
+ * Copyright 2020 Collabora Ltd.
+ */
+
+/dts-v1/;
+
+/ {
+	gpio_a: gpios@0 {
+		u-boot,dm-pre-reloc;
+		gpio-controller;
+		compatible = "sandbox_gpio_alias";
+		#gpio-cells = <1>;
+		gpio-bank-name = "a";
+		sandbox,gpio-count = <20>;
+	};
+
+};

+ 15 - 0
tools/dtoc/dtoc_test_invalid_driver.dts

@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test device tree file for dtoc
+ *
+ * Copyright 2017 Google, Inc
+ */
+
+/dts-v1/;
+
+/ {
+	spl-test {
+		u-boot,dm-pre-reloc;
+		compatible = "invalid";
+	};
+};

+ 42 - 0
tools/dtoc/dtoc_test_phandle_cd_gpios.dts

@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test device tree file for dtoc
+ *
+ * Copyright 2020 Collabora Ltd.
+ */
+
+/dts-v1/;
+
+/ {
+	phandle: phandle-target {
+		u-boot,dm-pre-reloc;
+		compatible = "target";
+		intval = <0>;
+		#gpio-cells = <0>;
+	};
+
+	phandle_1: phandle2-target {
+		u-boot,dm-pre-reloc;
+		compatible = "target";
+		intval = <1>;
+		#gpio-cells = <1>;
+	};
+	phandle_2: phandle3-target {
+		u-boot,dm-pre-reloc;
+		compatible = "target";
+		intval = <2>;
+		#gpio-cells = <2>;
+	};
+
+	phandle-source {
+		u-boot,dm-pre-reloc;
+		compatible = "source";
+		cd-gpios = <&phandle &phandle_1 11 &phandle_2 12 13 &phandle>;
+	};
+
+	phandle-source2 {
+		u-boot,dm-pre-reloc;
+		compatible = "source";
+		cd-gpios = <&phandle>;
+	};
+};

+ 219 - 68
tools/dtoc/test_dtoc.py

@@ -12,6 +12,7 @@ tool.
 import collections
 import os
 import struct
+import sys
 import unittest
 
 from dtoc import dtb_platdata
@@ -47,6 +48,9 @@ C_HEADER = '''/*
 #include <dt-structs.h>
 '''
 
+C_EMPTY_POPULATE_PHANDLE_DATA = '''void dm_populate_phandle_data(void) {
+}
+'''
 
 
 def get_dtb_file(dts_fname, capture_stderr=False):
@@ -101,6 +105,10 @@ class TestDtoc(unittest.TestCase):
             print('Failures written to /tmp/binman.{expected,actual}')
         self.assertEquals(expected, actual)
 
+
+    def run_test(self, args, dtb_file, output):
+        dtb_platdata.run_steps(args, dtb_file, False, output, True)
+
     def test_name(self):
         """Test conversion of device tree names to C identifiers"""
         self.assertEqual('serial_at_0x12', conv_name_to_c('serial@0x12'))
@@ -154,21 +162,22 @@ class TestDtoc(unittest.TestCase):
         """Test output from a device tree file with no nodes"""
         dtb_file = get_dtb_file('dtoc_test_empty.dts')
         output = tools.GetOutputFilename('output')
-        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        self.run_test(['struct'], dtb_file, output)
         with open(output) as infile:
             lines = infile.read().splitlines()
         self.assertEqual(HEADER.splitlines(), lines)
 
-        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        self.run_test(['platdata'], dtb_file, output)
         with open(output) as infile:
             lines = infile.read().splitlines()
-        self.assertEqual(C_HEADER.splitlines() + [''], lines)
+        self.assertEqual(C_HEADER.splitlines() + [''] +
+                         C_EMPTY_POPULATE_PHANDLE_DATA.splitlines(), lines)
 
     def test_simple(self):
         """Test output from some simple nodes with various types of data"""
         dtb_file = get_dtb_file('dtoc_test_simple.dts')
         output = tools.GetOutputFilename('output')
-        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        self.run_test(['struct'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(HEADER + '''
@@ -193,11 +202,11 @@ struct dtd_sandbox_spl_test_2 {
 };
 ''', data)
 
-        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        self.run_test(['platdata'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
-static const struct dtd_sandbox_spl_test dtv_spl_test = {
+static struct dtd_sandbox_spl_test dtv_spl_test = {
 \t.boolval\t\t= true,
 \t.bytearray\t\t= {0x6, 0x0, 0x0},
 \t.byteval\t\t= 0x5,
@@ -215,7 +224,7 @@ U_BOOT_DEVICE(spl_test) = {
 \t.platdata_size\t= sizeof(dtv_spl_test),
 };
 
-static const struct dtd_sandbox_spl_test dtv_spl_test2 = {
+static struct dtd_sandbox_spl_test dtv_spl_test2 = {
 \t.bytearray\t\t= {0x1, 0x23, 0x34},
 \t.byteval\t\t= 0x8,
 \t.intarray\t\t= {0x5, 0x0, 0x0, 0x0},
@@ -231,7 +240,7 @@ U_BOOT_DEVICE(spl_test2) = {
 \t.platdata_size\t= sizeof(dtv_spl_test2),
 };
 
-static const struct dtd_sandbox_spl_test dtv_spl_test3 = {
+static struct dtd_sandbox_spl_test dtv_spl_test3 = {
 \t.stringarray\t\t= {"one", "", ""},
 };
 U_BOOT_DEVICE(spl_test3) = {
@@ -240,7 +249,7 @@ U_BOOT_DEVICE(spl_test3) = {
 \t.platdata_size\t= sizeof(dtv_spl_test3),
 };
 
-static const struct dtd_sandbox_spl_test_2 dtv_spl_test4 = {
+static struct dtd_sandbox_spl_test_2 dtv_spl_test4 = {
 };
 U_BOOT_DEVICE(spl_test4) = {
 \t.name\t\t= "sandbox_spl_test_2",
@@ -248,7 +257,7 @@ U_BOOT_DEVICE(spl_test4) = {
 \t.platdata_size\t= sizeof(dtv_spl_test4),
 };
 
-static const struct dtd_sandbox_i2c_test dtv_i2c_at_0 = {
+static struct dtd_sandbox_i2c_test dtv_i2c_at_0 = {
 };
 U_BOOT_DEVICE(i2c_at_0) = {
 \t.name\t\t= "sandbox_i2c_test",
@@ -256,7 +265,7 @@ U_BOOT_DEVICE(i2c_at_0) = {
 \t.platdata_size\t= sizeof(dtv_i2c_at_0),
 };
 
-static const struct dtd_sandbox_pmic_test dtv_pmic_at_9 = {
+static struct dtd_sandbox_pmic_test dtv_pmic_at_9 = {
 \t.low_power\t\t= true,
 \t.reg\t\t\t= {0x9, 0x0},
 };
@@ -266,13 +275,78 @@ U_BOOT_DEVICE(pmic_at_9) = {
 \t.platdata_size\t= sizeof(dtv_pmic_at_9),
 };
 
+''' + C_EMPTY_POPULATE_PHANDLE_DATA, data)
+
+    def test_driver_alias(self):
+        """Test output from a device tree file with a driver alias"""
+        dtb_file = get_dtb_file('dtoc_test_driver_alias.dts')
+        output = tools.GetOutputFilename('output')
+        self.run_test(['struct'], dtb_file, output)
+        with open(output) as infile:
+            data = infile.read()
+        self._CheckStrings(HEADER + '''
+struct dtd_sandbox_gpio {
+\tconst char *\tgpio_bank_name;
+\tbool\t\tgpio_controller;
+\tfdt32_t\t\tsandbox_gpio_count;
+};
+#define dtd_sandbox_gpio_alias dtd_sandbox_gpio
+''', data)
+
+        self.run_test(['platdata'], dtb_file, output)
+        with open(output) as infile:
+            data = infile.read()
+        self._CheckStrings(C_HEADER + '''
+static struct dtd_sandbox_gpio dtv_gpios_at_0 = {
+\t.gpio_bank_name\t\t= "a",
+\t.gpio_controller\t= true,
+\t.sandbox_gpio_count\t= 0x14,
+};
+U_BOOT_DEVICE(gpios_at_0) = {
+\t.name\t\t= "sandbox_gpio",
+\t.platdata\t= &dtv_gpios_at_0,
+\t.platdata_size\t= sizeof(dtv_gpios_at_0),
+};
+
+void dm_populate_phandle_data(void) {
+}
+''', data)
+
+    def test_invalid_driver(self):
+        """Test output from a device tree file with an invalid driver"""
+        dtb_file = get_dtb_file('dtoc_test_invalid_driver.dts')
+        output = tools.GetOutputFilename('output')
+        with test_util.capture_sys_output() as (stdout, stderr):
+            dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        with open(output) as infile:
+            data = infile.read()
+        self._CheckStrings(HEADER + '''
+struct dtd_invalid {
+};
+''', data)
+
+        with test_util.capture_sys_output() as (stdout, stderr):
+            dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        with open(output) as infile:
+            data = infile.read()
+        self._CheckStrings(C_HEADER + '''
+static struct dtd_invalid dtv_spl_test = {
+};
+U_BOOT_DEVICE(spl_test) = {
+\t.name\t\t= "invalid",
+\t.platdata\t= &dtv_spl_test,
+\t.platdata_size\t= sizeof(dtv_spl_test),
+};
+
+void dm_populate_phandle_data(void) {
+}
 ''', data)
 
     def test_phandle(self):
         """Test output from a node containing a phandle reference"""
         dtb_file = get_dtb_file('dtoc_test_phandle.dts')
         output = tools.GetOutputFilename('output')
-        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        self.run_test(['struct'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(HEADER + '''
@@ -284,11 +358,11 @@ struct dtd_target {
 };
 ''', data)
 
-        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        self.run_test(['platdata'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
-static const struct dtd_target dtv_phandle_target = {
+static struct dtd_target dtv_phandle_target = {
 \t.intval\t\t\t= 0x0,
 };
 U_BOOT_DEVICE(phandle_target) = {
@@ -297,7 +371,7 @@ U_BOOT_DEVICE(phandle_target) = {
 \t.platdata_size\t= sizeof(dtv_phandle_target),
 };
 
-static const struct dtd_target dtv_phandle2_target = {
+static struct dtd_target dtv_phandle2_target = {
 \t.intval\t\t\t= 0x1,
 };
 U_BOOT_DEVICE(phandle2_target) = {
@@ -306,7 +380,7 @@ U_BOOT_DEVICE(phandle2_target) = {
 \t.platdata_size\t= sizeof(dtv_phandle2_target),
 };
 
-static const struct dtd_target dtv_phandle3_target = {
+static struct dtd_target dtv_phandle3_target = {
 \t.intval\t\t\t= 0x2,
 };
 U_BOOT_DEVICE(phandle3_target) = {
@@ -315,12 +389,12 @@ U_BOOT_DEVICE(phandle3_target) = {
 \t.platdata_size\t= sizeof(dtv_phandle3_target),
 };
 
-static const struct dtd_source dtv_phandle_source = {
+static struct dtd_source dtv_phandle_source = {
 \t.clocks\t\t\t= {
-\t\t\t{&dtv_phandle_target, {}},
-\t\t\t{&dtv_phandle2_target, {11}},
-\t\t\t{&dtv_phandle3_target, {12, 13}},
-\t\t\t{&dtv_phandle_target, {}},},
+\t\t\t{NULL, {}},
+\t\t\t{NULL, {11}},
+\t\t\t{NULL, {12, 13}},
+\t\t\t{NULL, {}},},
 };
 U_BOOT_DEVICE(phandle_source) = {
 \t.name\t\t= "source",
@@ -328,9 +402,9 @@ U_BOOT_DEVICE(phandle_source) = {
 \t.platdata_size\t= sizeof(dtv_phandle_source),
 };
 
-static const struct dtd_source dtv_phandle_source2 = {
+static struct dtd_source dtv_phandle_source2 = {
 \t.clocks\t\t\t= {
-\t\t\t{&dtv_phandle_target, {}},},
+\t\t\t{NULL, {}},},
 };
 U_BOOT_DEVICE(phandle_source2) = {
 \t.name\t\t= "source",
@@ -338,13 +412,20 @@ U_BOOT_DEVICE(phandle_source2) = {
 \t.platdata_size\t= sizeof(dtv_phandle_source2),
 };
 
+void dm_populate_phandle_data(void) {
+\tdtv_phandle_source.clocks[0].node = DM_GET_DEVICE(phandle_target);
+\tdtv_phandle_source.clocks[1].node = DM_GET_DEVICE(phandle2_target);
+\tdtv_phandle_source.clocks[2].node = DM_GET_DEVICE(phandle3_target);
+\tdtv_phandle_source.clocks[3].node = DM_GET_DEVICE(phandle_target);
+\tdtv_phandle_source2.clocks[0].node = DM_GET_DEVICE(phandle_target);
+}
 ''', data)
 
     def test_phandle_single(self):
         """Test output from a node containing a phandle reference"""
         dtb_file = get_dtb_file('dtoc_test_phandle_single.dts')
         output = tools.GetOutputFilename('output')
-        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        self.run_test(['struct'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(HEADER + '''
@@ -360,11 +441,11 @@ struct dtd_target {
         """Test that phandle targets are generated before their references"""
         dtb_file = get_dtb_file('dtoc_test_phandle_reorder.dts')
         output = tools.GetOutputFilename('output')
-        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        self.run_test(['platdata'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
-static const struct dtd_target dtv_phandle_target = {
+static struct dtd_target dtv_phandle_target = {
 };
 U_BOOT_DEVICE(phandle_target) = {
 \t.name\t\t= "target",
@@ -372,9 +453,72 @@ U_BOOT_DEVICE(phandle_target) = {
 \t.platdata_size\t= sizeof(dtv_phandle_target),
 };
 
-static const struct dtd_source dtv_phandle_source2 = {
+static struct dtd_source dtv_phandle_source2 = {
 \t.clocks\t\t\t= {
-\t\t\t{&dtv_phandle_target, {}},},
+\t\t\t{NULL, {}},},
+};
+U_BOOT_DEVICE(phandle_source2) = {
+\t.name\t\t= "source",
+\t.platdata\t= &dtv_phandle_source2,
+\t.platdata_size\t= sizeof(dtv_phandle_source2),
+};
+
+void dm_populate_phandle_data(void) {
+\tdtv_phandle_source2.clocks[0].node = DM_GET_DEVICE(phandle_target);
+}
+''', data)
+
+    def test_phandle_cd_gpio(self):
+        """Test that phandle targets are generated when unsing cd-gpios"""
+        dtb_file = get_dtb_file('dtoc_test_phandle_cd_gpios.dts')
+        output = tools.GetOutputFilename('output')
+        dtb_platdata.run_steps(['platdata'], dtb_file, False, output, True)
+        with open(output) as infile:
+            data = infile.read()
+        self._CheckStrings(C_HEADER + '''
+static struct dtd_target dtv_phandle_target = {
+\t.intval\t\t\t= 0x0,
+};
+U_BOOT_DEVICE(phandle_target) = {
+\t.name\t\t= "target",
+\t.platdata\t= &dtv_phandle_target,
+\t.platdata_size\t= sizeof(dtv_phandle_target),
+};
+
+static struct dtd_target dtv_phandle2_target = {
+\t.intval\t\t\t= 0x1,
+};
+U_BOOT_DEVICE(phandle2_target) = {
+\t.name\t\t= "target",
+\t.platdata\t= &dtv_phandle2_target,
+\t.platdata_size\t= sizeof(dtv_phandle2_target),
+};
+
+static struct dtd_target dtv_phandle3_target = {
+\t.intval\t\t\t= 0x2,
+};
+U_BOOT_DEVICE(phandle3_target) = {
+\t.name\t\t= "target",
+\t.platdata\t= &dtv_phandle3_target,
+\t.platdata_size\t= sizeof(dtv_phandle3_target),
+};
+
+static struct dtd_source dtv_phandle_source = {
+\t.cd_gpios\t\t= {
+\t\t\t{NULL, {}},
+\t\t\t{NULL, {11}},
+\t\t\t{NULL, {12, 13}},
+\t\t\t{NULL, {}},},
+};
+U_BOOT_DEVICE(phandle_source) = {
+\t.name\t\t= "source",
+\t.platdata\t= &dtv_phandle_source,
+\t.platdata_size\t= sizeof(dtv_phandle_source),
+};
+
+static struct dtd_source dtv_phandle_source2 = {
+\t.cd_gpios\t\t= {
+\t\t\t{NULL, {}},},
 };
 U_BOOT_DEVICE(phandle_source2) = {
 \t.name\t\t= "source",
@@ -382,6 +526,13 @@ U_BOOT_DEVICE(phandle_source2) = {
 \t.platdata_size\t= sizeof(dtv_phandle_source2),
 };
 
+void dm_populate_phandle_data(void) {
+\tdtv_phandle_source.cd_gpios[0].node = DM_GET_DEVICE(phandle_target);
+\tdtv_phandle_source.cd_gpios[1].node = DM_GET_DEVICE(phandle2_target);
+\tdtv_phandle_source.cd_gpios[2].node = DM_GET_DEVICE(phandle3_target);
+\tdtv_phandle_source.cd_gpios[3].node = DM_GET_DEVICE(phandle_target);
+\tdtv_phandle_source2.cd_gpios[0].node = DM_GET_DEVICE(phandle_target);
+}
 ''', data)
 
     def test_phandle_bad(self):
@@ -390,7 +541,7 @@ U_BOOT_DEVICE(phandle_source2) = {
                                 capture_stderr=True)
         output = tools.GetOutputFilename('output')
         with self.assertRaises(ValueError) as e:
-            dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+            self.run_test(['struct'], dtb_file, output)
         self.assertIn("Cannot parse 'clocks' in node 'phandle-source'",
                       str(e.exception))
 
@@ -400,15 +551,15 @@ U_BOOT_DEVICE(phandle_source2) = {
                                 capture_stderr=True)
         output = tools.GetOutputFilename('output')
         with self.assertRaises(ValueError) as e:
-            dtb_platdata.run_steps(['struct'], dtb_file, False, output)
-        self.assertIn("Node 'phandle-target' has no '#clock-cells' property",
+            self.run_test(['struct'], dtb_file, output)
+        self.assertIn("Node 'phandle-target' has no cells property",
                       str(e.exception))
 
     def test_aliases(self):
         """Test output from a node with multiple compatible strings"""
         dtb_file = get_dtb_file('dtoc_test_aliases.dts')
         output = tools.GetOutputFilename('output')
-        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        self.run_test(['struct'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(HEADER + '''
@@ -419,11 +570,11 @@ struct dtd_compat1 {
 #define dtd_compat3 dtd_compat1
 ''', data)
 
-        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        self.run_test(['platdata'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
-static const struct dtd_compat1 dtv_spl_test = {
+static struct dtd_compat1 dtv_spl_test = {
 \t.intval\t\t\t= 0x1,
 };
 U_BOOT_DEVICE(spl_test) = {
@@ -432,13 +583,13 @@ U_BOOT_DEVICE(spl_test) = {
 \t.platdata_size\t= sizeof(dtv_spl_test),
 };
 
-''', data)
+''' + C_EMPTY_POPULATE_PHANDLE_DATA, data)
 
     def test_addresses64(self):
         """Test output from a node with a 'reg' property with na=2, ns=2"""
         dtb_file = get_dtb_file('dtoc_test_addr64.dts')
         output = tools.GetOutputFilename('output')
-        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        self.run_test(['struct'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(HEADER + '''
@@ -453,11 +604,11 @@ struct dtd_test3 {
 };
 ''', data)
 
-        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        self.run_test(['platdata'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
-static const struct dtd_test1 dtv_test1 = {
+static struct dtd_test1 dtv_test1 = {
 \t.reg\t\t\t= {0x1234, 0x5678},
 };
 U_BOOT_DEVICE(test1) = {
@@ -466,7 +617,7 @@ U_BOOT_DEVICE(test1) = {
 \t.platdata_size\t= sizeof(dtv_test1),
 };
 
-static const struct dtd_test2 dtv_test2 = {
+static struct dtd_test2 dtv_test2 = {
 \t.reg\t\t\t= {0x1234567890123456, 0x9876543210987654},
 };
 U_BOOT_DEVICE(test2) = {
@@ -475,7 +626,7 @@ U_BOOT_DEVICE(test2) = {
 \t.platdata_size\t= sizeof(dtv_test2),
 };
 
-static const struct dtd_test3 dtv_test3 = {
+static struct dtd_test3 dtv_test3 = {
 \t.reg\t\t\t= {0x1234567890123456, 0x9876543210987654, 0x2, 0x3},
 };
 U_BOOT_DEVICE(test3) = {
@@ -484,13 +635,13 @@ U_BOOT_DEVICE(test3) = {
 \t.platdata_size\t= sizeof(dtv_test3),
 };
 
-''', data)
+''' + C_EMPTY_POPULATE_PHANDLE_DATA, data)
 
     def test_addresses32(self):
         """Test output from a node with a 'reg' property with na=1, ns=1"""
         dtb_file = get_dtb_file('dtoc_test_addr32.dts')
         output = tools.GetOutputFilename('output')
-        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        self.run_test(['struct'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(HEADER + '''
@@ -502,11 +653,11 @@ struct dtd_test2 {
 };
 ''', data)
 
-        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        self.run_test(['platdata'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
-static const struct dtd_test1 dtv_test1 = {
+static struct dtd_test1 dtv_test1 = {
 \t.reg\t\t\t= {0x1234, 0x5678},
 };
 U_BOOT_DEVICE(test1) = {
@@ -515,7 +666,7 @@ U_BOOT_DEVICE(test1) = {
 \t.platdata_size\t= sizeof(dtv_test1),
 };
 
-static const struct dtd_test2 dtv_test2 = {
+static struct dtd_test2 dtv_test2 = {
 \t.reg\t\t\t= {0x12345678, 0x98765432, 0x2, 0x3},
 };
 U_BOOT_DEVICE(test2) = {
@@ -524,13 +675,13 @@ U_BOOT_DEVICE(test2) = {
 \t.platdata_size\t= sizeof(dtv_test2),
 };
 
-''', data)
+''' + C_EMPTY_POPULATE_PHANDLE_DATA, data)
 
     def test_addresses64_32(self):
         """Test output from a node with a 'reg' property with na=2, ns=1"""
         dtb_file = get_dtb_file('dtoc_test_addr64_32.dts')
         output = tools.GetOutputFilename('output')
-        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        self.run_test(['struct'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(HEADER + '''
@@ -545,11 +696,11 @@ struct dtd_test3 {
 };
 ''', data)
 
-        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        self.run_test(['platdata'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
-static const struct dtd_test1 dtv_test1 = {
+static struct dtd_test1 dtv_test1 = {
 \t.reg\t\t\t= {0x123400000000, 0x5678},
 };
 U_BOOT_DEVICE(test1) = {
@@ -558,7 +709,7 @@ U_BOOT_DEVICE(test1) = {
 \t.platdata_size\t= sizeof(dtv_test1),
 };
 
-static const struct dtd_test2 dtv_test2 = {
+static struct dtd_test2 dtv_test2 = {
 \t.reg\t\t\t= {0x1234567890123456, 0x98765432},
 };
 U_BOOT_DEVICE(test2) = {
@@ -567,7 +718,7 @@ U_BOOT_DEVICE(test2) = {
 \t.platdata_size\t= sizeof(dtv_test2),
 };
 
-static const struct dtd_test3 dtv_test3 = {
+static struct dtd_test3 dtv_test3 = {
 \t.reg\t\t\t= {0x1234567890123456, 0x98765432, 0x2, 0x3},
 };
 U_BOOT_DEVICE(test3) = {
@@ -576,13 +727,13 @@ U_BOOT_DEVICE(test3) = {
 \t.platdata_size\t= sizeof(dtv_test3),
 };
 
-''', data)
+''' + C_EMPTY_POPULATE_PHANDLE_DATA, data)
 
     def test_addresses32_64(self):
         """Test output from a node with a 'reg' property with na=1, ns=2"""
         dtb_file = get_dtb_file('dtoc_test_addr32_64.dts')
         output = tools.GetOutputFilename('output')
-        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        self.run_test(['struct'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(HEADER + '''
@@ -597,11 +748,11 @@ struct dtd_test3 {
 };
 ''', data)
 
-        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        self.run_test(['platdata'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
-static const struct dtd_test1 dtv_test1 = {
+static struct dtd_test1 dtv_test1 = {
 \t.reg\t\t\t= {0x1234, 0x567800000000},
 };
 U_BOOT_DEVICE(test1) = {
@@ -610,7 +761,7 @@ U_BOOT_DEVICE(test1) = {
 \t.platdata_size\t= sizeof(dtv_test1),
 };
 
-static const struct dtd_test2 dtv_test2 = {
+static struct dtd_test2 dtv_test2 = {
 \t.reg\t\t\t= {0x12345678, 0x9876543210987654},
 };
 U_BOOT_DEVICE(test2) = {
@@ -619,7 +770,7 @@ U_BOOT_DEVICE(test2) = {
 \t.platdata_size\t= sizeof(dtv_test2),
 };
 
-static const struct dtd_test3 dtv_test3 = {
+static struct dtd_test3 dtv_test3 = {
 \t.reg\t\t\t= {0x12345678, 0x9876543210987654, 0x2, 0x3},
 };
 U_BOOT_DEVICE(test3) = {
@@ -628,7 +779,7 @@ U_BOOT_DEVICE(test3) = {
 \t.platdata_size\t= sizeof(dtv_test3),
 };
 
-''', data)
+''' + C_EMPTY_POPULATE_PHANDLE_DATA, data)
 
     def test_bad_reg(self):
         """Test that a reg property with an invalid type generates an error"""
@@ -636,7 +787,7 @@ U_BOOT_DEVICE(test3) = {
         dtb_file = get_dtb_file('dtoc_test_bad_reg.dts', capture_stderr=True)
         output = tools.GetOutputFilename('output')
         with self.assertRaises(ValueError) as e:
-            dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+            self.run_test(['struct'], dtb_file, output)
         self.assertIn("Node 'spl-test' reg property is not an int",
                       str(e.exception))
 
@@ -646,7 +797,7 @@ U_BOOT_DEVICE(test3) = {
         dtb_file = get_dtb_file('dtoc_test_bad_reg2.dts', capture_stderr=True)
         output = tools.GetOutputFilename('output')
         with self.assertRaises(ValueError) as e:
-            dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+            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)",
                       str(e.exception))
 
@@ -654,7 +805,7 @@ U_BOOT_DEVICE(test3) = {
         """Test that a subequent node can add a new property to a struct"""
         dtb_file = get_dtb_file('dtoc_test_add_prop.dts')
         output = tools.GetOutputFilename('output')
-        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        self.run_test(['struct'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(HEADER + '''
@@ -664,11 +815,11 @@ struct dtd_sandbox_spl_test {
 };
 ''', data)
 
-        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        self.run_test(['platdata'], dtb_file, output)
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
-static const struct dtd_sandbox_spl_test dtv_spl_test = {
+static struct dtd_sandbox_spl_test dtv_spl_test = {
 \t.intval\t\t\t= 0x1,
 };
 U_BOOT_DEVICE(spl_test) = {
@@ -677,7 +828,7 @@ U_BOOT_DEVICE(spl_test) = {
 \t.platdata_size\t= sizeof(dtv_spl_test),
 };
 
-static const struct dtd_sandbox_spl_test dtv_spl_test2 = {
+static struct dtd_sandbox_spl_test dtv_spl_test2 = {
 \t.intarray\t\t= 0x5,
 };
 U_BOOT_DEVICE(spl_test2) = {
@@ -686,18 +837,18 @@ U_BOOT_DEVICE(spl_test2) = {
 \t.platdata_size\t= sizeof(dtv_spl_test2),
 };
 
-''', data)
+''' + C_EMPTY_POPULATE_PHANDLE_DATA, data)
 
     def testStdout(self):
         """Test output to stdout"""
         dtb_file = get_dtb_file('dtoc_test_simple.dts')
         with test_util.capture_sys_output() as (stdout, stderr):
-            dtb_platdata.run_steps(['struct'], dtb_file, False, '-')
+            self.run_test(['struct'], dtb_file, '-')
 
     def testNoCommand(self):
         """Test running dtoc without a command"""
         with self.assertRaises(ValueError) as e:
-            dtb_platdata.run_steps([], '', False, '')
+            self.run_test([], '', '')
         self.assertIn("Please specify a command: struct, platdata",
                       str(e.exception))
 
@@ -706,6 +857,6 @@ U_BOOT_DEVICE(spl_test2) = {
         dtb_file = get_dtb_file('dtoc_test_simple.dts')
         output = tools.GetOutputFilename('output')
         with self.assertRaises(ValueError) as e:
-            dtb_platdata.run_steps(['invalid-cmd'], dtb_file, False, output)
+            self.run_test(['invalid-cmd'], dtb_file, output)
         self.assertIn("Unknown command 'invalid-cmd': (use: struct, platdata)",
                       str(e.exception))

+ 15 - 9
tools/patman/checkpatch.py

@@ -38,7 +38,7 @@ def FindCheckPatch():
     sys.exit('Cannot find checkpatch.pl - please put it in your ' +
              '~/bin directory or use --no-check')
 
-def CheckPatch(fname, verbose=False):
+def CheckPatch(fname, verbose=False, show_types=False):
     """Run checkpatch.pl on a file.
 
     Returns:
@@ -64,8 +64,10 @@ def CheckPatch(fname, verbose=False):
     result.problems = []
     chk = FindCheckPatch()
     item = {}
-    result.stdout = command.Output(chk, '--no-tree', fname,
-                                   raise_on_error=False)
+    args = [chk, '--no-tree']
+    if show_types:
+        args.append('--show-types')
+    result.stdout = command.Output(*args, fname, raise_on_error=False)
     #pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE)
     #stdout, stderr = pipe.communicate()
 
@@ -81,9 +83,10 @@ def CheckPatch(fname, verbose=False):
                                ' checks, (\d+)')
     re_ok = re.compile('.*has no obvious style problems')
     re_bad = re.compile('.*has style problems, please review')
-    re_error = re.compile('ERROR: (.*)')
-    re_warning = re.compile(emacs_prefix + 'WARNING:(?:[A-Z_]+:)? (.*)')
-    re_check = re.compile('CHECK: (.*)')
+    type_name = '([A-Z_]+:)?'
+    re_error = re.compile('ERROR:%s (.*)' % type_name)
+    re_warning = re.compile(emacs_prefix + 'WARNING:%s (.*)' % type_name)
+    re_check = re.compile('CHECK:%s (.*)' % type_name)
     re_file = re.compile('#\d+: FILE: ([^:]*):(\d+):')
     re_note = re.compile('NOTE: (.*)')
     indent = ' ' * 6
@@ -129,13 +132,16 @@ def CheckPatch(fname, verbose=False):
         check_match = re_check.match(line)
         subject_match = line.startswith('Subject:')
         if err_match:
-            item['msg'] = err_match.group(1)
+            item['cptype'] = err_match.group(1)
+            item['msg'] = err_match.group(2)
             item['type'] = 'error'
         elif warn_match:
-            item['msg'] = warn_match.group(1)
+            item['cptype'] = warn_match.group(1)
+            item['msg'] = warn_match.group(2)
             item['type'] = 'warning'
         elif check_match:
-            item['msg'] = check_match.group(1)
+            item['cptype'] = check_match.group(1)
+            item['msg'] = check_match.group(2)
             item['type'] = 'check'
         elif file_match:
             item['file'] = file_match.group(1)

+ 3 - 4
tools/patman/command.py

@@ -5,7 +5,6 @@
 import os
 
 from patman import cros_subprocess
-from patman import tools
 
 """Shell command ease-ups for Python."""
 
@@ -35,9 +34,9 @@ class CommandResult:
 
     def ToOutput(self, binary):
         if not binary:
-            self.stdout = tools.ToString(self.stdout)
-            self.stderr = tools.ToString(self.stderr)
-            self.combined = tools.ToString(self.combined)
+            self.stdout = self.stdout.decode('utf-8')
+            self.stderr = self.stderr.decode('utf-8')
+            self.combined = self.combined.decode('utf-8')
         return self
 
 

+ 7 - 7
tools/patman/get_maintainer.py

@@ -5,17 +5,16 @@
 import os
 
 from patman import command
-from patman import gitutil
 
-def FindGetMaintainer():
+def FindGetMaintainer(try_list):
     """Look for the get_maintainer.pl script.
 
+    Args:
+        try_list: List of directories to try for the get_maintainer.pl script
+
     Returns:
         If the script is found we'll return a path to it; else None.
     """
-    try_list = [
-        os.path.join(gitutil.GetTopLevel(), 'scripts'),
-        ]
     # Look in the list
     for path in try_list:
         fname = os.path.join(path, 'get_maintainer.pl')
@@ -24,7 +23,7 @@ def FindGetMaintainer():
 
     return None
 
-def GetMaintainer(fname, verbose=False):
+def GetMaintainer(dir_list, fname, verbose=False):
     """Run get_maintainer.pl on a file if we find it.
 
     We look for get_maintainer.pl in the 'scripts' directory at the top of
@@ -32,12 +31,13 @@ def GetMaintainer(fname, verbose=False):
     then we fail silently.
 
     Args:
+        dir_list: List of directories to try for the get_maintainer.pl script
         fname: Path to the patch file to run get_maintainer.pl on.
 
     Returns:
         A list of email addresses to CC to.
     """
-    get_maintainer = FindGetMaintainer()
+    get_maintainer = FindGetMaintainer(dir_list)
     if not get_maintainer:
         if verbose:
             print("WARNING: Couldn't find get_maintainer.pl")

+ 4 - 6
tools/patman/gitutil.py

@@ -7,9 +7,7 @@ import os
 import subprocess
 import sys
 
-from patman import checkpatch
 from patman import command
-from patman import series
 from patman import settings
 from patman import terminal
 from patman import tools
@@ -369,9 +367,9 @@ def EmailPatches(series, cover_fname, args, dry_run, raise_on_error, cc_fname,
     >>> alias['boys'] = ['fred', ' john']
     >>> alias['all'] = ['fred ', 'john', '   mary   ']
     >>> alias[os.getenv('USER')] = ['this-is-me@me.com']
-    >>> series = series.Series()
-    >>> series.to = ['fred']
-    >>> series.cc = ['mary']
+    >>> series = {}
+    >>> series['to'] = ['fred']
+    >>> series['cc'] = ['mary']
     >>> EmailPatches(series, 'cover', ['p1', 'p2'], True, True, 'cc-fname', \
             False, alias)
     'git send-email --annotate --to "f.bloggs@napier.co.nz" --cc \
@@ -380,7 +378,7 @@ def EmailPatches(series, cover_fname, args, dry_run, raise_on_error, cc_fname,
             alias)
     'git send-email --annotate --to "f.bloggs@napier.co.nz" --cc \
 "m.poppins@cloud.net" --cc-cmd "./patman --cc-cmd cc-fname" p1'
-    >>> series.cc = ['all']
+    >>> series['cc'] = ['all']
     >>> EmailPatches(series, 'cover', ['p1', 'p2'], True, True, 'cc-fname', \
             True, alias)
     'git send-email --annotate --to "this-is-me@me.com" --cc-cmd "./patman \

+ 3 - 3
tools/patman/main.py

@@ -25,7 +25,7 @@ from patman import patchstream
 from patman import project
 from patman import settings
 from patman import terminal
-from patman import test
+from patman import test_checkpatch
 
 
 parser = OptionParser()
@@ -80,7 +80,7 @@ specified by tags you place in the commits. Use -n to do a dry run first."""
 # Parse options twice: first to get the project and second to handle
 # defaults properly (which depends on project).
 (options, args) = parser.parse_args()
-settings.Setup(parser, options.project, '')
+settings.Setup(gitutil, parser, options.project, '')
 (options, args) = parser.parse_args()
 
 if __name__ != "__main__":
@@ -93,7 +93,7 @@ elif options.test:
 
     sys.argv = [sys.argv[0]]
     result = unittest.TestResult()
-    for module in (test.TestPatch, func_test.TestFunctional):
+    for module in (test_checkpatch.TestPatch, func_test.TestFunctional):
         suite = unittest.TestLoader().loadTestsFromTestCase(module)
         suite.run(result)
 

+ 2 - 1
tools/patman/series.py

@@ -263,7 +263,8 @@ class Series(dict):
             if type(add_maintainers) == type(cc):
                 cc += add_maintainers
             elif add_maintainers:
-                cc += get_maintainer.GetMaintainer(commit.patch)
+                dir_list = [os.path.join(gitutil.GetTopLevel(), 'scripts')]
+                cc += get_maintainer.GetMaintainer(dir_list, commit.patch)
             for x in set(cc) & set(settings.bounces):
                 print(col.Color(col.YELLOW, 'Skipping "%s"' % x))
             cc = set(cc) - set(settings.bounces)

+ 3 - 4
tools/patman/settings.py

@@ -11,7 +11,6 @@ import os
 import re
 
 from patman import command
-from patman import gitutil
 from patman import tools
 
 """Default settings per-project.
@@ -185,7 +184,7 @@ def ReadGitAliases(fname):
 
     fd.close()
 
-def CreatePatmanConfigFile(config_fname):
+def CreatePatmanConfigFile(gitutil, config_fname):
     """Creates a config file under $(HOME)/.patman if it can't find one.
 
     Args:
@@ -301,7 +300,7 @@ def GetItems(config, section):
     except:
         raise
 
-def Setup(parser, project_name, config_fname=''):
+def Setup(gitutil, parser, project_name, config_fname=''):
     """Set up the settings module by reading config files.
 
     Args:
@@ -318,7 +317,7 @@ def Setup(parser, project_name, config_fname=''):
 
     if not os.path.exists(config_fname):
         print("No config file found ~/.patman\nCreating one...\n")
-        CreatePatmanConfigFile(config_fname)
+        CreatePatmanConfigFile(gitutil, config_fname)
 
     config.read(config_fname)
 

+ 121 - 4
tools/patman/test.py → tools/patman/test_checkpatch.py

@@ -1,6 +1,8 @@
 # -*- coding: utf-8 -*-
 # SPDX-License-Identifier: GPL-2.0+
 #
+# Tests for U-Boot-specific checkpatch.pl features
+#
 # Copyright (c) 2011 The Chromium OS Authors.
 #
 
@@ -15,11 +17,76 @@ from patman import series
 from patman import commit
 
 
-class TestPatch(unittest.TestCase):
-    """Test this program
+class Line:
+    def __init__(self, fname, text):
+        self.fname = fname
+        self.text = text
+
+
+class PatchMaker:
+    def __init__(self):
+        self.lines = []
+
+    def add_line(self, fname, text):
+        self.lines.append(Line(fname, text))
+
+    def get_patch_text(self):
+        base = '''From 125b77450f4c66b8fd9654319520bbe795c9ef31 Mon Sep 17 00:00:00 2001
+From: Simon Glass <sjg@chromium.org>
+Date: Sun, 14 Jun 2020 09:45:14 -0600
+Subject: [PATCH] Test commit
+
+This is a test commit.
+
+Signed-off-by: Simon Glass <sjg@chromium.org>
+---
+
+'''
+        lines = base.splitlines()
+
+        # Create the diffstat
+        change = 0
+        insert = 0
+        for line in self.lines:
+            lines.append(' %s      | 1 +' % line.fname)
+            change += 1
+            insert += 1
+        lines.append(' %d files changed, %d insertions(+)' % (change, insert))
+        lines.append('')
+
+        # Create the patch info for each file
+        for line in self.lines:
+            lines.append('diff --git a/%s b/%s' % (line.fname, line.fname))
+            lines.append('index 7837d459f18..5ba7840f68e 100644')
+            lines.append('--- a/%s' % line.fname)
+            lines.append('+++ b/%s' % line.fname)
+            lines += ('''@@ -121,6 +121,7 @@ enum uclass_id {
+ 	UCLASS_W1,		/* Dallas 1-Wire bus */
+ 	UCLASS_W1_EEPROM,	/* one-wire EEPROMs */
+ 	UCLASS_WDT,		/* Watchdog Timer driver */
++%s
+
+ 	UCLASS_COUNT,
+ 	UCLASS_INVALID = -1,
+''' % line.text).splitlines()
+        lines.append('---')
+        lines.append('2.17.1')
 
-    TODO: Write tests for the rest of the functionality
-    """
+        return '\n'.join(lines)
+
+    def get_patch(self):
+        inhandle, inname = tempfile.mkstemp()
+        infd = os.fdopen(inhandle, 'w')
+        infd.write(self.get_patch_text())
+        infd.close()
+        return inname
+
+    def run_checkpatch(self):
+        return checkpatch.CheckPatch(self.get_patch(), show_types=True)
+
+
+class TestPatch(unittest.TestCase):
+    """Test the u_boot_line() function in checkpatch.pl"""
 
     def testBasic(self):
         """Test basic filter operation"""
@@ -281,6 +348,56 @@ index 0000000..2234c87
         self.assertEqual(result.lines, 62)
         os.remove(inf)
 
+    def checkSingleMessage(self, pm, msg, pmtype = 'warning'):
+        """Helper function to run checkpatch and check the result
+
+        Args:
+            pm: PatchMaker object to use
+            msg" Expected message (e.g. 'LIVETREE')
+            pmtype: Type of problem ('error', 'warning')
+        """
+        result = pm.run_checkpatch()
+        if pmtype == 'warning':
+            self.assertEqual(result.warnings, 1)
+        elif pmtype == 'error':
+            self.assertEqual(result.errors, 1)
+        if len(result.problems) != 1:
+            print(result.problems)
+        self.assertEqual(len(result.problems), 1)
+        self.assertIn(msg, result.problems[0]['cptype'])
+
+    def testUclass(self):
+        """Test for possible new uclass"""
+        pm = PatchMaker()
+        pm.add_line('include/dm/uclass-id.h', 'UCLASS_WIBBLE,')
+        self.checkSingleMessage(pm, 'NEW_UCLASS')
+
+    def testLivetree(self):
+        """Test for Use the livetree API"""
+        pm = PatchMaker()
+        pm.add_line('common/main.c', 'fdtdec_do_something()')
+        self.checkSingleMessage(pm, 'LIVETREE')
+
+    def testNewCommand(self):
+        """Test for Use the livetree API"""
+        pm = PatchMaker()
+        pm.add_line('common/main.c', 'do_wibble(struct cmd_tbl *cmd_tbl)')
+        self.checkSingleMessage(pm, 'CMD_TEST')
+
+    def testNewCommand(self):
+        """Test for Use the livetree API"""
+        pm = PatchMaker()
+        pm.add_line('common/main.c', '#ifdef CONFIG_YELLOW')
+        pm.add_line('common/init.h', '#ifdef CONFIG_YELLOW')
+        pm.add_line('fred.dtsi', '#ifdef CONFIG_YELLOW')
+        self.checkSingleMessage(pm, "PREFER_IF")
+
+    def testCommandUseDefconfig(self):
+        """Test for Use the livetree API"""
+        pm = PatchMaker()
+        pm.add_line('common/main.c', '#undef CONFIG_CMD_WHICH')
+        self.checkSingleMessage(pm, 'DEFINE_CONFIG_CMD', 'error')
+
 
 if __name__ == "__main__":
     unittest.main()

+ 0 - 1
tools/patman/test_util.py

@@ -11,7 +11,6 @@ import sys
 import unittest
 
 from patman import command
-from patman import test_util
 
 from io import StringIO