瀏覽代碼

Merge git://git.denx.de/u-boot-dm

Tom Rini 8 年之前
父節點
當前提交
79493609c5
共有 87 個文件被更改,包括 1956 次插入486 次删除
  1. 23 11
      arch/sandbox/cpu/os.c
  2. 6 6
      arch/sandbox/include/asm/io.h
  3. 13 0
      cmd/Kconfig
  4. 1 0
      cmd/Makefile
  5. 365 0
      cmd/cros_ec.c
  6. 2 0
      configs/am335x_boneblack_vboot_defconfig
  7. 2 0
      configs/am335x_evm_defconfig
  8. 2 0
      configs/am43xx_evm_defconfig
  9. 2 0
      configs/am43xx_evm_usbhost_boot_defconfig
  10. 2 0
      configs/am43xx_hs_evm_defconfig
  11. 7 0
      configs/am57xx_evm_defconfig
  12. 2 0
      configs/am57xx_hs_evm_defconfig
  13. 2 0
      configs/apalis_t30_defconfig
  14. 2 0
      configs/beaver_defconfig
  15. 2 0
      configs/cardhu_defconfig
  16. 2 0
      configs/cei-tk1-som_defconfig
  17. 2 0
      configs/colibri_t20_defconfig
  18. 2 0
      configs/colibri_t30_defconfig
  19. 2 0
      configs/dalmore_defconfig
  20. 5 0
      configs/dra7xx_evm_defconfig
  21. 2 0
      configs/dra7xx_hs_evm_defconfig
  22. 2 0
      configs/e2220-1170_defconfig
  23. 2 0
      configs/harmony_defconfig
  24. 2 0
      configs/jetson-tk1_defconfig
  25. 2 0
      configs/k2g_evm_defconfig
  26. 2 0
      configs/medcom-wide_defconfig
  27. 3 1
      configs/mx6ull_14x14_evk_defconfig
  28. 2 0
      configs/nyan-big_defconfig
  29. 2 0
      configs/p2371-0000_defconfig
  30. 2 0
      configs/p2371-2180_defconfig
  31. 2 0
      configs/p2571_defconfig
  32. 2 0
      configs/p2771-0000-000_defconfig
  33. 2 0
      configs/p2771-0000-500_defconfig
  34. 2 0
      configs/paz00_defconfig
  35. 1 0
      configs/pic32mzdask_defconfig
  36. 2 0
      configs/plutux_defconfig
  37. 1 0
      configs/sandbox_noblk_defconfig
  38. 2 0
      configs/seaboard_defconfig
  39. 2 0
      configs/tec-ng_defconfig
  40. 2 0
      configs/tec_defconfig
  41. 2 0
      configs/trimslice_defconfig
  42. 2 0
      configs/venice2_defconfig
  43. 2 0
      configs/ventana_defconfig
  44. 2 0
      configs/whistler_defconfig
  45. 1 0
      drivers/block/Kconfig
  46. 37 348
      drivers/misc/cros_ec.c
  47. 1 0
      drivers/mmc/Kconfig
  48. 1 0
      drivers/mmc/mmc-uclass.c
  49. 2 2
      drivers/mmc/mmc_private.h
  50. 8 2
      drivers/mmc/mmc_write.c
  51. 14 0
      drivers/power/pmic/Kconfig
  52. 2 0
      drivers/power/pmic/Makefile
  53. 86 0
      drivers/power/pmic/lp873x.c
  54. 104 0
      drivers/power/pmic/palmas.c
  55. 24 0
      drivers/power/regulator/Kconfig
  56. 3 0
      drivers/power/regulator/Makefile
  57. 137 0
      drivers/power/regulator/gpio-regulator.c
  58. 357 0
      drivers/power/regulator/lp873x_regulator.c
  59. 453 0
      drivers/power/regulator/palmas_regulator.c
  60. 1 0
      fs/sandbox/sandboxfs.c
  61. 11 0
      include/cros_ec.h
  62. 10 1
      include/os.h
  63. 19 0
      include/power/lp873x.h
  64. 25 0
      include/power/palmas.h
  65. 5 0
      include/power/regulator.h
  66. 9 0
      tools/buildman/README
  67. 23 10
      tools/buildman/builder.py
  68. 1 15
      tools/buildman/builderthread.py
  69. 1 1
      tools/buildman/buildman.py
  70. 2 2
      tools/buildman/test.py
  71. 16 2
      tools/buildman/toolchain.py
  72. 5 5
      tools/dtoc/dtoc.py
  73. 2 2
      tools/dtoc/fdt_fallback.py
  74. 3 6
      tools/dtoc/fdt_normal.py
  75. 13 3
      tools/dtoc/fdt_select.py
  76. 3 0
      tools/dtoc/fdt_util.py
  77. 8 8
      tools/patman/checkpatch.py
  78. 1 1
      tools/patman/command.py
  79. 1 1
      tools/patman/cros_subprocess.py
  80. 1 1
      tools/patman/get_maintainer.py
  81. 9 9
      tools/patman/gitutil.py
  82. 3 3
      tools/patman/patchstream.py
  83. 6 6
      tools/patman/patman.py
  84. 22 20
      tools/patman/series.py
  85. 23 14
      tools/patman/settings.py
  86. 9 5
      tools/patman/terminal.py
  87. 1 1
      tools/patman/test.py

+ 23 - 11
arch/sandbox/cpu/os.c

@@ -313,21 +313,23 @@ void os_dirent_free(struct os_dirent_node *node)
 
 int os_dirent_ls(const char *dirname, struct os_dirent_node **headp)
 {
-	struct dirent entry, *result;
+	struct dirent *entry;
 	struct os_dirent_node *head, *node, *next;
 	struct stat buf;
 	DIR *dir;
 	int ret;
 	char *fname;
 	int len;
+	int dirlen;
 
 	*headp = NULL;
 	dir = opendir(dirname);
 	if (!dir)
 		return -1;
 
-	/* Create a buffer for the maximum filename length */
-	len = sizeof(entry.d_name) + strlen(dirname) + 2;
+	/* Create a buffer upfront, with typically sufficient size */
+	dirlen = strlen(dirname) + 2;
+	len = dirlen + 256;
 	fname = malloc(len);
 	if (!fname) {
 		ret = -ENOMEM;
@@ -335,18 +337,26 @@ int os_dirent_ls(const char *dirname, struct os_dirent_node **headp)
 	}
 
 	for (node = head = NULL;; node = next) {
-		ret = readdir_r(dir, &entry, &result);
-		if (ret || !result)
+		errno = 0;
+		entry = readdir(dir);
+		if (!entry) {
+			ret = errno;
 			break;
-		next = malloc(sizeof(*node) + strlen(entry.d_name) + 1);
-		if (!next) {
+		}
+		next = malloc(sizeof(*node) + strlen(entry->d_name) + 1);
+		if (dirlen + strlen(entry->d_name) > len) {
+			len = dirlen + strlen(entry->d_name);
+			fname = realloc(fname, len);
+		}
+		if (!next || !fname) {
+			free(next);
 			os_dirent_free(head);
 			ret = -ENOMEM;
 			goto done;
 		}
 		next->next = NULL;
-		strcpy(next->name, entry.d_name);
-		switch (entry.d_type) {
+		strcpy(next->name, entry->d_name);
+		switch (entry->d_type) {
 		case DT_REG:
 			next->type = OS_FILET_REG;
 			break;
@@ -356,6 +366,8 @@ int os_dirent_ls(const char *dirname, struct os_dirent_node **headp)
 		case DT_LNK:
 			next->type = OS_FILET_LNK;
 			break;
+		default:
+			next->type = OS_FILET_UNKNOWN;
 		}
 		next->size = 0;
 		snprintf(fname, len, "%s/%s", dirname, next->name);
@@ -363,8 +375,8 @@ int os_dirent_ls(const char *dirname, struct os_dirent_node **headp)
 			next->size = buf.st_size;
 		if (node)
 			node->next = next;
-		if (!head)
-			head = node;
+		else
+			head = next;
 	}
 	*headp = head;
 

+ 6 - 6
arch/sandbox/include/asm/io.h

@@ -40,12 +40,12 @@ static inline void unmap_sysmem(const void *vaddr)
 phys_addr_t map_to_sysmem(const void *ptr);
 
 /* Define nops for sandbox I/O access */
-#define readb(addr) 0
-#define readw(addr) 0
-#define readl(addr) 0
-#define writeb(v, addr)
-#define writew(v, addr)
-#define writel(v, addr)
+#define readb(addr) ((void)addr, 0)
+#define readw(addr) ((void)addr, 0)
+#define readl(addr) ((void)addr, 0)
+#define writeb(v, addr) ((void)addr)
+#define writew(v, addr) ((void)addr)
+#define writel(v, addr) ((void)addr)
 
 /* I/O access functions */
 int inl(unsigned int addr);

+ 13 - 0
cmd/Kconfig

@@ -677,6 +677,19 @@ config CMD_TPM_TEST
 
 endmenu
 
+menu "Firmware commands"
+config CMD_CROS_EC
+	bool "Enable crosec command"
+	depends on CROS_EC
+	default y
+	help
+	  Enable command-line access to the Chrome OS EC (Embedded
+	  Controller). This provides the 'crosec' command which has
+	  a number of sub-commands for performing EC tasks such as
+	  updating its flash, accessing a small saved context area
+	  and talking to the I2C bus behind the EC (if there is one).
+endmenu
+
 menu "Filesystem commands"
 config CMD_EXT2
 	bool "ext2 command support"

+ 1 - 0
cmd/Makefile

@@ -128,6 +128,7 @@ obj-$(CONFIG_CMD_TRACE) += trace.o
 obj-$(CONFIG_HUSH_PARSER) += test.o
 obj-$(CONFIG_CMD_TPM) += tpm.o
 obj-$(CONFIG_CMD_TPM_TEST) += tpm_test.o
+obj-$(CONFIG_CMD_CROS_EC) += cros_ec.o
 obj-$(CONFIG_CMD_TSI148) += tsi148.o
 obj-$(CONFIG_CMD_UBI) += ubi.o
 obj-$(CONFIG_CMD_UBIFS) += ubifs.o

+ 365 - 0
cmd/cros_ec.c

@@ -0,0 +1,365 @@
+/*
+ * Chromium OS cros_ec driver
+ *
+ * Copyright (c) 2016 The Chromium OS Authors.
+ * Copyright (c) 2016 National Instruments Corp
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <cros_ec.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/uclass-internal.h>
+
+/* Note: depends on enum ec_current_image */
+static const char * const ec_current_image_name[] = {"unknown", "RO", "RW"};
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * Perform a flash read or write command
+ *
+ * @param dev		CROS-EC device to read/write
+ * @param is_write	1 do to a write, 0 to do a read
+ * @param argc		Number of arguments
+ * @param argv		Arguments (2 is region, 3 is address)
+ * @return 0 for ok, 1 for a usage error or -ve for ec command error
+ *	(negative EC_RES_...)
+ */
+static int do_read_write(struct cros_ec_dev *dev, int is_write, int argc,
+			 char * const argv[])
+{
+	uint32_t offset, size = -1U, region_size;
+	unsigned long addr;
+	char *endp;
+	int region;
+	int ret;
+
+	region = cros_ec_decode_region(argc - 2, argv + 2);
+	if (region == -1)
+		return 1;
+	if (argc < 4)
+		return 1;
+	addr = simple_strtoul(argv[3], &endp, 16);
+	if (*argv[3] == 0 || *endp != 0)
+		return 1;
+	if (argc > 4) {
+		size = simple_strtoul(argv[4], &endp, 16);
+		if (*argv[4] == 0 || *endp != 0)
+			return 1;
+	}
+
+	ret = cros_ec_flash_offset(dev, region, &offset, &region_size);
+	if (ret) {
+		debug("%s: Could not read region info\n", __func__);
+		return ret;
+	}
+	if (size == -1U)
+		size = region_size;
+
+	ret = is_write ?
+		cros_ec_flash_write(dev, (uint8_t *)addr, offset, size) :
+		cros_ec_flash_read(dev, (uint8_t *)addr, offset, size);
+	if (ret) {
+		debug("%s: Could not %s region\n", __func__,
+		      is_write ? "write" : "read");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int do_cros_ec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	struct cros_ec_dev *dev;
+	struct udevice *udev;
+	const char *cmd;
+	int ret = 0;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	cmd = argv[1];
+	if (0 == strcmp("init", cmd)) {
+		/* Remove any existing device */
+		ret = uclass_find_device(UCLASS_CROS_EC, 0, &udev);
+		if (!ret)
+			device_remove(udev);
+		ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev);
+		if (ret) {
+			printf("Could not init cros_ec device (err %d)\n", ret);
+			return 1;
+		}
+		return 0;
+	}
+
+	ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev);
+	if (ret) {
+		printf("Cannot get cros-ec device (err=%d)\n", ret);
+		return 1;
+	}
+	dev = dev_get_uclass_priv(udev);
+	if (0 == strcmp("id", cmd)) {
+		char id[MSG_BYTES];
+
+		if (cros_ec_read_id(dev, id, sizeof(id))) {
+			debug("%s: Could not read KBC ID\n", __func__);
+			return 1;
+		}
+		printf("%s\n", id);
+	} else if (0 == strcmp("info", cmd)) {
+		struct ec_response_mkbp_info info;
+
+		if (cros_ec_info(dev, &info)) {
+			debug("%s: Could not read KBC info\n", __func__);
+			return 1;
+		}
+		printf("rows     = %u\n", info.rows);
+		printf("cols     = %u\n", info.cols);
+		printf("switches = %#x\n", info.switches);
+	} else if (0 == strcmp("curimage", cmd)) {
+		enum ec_current_image image;
+
+		if (cros_ec_read_current_image(dev, &image)) {
+			debug("%s: Could not read KBC image\n", __func__);
+			return 1;
+		}
+		printf("%d\n", image);
+	} else if (0 == strcmp("hash", cmd)) {
+		struct ec_response_vboot_hash hash;
+		int i;
+
+		if (cros_ec_read_hash(dev, &hash)) {
+			debug("%s: Could not read KBC hash\n", __func__);
+			return 1;
+		}
+
+		if (hash.hash_type == EC_VBOOT_HASH_TYPE_SHA256)
+			printf("type:    SHA-256\n");
+		else
+			printf("type:    %d\n", hash.hash_type);
+
+		printf("offset:  0x%08x\n", hash.offset);
+		printf("size:    0x%08x\n", hash.size);
+
+		printf("digest:  ");
+		for (i = 0; i < hash.digest_size; i++)
+			printf("%02x", hash.hash_digest[i]);
+		printf("\n");
+	} else if (0 == strcmp("reboot", cmd)) {
+		int region;
+		enum ec_reboot_cmd cmd;
+
+		if (argc >= 3 && !strcmp(argv[2], "cold")) {
+			cmd = EC_REBOOT_COLD;
+		} else {
+			region = cros_ec_decode_region(argc - 2, argv + 2);
+			if (region == EC_FLASH_REGION_RO)
+				cmd = EC_REBOOT_JUMP_RO;
+			else if (region == EC_FLASH_REGION_RW)
+				cmd = EC_REBOOT_JUMP_RW;
+			else
+				return CMD_RET_USAGE;
+		}
+
+		if (cros_ec_reboot(dev, cmd, 0)) {
+			debug("%s: Could not reboot KBC\n", __func__);
+			return 1;
+		}
+	} else if (0 == strcmp("events", cmd)) {
+		uint32_t events;
+
+		if (cros_ec_get_host_events(dev, &events)) {
+			debug("%s: Could not read host events\n", __func__);
+			return 1;
+		}
+		printf("0x%08x\n", events);
+	} else if (0 == strcmp("clrevents", cmd)) {
+		uint32_t events = 0x7fffffff;
+
+		if (argc >= 3)
+			events = simple_strtol(argv[2], NULL, 0);
+
+		if (cros_ec_clear_host_events(dev, events)) {
+			debug("%s: Could not clear host events\n", __func__);
+			return 1;
+		}
+	} else if (0 == strcmp("read", cmd)) {
+		ret = do_read_write(dev, 0, argc, argv);
+		if (ret > 0)
+			return CMD_RET_USAGE;
+	} else if (0 == strcmp("write", cmd)) {
+		ret = do_read_write(dev, 1, argc, argv);
+		if (ret > 0)
+			return CMD_RET_USAGE;
+	} else if (0 == strcmp("erase", cmd)) {
+		int region = cros_ec_decode_region(argc - 2, argv + 2);
+		uint32_t offset, size;
+
+		if (region == -1)
+			return CMD_RET_USAGE;
+		if (cros_ec_flash_offset(dev, region, &offset, &size)) {
+			debug("%s: Could not read region info\n", __func__);
+			ret = -1;
+		} else {
+			ret = cros_ec_flash_erase(dev, offset, size);
+			if (ret) {
+				debug("%s: Could not erase region\n",
+				      __func__);
+			}
+		}
+	} else if (0 == strcmp("regioninfo", cmd)) {
+		int region = cros_ec_decode_region(argc - 2, argv + 2);
+		uint32_t offset, size;
+
+		if (region == -1)
+			return CMD_RET_USAGE;
+		ret = cros_ec_flash_offset(dev, region, &offset, &size);
+		if (ret) {
+			debug("%s: Could not read region info\n", __func__);
+		} else {
+			printf("Region: %s\n", region == EC_FLASH_REGION_RO ?
+					"RO" : "RW");
+			printf("Offset: %x\n", offset);
+			printf("Size:   %x\n", size);
+		}
+	} else if (0 == strcmp("flashinfo", cmd)) {
+		struct ec_response_flash_info p;
+
+		ret = cros_ec_read_flashinfo(dev, &p);
+		if (!ret) {
+			printf("Flash size:         %u\n", p.flash_size);
+			printf("Write block size:   %u\n", p.write_block_size);
+			printf("Erase block size:   %u\n", p.erase_block_size);
+		}
+	} else if (0 == strcmp("vbnvcontext", cmd)) {
+		uint8_t block[EC_VBNV_BLOCK_SIZE];
+		char buf[3];
+		int i, len;
+		unsigned long result;
+
+		if (argc <= 2) {
+			ret = cros_ec_read_vbnvcontext(dev, block);
+			if (!ret) {
+				printf("vbnv_block: ");
+				for (i = 0; i < EC_VBNV_BLOCK_SIZE; i++)
+					printf("%02x", block[i]);
+				putc('\n');
+			}
+		} else {
+			/*
+			 * TODO(clchiou): Move this to a utility function as
+			 * cmd_spi might want to call it.
+			 */
+			memset(block, 0, EC_VBNV_BLOCK_SIZE);
+			len = strlen(argv[2]);
+			buf[2] = '\0';
+			for (i = 0; i < EC_VBNV_BLOCK_SIZE; i++) {
+				if (i * 2 >= len)
+					break;
+				buf[0] = argv[2][i * 2];
+				if (i * 2 + 1 >= len)
+					buf[1] = '0';
+				else
+					buf[1] = argv[2][i * 2 + 1];
+				strict_strtoul(buf, 16, &result);
+				block[i] = result;
+			}
+			ret = cros_ec_write_vbnvcontext(dev, block);
+		}
+		if (ret) {
+			debug("%s: Could not %s VbNvContext\n", __func__,
+			      argc <= 2 ?  "read" : "write");
+		}
+	} else if (0 == strcmp("test", cmd)) {
+		int result = cros_ec_test(dev);
+
+		if (result)
+			printf("Test failed with error %d\n", result);
+		else
+			puts("Test passed\n");
+	} else if (0 == strcmp("version", cmd)) {
+		struct ec_response_get_version *p;
+		char *build_string;
+
+		ret = cros_ec_read_version(dev, &p);
+		if (!ret) {
+			/* Print versions */
+			printf("RO version:    %1.*s\n",
+			       (int)sizeof(p->version_string_ro),
+			       p->version_string_ro);
+			printf("RW version:    %1.*s\n",
+			       (int)sizeof(p->version_string_rw),
+			       p->version_string_rw);
+			printf("Firmware copy: %s\n",
+			       (p->current_image <
+			       ARRAY_SIZE(ec_current_image_name) ?
+			       ec_current_image_name[p->current_image] :
+			       "?"));
+			ret = cros_ec_read_build_info(dev, &build_string);
+			if (!ret)
+				printf("Build info:    %s\n", build_string);
+		}
+	} else if (0 == strcmp("ldo", cmd)) {
+		uint8_t index, state;
+		char *endp;
+
+		if (argc < 3)
+			return CMD_RET_USAGE;
+		index = simple_strtoul(argv[2], &endp, 10);
+		if (*argv[2] == 0 || *endp != 0)
+			return CMD_RET_USAGE;
+		if (argc > 3) {
+			state = simple_strtoul(argv[3], &endp, 10);
+			if (*argv[3] == 0 || *endp != 0)
+				return CMD_RET_USAGE;
+			ret = cros_ec_set_ldo(udev, index, state);
+		} else {
+			ret = cros_ec_get_ldo(udev, index, &state);
+			if (!ret) {
+				printf("LDO%d: %s\n", index,
+				       state == EC_LDO_STATE_ON ?
+				       "on" : "off");
+			}
+		}
+
+		if (ret) {
+			debug("%s: Could not access LDO%d\n", __func__, index);
+			return ret;
+		}
+	} else {
+		return CMD_RET_USAGE;
+	}
+
+	if (ret < 0) {
+		printf("Error: CROS-EC command failed (error %d)\n", ret);
+		ret = 1;
+	}
+
+	return ret;
+}
+
+U_BOOT_CMD(
+	crosec,	6,	1,	do_cros_ec,
+	"CROS-EC utility command",
+	"init                Re-init CROS-EC (done on startup automatically)\n"
+	"crosec id                  Read CROS-EC ID\n"
+	"crosec info                Read CROS-EC info\n"
+	"crosec curimage            Read CROS-EC current image\n"
+	"crosec hash                Read CROS-EC hash\n"
+	"crosec reboot [rw | ro | cold]  Reboot CROS-EC\n"
+	"crosec events              Read CROS-EC host events\n"
+	"crosec clrevents [mask]    Clear CROS-EC host events\n"
+	"crosec regioninfo <ro|rw>  Read image info\n"
+	"crosec flashinfo           Read flash info\n"
+	"crosec erase <ro|rw>       Erase EC image\n"
+	"crosec read <ro|rw> <addr> [<size>]   Read EC image\n"
+	"crosec write <ro|rw> <addr> [<size>]  Write EC image\n"
+	"crosec vbnvcontext [hexstring]        Read [write] VbNvContext from EC\n"
+	"crosec ldo <idx> [<state>] Switch/Read LDO state\n"
+	"crosec test                run tests on cros_ec\n"
+	"crosec version             Read CROS-EC version"
+);

+ 2 - 0
configs/am335x_boneblack_vboot_defconfig

@@ -38,10 +38,12 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
+# CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_DM_I2C=y
 CONFIG_DM_MMC=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_DM_ETH=y

+ 2 - 0
configs/am335x_evm_defconfig

@@ -34,11 +34,13 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
 CONFIG_OF_LIST="am335x-evm am335x-bone am335x-boneblack am335x-evmsk am335x-bonegreen am335x-icev2"
+# CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
 CONFIG_DFU_NAND=y
 CONFIG_DFU_RAM=y
 CONFIG_DM_I2C=y
 CONFIG_DM_MMC=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_DM_ETH=y

+ 2 - 0
configs/am43xx_evm_defconfig

@@ -35,12 +35,14 @@ CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
 CONFIG_OF_LIST="am437x-gp-evm am437x-sk-evm am43x-epos-evm am437x-idk-evm"
 CONFIG_DM=y
+# CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_DFU_SF=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_DM_MMC=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_MACRONIX=y

+ 2 - 0
configs/am43xx_evm_usbhost_boot_defconfig

@@ -38,11 +38,13 @@ CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
 CONFIG_OF_LIST="am437x-gp-evm am437x-sk-evm am43x-epos-evm am437x-idk-evm"
 CONFIG_DM=y
+# CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_DFU_SF=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_MMC=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_DM_SERIAL=y

+ 2 - 0
configs/am43xx_hs_evm_defconfig

@@ -38,12 +38,14 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
 CONFIG_DM=y
+# CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_DFU_SF=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_DM_MMC=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_DM_ETH=y

+ 7 - 0
configs/am57xx_evm_defconfig

@@ -29,6 +29,7 @@ CONFIG_CMD_GPIO=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_CMD_REGULATOR=y
 CONFIG_CMD_EXT2=y
 CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
@@ -37,13 +38,19 @@ CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
 CONFIG_OF_LIST="am57xx-beagle-x15 am572x-idk"
 CONFIG_DM=y
+# CONFIG_BLK is not set
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_DM_MMC=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_PALMAS=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_PALMAS=y
 CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
 CONFIG_DM_SPI=y

+ 2 - 0
configs/am57xx_hs_evm_defconfig

@@ -38,9 +38,11 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
 CONFIG_DM=y
+# CONFIG_BLK is not set
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_DM_MMC=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y

+ 2 - 0
configs/apalis_t30_defconfig

@@ -27,8 +27,10 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM=y
+# CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_E1000=y
 CONFIG_PCI_TEGRA=y
 CONFIG_SYS_NS16550=y

+ 2 - 0
configs/beaver_defconfig

@@ -30,9 +30,11 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM=y
+# CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_DFU_SF=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_RTL8169=y

+ 2 - 0
configs/cardhu_defconfig

@@ -28,6 +28,8 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM=y
+# CONFIG_BLK is not set
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_RTL8169=y

+ 2 - 0
configs/cei-tk1-som_defconfig

@@ -30,9 +30,11 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM=y
+# CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_DFU_SF=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_RTL8169=y

+ 2 - 0
configs/colibri_t20_defconfig

@@ -31,8 +31,10 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_CMD_UBI=y
 CONFIG_SPL_DM=y
+# CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_MTD_UBI_FASTMAP=y
 CONFIG_DM_PMIC=y
 CONFIG_DM_REGULATOR=y

+ 2 - 0
configs/colibri_t30_defconfig

@@ -27,8 +27,10 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM=y
+# CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_SYS_NS16550=y
 CONFIG_USB=y
 CONFIG_DM_USB=y

+ 2 - 0
configs/dalmore_defconfig

@@ -30,9 +30,11 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM=y
+# CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_DFU_SF=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SYS_NS16550=y

+ 5 - 0
configs/dra7xx_evm_defconfig

@@ -47,6 +47,7 @@ CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
 CONFIG_OF_LIST="dra7-evm dra72-evm dra72-evm-revc"
 CONFIG_DM=y
+# CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_DFU_SF=y
@@ -54,13 +55,17 @@ CONFIG_DM_GPIO=y
 CONFIG_PCF8575_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_DM_MMC=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_DM_ETH=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_PALMAS=y
 CONFIG_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_REGULATOR_PALMAS=y
 CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
 CONFIG_DM_SPI=y

+ 2 - 0
configs/dra7xx_hs_evm_defconfig

@@ -50,6 +50,7 @@ CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
 CONFIG_OF_LIST="dra7-evm dra72-evm"
 CONFIG_DM=y
+# CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_DFU_SF=y
@@ -57,6 +58,7 @@ CONFIG_DM_GPIO=y
 CONFIG_PCF8575_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_DM_MMC=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y

+ 2 - 0
configs/e2220-1170_defconfig

@@ -27,9 +27,11 @@ CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+# CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_DFU_SF=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SYS_NS16550=y

+ 2 - 0
configs/harmony_defconfig

@@ -27,6 +27,8 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM=y
+# CONFIG_BLK is not set
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_DM_PMIC=y
 CONFIG_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_FIXED=y

+ 2 - 0
configs/jetson-tk1_defconfig

@@ -30,9 +30,11 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM=y
+# CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_DFU_SF=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_RTL8169=y

+ 2 - 0
configs/k2g_evm_defconfig

@@ -35,7 +35,9 @@ CONFIG_CMD_FS_GENERIC=y
 CONFIG_CMD_UBI=y
 CONFIG_OF_CONTROL=y
 CONFIG_DM=y
+# CONFIG_BLK is not set
 CONFIG_DM_MMC=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y

+ 2 - 0
configs/medcom-wide_defconfig

@@ -28,6 +28,8 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM=y
+# CONFIG_BLK is not set
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_DM_PMIC=y
 CONFIG_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_FIXED=y

+ 3 - 1
configs/mx6ull_14x14_evk_defconfig

@@ -1,7 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_MX6=y
 CONFIG_TARGET_MX6ULL_14X14_EVK=y
-CONFIG_DM_GPIO=y
 CONFIG_DEFAULT_DEVICE_TREE="imx6ull-14x14-evk"
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ullevk/imximage.cfg"
 CONFIG_BOOTDELAY=3
@@ -21,9 +20,12 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
+# CONFIG_BLK is not set
+CONFIG_DM_GPIO=y
 CONFIG_DM_74X164=y
 CONFIG_DM_I2C=y
 CONFIG_DM_MMC=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_IMX6=y
 CONFIG_DM_REGULATOR=y

+ 2 - 0
configs/nyan-big_defconfig

@@ -36,6 +36,7 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM=y
+# CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_DFU_SF=y
@@ -43,6 +44,7 @@ CONFIG_CROS_EC_KEYB=y
 CONFIG_CMD_CROS_EC=y
 CONFIG_CROS_EC=y
 CONFIG_CROS_EC_SPI=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_DM_PMIC=y

+ 2 - 0
configs/p2371-0000_defconfig

@@ -28,9 +28,11 @@ CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+# CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_DFU_SF=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SYS_NS16550=y

+ 2 - 0
configs/p2371-2180_defconfig

@@ -28,9 +28,11 @@ CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+# CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_DFU_SF=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_RTL8169=y

+ 2 - 0
configs/p2571_defconfig

@@ -28,9 +28,11 @@ CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+# CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_DFU_SF=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SYS_NS16550=y

+ 2 - 0
configs/p2771-0000-000_defconfig

@@ -25,7 +25,9 @@ CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+# CONFIG_BLK is not set
 CONFIG_TEGRA186_BPMP_I2C=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_E1000=y
 CONFIG_RTL8169=y
 CONFIG_PCI_TEGRA=y

+ 2 - 0
configs/p2771-0000-500_defconfig

@@ -25,7 +25,9 @@ CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+# CONFIG_BLK is not set
 CONFIG_TEGRA186_BPMP_I2C=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_E1000=y
 CONFIG_RTL8169=y
 CONFIG_PCI_TEGRA=y

+ 2 - 0
configs/paz00_defconfig

@@ -27,6 +27,8 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM=y
+# CONFIG_BLK is not set
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_DM_PMIC=y
 CONFIG_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_FIXED=y

+ 1 - 0
configs/pic32mzdask_defconfig

@@ -45,3 +45,4 @@ CONFIG_USB_MUSB_PIC32=y
 CONFIG_USB_STORAGE=y
 CONFIG_USE_TINY_PRINTF=y
 CONFIG_CMD_DHRYSTONE=y
+# CONFIG_BLK is not set

+ 2 - 0
configs/plutux_defconfig

@@ -26,6 +26,8 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM=y
+# CONFIG_BLK is not set
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_SYS_NS16550=y
 CONFIG_USB=y
 CONFIG_DM_USB=y

+ 1 - 0
configs/sandbox_noblk_defconfig

@@ -68,6 +68,7 @@ CONFIG_DEVRES=y
 CONFIG_DEBUG_DEVRES=y
 CONFIG_ADC=y
 CONFIG_ADC_SANDBOX=y
+# CONFIG_BLK is not set
 CONFIG_CLK=y
 CONFIG_CPU=y
 CONFIG_DM_DEMO=y

+ 2 - 0
configs/seaboard_defconfig

@@ -28,6 +28,8 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM=y
+# CONFIG_BLK is not set
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_DM_PMIC=y
 CONFIG_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_FIXED=y

+ 2 - 0
configs/tec-ng_defconfig

@@ -29,6 +29,8 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM=y
+# CONFIG_BLK is not set
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SYS_NS16550=y

+ 2 - 0
configs/tec_defconfig

@@ -28,6 +28,8 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM=y
+# CONFIG_BLK is not set
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_DM_PMIC=y
 CONFIG_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_FIXED=y

+ 2 - 0
configs/trimslice_defconfig

@@ -28,6 +28,8 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM=y
+# CONFIG_BLK is not set
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_RTL8169=y

+ 2 - 0
configs/venice2_defconfig

@@ -30,9 +30,11 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM=y
+# CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_DFU_SF=y
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SYS_NS16550=y

+ 2 - 0
configs/ventana_defconfig

@@ -27,6 +27,8 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM=y
+# CONFIG_BLK is not set
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_DM_PMIC=y
 CONFIG_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_FIXED=y

+ 2 - 0
configs/whistler_defconfig

@@ -26,6 +26,8 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM=y
+# CONFIG_BLK is not set
+# CONFIG_DM_MMC_OPS is not set
 CONFIG_SYS_NS16550=y
 CONFIG_USB=y
 CONFIG_DM_USB=y

+ 1 - 0
drivers/block/Kconfig

@@ -1,6 +1,7 @@
 config BLK
 	bool "Support block devices"
 	depends on DM
+	default y if DM_MMC
 	help
 	  Enable support for block devices, such as SCSI, MMC and USB
 	  flash sticks. These provide a block-level interface which permits

+ 37 - 348
drivers/misc/cros_ec.c

@@ -43,9 +43,6 @@ enum {
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* Note: depends on enum ec_current_image */
-static const char * const ec_current_image_name[] = {"unknown", "RO", "RW"};
-
 void cros_ec_dump_data(const char *name, int cmd, const uint8_t *data, int len)
 {
 #ifdef DEBUG
@@ -750,15 +747,24 @@ int cros_ec_flash_erase(struct cros_ec_dev *dev, uint32_t offset, uint32_t size)
 static int cros_ec_flash_write_block(struct cros_ec_dev *dev,
 		const uint8_t *data, uint32_t offset, uint32_t size)
 {
-	struct ec_params_flash_write p;
+	struct ec_params_flash_write *p;
+	int ret;
 
-	p.offset = offset;
-	p.size = size;
-	assert(data && p.size <= EC_FLASH_WRITE_VER0_SIZE);
-	memcpy(&p + 1, data, p.size);
+	p = malloc(sizeof(*p) + size);
+	if (!p)
+		return -ENOMEM;
+
+	p->offset = offset;
+	p->size = size;
+	assert(data && p->size <= EC_FLASH_WRITE_VER0_SIZE);
+	memcpy(p + 1, data, p->size);
+
+	ret = ec_command_inptr(dev, EC_CMD_FLASH_WRITE, 0,
+			  p, sizeof(*p) + size, NULL, 0) >= 0 ? 0 : -1;
 
-	return ec_command_inptr(dev, EC_CMD_FLASH_WRITE, 0,
-			  &p, sizeof(p), NULL, 0) >= 0 ? 0 : -1;
+	free(p);
+
+	return ret;
 }
 
 /**
@@ -790,6 +796,27 @@ static int cros_ec_data_is_erased(const uint32_t *data, int size)
 	return 1;
 }
 
+/**
+ * Read back flash parameters
+ *
+ * This function reads back parameters of the flash as reported by the EC
+ *
+ * @param dev  Pointer to device
+ * @param info Pointer to output flash info struct
+ */
+int cros_ec_read_flashinfo(struct cros_ec_dev *dev,
+			  struct ec_response_flash_info *info)
+{
+	int ret;
+
+	ret = ec_command(dev, EC_CMD_FLASH_INFO, 0,
+			 NULL, 0, info, sizeof(*info));
+	if (ret < 0)
+		return ret;
+
+	return ret < sizeof(*info) ? -1 : 0;
+}
+
 int cros_ec_flash_write(struct cros_ec_dev *dev, const uint8_t *data,
 		     uint32_t offset, uint32_t size)
 {
@@ -1134,344 +1161,6 @@ int cros_ec_i2c_tunnel(struct udevice *dev, int port, struct i2c_msg *in,
 	return 0;
 }
 
-#ifdef CONFIG_CMD_CROS_EC
-
-/**
- * Perform a flash read or write command
- *
- * @param dev		CROS-EC device to read/write
- * @param is_write	1 do to a write, 0 to do a read
- * @param argc		Number of arguments
- * @param argv		Arguments (2 is region, 3 is address)
- * @return 0 for ok, 1 for a usage error or -ve for ec command error
- *	(negative EC_RES_...)
- */
-static int do_read_write(struct cros_ec_dev *dev, int is_write, int argc,
-			 char * const argv[])
-{
-	uint32_t offset, size = -1U, region_size;
-	unsigned long addr;
-	char *endp;
-	int region;
-	int ret;
-
-	region = cros_ec_decode_region(argc - 2, argv + 2);
-	if (region == -1)
-		return 1;
-	if (argc < 4)
-		return 1;
-	addr = simple_strtoul(argv[3], &endp, 16);
-	if (*argv[3] == 0 || *endp != 0)
-		return 1;
-	if (argc > 4) {
-		size = simple_strtoul(argv[4], &endp, 16);
-		if (*argv[4] == 0 || *endp != 0)
-			return 1;
-	}
-
-	ret = cros_ec_flash_offset(dev, region, &offset, &region_size);
-	if (ret) {
-		debug("%s: Could not read region info\n", __func__);
-		return ret;
-	}
-	if (size == -1U)
-		size = region_size;
-
-	ret = is_write ?
-		cros_ec_flash_write(dev, (uint8_t *)addr, offset, size) :
-		cros_ec_flash_read(dev, (uint8_t *)addr, offset, size);
-	if (ret) {
-		debug("%s: Could not %s region\n", __func__,
-		      is_write ? "write" : "read");
-		return ret;
-	}
-
-	return 0;
-}
-
-static int do_cros_ec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-	struct cros_ec_dev *dev;
-	struct udevice *udev;
-	const char *cmd;
-	int ret = 0;
-
-	if (argc < 2)
-		return CMD_RET_USAGE;
-
-	cmd = argv[1];
-	if (0 == strcmp("init", cmd)) {
-		/* Remove any existing device */
-		ret = uclass_find_device(UCLASS_CROS_EC, 0, &udev);
-		if (!ret)
-			device_remove(udev);
-		ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev);
-		if (ret) {
-			printf("Could not init cros_ec device (err %d)\n", ret);
-			return 1;
-		}
-		return 0;
-	}
-
-	ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev);
-	if (ret) {
-		printf("Cannot get cros-ec device (err=%d)\n", ret);
-		return 1;
-	}
-	dev = dev_get_uclass_priv(udev);
-	if (0 == strcmp("id", cmd)) {
-		char id[MSG_BYTES];
-
-		if (cros_ec_read_id(dev, id, sizeof(id))) {
-			debug("%s: Could not read KBC ID\n", __func__);
-			return 1;
-		}
-		printf("%s\n", id);
-	} else if (0 == strcmp("info", cmd)) {
-		struct ec_response_mkbp_info info;
-
-		if (cros_ec_info(dev, &info)) {
-			debug("%s: Could not read KBC info\n", __func__);
-			return 1;
-		}
-		printf("rows     = %u\n", info.rows);
-		printf("cols     = %u\n", info.cols);
-		printf("switches = %#x\n", info.switches);
-	} else if (0 == strcmp("curimage", cmd)) {
-		enum ec_current_image image;
-
-		if (cros_ec_read_current_image(dev, &image)) {
-			debug("%s: Could not read KBC image\n", __func__);
-			return 1;
-		}
-		printf("%d\n", image);
-	} else if (0 == strcmp("hash", cmd)) {
-		struct ec_response_vboot_hash hash;
-		int i;
-
-		if (cros_ec_read_hash(dev, &hash)) {
-			debug("%s: Could not read KBC hash\n", __func__);
-			return 1;
-		}
-
-		if (hash.hash_type == EC_VBOOT_HASH_TYPE_SHA256)
-			printf("type:    SHA-256\n");
-		else
-			printf("type:    %d\n", hash.hash_type);
-
-		printf("offset:  0x%08x\n", hash.offset);
-		printf("size:    0x%08x\n", hash.size);
-
-		printf("digest:  ");
-		for (i = 0; i < hash.digest_size; i++)
-			printf("%02x", hash.hash_digest[i]);
-		printf("\n");
-	} else if (0 == strcmp("reboot", cmd)) {
-		int region;
-		enum ec_reboot_cmd cmd;
-
-		if (argc >= 3 && !strcmp(argv[2], "cold"))
-			cmd = EC_REBOOT_COLD;
-		else {
-			region = cros_ec_decode_region(argc - 2, argv + 2);
-			if (region == EC_FLASH_REGION_RO)
-				cmd = EC_REBOOT_JUMP_RO;
-			else if (region == EC_FLASH_REGION_RW)
-				cmd = EC_REBOOT_JUMP_RW;
-			else
-				return CMD_RET_USAGE;
-		}
-
-		if (cros_ec_reboot(dev, cmd, 0)) {
-			debug("%s: Could not reboot KBC\n", __func__);
-			return 1;
-		}
-	} else if (0 == strcmp("events", cmd)) {
-		uint32_t events;
-
-		if (cros_ec_get_host_events(dev, &events)) {
-			debug("%s: Could not read host events\n", __func__);
-			return 1;
-		}
-		printf("0x%08x\n", events);
-	} else if (0 == strcmp("clrevents", cmd)) {
-		uint32_t events = 0x7fffffff;
-
-		if (argc >= 3)
-			events = simple_strtol(argv[2], NULL, 0);
-
-		if (cros_ec_clear_host_events(dev, events)) {
-			debug("%s: Could not clear host events\n", __func__);
-			return 1;
-		}
-	} else if (0 == strcmp("read", cmd)) {
-		ret = do_read_write(dev, 0, argc, argv);
-		if (ret > 0)
-			return CMD_RET_USAGE;
-	} else if (0 == strcmp("write", cmd)) {
-		ret = do_read_write(dev, 1, argc, argv);
-		if (ret > 0)
-			return CMD_RET_USAGE;
-	} else if (0 == strcmp("erase", cmd)) {
-		int region = cros_ec_decode_region(argc - 2, argv + 2);
-		uint32_t offset, size;
-
-		if (region == -1)
-			return CMD_RET_USAGE;
-		if (cros_ec_flash_offset(dev, region, &offset, &size)) {
-			debug("%s: Could not read region info\n", __func__);
-			ret = -1;
-		} else {
-			ret = cros_ec_flash_erase(dev, offset, size);
-			if (ret) {
-				debug("%s: Could not erase region\n",
-				      __func__);
-			}
-		}
-	} else if (0 == strcmp("regioninfo", cmd)) {
-		int region = cros_ec_decode_region(argc - 2, argv + 2);
-		uint32_t offset, size;
-
-		if (region == -1)
-			return CMD_RET_USAGE;
-		ret = cros_ec_flash_offset(dev, region, &offset, &size);
-		if (ret) {
-			debug("%s: Could not read region info\n", __func__);
-		} else {
-			printf("Region: %s\n", region == EC_FLASH_REGION_RO ?
-					"RO" : "RW");
-			printf("Offset: %x\n", offset);
-			printf("Size:   %x\n", size);
-		}
-	} else if (0 == strcmp("vbnvcontext", cmd)) {
-		uint8_t block[EC_VBNV_BLOCK_SIZE];
-		char buf[3];
-		int i, len;
-		unsigned long result;
-
-		if (argc <= 2) {
-			ret = cros_ec_read_vbnvcontext(dev, block);
-			if (!ret) {
-				printf("vbnv_block: ");
-				for (i = 0; i < EC_VBNV_BLOCK_SIZE; i++)
-					printf("%02x", block[i]);
-				putc('\n');
-			}
-		} else {
-			/*
-			 * TODO(clchiou): Move this to a utility function as
-			 * cmd_spi might want to call it.
-			 */
-			memset(block, 0, EC_VBNV_BLOCK_SIZE);
-			len = strlen(argv[2]);
-			buf[2] = '\0';
-			for (i = 0; i < EC_VBNV_BLOCK_SIZE; i++) {
-				if (i * 2 >= len)
-					break;
-				buf[0] = argv[2][i * 2];
-				if (i * 2 + 1 >= len)
-					buf[1] = '0';
-				else
-					buf[1] = argv[2][i * 2 + 1];
-				strict_strtoul(buf, 16, &result);
-				block[i] = result;
-			}
-			ret = cros_ec_write_vbnvcontext(dev, block);
-		}
-		if (ret) {
-			debug("%s: Could not %s VbNvContext\n", __func__,
-					argc <= 2 ?  "read" : "write");
-		}
-	} else if (0 == strcmp("test", cmd)) {
-		int result = cros_ec_test(dev);
-
-		if (result)
-			printf("Test failed with error %d\n", result);
-		else
-			puts("Test passed\n");
-	} else if (0 == strcmp("version", cmd)) {
-		struct ec_response_get_version *p;
-		char *build_string;
-
-		ret = cros_ec_read_version(dev, &p);
-		if (!ret) {
-			/* Print versions */
-			printf("RO version:    %1.*s\n",
-			       (int)sizeof(p->version_string_ro),
-			       p->version_string_ro);
-			printf("RW version:    %1.*s\n",
-			       (int)sizeof(p->version_string_rw),
-			       p->version_string_rw);
-			printf("Firmware copy: %s\n",
-				(p->current_image <
-					ARRAY_SIZE(ec_current_image_name) ?
-				ec_current_image_name[p->current_image] :
-				"?"));
-			ret = cros_ec_read_build_info(dev, &build_string);
-			if (!ret)
-				printf("Build info:    %s\n", build_string);
-		}
-	} else if (0 == strcmp("ldo", cmd)) {
-		uint8_t index, state;
-		char *endp;
-
-		if (argc < 3)
-			return CMD_RET_USAGE;
-		index = simple_strtoul(argv[2], &endp, 10);
-		if (*argv[2] == 0 || *endp != 0)
-			return CMD_RET_USAGE;
-		if (argc > 3) {
-			state = simple_strtoul(argv[3], &endp, 10);
-			if (*argv[3] == 0 || *endp != 0)
-				return CMD_RET_USAGE;
-			ret = cros_ec_set_ldo(udev, index, state);
-		} else {
-			ret = cros_ec_get_ldo(udev, index, &state);
-			if (!ret) {
-				printf("LDO%d: %s\n", index,
-					state == EC_LDO_STATE_ON ?
-					"on" : "off");
-			}
-		}
-
-		if (ret) {
-			debug("%s: Could not access LDO%d\n", __func__, index);
-			return ret;
-		}
-	} else {
-		return CMD_RET_USAGE;
-	}
-
-	if (ret < 0) {
-		printf("Error: CROS-EC command failed (error %d)\n", ret);
-		ret = 1;
-	}
-
-	return ret;
-}
-
-U_BOOT_CMD(
-	crosec,	6,	1,	do_cros_ec,
-	"CROS-EC utility command",
-	"init                Re-init CROS-EC (done on startup automatically)\n"
-	"crosec id                  Read CROS-EC ID\n"
-	"crosec info                Read CROS-EC info\n"
-	"crosec curimage            Read CROS-EC current image\n"
-	"crosec hash                Read CROS-EC hash\n"
-	"crosec reboot [rw | ro | cold]  Reboot CROS-EC\n"
-	"crosec events              Read CROS-EC host events\n"
-	"crosec clrevents [mask]    Clear CROS-EC host events\n"
-	"crosec regioninfo <ro|rw>  Read image info\n"
-	"crosec erase <ro|rw>       Erase EC image\n"
-	"crosec read <ro|rw> <addr> [<size>]   Read EC image\n"
-	"crosec write <ro|rw> <addr> [<size>]  Write EC image\n"
-	"crosec vbnvcontext [hexstring]        Read [write] VbNvContext from EC\n"
-	"crosec ldo <idx> [<state>] Switch/Read LDO state\n"
-	"crosec test                run tests on cros_ec\n"
-	"crosec version             Read CROS-EC version"
-);
-#endif
-
 UCLASS_DRIVER(cros_ec) = {
 	.id		= UCLASS_CROS_EC,
 	.name		= "cros_ec",

+ 1 - 0
drivers/mmc/Kconfig

@@ -19,6 +19,7 @@ config DM_MMC
 config DM_MMC_OPS
 	bool "Support MMC controller operations using Driver Model"
 	depends on DM_MMC
+	default y if DM_MMC
 	help
 	  Driver model provides a means of supporting device operations. This
 	  option moves MMC operations under the control of driver model. The

+ 1 - 0
drivers/mmc/mmc-uclass.c

@@ -262,6 +262,7 @@ static const struct blk_ops mmc_blk_ops = {
 	.read	= mmc_bread,
 #ifndef CONFIG_SPL_BUILD
 	.write	= mmc_bwrite,
+	.erase	= mmc_berase,
 #endif
 	.select_hwpart	= mmc_select_hwpart,
 };

+ 2 - 2
drivers/mmc/mmc_private.h

@@ -29,15 +29,15 @@ ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
 #endif
 
 #if !(defined(CONFIG_SPL_BUILD) && !defined(CONFIG_SPL_SAVEENV))
-unsigned long mmc_berase(struct blk_desc *block_dev, lbaint_t start,
-			 lbaint_t blkcnt);
 
 #ifdef CONFIG_BLK
 ulong mmc_bwrite(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
 		 const void *src);
+ulong mmc_berase(struct udevice *dev, lbaint_t start, lbaint_t blkcnt);
 #else
 ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
 		 const void *src);
+ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt);
 #endif
 
 #else /* CONFIG_SPL_BUILD and CONFIG_SPL_SAVEENV is not defined */

+ 8 - 2
drivers/mmc/mmc_write.c

@@ -66,9 +66,15 @@ err_out:
 	return err;
 }
 
-unsigned long mmc_berase(struct blk_desc *block_dev, lbaint_t start,
-			 lbaint_t blkcnt)
+#ifdef CONFIG_BLK
+ulong mmc_berase(struct udevice *dev, lbaint_t start, lbaint_t blkcnt)
+#else
+ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt)
+#endif
 {
+#ifdef CONFIG_BLK
+	struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
+#endif
 	int dev_num = block_dev->devnum;
 	int err = 0;
 	u32 start_rem, blkcnt_rem;

+ 14 - 0
drivers/power/pmic/Kconfig

@@ -143,3 +143,17 @@ config PMIC_TPS65090
 	FETs and a battery charger. This driver provides register access
 	only, and you can enable the regulator/charger drivers separately if
 	required.
+
+config PMIC_PALMAS
+	bool "Enable driver for Texas Instruments PALMAS PMIC"
+	depends on DM_PMIC
+	---help---
+	The PALMAS is a PMIC containing several LDOs, SMPS.
+	This driver binds the pmic children.
+
+config PMIC_LP873X
+	bool "Enable driver for Texas Instruments LP873X PMIC"
+	depends on DM_PMIC
+	---help---
+	The LP873X is a PMIC containing couple of LDOs and couple of SMPS.
+	This driver binds the pmic children.

+ 2 - 0
drivers/power/pmic/Makefile

@@ -16,6 +16,8 @@ obj-$(CONFIG_PMIC_RK808) += rk808.o
 obj-$(CONFIG_PMIC_RN5T567) += rn5t567.o
 obj-$(CONFIG_PMIC_TPS65090) += tps65090.o
 obj-$(CONFIG_PMIC_S5M8767) += s5m8767.o
+obj-$(CONFIG_$(SPL_)PMIC_PALMAS) += palmas.o
+obj-$(CONFIG_$(SPL_)PMIC_LP873X) += lp873x.o
 
 obj-$(CONFIG_POWER_LTC3676) += pmic_ltc3676.o
 obj-$(CONFIG_POWER_MAX77696) += pmic_max77696.o

+ 86 - 0
drivers/power/pmic/lp873x.c

@@ -0,0 +1,86 @@
+/*
+ * (C) Copyright 2016 Texas Instruments Incorporated, <www.ti.com>
+ * Keerthy <j-keerthy@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <errno.h>
+#include <dm.h>
+#include <i2c.h>
+#include <power/pmic.h>
+#include <power/regulator.h>
+#include <power/lp873x.h>
+#include <dm/device.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const struct pmic_child_info pmic_children_info[] = {
+	{ .prefix = "ldo", .driver = LP873X_LDO_DRIVER },
+	{ .prefix = "buck", .driver = LP873X_BUCK_DRIVER },
+	{ },
+};
+
+static int lp873x_write(struct udevice *dev, uint reg, const uint8_t *buff,
+			  int len)
+{
+	if (dm_i2c_write(dev, reg, buff, len)) {
+		error("write error to device: %p register: %#x!", dev, reg);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int lp873x_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
+{
+	if (dm_i2c_read(dev, reg, buff, len)) {
+		error("read error from device: %p register: %#x!", dev, reg);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int lp873x_bind(struct udevice *dev)
+{
+	int regulators_node;
+	const void *blob = gd->fdt_blob;
+	int children;
+	int node = dev->of_offset;
+
+	regulators_node = fdt_subnode_offset(blob, node, "regulators");
+
+	if (regulators_node <= 0) {
+		printf("%s: %s reg subnode not found!", __func__, dev->name);
+		return -ENXIO;
+	}
+
+	children = pmic_bind_children(dev, regulators_node, pmic_children_info);
+	if (!children)
+		printf("%s: %s - no child found\n", __func__, dev->name);
+
+	/* Always return success for this device */
+	return 0;
+}
+
+static struct dm_pmic_ops lp873x_ops = {
+	.read = lp873x_read,
+	.write = lp873x_write,
+};
+
+static const struct udevice_id lp873x_ids[] = {
+	{ .compatible = "ti,lp8732", .data = LP8732 },
+	{ .compatible = "ti,lp8733" , .data = LP8733 },
+	{ }
+};
+
+U_BOOT_DRIVER(pmic_lp873x) = {
+	.name = "lp873x_pmic",
+	.id = UCLASS_PMIC,
+	.of_match = lp873x_ids,
+	.bind = lp873x_bind,
+	.ops = &lp873x_ops,
+};

+ 104 - 0
drivers/power/pmic/palmas.c

@@ -0,0 +1,104 @@
+/*
+ * (C) Copyright 2016 Texas Instruments Incorporated, <www.ti.com>
+ * Keerthy <j-keerthy@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <errno.h>
+#include <dm.h>
+#include <i2c.h>
+#include <power/pmic.h>
+#include <power/regulator.h>
+#include <power/palmas.h>
+#include <dm/device.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const struct pmic_child_info pmic_children_info[] = {
+	{ .prefix = "ldo", .driver = PALMAS_LDO_DRIVER },
+	{ .prefix = "smps", .driver = PALMAS_SMPS_DRIVER },
+	{ },
+};
+
+static int palmas_write(struct udevice *dev, uint reg, const uint8_t *buff,
+			  int len)
+{
+	if (dm_i2c_write(dev, reg, buff, len)) {
+		error("write error to device: %p register: %#x!", dev, reg);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int palmas_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
+{
+	if (dm_i2c_read(dev, reg, buff, len)) {
+		error("read error from device: %p register: %#x!", dev, reg);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int palmas_bind(struct udevice *dev)
+{
+	int pmic_node = -1, regulators_node;
+	const void *blob = gd->fdt_blob;
+	int children;
+	int node = dev->of_offset;
+	int subnode, len;
+
+	fdt_for_each_subnode(blob, subnode, node) {
+		const char *name;
+		char *temp;
+
+		name = fdt_get_name(blob, subnode, &len);
+		temp = strstr(name, "pmic");
+		if (temp) {
+			pmic_node = subnode;
+			break;
+		}
+	}
+
+	if (pmic_node <= 0) {
+		debug("%s: %s pmic subnode not found!", __func__, dev->name);
+		return -ENXIO;
+	}
+
+	regulators_node = fdt_subnode_offset(blob, pmic_node, "regulators");
+
+	if (regulators_node <= 0) {
+		debug("%s: %s reg subnode not found!", __func__, dev->name);
+		return -ENXIO;
+	}
+
+	children = pmic_bind_children(dev, regulators_node, pmic_children_info);
+	if (!children)
+		debug("%s: %s - no child found\n", __func__, dev->name);
+
+	/* Always return success for this device */
+	return 0;
+}
+
+static struct dm_pmic_ops palmas_ops = {
+	.read = palmas_read,
+	.write = palmas_write,
+};
+
+static const struct udevice_id palmas_ids[] = {
+	{ .compatible = "ti,tps659038", .data = TPS659038 },
+	{ .compatible = "ti,tps65917" , .data = TPS65917 },
+	{ }
+};
+
+U_BOOT_DRIVER(pmic_palmas) = {
+	.name = "palmas_pmic",
+	.id = UCLASS_PMIC,
+	.of_match = palmas_ids,
+	.bind = palmas_bind,
+	.ops = &palmas_ops,
+};

+ 24 - 0
drivers/power/regulator/Kconfig

@@ -68,6 +68,14 @@ config DM_REGULATOR_FIXED
 	features for fixed value regulators. The driver implements get/set api
 	for enable and get only for voltage value.
 
+config DM_REGULATOR_GPIO
+	bool "Enable Driver Model for GPIO REGULATOR"
+	depends on DM_REGULATOR
+	---help---
+	This config enables implementation of driver-model regulator uclass
+	features for gpio regulators. The driver implements get/set for
+	voltage value.
+
 config REGULATOR_RK808
 	bool "Enable driver for RK808 regulators"
 	depends on DM_REGULATOR && PMIC_RK808
@@ -125,3 +133,19 @@ config REGULATOR_TPS65090
 	regulators, one for each FET. The standard regulator interface is
 	supported, but it is only possible to turn the regulators on or off.
 	There is no voltage/current control.
+
+config DM_REGULATOR_PALMAS
+	bool "Enable driver for PALMAS PMIC regulators"
+       depends on PMIC_PALMAS
+	---help---
+	This enables implementation of driver-model regulator uclass
+	features for REGULATOR PALMAS and the family of PALMAS PMICs.
+	The driver implements get/set api for: value and enable.
+
+config DM_REGULATOR_LP873X
+	bool "Enable driver for LP873X PMIC regulators"
+        depends on PMIC_LP873X
+	---help---
+	This enables implementation of driver-model regulator uclass
+	features for REGULATOR LP873X and the family of LP873X PMICs.
+	The driver implements get/set api for: value and enable.

+ 3 - 0
drivers/power/regulator/Makefile

@@ -11,7 +11,10 @@ obj-$(CONFIG_DM_REGULATOR_MAX77686) += max77686.o
 obj-$(CONFIG_DM_REGULATOR_PFUZE100) += pfuze100.o
 obj-$(CONFIG_REGULATOR_PWM) += pwm_regulator.o
 obj-$(CONFIG_$(SPL_)DM_REGULATOR_FIXED) += fixed.o
+obj-$(CONFIG_$(SPL_)DM_REGULATOR_GPIO) += gpio-regulator.o
 obj-$(CONFIG_REGULATOR_RK808) += rk808.o
 obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
 obj-$(CONFIG_DM_REGULATOR_SANDBOX) += sandbox.o
 obj-$(CONFIG_REGULATOR_TPS65090) += tps65090_regulator.o
+obj-$(CONFIG_$(SPL_)DM_REGULATOR_PALMAS) += palmas_regulator.o
+obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP873X) += lp873x_regulator.o

+ 137 - 0
drivers/power/regulator/gpio-regulator.c

@@ -0,0 +1,137 @@
+/*
+ * (C) Copyright 2016 Texas Instruments Incorporated, <www.ti.com>
+ * Keerthy <j-keerthy@ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <errno.h>
+#include <dm.h>
+#include <i2c.h>
+#include <asm/gpio.h>
+#include <power/pmic.h>
+#include <power/regulator.h>
+
+#define GPIO_REGULATOR_MAX_STATES	2
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct gpio_regulator_platdata {
+	struct gpio_desc gpio; /* GPIO for regulator voltage control */
+	int states[GPIO_REGULATOR_MAX_STATES];
+	int voltages[GPIO_REGULATOR_MAX_STATES];
+};
+
+static int gpio_regulator_ofdata_to_platdata(struct udevice *dev)
+{
+	struct dm_regulator_uclass_platdata *uc_pdata;
+	struct gpio_regulator_platdata *dev_pdata;
+	struct gpio_desc *gpio;
+	const void *blob = gd->fdt_blob;
+	int node = dev->of_offset;
+	int ret, count, i, j;
+	u32 states_array[8];
+
+	dev_pdata = dev_get_platdata(dev);
+	uc_pdata = dev_get_uclass_platdata(dev);
+	if (!uc_pdata)
+		return -ENXIO;
+
+	/* Set type to gpio */
+	uc_pdata->type = REGULATOR_TYPE_GPIO;
+
+	/*
+	 * Get gpio regulator gpio desc
+	 * Assuming one GPIO per regulator.
+	 * Can be extended later to multiple GPIOs
+	 * per gpio-regulator. As of now no instance with multiple
+	 * gpios is presnt
+	 */
+	gpio = &dev_pdata->gpio;
+	ret = gpio_request_by_name(dev, "gpios", 0, gpio, GPIOD_IS_OUT);
+	if (ret)
+		debug("regulator gpio - not found! Error: %d", ret);
+
+	count = fdtdec_get_int_array_count(blob, node, "states",
+					   states_array, 8);
+
+	if (!count)
+		return -EINVAL;
+
+	for (i = 0, j = 0; i < count; i += 2) {
+		dev_pdata->voltages[j] = states_array[i];
+		dev_pdata->states[j] = states_array[i + 1];
+		j++;
+	}
+
+	return 0;
+}
+
+static int gpio_regulator_get_value(struct udevice *dev)
+{
+	struct dm_regulator_uclass_platdata *uc_pdata;
+	struct gpio_regulator_platdata *dev_pdata = dev_get_platdata(dev);
+	int enable;
+
+	if (!dev_pdata->gpio.dev)
+		return -ENOSYS;
+
+	uc_pdata = dev_get_uclass_platdata(dev);
+	if (uc_pdata->min_uV > uc_pdata->max_uV) {
+		debug("Invalid constraints for: %s\n", uc_pdata->name);
+		return -EINVAL;
+	}
+
+	enable = dm_gpio_get_value(&dev_pdata->gpio);
+	if (enable == dev_pdata->states[0])
+		return dev_pdata->voltages[0];
+	else
+		return dev_pdata->voltages[1];
+}
+
+static int gpio_regulator_set_value(struct udevice *dev, int uV)
+{
+	struct gpio_regulator_platdata *dev_pdata = dev_get_platdata(dev);
+	int ret;
+	bool enable;
+
+	if (!dev_pdata->gpio.dev)
+		return -ENOSYS;
+
+	if (uV == dev_pdata->voltages[0])
+		enable = dev_pdata->states[0];
+	else if (uV == dev_pdata->voltages[1])
+		enable = dev_pdata->states[1];
+	else
+		return -EINVAL;
+
+	ret = dm_gpio_set_value(&dev_pdata->gpio, enable);
+	if (ret) {
+		error("Can't set regulator : %s gpio to: %d\n", dev->name,
+		      enable);
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct dm_regulator_ops gpio_regulator_ops = {
+	.get_value	= gpio_regulator_get_value,
+	.set_value	= gpio_regulator_set_value,
+};
+
+static const struct udevice_id gpio_regulator_ids[] = {
+	{ .compatible = "regulator-gpio" },
+	{ },
+};
+
+U_BOOT_DRIVER(gpio_regulator) = {
+	.name = "gpio regulator",
+	.id = UCLASS_REGULATOR,
+	.ops = &gpio_regulator_ops,
+	.of_match = gpio_regulator_ids,
+	.ofdata_to_platdata = gpio_regulator_ofdata_to_platdata,
+	.platdata_auto_alloc_size = sizeof(struct gpio_regulator_platdata),
+};

+ 357 - 0
drivers/power/regulator/lp873x_regulator.c

@@ -0,0 +1,357 @@
+/*
+ * (C) Copyright 2016
+ * Texas Instruments Incorporated, <www.ti.com>
+ *
+ * Keerthy <j-keerthy@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <errno.h>
+#include <dm.h>
+#include <i2c.h>
+#include <power/pmic.h>
+#include <power/regulator.h>
+#include <power/lp873x.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const char lp873x_buck_ctrl[LP873X_BUCK_NUM] = {0x2, 0x4};
+static const char lp873x_buck_volt[LP873X_BUCK_NUM] = {0x6, 0x7};
+static const char lp873x_ldo_ctrl[LP873X_LDO_NUM] = {0x8, 0x9};
+static const char lp873x_ldo_volt[LP873X_LDO_NUM] = {0xA, 0xB};
+
+static int lp873x_buck_enable(struct udevice *dev, int op, bool *enable)
+{
+	int ret;
+	unsigned int adr;
+	struct dm_regulator_uclass_platdata *uc_pdata;
+
+	uc_pdata = dev_get_uclass_platdata(dev);
+	adr = uc_pdata->ctrl_reg;
+
+	ret = pmic_reg_read(dev->parent, adr);
+	if (ret < 0)
+		return ret;
+
+	if (op == PMIC_OP_GET) {
+		ret &= LP873X_BUCK_MODE_MASK;
+
+		if (ret)
+			*enable = true;
+		else
+			*enable = false;
+
+		return 0;
+	} else if (op == PMIC_OP_SET) {
+		if (*enable)
+			ret |= LP873X_BUCK_MODE_MASK;
+		else
+			ret &= ~(LP873X_BUCK_MODE_MASK);
+		ret = pmic_reg_write(dev->parent, adr, ret);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int lp873x_buck_volt2hex(int uV)
+{
+	if (uV > LP873X_BUCK_VOLT_MAX)
+		return -EINVAL;
+	else if (uV > 1400000)
+		return (uV - 1420000) / 20000 + 0x9E;
+	else if (uV > 730000)
+		return (uV - 735000) / 5000 + 0x18;
+	else if (uV >= 700000)
+		return (uV - 700000) / 10000 + 0x1;
+	else
+		return -EINVAL;
+}
+
+static int lp873x_buck_hex2volt(int hex)
+{
+	if (hex > LP873X_BUCK_VOLT_MAX_HEX)
+		return -EINVAL;
+	else if (hex > 0x9D)
+		return 1400000 + (hex - 0x9D) * 20000;
+	else if (hex > 0x17)
+		return 730000 + (hex - 0x17) * 5000;
+	else if (hex >= 0x14)
+		return 700000 + (hex - 0x14) * 10000;
+	else
+		return -EINVAL;
+}
+
+static int lp873x_buck_val(struct udevice *dev, int op, int *uV)
+{
+	unsigned int hex, adr;
+	int ret;
+	struct dm_regulator_uclass_platdata *uc_pdata;
+
+	uc_pdata = dev_get_uclass_platdata(dev);
+
+	if (op == PMIC_OP_GET)
+		*uV = 0;
+
+	adr = uc_pdata->volt_reg;
+
+	ret = pmic_reg_read(dev->parent, adr);
+	if (ret < 0)
+		return ret;
+
+	if (op == PMIC_OP_GET) {
+		ret &= LP873X_BUCK_VOLT_MASK;
+		ret = lp873x_buck_hex2volt(ret);
+		if (ret < 0)
+			return ret;
+		*uV = ret;
+
+		return 0;
+	}
+
+	hex = lp873x_buck_volt2hex(*uV);
+	if (hex < 0)
+		return hex;
+
+	ret &= 0x0;
+	ret |= hex;
+
+	ret = pmic_reg_write(dev->parent, adr, ret);
+
+	return ret;
+}
+
+static int lp873x_ldo_enable(struct udevice *dev, int op, bool *enable)
+{
+	int ret;
+	unsigned int adr;
+	struct dm_regulator_uclass_platdata *uc_pdata;
+
+	uc_pdata = dev_get_uclass_platdata(dev);
+	adr = uc_pdata->ctrl_reg;
+
+	ret = pmic_reg_read(dev->parent, adr);
+	if (ret < 0)
+		return ret;
+
+	if (op == PMIC_OP_GET) {
+		ret &= LP873X_LDO_MODE_MASK;
+
+		if (ret)
+			*enable = true;
+		else
+			*enable = false;
+
+		return 0;
+	} else if (op == PMIC_OP_SET) {
+		if (*enable)
+			ret |= LP873X_LDO_MODE_MASK;
+		else
+			ret &= ~(LP873X_LDO_MODE_MASK);
+
+		ret = pmic_reg_write(dev->parent, adr, ret);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int lp873x_ldo_volt2hex(int uV)
+{
+	if (uV > LP873X_LDO_VOLT_MAX)
+		return -EINVAL;
+
+	return (uV - 800000) / 100000;
+}
+
+static int lp873x_ldo_hex2volt(int hex)
+{
+	if (hex > LP873X_LDO_VOLT_MAX_HEX)
+		return -EINVAL;
+
+	if (!hex)
+		return 0;
+
+	return (hex * 100000) + 800000;
+}
+
+static int lp873x_ldo_val(struct udevice *dev, int op, int *uV)
+{
+	unsigned int hex, adr;
+	int ret;
+
+	struct dm_regulator_uclass_platdata *uc_pdata;
+
+	if (op == PMIC_OP_GET)
+		*uV = 0;
+
+	uc_pdata = dev_get_uclass_platdata(dev);
+
+	adr = uc_pdata->volt_reg;
+
+	ret = pmic_reg_read(dev->parent, adr);
+	if (ret < 0)
+		return ret;
+
+	if (op == PMIC_OP_GET) {
+		ret &= LP873X_LDO_VOLT_MASK;
+		ret = lp873x_ldo_hex2volt(ret);
+		if (ret < 0)
+			return ret;
+		*uV = ret;
+		return 0;
+	}
+
+	hex = lp873x_ldo_volt2hex(*uV);
+	if (hex < 0)
+		return hex;
+
+	ret &= ~LP873X_LDO_VOLT_MASK;
+	ret |= hex;
+	if (*uV > 1650000)
+		ret |= 0x80;
+	ret = pmic_reg_write(dev->parent, adr, ret);
+
+	return ret;
+}
+
+static int lp873x_ldo_probe(struct udevice *dev)
+{
+	struct dm_regulator_uclass_platdata *uc_pdata;
+
+	uc_pdata = dev_get_uclass_platdata(dev);
+	uc_pdata->type = REGULATOR_TYPE_LDO;
+
+	int idx = dev->driver_data;
+	if (idx >= LP873X_LDO_NUM) {
+		printf("Wrong ID for regulator\n");
+		return -1;
+	}
+
+	uc_pdata->ctrl_reg = lp873x_ldo_ctrl[idx];
+	uc_pdata->volt_reg = lp873x_ldo_volt[idx];
+
+	return 0;
+}
+
+static int ldo_get_value(struct udevice *dev)
+{
+	int uV;
+	int ret;
+
+	ret = lp873x_ldo_val(dev, PMIC_OP_GET, &uV);
+	if (ret)
+		return ret;
+
+	return uV;
+}
+
+static int ldo_set_value(struct udevice *dev, int uV)
+{
+	return lp873x_ldo_val(dev, PMIC_OP_SET, &uV);
+}
+
+static bool ldo_get_enable(struct udevice *dev)
+{
+	bool enable = false;
+	int ret;
+
+	ret = lp873x_ldo_enable(dev, PMIC_OP_GET, &enable);
+	if (ret)
+		return ret;
+
+	return enable;
+}
+
+static int ldo_set_enable(struct udevice *dev, bool enable)
+{
+	return lp873x_ldo_enable(dev, PMIC_OP_SET, &enable);
+}
+
+static int lp873x_buck_probe(struct udevice *dev)
+{
+	struct dm_regulator_uclass_platdata *uc_pdata;
+	int idx;
+
+	uc_pdata = dev_get_uclass_platdata(dev);
+	uc_pdata->type = REGULATOR_TYPE_BUCK;
+
+	idx = dev->driver_data;
+	if (idx >= LP873X_BUCK_NUM) {
+		printf("Wrong ID for regulator\n");
+		return -1;
+	}
+
+	uc_pdata->ctrl_reg = lp873x_buck_ctrl[idx];
+	uc_pdata->volt_reg = lp873x_buck_volt[idx];
+
+	return 0;
+}
+
+static int buck_get_value(struct udevice *dev)
+{
+	int uV;
+	int ret;
+
+	ret = lp873x_buck_val(dev, PMIC_OP_GET, &uV);
+	if (ret)
+		return ret;
+
+	return uV;
+}
+
+static int buck_set_value(struct udevice *dev, int uV)
+{
+	return lp873x_buck_val(dev, PMIC_OP_SET, &uV);
+}
+
+static bool buck_get_enable(struct udevice *dev)
+{
+	bool enable = false;
+	int ret;
+
+
+	ret = lp873x_buck_enable(dev, PMIC_OP_GET, &enable);
+	if (ret)
+		return ret;
+
+	return enable;
+}
+
+static int buck_set_enable(struct udevice *dev, bool enable)
+{
+	return lp873x_buck_enable(dev, PMIC_OP_SET, &enable);
+}
+
+static const struct dm_regulator_ops lp873x_ldo_ops = {
+	.get_value  = ldo_get_value,
+	.set_value  = ldo_set_value,
+	.get_enable = ldo_get_enable,
+	.set_enable = ldo_set_enable,
+};
+
+U_BOOT_DRIVER(lp873x_ldo) = {
+	.name = LP873X_LDO_DRIVER,
+	.id = UCLASS_REGULATOR,
+	.ops = &lp873x_ldo_ops,
+	.probe = lp873x_ldo_probe,
+};
+
+static const struct dm_regulator_ops lp873x_buck_ops = {
+	.get_value  = buck_get_value,
+	.set_value  = buck_set_value,
+	.get_enable = buck_get_enable,
+	.set_enable = buck_set_enable,
+};
+
+U_BOOT_DRIVER(lp873x_buck) = {
+	.name = LP873X_BUCK_DRIVER,
+	.id = UCLASS_REGULATOR,
+	.ops = &lp873x_buck_ops,
+	.probe = lp873x_buck_probe,
+};

+ 453 - 0
drivers/power/regulator/palmas_regulator.c

@@ -0,0 +1,453 @@
+/*
+ * (C) Copyright 2016
+ * Texas Instruments Incorporated, <www.ti.com>
+ *
+ * Keerthy <j-keerthy@ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <errno.h>
+#include <dm.h>
+#include <i2c.h>
+#include <power/pmic.h>
+#include <power/regulator.h>
+#include <power/palmas.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define	REGULATOR_ON		0x1
+#define	REGULATOR_OFF		0x0
+
+#define	SMPS_MODE_MASK		0x3
+#define	SMPS_MODE_SHIFT		0x0
+#define	LDO_MODE_MASK		0x1
+#define	LDO_MODE_SHIFT		0x0
+
+static const char palmas_smps_ctrl[][PALMAS_SMPS_NUM] = {
+	{0x20, 0x24, 0x28, 0x2c, 0x30, 0x34, 0x38, 0x3c},
+	{0x20, 0x24, 0x28, 0x2c, 0x30, 0x34, 0x38},
+	{0x20, 0x24, 0x2c, 0x30, 0x38},
+};
+
+static const char palmas_smps_volt[][PALMAS_SMPS_NUM] = {
+	{0x23, 0x27, 0x2b, 0x2f, 0x33, 0x37, 0x3b, 0x3c},
+	{0x23, 0x27, 0x2b, 0x2f, 0x33, 0x37, 0x3b},
+	{0x23, 0x27, 0x2f, 0x33, 0x3B}
+};
+
+static const char palmas_ldo_ctrl[][PALMAS_LDO_NUM] = {
+	{0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x62, 0x64},
+	{0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x62, 0x64},
+	{0x50, 0x52, 0x54, 0x5e, 0x62}
+};
+
+static const char palmas_ldo_volt[][PALMAS_LDO_NUM] = {
+	{0x51, 0x53, 0x55, 0x57, 0x59, 0x5b, 0x5d, 0x5f, 0x61, 0x63, 0x65},
+	{0x51, 0x53, 0x55, 0x57, 0x59, 0x5b, 0x5d, 0x5f, 0x61, 0x63, 0x65},
+	{0x51, 0x53, 0x55, 0x5f, 0x63}
+};
+
+static int palmas_smps_enable(struct udevice *dev, int op, bool *enable)
+{
+	int ret;
+	unsigned int adr;
+	struct dm_regulator_uclass_platdata *uc_pdata;
+
+	uc_pdata = dev_get_uclass_platdata(dev);
+	adr = uc_pdata->ctrl_reg;
+
+	ret = pmic_reg_read(dev->parent, adr);
+		if (ret < 0)
+			return ret;
+
+	if (op == PMIC_OP_GET) {
+		ret &= PALMAS_SMPS_STATUS_MASK;
+
+		if (ret)
+			*enable = true;
+		else
+			*enable = false;
+
+		return 0;
+	} else if (op == PMIC_OP_SET) {
+		if (*enable)
+			ret |= PALMAS_SMPS_MODE_MASK;
+		else
+			ret &= ~(PALMAS_SMPS_MODE_MASK);
+
+		ret = pmic_reg_write(dev->parent, adr, ret);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int palmas_smps_volt2hex(int uV)
+{
+	if (uV > PALMAS_LDO_VOLT_MAX)
+		return -EINVAL;
+
+	if (uV > 1650000)
+		return (uV - 1000000) / 20000 + 0x6;
+
+	if (uV == 500000)
+		return 0x6;
+	else
+		return 0x6 + ((uV - 500000) / 10000);
+}
+
+static int palmas_smps_hex2volt(int hex, bool range)
+{
+	unsigned int uV = 0;
+
+	if (hex > PALMAS_SMPS_VOLT_MAX_HEX)
+		return -EINVAL;
+
+	if (hex < 0x7)
+		uV = 500000;
+	else
+		uV = 500000 + (hex - 0x6) * 10000;
+
+	if (range)
+		uV *= 2;
+
+	return uV;
+}
+
+static int palmas_smps_val(struct udevice *dev, int op, int *uV)
+{
+	unsigned int hex, adr;
+	int ret;
+	bool range;
+	struct dm_regulator_uclass_platdata *uc_pdata;
+
+	uc_pdata = dev_get_uclass_platdata(dev);
+
+	if (op == PMIC_OP_GET)
+		*uV = 0;
+
+	adr = uc_pdata->volt_reg;
+
+	ret = pmic_reg_read(dev->parent, adr);
+	if (ret < 0)
+		return ret;
+
+	if (op == PMIC_OP_GET) {
+		if (ret & PALMAS_SMPS_RANGE_MASK)
+			range =  true;
+		else
+			range = false;
+
+		ret &= PALMAS_SMPS_VOLT_MASK;
+		ret = palmas_smps_hex2volt(ret, range);
+		if (ret < 0)
+			return ret;
+		*uV = ret;
+
+		return 0;
+	}
+
+	hex = palmas_smps_volt2hex(*uV);
+	if (hex < 0)
+		return hex;
+
+	ret &= ~PALMAS_SMPS_VOLT_MASK;
+	ret |= hex;
+	if (*uV > 1650000)
+		ret |= PALMAS_SMPS_RANGE_MASK;
+
+	return pmic_reg_write(dev->parent, adr, ret);
+}
+
+static int palmas_ldo_enable(struct udevice *dev, int op, bool *enable)
+{
+	int ret;
+	unsigned int adr;
+	struct dm_regulator_uclass_platdata *uc_pdata;
+
+	uc_pdata = dev_get_uclass_platdata(dev);
+	adr = uc_pdata->ctrl_reg;
+
+	ret = pmic_reg_read(dev->parent, adr);
+		if (ret < 0)
+			return ret;
+
+	if (op == PMIC_OP_GET) {
+		ret &= PALMAS_LDO_STATUS_MASK;
+
+		if (ret)
+			*enable = true;
+		else
+			*enable = false;
+
+		return 0;
+	} else if (op == PMIC_OP_SET) {
+		if (*enable)
+			ret |= PALMAS_LDO_MODE_MASK;
+		else
+			ret &= ~(PALMAS_LDO_MODE_MASK);
+
+		ret = pmic_reg_write(dev->parent, adr, ret);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int palmas_ldo_volt2hex(int uV)
+{
+	if (uV > PALMAS_LDO_VOLT_MAX)
+		return -EINVAL;
+
+	return (uV - 850000) / 50000;
+}
+
+static int palmas_ldo_hex2volt(int hex)
+{
+	if (hex > PALMAS_LDO_VOLT_MAX_HEX)
+		return -EINVAL;
+
+	if (!hex)
+		return 0;
+
+	return (hex * 50000) + 850000;
+}
+
+static int palmas_ldo_val(struct udevice *dev, int op, int *uV)
+{
+	unsigned int hex, adr;
+	int ret;
+
+	struct dm_regulator_uclass_platdata *uc_pdata;
+
+	if (op == PMIC_OP_GET)
+		*uV = 0;
+
+	uc_pdata = dev_get_uclass_platdata(dev);
+
+	adr = uc_pdata->volt_reg;
+
+	ret = pmic_reg_read(dev->parent, adr);
+	if (ret < 0)
+		return ret;
+
+	if (op == PMIC_OP_GET) {
+		ret &= PALMAS_LDO_VOLT_MASK;
+		ret = palmas_ldo_hex2volt(ret);
+		if (ret < 0)
+			return ret;
+		*uV = ret;
+		return 0;
+	}
+
+	hex = palmas_ldo_volt2hex(*uV);
+	if (hex < 0)
+		return hex;
+
+	ret &= ~PALMAS_LDO_VOLT_MASK;
+	ret |= hex;
+	if (*uV > 1650000)
+		ret |= 0x80;
+
+	return pmic_reg_write(dev->parent, adr, ret);
+}
+
+static int palmas_ldo_probe(struct udevice *dev)
+{
+	struct dm_regulator_uclass_platdata *uc_pdata;
+	struct udevice *parent;
+
+	uc_pdata = dev_get_uclass_platdata(dev);
+
+	parent = dev_get_parent(dev);
+	int type = dev_get_driver_data(parent);
+
+	uc_pdata->type = REGULATOR_TYPE_LDO;
+
+	if (dev->driver_data) {
+		u8 idx = dev->driver_data - 1;
+		uc_pdata->ctrl_reg = palmas_ldo_ctrl[type][idx];
+		uc_pdata->volt_reg = palmas_ldo_volt[type][idx];
+	} else {
+		/* check for ldoln and ldousb cases */
+		if (!strcmp("ldoln", dev->name)) {
+			uc_pdata->ctrl_reg = palmas_ldo_ctrl[type][9];
+			uc_pdata->volt_reg = palmas_ldo_volt[type][9];
+		} else if (!strcmp("ldousb", dev->name)) {
+			uc_pdata->ctrl_reg = palmas_ldo_ctrl[type][10];
+			uc_pdata->volt_reg = palmas_ldo_volt[type][10];
+		}
+	}
+
+	return 0;
+}
+
+static int ldo_get_value(struct udevice *dev)
+{
+	int uV;
+	int ret;
+
+	ret = palmas_ldo_val(dev, PMIC_OP_GET, &uV);
+	if (ret)
+		return ret;
+
+	return uV;
+}
+
+static int ldo_set_value(struct udevice *dev, int uV)
+{
+	return palmas_ldo_val(dev, PMIC_OP_SET, &uV);
+}
+
+static bool ldo_get_enable(struct udevice *dev)
+{
+	bool enable = false;
+	int ret;
+
+	ret = palmas_ldo_enable(dev, PMIC_OP_GET, &enable);
+	if (ret)
+		return ret;
+
+	return enable;
+}
+
+static int ldo_set_enable(struct udevice *dev, bool enable)
+{
+	return palmas_ldo_enable(dev, PMIC_OP_SET, &enable);
+}
+
+static int palmas_smps_probe(struct udevice *dev)
+{
+	struct dm_regulator_uclass_platdata *uc_pdata;
+	struct udevice *parent;
+	int idx;
+
+	uc_pdata = dev_get_uclass_platdata(dev);
+
+	parent = dev_get_parent(dev);
+	int type = dev_get_driver_data(parent);
+
+	uc_pdata->type = REGULATOR_TYPE_BUCK;
+
+	switch (type) {
+	case PALMAS:
+	case TPS659038:
+		switch (dev->driver_data) {
+		case 123:
+		case 12:
+			uc_pdata->ctrl_reg = palmas_smps_ctrl[type][0];
+			uc_pdata->volt_reg = palmas_smps_volt[type][0];
+			break;
+		case 3:
+			uc_pdata->ctrl_reg = palmas_smps_ctrl[type][1];
+			uc_pdata->volt_reg = palmas_smps_volt[type][1];
+			break;
+		case 45:
+			uc_pdata->ctrl_reg = palmas_smps_ctrl[type][2];
+			uc_pdata->volt_reg = palmas_smps_volt[type][2];
+			break;
+		case 6:
+		case 7:
+		case 8:
+		case 9:
+		case 10:
+			idx = dev->driver_data - 4;
+			uc_pdata->ctrl_reg = palmas_smps_ctrl[type][idx];
+			uc_pdata->volt_reg = palmas_smps_volt[type][idx];
+			break;
+
+		default:
+			printf("Wrong ID for regulator\n");
+		}
+		break;
+
+	case TPS65917:
+		switch (dev->driver_data) {
+		case 1:
+		case 2:
+		case 3:
+		case 4:
+		case 5:
+			idx = dev->driver_data - 1;
+			uc_pdata->ctrl_reg = palmas_smps_ctrl[type][idx];
+			uc_pdata->volt_reg = palmas_smps_volt[type][idx];
+			break;
+
+		default:
+			printf("Wrong ID for regulator\n");
+		}
+		break;
+
+	default:
+			printf("Invalid PMIC ID\n");
+	}
+
+	return 0;
+}
+
+static int smps_get_value(struct udevice *dev)
+{
+	int uV;
+	int ret;
+
+	ret = palmas_smps_val(dev, PMIC_OP_GET, &uV);
+	if (ret)
+		return ret;
+
+	return uV;
+}
+
+static int smps_set_value(struct udevice *dev, int uV)
+{
+	return palmas_smps_val(dev, PMIC_OP_SET, &uV);
+}
+
+static bool smps_get_enable(struct udevice *dev)
+{
+	bool enable = false;
+	int ret;
+
+	ret = palmas_smps_enable(dev, PMIC_OP_GET, &enable);
+	if (ret)
+		return ret;
+
+	return enable;
+}
+
+static int smps_set_enable(struct udevice *dev, bool enable)
+{
+	return palmas_smps_enable(dev, PMIC_OP_SET, &enable);
+}
+
+static const struct dm_regulator_ops palmas_ldo_ops = {
+	.get_value  = ldo_get_value,
+	.set_value  = ldo_set_value,
+	.get_enable = ldo_get_enable,
+	.set_enable = ldo_set_enable,
+};
+
+U_BOOT_DRIVER(palmas_ldo) = {
+	.name = PALMAS_LDO_DRIVER,
+	.id = UCLASS_REGULATOR,
+	.ops = &palmas_ldo_ops,
+	.probe = palmas_ldo_probe,
+};
+
+static const struct dm_regulator_ops palmas_smps_ops = {
+	.get_value  = smps_get_value,
+	.set_value  = smps_set_value,
+	.get_enable = smps_get_enable,
+	.set_enable = smps_set_enable,
+};
+
+U_BOOT_DRIVER(palmas_smps) = {
+	.name = PALMAS_SMPS_DRIVER,
+	.id = UCLASS_REGULATOR,
+	.ops = &palmas_smps_ops,
+	.probe = palmas_smps_probe,
+};

+ 1 - 0
fs/sandbox/sandboxfs.c

@@ -94,6 +94,7 @@ int sandbox_fs_ls(const char *dirname)
 		printf("%s %10lu %s\n", os_dirent_get_typename(node->type),
 		       node->size, node->name);
 	}
+	os_dirent_free(head);
 
 	return 0;
 }

+ 11 - 0
include/cros_ec.h

@@ -280,6 +280,17 @@ int cros_ec_flash_erase(struct cros_ec_dev *dev, uint32_t offset,
 int cros_ec_flash_read(struct cros_ec_dev *dev, uint8_t *data, uint32_t offset,
 		    uint32_t size);
 
+/**
+ * Read back flash parameters
+ *
+ * This function reads back parameters of the flash as reported by the EC
+ *
+ * @param dev  Pointer to device
+ * @param info Pointer to output flash info struct
+ */
+int cros_ec_read_flashinfo(struct cros_ec_dev *dev,
+			  struct ec_response_flash_info *info);
+
 /**
  * Write data to the flash
  *

+ 10 - 1
include/os.h

@@ -214,10 +214,19 @@ struct os_dirent_node {
  */
 int os_dirent_ls(const char *dirname, struct os_dirent_node **headp);
 
+/**
+ * Free directory list
+ *
+ * This frees a linked list containing a directory listing.
+ *
+ * @param node		Pointer to head of linked list
+ */
+void os_dirent_free(struct os_dirent_node *node);
+
 /**
  * Get the name of a directory entry type
  *
- * @param type		Type to cehck
+ * @param type		Type to check
  * @return string containing the name of that type, or "???" if none/invalid
  */
 const char *os_dirent_get_typename(enum os_dirent_t type);

+ 19 - 0
include/power/lp873x.h

@@ -0,0 +1,19 @@
+#define	LP8732		0x0
+#define LP8733		0x1
+
+#define LP873X_LDO_NUM		2
+#define LP873X_BUCK_NUM		2
+
+/* Drivers name */
+#define LP873X_LDO_DRIVER	"lp873x_ldo"
+#define LP873X_BUCK_DRIVER	"lp873x_buck"
+
+#define LP873X_BUCK_VOLT_MASK		0xFF
+#define LP873X_BUCK_VOLT_MAX_HEX	0xFF
+#define LP873X_BUCK_VOLT_MAX		3360000
+#define LP873X_BUCK_MODE_MASK		0x1
+
+#define LP873X_LDO_VOLT_MASK    0x1F
+#define LP873X_LDO_VOLT_MAX_HEX 0x19
+#define LP873X_LDO_VOLT_MAX     3300000
+#define LP873X_LDO_MODE_MASK	0x1

+ 25 - 0
include/power/palmas.h

@@ -0,0 +1,25 @@
+#define	PALMAS		0x0
+#define TPS659038	0x1
+#define TPS65917	0x2
+
+/* I2C device address for pmic palmas */
+#define PALMAS_I2C_ADDR	(0x12 >> 1)
+#define PALMAS_LDO_NUM		11
+#define PALMAS_SMPS_NUM	8
+
+/* Drivers name */
+#define PALMAS_LDO_DRIVER     "palmas_ldo"
+#define PALMAS_SMPS_DRIVER    "palmas_smps"
+
+#define PALMAS_SMPS_VOLT_MASK		0x7F
+#define PALMAS_SMPS_RANGE_MASK		0x80
+#define PALMAS_SMPS_VOLT_MAX_HEX	0x7F
+#define PALMAS_SMPS_VOLT_MAX		3300000
+#define PALMAS_SMPS_MODE_MASK		0x3
+#define	PALMAS_SMPS_STATUS_MASK		0x30
+
+#define PALMAS_LDO_VOLT_MASK    0x3F
+#define PALMAS_LDO_VOLT_MAX_HEX 0x3F
+#define PALMAS_LDO_VOLT_MAX     3300000
+#define PALMAS_LDO_MODE_MASK	0x1
+#define PALMAS_LDO_STATUS_MASK	0x10

+ 5 - 0
include/power/regulator.h

@@ -108,6 +108,7 @@ enum regulator_type {
 	REGULATOR_TYPE_BUCK,
 	REGULATOR_TYPE_DVS,
 	REGULATOR_TYPE_FIXED,
+	REGULATOR_TYPE_GPIO,
 	REGULATOR_TYPE_OTHER,
 };
 
@@ -152,6 +153,8 @@ enum regulator_flag {
  * TODO(sjg@chromium.org): Consider putting the above two into @flags
  * @flags:     - flags value (see REGULATOR_FLAG_...)
  * @name**     - fdt regulator name - should be taken from the device tree
+ * ctrl_reg:   - Control register offset used to enable/disable regulator
+ * volt_reg:   - register offset for writing voltage vsel values
  *
  * Note:
  * *  - set automatically on device probe by the uclass's '.pre_probe' method.
@@ -171,6 +174,8 @@ struct dm_regulator_uclass_platdata {
 	bool boot_on;
 	const char *name;
 	int flags;
+	u8 ctrl_reg;
+	u8 volt_reg;
 };
 
 /* Regulator device operations */

+ 9 - 0
tools/buildman/README

@@ -211,6 +211,15 @@ arm: arm-none-eabi-
 
 and buildman will find arm-none-eabi-gcc in /usr/bin if you have it installed.
 
+[toolchain-wrapper]
+wrapper: ccache
+
+This tells buildman to use a compiler wrapper in front of CROSS_COMPILE. In
+this example, ccache. It doesn't affect the toolchain scan. The wrapper is
+added when CROSS_COMPILE environtal variable is set. The name in this
+section is ignored. If more than one line is provided, only the last one
+is taken.
+
 3. Make sure you have the require Python pre-requisites
 
 Buildman uses multiprocessing, Queue, shutil, StringIO, ConfigParser and

+ 23 - 10
tools/buildman/builder.py

@@ -12,8 +12,10 @@ import os
 import re
 import Queue
 import shutil
+import signal
 import string
 import sys
+import threading
 import time
 
 import builderthread
@@ -126,7 +128,6 @@ class Builder:
     """Class for building U-Boot for a particular commit.
 
     Public members: (many should ->private)
-        active: True if the builder is active and has not been stopped
         already_done: Number of builds already completed
         base_dir: Base directory to use for builder
         checkout: True to check out source, False to skip that step.
@@ -234,7 +235,6 @@ class Builder:
         self.base_dir = base_dir
         self._working_dir = os.path.join(base_dir, '.bm-work')
         self.threads = []
-        self.active = True
         self.do_make = self.Make
         self.gnu_make = gnu_make
         self.checkout = checkout
@@ -283,11 +283,17 @@ class Builder:
         ignore_lines = ['(make.*Waiting for unfinished)', '(Segmentation fault)']
         self.re_make_err = re.compile('|'.join(ignore_lines))
 
+        # Handle existing graceful with SIGINT / Ctrl-C
+        signal.signal(signal.SIGINT, self.signal_handler)
+
     def __del__(self):
         """Get rid of all threads created by the builder"""
         for t in self.threads:
             del t
 
+    def signal_handler(self, signal, frame):
+        sys.exit(1)
+
     def SetDisplayOptions(self, show_errors=False, show_sizes=False,
                           show_detail=False, show_bloat=False,
                           list_error_boards=False, show_config=False):
@@ -389,11 +395,6 @@ class Builder:
         if result:
             target = result.brd.target
 
-            if result.return_code < 0:
-                self.active = False
-                command.StopAll()
-                return
-
             self.upto += 1
             if result.return_code != 0:
                 self.fail += 1
@@ -1366,8 +1367,10 @@ class Builder:
             if os.path.exists(git_dir):
                 gitutil.Fetch(git_dir, thread_dir)
             else:
-                Print('Cloning repo for thread %d' % thread_num)
+                Print('\rCloning repo for thread %d' % thread_num,
+                      newline=False)
                 gitutil.Clone(src_dir, thread_dir)
+                Print('\r%s\r' % (' ' * 30), newline=False)
 
     def _PrepareWorkingSpace(self, max_threads, setup_git):
         """Prepare the working directory for use.
@@ -1395,8 +1398,14 @@ class Builder:
         for commit_upto in range(self.commit_count):
             dir_list.append(self._GetOutputDir(commit_upto))
 
+        to_remove = []
         for dirname in glob.glob(os.path.join(self.base_dir, '*')):
             if dirname not in dir_list:
+                to_remove.append(dirname)
+        if to_remove:
+            Print('Removing %d old build directories' % len(to_remove),
+                  newline=False)
+            for dirname in to_remove:
                 shutil.rmtree(dirname)
 
     def BuildBoards(self, commits, board_selected, keep_outputs, verbose):
@@ -1422,6 +1431,7 @@ class Builder:
         self._PrepareWorkingSpace(min(self.num_threads, len(board_selected)),
                 commits is not None)
         self._PrepareOutputSpace()
+        Print('\rStarting build...', newline=False)
         self.SetupBuild(board_selected, commits)
         self.ProcessResult(None)
 
@@ -1434,8 +1444,11 @@ class Builder:
             job.step = self._step
             self.queue.put(job)
 
-        # Wait until all jobs are started
-        self.queue.join()
+        term = threading.Thread(target=self.queue.join)
+        term.setDaemon(True)
+        term.start()
+        while term.isAlive():
+            term.join(100)
 
         # Wait until we have processed all output
         self.out_queue.join()

+ 1 - 15
tools/buildman/builderthread.py

@@ -304,10 +304,6 @@ class BuilderThread(threading.Thread):
                 print >>fd, 'arch', result.toolchain.arch
                 fd.write('%s' % result.return_code)
 
-            with open(os.path.join(build_dir, 'toolchain'), 'w') as fd:
-                print >>fd, 'gcc', result.toolchain.gcc
-                print >>fd, 'path', result.toolchain.path
-
             # Write out the image and function size information and an objdump
             env = result.toolchain.MakeEnvironment(self.builder.full_path)
             lines = []
@@ -470,17 +466,7 @@ class BuilderThread(threading.Thread):
         This thread picks a job from the queue, runs it, and then goes to the
         next job.
         """
-        alive = True
         while True:
             job = self.builder.queue.get()
-            if self.builder.active and alive:
-                self.RunJob(job)
-            '''
-            try:
-                if self.builder.active and alive:
-                    self.RunJob(job)
-            except Exception as err:
-                alive = False
-                print err
-            '''
+            self.RunJob(job)
             self.builder.queue.task_done()

+ 1 - 1
tools/buildman/buildman.py

@@ -15,7 +15,7 @@ import unittest
 
 # Bring in the patman libraries
 our_path = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(os.path.join(our_path, '../patman'))
+sys.path.insert(1, os.path.join(our_path, '../patman'))
 
 # Our modules
 import board

+ 2 - 2
tools/buildman/test.py

@@ -198,9 +198,9 @@ class TestBuild(unittest.TestCase):
             if line.text.strip():
                 count += 1
 
-        # We should get one starting message, then an update for every commit
+        # We should get two starting messages, then an update for every commit
         # built.
-        self.assertEqual(count, len(commits) * len(boards) + 1)
+        self.assertEqual(count, len(commits) * len(boards) + 2)
         build.SetDisplayOptions(show_errors=True);
         build.ShowSummary(self.commits, board_selected)
         #terminal.EchoPrintTestLines()

+ 16 - 2
tools/buildman/toolchain.py

@@ -127,6 +127,18 @@ class Toolchain:
                 return PRIORITY_CALC + prio
         return PRIORITY_CALC + prio
 
+    def GetWrapper(self, show_warning=True):
+        """Get toolchain wrapper from the setting file.
+        """
+	value = ''
+	for name, value in bsettings.GetItems('toolchain-wrapper'):
+            if not value:
+                print "Warning: Wrapper not found"
+        if value:
+            value = value + ' '
+
+        return value
+
     def MakeEnvironment(self, full_path):
         """Returns an environment for using the toolchain.
 
@@ -138,10 +150,12 @@ class Toolchain:
                 PATH
         """
         env = dict(os.environ)
+        wrapper = self.GetWrapper()
+
         if full_path:
-            env['CROSS_COMPILE'] = os.path.join(self.path, self.cross)
+            env['CROSS_COMPILE'] = wrapper + os.path.join(self.path, self.cross)
         else:
-            env['CROSS_COMPILE'] = self.cross
+            env['CROSS_COMPILE'] = wrapper + self.cross
             env['PATH'] = self.path + ':' + env['PATH']
 
         return env

+ 5 - 5
tools/dtoc/dtoc.py

@@ -60,7 +60,7 @@ def Conv_name_to_c(name):
 def TabTo(num_tabs, str):
     if len(str) >= num_tabs * 8:
         return str + ' '
-    return str + '\t' * (num_tabs - len(str) / 8)
+    return str + '\t' * (num_tabs - len(str) // 8)
 
 class DtbPlatdata:
     """Provide a means to convert device tree binary data to platform data
@@ -224,14 +224,14 @@ class DtbPlatdata:
             fields = {}
 
             # Get a list of all the valid properties in this node.
-            for name, prop in node.props.iteritems():
+            for name, prop in node.props.items():
                 if name not in PROP_IGNORE_LIST and name[0] != '#':
                     fields[name] = copy.deepcopy(prop)
 
             # If we've seen this node_name before, update the existing struct.
             if node_name in structs:
                 struct = structs[node_name]
-                for name, prop in fields.iteritems():
+                for name, prop in fields.items():
                     oldprop = struct.get(name)
                     if oldprop:
                         oldprop.Widen(prop)
@@ -246,7 +246,7 @@ class DtbPlatdata:
         for node in self._valid_nodes:
             node_name = self.GetCompatName(node)
             struct = structs[node_name]
-            for name, prop in node.props.iteritems():
+            for name, prop in node.props.items():
                 if name not in PROP_IGNORE_LIST and name[0] != '#':
                     prop.Widen(struct[name])
             upto += 1
@@ -298,7 +298,7 @@ class DtbPlatdata:
             var_name = Conv_name_to_c(node.name)
             self.Buf('static struct %s%s %s%s = {\n' %
                 (STRUCT_PREFIX, struct_name, VAL_PREFIX, var_name))
-            for pname, prop in node.props.iteritems():
+            for pname, prop in node.props.items():
                 if pname in PROP_IGNORE_LIST or pname[0] == '#':
                     continue
                 ptype = TYPE_NAMES[prop.type]

+ 2 - 2
tools/dtoc/fdt_fallback.py

@@ -58,7 +58,7 @@ class Node(NodeBase):
         This fills in the props and subnodes properties, recursively
         searching into subnodes so that the entire tree is built.
         """
-        for name, byte_list_str in self._fdt.GetProps(self.path).iteritems():
+        for name, byte_list_str in self._fdt.GetProps(self.path).items():
             prop = Prop(self, name, byte_list_str)
             self.props[name] = prop
 
@@ -160,7 +160,7 @@ class FdtFallback(Fdt):
         if default is not None:
           args += ['-d', str(default)]
         if typespec is not None:
-          args += ['-t%s' % typespec]
+          args += ['-t', typespec]
         out = command.Output('fdtget', *args)
         return out.strip()
 

+ 3 - 6
tools/dtoc/fdt_normal.py

@@ -81,7 +81,7 @@ class Node(NodeBase):
         This fills in the props and subnodes properties, recursively
         searching into subnodes so that the entire tree is built.
         """
-        self.props = self._fdt.GetProps(self, self.path)
+        self.props = self._fdt.GetProps(self)
 
         offset = libfdt.fdt_first_subnode(self._fdt.GetFdt(), self.Offset())
         while offset >= 0:
@@ -159,7 +159,7 @@ class FdtNormal(Fdt):
         fdt_len = libfdt.fdt_totalsize(self._fdt)
         del self._fdt[fdt_len:]
 
-    def GetProps(self, node, path):
+    def GetProps(self, node):
         """Get all properties from a node.
 
         Args:
@@ -172,11 +172,8 @@ class FdtNormal(Fdt):
         Raises:
             ValueError: if the node does not exist.
         """
-        offset = libfdt.fdt_path_offset(self._fdt, path)
-        if offset < 0:
-            libfdt.Raise(offset)
         props_dict = {}
-        poffset = libfdt.fdt_first_property_offset(self._fdt, offset)
+        poffset = libfdt.fdt_first_property_offset(self._fdt, node._offset)
         while poffset >= 0:
             dprop, plen = libfdt.fdt_get_property_by_offset(self._fdt, poffset)
             prop = Prop(node, poffset, libfdt.String(self._fdt, dprop.nameoff),

+ 13 - 3
tools/dtoc/fdt_select.py

@@ -6,6 +6,8 @@
 # SPDX-License-Identifier:      GPL-2.0+
 #
 
+import fdt_fallback
+
 # Bring in either the normal fdt library (which relies on libfdt) or the
 # fallback one (which uses fdtget and is slower). Both provide the same
 # interface for this file to use.
@@ -14,13 +16,21 @@ try:
     have_libfdt = True
 except ImportError:
     have_libfdt = False
-    import fdt_fallback
 
-def FdtScan(fname):
+force_fallback = False
+
+def FdtScan(fname, _force_fallback=False):
     """Returns a new Fdt object from the implementation we are using"""
-    if have_libfdt:
+    if have_libfdt and not force_fallback and not _force_fallback:
         dtb = fdt_normal.FdtNormal(fname)
     else:
         dtb = fdt_fallback.FdtFallback(fname)
     dtb.Scan()
     return dtb
+
+def UseFallback(fallback):
+    global force_fallback
+
+    old_val = force_fallback
+    force_fallback = fallback
+    return old_val

+ 3 - 0
tools/dtoc/fdt_util.py

@@ -8,6 +8,7 @@
 
 import os
 import struct
+import sys
 import tempfile
 
 import command
@@ -22,6 +23,8 @@ def fdt32_to_cpu(val):
     Return:
         A native-endian integer value
     """
+    if sys.version_info > (3, 0):
+        val = val.encode('raw_unicode_escape')
     return struct.unpack('>I', val)[0]
 
 def EnsureCompiled(fname):

+ 8 - 8
tools/patman/checkpatch.py

@@ -83,7 +83,7 @@ def CheckPatch(fname, verbose=False):
 
     for line in result.stdout.splitlines():
         if verbose:
-            print line
+            print(line)
 
         # A blank line indicates the end of a message
         if not line and item:
@@ -151,17 +151,17 @@ def CheckPatches(verbose, args):
             error_count += result.errors
             warning_count += result.warnings
             check_count += result.checks
-            print '%d errors, %d warnings, %d checks for %s:' % (result.errors,
-                    result.warnings, result.checks, col.Color(col.BLUE, fname))
+            print('%d errors, %d warnings, %d checks for %s:' % (result.errors,
+                    result.warnings, result.checks, col.Color(col.BLUE, fname)))
             if (len(result.problems) != result.errors + result.warnings +
                     result.checks):
-                print "Internal error: some problems lost"
+                print("Internal error: some problems lost")
             for item in result.problems:
-                print GetWarningMsg(col, item.get('type', '<unknown>'),
+                print(GetWarningMsg(col, item.get('type', '<unknown>'),
                         item.get('file', '<unknown>'),
-                        item.get('line', 0), item.get('msg', 'message'))
+                        item.get('line', 0), item.get('msg', 'message')))
             print
-            #print stdout
+            #print(stdout)
     if error_count or warning_count or check_count:
         str = 'checkpatch.pl found %d error(s), %d warning(s), %d checks(s)'
         color = col.GREEN
@@ -169,6 +169,6 @@ def CheckPatches(verbose, args):
             color = col.YELLOW
         if error_count:
             color = col.RED
-        print col.Color(color, str % (error_count, warning_count, check_count))
+        print(col.Color(color, str % (error_count, warning_count, check_count)))
         return False
     return True

+ 1 - 1
tools/patman/command.py

@@ -85,7 +85,7 @@ def RunPipe(pipe_list, infile=None, outfile=None,
 
         try:
             last_pipe = cros_subprocess.Popen(cmd, cwd=cwd, **kwargs)
-        except Exception, err:
+        except Exception as err:
             result.exception = err
             if raise_on_error:
                 raise Exception("Error running '%s': %s" % (user_pipestr, str))

+ 1 - 1
tools/patman/cros_subprocess.py

@@ -166,7 +166,7 @@ class Popen(subprocess.Popen):
         while read_set or write_set:
             try:
                 rlist, wlist, _ = select.select(read_set, write_set, [], 0.2)
-            except select.error, e:
+            except select.error as e:
                 if e.args[0] == errno.EINTR:
                     continue
                 raise

+ 1 - 1
tools/patman/get_maintainer.py

@@ -40,7 +40,7 @@ def GetMaintainer(fname, verbose=False):
     get_maintainer = FindGetMaintainer()
     if not get_maintainer:
         if verbose:
-            print "WARNING: Couldn't find get_maintainer.pl"
+            print("WARNING: Couldn't find get_maintainer.pl")
         return []
 
     stdout = command.Output(get_maintainer, '--norolestats', fname)

+ 9 - 9
tools/patman/gitutil.py

@@ -139,7 +139,7 @@ def GetUpstream(git_dir, branch):
         leaf = merge.split('/')[-1]
         return '%s/%s' % (remote, leaf), None
     else:
-        raise ValueError, ("Cannot determine upstream branch for branch "
+        raise ValueError("Cannot determine upstream branch for branch "
                 "'%s' remote='%s', merge='%s'" % (branch, remote, merge))
 
 
@@ -224,7 +224,7 @@ def Checkout(commit_hash, git_dir=None, work_tree=None, force=False):
     result = command.RunPipe([pipe], capture=True, raise_on_error=False,
                              capture_stderr=True)
     if result.return_code != 0:
-        raise OSError, 'git checkout (%s): %s' % (pipe, result.stderr)
+        raise OSError('git checkout (%s): %s' % (pipe, result.stderr))
 
 def Clone(git_dir, output_dir):
     """Checkout the selected commit for this build
@@ -236,7 +236,7 @@ def Clone(git_dir, output_dir):
     result = command.RunPipe([pipe], capture=True, cwd=output_dir,
                              capture_stderr=True)
     if result.return_code != 0:
-        raise OSError, 'git clone: %s' % result.stderr
+        raise OSError('git clone: %s' % result.stderr)
 
 def Fetch(git_dir=None, work_tree=None):
     """Fetch from the origin repo
@@ -252,7 +252,7 @@ def Fetch(git_dir=None, work_tree=None):
     pipe.append('fetch')
     result = command.RunPipe([pipe], capture=True, capture_stderr=True)
     if result.return_code != 0:
-        raise OSError, 'git fetch: %s' % result.stderr
+        raise OSError('git fetch: %s' % result.stderr)
 
 def CreatePatches(start, count, series):
     """Create a series of patches from the top of the current branch.
@@ -489,18 +489,18 @@ def LookupEmail(lookup_name, alias=None, raise_on_error=True, level=0):
     if level > 10:
         msg = "Recursive email alias at '%s'" % lookup_name
         if raise_on_error:
-            raise OSError, msg
+            raise OSError(msg)
         else:
-            print col.Color(col.RED, msg)
+            print(col.Color(col.RED, msg))
             return out_list
 
     if lookup_name:
         if not lookup_name in alias:
             msg = "Alias '%s' not found" % lookup_name
             if raise_on_error:
-                raise ValueError, msg
+                raise ValueError(msg)
             else:
-                print col.Color(col.RED, msg)
+                print(col.Color(col.RED, msg))
                 return out_list
         for item in alias[lookup_name]:
             todo = LookupEmail(item, alias, raise_on_error, level + 1)
@@ -508,7 +508,7 @@ def LookupEmail(lookup_name, alias=None, raise_on_error=True, level=0):
                 if not new_item in out_list:
                     out_list.append(new_item)
 
-    #print "No match for alias '%s'" % lookup_name
+    #print("No match for alias '%s'" % lookup_name)
     return out_list
 
 def GetTopLevel():

+ 3 - 3
tools/patman/patchstream.py

@@ -480,12 +480,12 @@ def FixPatches(series, fnames):
         commit.patch = fname
         result = FixPatch(backup_dir, fname, series, commit)
         if result:
-            print '%d warnings for %s:' % (len(result), fname)
+            print('%d warnings for %s:' % (len(result), fname))
             for warn in result:
-                print '\t', warn
+                print('\t', warn)
             print
         count += 1
-    print 'Cleaned %d patches' % count
+    print('Cleaned %d patches' % count)
     return series
 
 def InsertCoverLetter(fname, series, count):

+ 6 - 6
tools/patman/patman.py

@@ -93,11 +93,11 @@ elif options.test:
         suite.run(result)
 
     # TODO: Surely we can just 'print' result?
-    print result
+    print(result)
     for test, err in result.errors:
-        print err
+        print(err)
     for test, err in result.failures:
-        print err
+        print(err)
 
 # Called from git with a patch filename as argument
 # Printout a list of additional CC recipients for this patch
@@ -110,7 +110,7 @@ elif options.cc_cmd:
             for cc in match.group(2).split(', '):
                 cc = cc.strip()
                 if cc:
-                    print cc
+                    print(cc)
     fd.close()
 
 elif options.full_help:
@@ -166,12 +166,12 @@ else:
                 options.dry_run, not options.ignore_bad_tags, cc_file,
                 in_reply_to=options.in_reply_to, thread=options.thread)
     else:
-        print col.Color(col.RED, "Not sending emails due to errors/warnings")
+        print(col.Color(col.RED, "Not sending emails due to errors/warnings"))
 
     # For a dry run, just show our actions as a sanity check
     if options.dry_run:
         series.ShowActions(args, cmd, options.process_tags)
         if not its_a_go:
-            print col.Color(col.RED, "Email would not be sent")
+            print(col.Color(col.RED, "Email would not be sent"))
 
     os.remove(cc_file)

+ 22 - 20
tools/patman/series.py

@@ -3,6 +3,8 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
+from __future__ import print_function
+
 import itertools
 import os
 
@@ -101,38 +103,38 @@ class Series(dict):
         cc_set = set(gitutil.BuildEmailList(self.cc));
 
         col = terminal.Color()
-        print 'Dry run, so not doing much. But I would do this:'
-        print
-        print 'Send a total of %d patch%s with %scover letter.' % (
+        print('Dry run, so not doing much. But I would do this:')
+        print()
+        print('Send a total of %d patch%s with %scover letter.' % (
                 len(args), '' if len(args) == 1 else 'es',
-                self.get('cover') and 'a ' or 'no ')
+                self.get('cover') and 'a ' or 'no '))
 
         # TODO: Colour the patches according to whether they passed checks
         for upto in range(len(args)):
             commit = self.commits[upto]
-            print col.Color(col.GREEN, '   %s' % args[upto])
+            print(col.Color(col.GREEN, '   %s' % args[upto]))
             cc_list = list(self._generated_cc[commit.patch])
             for email in set(cc_list) - to_set - cc_set:
                 if email == None:
                     email = col.Color(col.YELLOW, "<alias '%s' not found>"
                             % tag)
                 if email:
-                    print '      Cc: ',email
+                    print('      Cc: ', email)
         print
         for item in to_set:
-            print 'To:\t ', item
+            print('To:\t ', item)
         for item in cc_set - to_set:
-            print 'Cc:\t ', item
-        print 'Version: ', self.get('version')
-        print 'Prefix:\t ', self.get('prefix')
+            print('Cc:\t ', item)
+        print('Version: ', self.get('version'))
+        print('Prefix:\t ', self.get('prefix'))
         if self.cover:
-            print 'Cover: %d lines' % len(self.cover)
+            print('Cover: %d lines' % len(self.cover))
             cover_cc = gitutil.BuildEmailList(self.get('cover_cc', ''))
             all_ccs = itertools.chain(cover_cc, *self._generated_cc.values())
             for email in set(all_ccs) - to_set - cc_set:
-                    print '      Cc: ',email
+                    print('      Cc: ', email)
         if cmd:
-            print 'Git command: %s' % cmd
+            print('Git command: %s' % cmd)
 
     def MakeChangeLog(self, commit):
         """Create a list of changes for each version.
@@ -191,13 +193,13 @@ class Series(dict):
                 else:
                     if version > 1:
                         str = 'Change log missing for v%d' % version
-                        print col.Color(col.RED, str)
+                        print(col.Color(col.RED, str))
             for version in changes_copy:
                 str = 'Change log for unknown version v%d' % version
-                print col.Color(col.RED, str)
+                print(col.Color(col.RED, str))
         elif self.changes:
             str = 'Change log exists, but no version is set'
-            print col.Color(col.RED, str)
+            print(col.Color(col.RED, str))
 
     def MakeCcFile(self, process_tags, cover_fname, raise_on_error,
                    add_maintainers):
@@ -225,15 +227,15 @@ class Series(dict):
                                                raise_on_error=raise_on_error)
             list += gitutil.BuildEmailList(commit.cc_list,
                                            raise_on_error=raise_on_error)
-	    if add_maintainers:
+            if add_maintainers:
                 list += get_maintainer.GetMaintainer(commit.patch)
             all_ccs += list
-            print >>fd, commit.patch, ', '.join(set(list))
+            print(commit.patch, ', '.join(set(list)), file=fd)
             self._generated_cc[commit.patch] = list
 
         if cover_fname:
             cover_cc = gitutil.BuildEmailList(self.get('cover_cc', ''))
-            print >>fd, cover_fname, ', '.join(set(cover_cc + all_ccs))
+            print(cover_fname, ', '.join(set(cover_cc + all_ccs)), file=fd)
 
         fd.close()
         return fname
@@ -259,7 +261,7 @@ class Series(dict):
         """
         git_prefix = gitutil.GetDefaultSubjectPrefix()
         if git_prefix:
-	    git_prefix = '%s][' % git_prefix
+            git_prefix = '%s][' % git_prefix
         else:
             git_prefix = ''
 

+ 23 - 14
tools/patman/settings.py

@@ -3,7 +3,13 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
-import ConfigParser
+from __future__ import print_function
+
+try:
+    import configparser as ConfigParser
+except:
+    import ConfigParser
+
 import os
 import re
 
@@ -30,7 +36,10 @@ class _ProjectConfigParser(ConfigParser.SafeConfigParser):
     - Merge general default settings/aliases with project-specific ones.
 
     # Sample config used for tests below...
-    >>> import StringIO
+    >>> try:
+    ...     from StringIO import StringIO
+    ... except ImportError:
+    ...     from io import StringIO
     >>> sample_config = '''
     ... [alias]
     ... me: Peter P. <likesspiders@example.com>
@@ -48,25 +57,25 @@ class _ProjectConfigParser(ConfigParser.SafeConfigParser):
 
     # Check to make sure that bogus project gets general alias.
     >>> config = _ProjectConfigParser("zzz")
-    >>> config.readfp(StringIO.StringIO(sample_config))
+    >>> config.readfp(StringIO(sample_config))
     >>> config.get("alias", "enemies")
     'Evil <evil@example.com>'
 
     # Check to make sure that alias gets overridden by project.
     >>> config = _ProjectConfigParser("sm")
-    >>> config.readfp(StringIO.StringIO(sample_config))
+    >>> config.readfp(StringIO(sample_config))
     >>> config.get("alias", "enemies")
     'Green G. <ugly@example.com>'
 
     # Check to make sure that settings get merged with project.
     >>> config = _ProjectConfigParser("linux")
-    >>> config.readfp(StringIO.StringIO(sample_config))
+    >>> config.readfp(StringIO(sample_config))
     >>> sorted(config.items("settings"))
     [('am_hero', 'True'), ('process_tags', 'False')]
 
     # Check to make sure that settings works with unknown project.
     >>> config = _ProjectConfigParser("unknown")
-    >>> config.readfp(StringIO.StringIO(sample_config))
+    >>> config.readfp(StringIO(sample_config))
     >>> sorted(config.items("settings"))
     [('am_hero', 'True')]
     """
@@ -88,7 +97,7 @@ class _ProjectConfigParser(ConfigParser.SafeConfigParser):
         if not self.has_section(project_settings):
             self.add_section(project_settings)
         project_defaults = _default_settings.get(project_name, {})
-        for setting_name, setting_value in project_defaults.iteritems():
+        for setting_name, setting_value in project_defaults.items():
             self.set(project_settings, setting_name, setting_value)
 
     def get(self, section, option, *args, **kwargs):
@@ -156,7 +165,7 @@ def ReadGitAliases(fname):
     try:
         fd = open(fname, 'r')
     except IOError:
-        print "Warning: Cannot find alias file '%s'" % fname
+        print("Warning: Cannot find alias file '%s'" % fname)
         return
 
     re_line = re.compile('alias\s+(\S+)\s+(.*)')
@@ -167,7 +176,7 @@ def ReadGitAliases(fname):
 
         m = re_line.match(line)
         if not m:
-            print "Warning: Alias file line '%s' not understood" % line
+            print("Warning: Alias file line '%s' not understood" % line)
             continue
 
         list = alias.get(m.group(1), [])
@@ -200,10 +209,10 @@ def CreatePatmanConfigFile(config_fname):
     try:
         f = open(config_fname, 'w')
     except IOError:
-        print "Couldn't create patman config file\n"
+        print("Couldn't create patman config file\n")
         raise
 
-    print >>f, "[alias]\nme: %s <%s>" % (name, email)
+    print("[alias]\nme: %s <%s>" % (name, email), file=f)
     f.close();
 
 def _UpdateDefaults(parser, config):
@@ -233,7 +242,7 @@ def _UpdateDefaults(parser, config):
                 val = config.getint('settings', name)
             parser.set_default(name, val)
         else:
-            print "WARNING: Unknown setting %s" % name
+            print("WARNING: Unknown setting %s" % name)
 
 def _ReadAliasFile(fname):
     """Read in the U-Boot git alias file if it exists.
@@ -258,7 +267,7 @@ def _ReadAliasFile(fname):
                     continue
                 alias[words[1]] = [s.strip() for s in words[2].split(',')]
         if bad_line:
-            print bad_line
+            print(bad_line)
 
 def Setup(parser, project_name, config_fname=''):
     """Set up the settings module by reading config files.
@@ -276,7 +285,7 @@ def Setup(parser, project_name, config_fname=''):
         config_fname = '%s/.patman' % os.getenv('HOME')
 
     if not os.path.exists(config_fname):
-        print "No config file found ~/.patman\nCreating one...\n"
+        print("No config file found ~/.patman\nCreating one...\n")
         CreatePatmanConfigFile(config_fname)
 
     config.read(config_fname)

+ 9 - 5
tools/patman/terminal.py

@@ -8,6 +8,8 @@
 This module handles terminal interaction including ANSI color codes.
 """
 
+from __future__ import print_function
+
 import os
 import sys
 
@@ -52,9 +54,11 @@ def Print(text='', newline=True, colour=None):
         if colour:
             col = Color()
             text = col.Color(colour, text)
-        print text,
+        print(text, end='')
         if newline:
-            print
+            print()
+        else:
+            sys.stdout.flush()
 
 def SetPrintTestMode():
     """Go into test mode, where all printing is recorded"""
@@ -79,11 +83,11 @@ def EchoPrintTestLines():
     for line in print_test_list:
         if line.colour:
             col = Color()
-            print col.Color(line.colour, line.text),
+            print(col.Color(line.colour, line.text), end='')
         else:
-            print line.text,
+            print(line.text, end='')
         if line.newline:
-            print
+            print()
 
 
 class Color(object):

+ 1 - 1
tools/patman/test.py

@@ -181,7 +181,7 @@ index 0000000..2234c87
         elif data_type == 'indent':
             indent = tab
         else:
-            print 'not implemented'
+            print('not implemented')
         return data % (signoff, tab, indent, tab)
 
     def SetupData(self, data_type):