diff options
| author | Tom Rini <trini@konsulko.com> | 2018-11-23 17:25:27 -0500 | 
|---|---|---|
| committer | Tom Rini <trini@konsulko.com> | 2018-11-23 17:25:27 -0500 | 
| commit | 5830791d91d1200854ef78fcb32f808c8080f0f0 (patch) | |
| tree | c9ec3c59244371d8ad9992a2ba332a7b50d33950 /drivers | |
| parent | a3e1653ddeb02f39481eba572275016171e9670c (diff) | |
| parent | a58986ca8b53d8c7a441397082f84edc7f47d19f (diff) | |
Merge tag 'pull-tg18' of git://git.denx.de/u-boot-dm
Various minor sandbox improvements
Better buildman warning handling
Misc other things
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/clk/clk_vexpress_osc.c | 4 | ||||
| -rw-r--r-- | drivers/core/dump.c | 8 | ||||
| -rw-r--r-- | drivers/misc/altera_sysid.c | 2 | ||||
| -rw-r--r-- | drivers/misc/cros_ec.c | 370 | ||||
| -rw-r--r-- | drivers/misc/cros_ec_sandbox.c | 2 | ||||
| -rw-r--r-- | drivers/misc/misc_sandbox.c | 4 | ||||
| -rw-r--r-- | drivers/misc/rockchip-efuse.c | 2 | ||||
| -rw-r--r-- | drivers/misc/stm32mp_fuse.c | 12 | ||||
| -rw-r--r-- | drivers/mtd/spi/sandbox.c | 10 | ||||
| -rw-r--r-- | drivers/mtd/spi/sf-uclass.c | 9 | ||||
| -rw-r--r-- | drivers/mtd/spi/sf_internal.h | 3 | ||||
| -rw-r--r-- | drivers/mtd/spi/sf_probe.c | 8 | ||||
| -rw-r--r-- | drivers/mtd/spi/spi_flash.c | 12 | ||||
| -rw-r--r-- | drivers/pci/pci-uclass.c | 11 | ||||
| -rw-r--r-- | drivers/spi/spi-uclass.c | 15 | ||||
| -rw-r--r-- | drivers/tpm/tpm_tis_sandbox.c | 6 | ||||
| -rw-r--r-- | drivers/video/vidconsole-uclass.c | 2 | ||||
| -rw-r--r-- | drivers/video/video-uclass.c | 27 | 
18 files changed, 466 insertions, 41 deletions
| diff --git a/drivers/clk/clk_vexpress_osc.c b/drivers/clk/clk_vexpress_osc.c index 7fef4b2e312..c692a6d0b89 100644 --- a/drivers/clk/clk_vexpress_osc.c +++ b/drivers/clk/clk_vexpress_osc.c @@ -29,7 +29,7 @@ static ulong vexpress_osc_clk_get_rate(struct clk *clk)  	data = CLK_FUNCTION | priv->osc;  	err = misc_read(vexpress_cfg, 0, &data, sizeof(data)); -	if (err) +	if (err < 0)  		return err;  	return data; @@ -53,7 +53,7 @@ static ulong vexpress_osc_clk_set_rate(struct clk *clk, ulong rate)  	buffer[0] = CLK_FUNCTION | priv->osc;  	buffer[1] = rate;  	err = misc_write(vexpress_cfg, 0, buffer, 2 * sizeof(u32)); -	if (err) +	if (err < 0)  		return err;  	return rate; diff --git a/drivers/core/dump.c b/drivers/core/dump.c index 90680844043..04217cbde87 100644 --- a/drivers/core/dump.c +++ b/drivers/core/dump.c @@ -15,8 +15,8 @@ static void show_devices(struct udevice *dev, int depth, int last_flag)  	int i, is_last;  	struct udevice *child; -	/* print the first 11 characters to not break the tree-format. */ -	printf(" %-10.10s  %d  [ %c ]   %-10.10s  ", dev->uclass->uc_drv->name, +	/* print the first 20 characters to not break the tree-format. */ +	printf(" %-10.10s  %d  [ %c ]   %-20.20s  ", dev->uclass->uc_drv->name,  	       dev_get_uclass_index(dev, NULL),  	       dev->flags & DM_FLAG_ACTIVATED ? '+' : ' ', dev->driver->name); @@ -49,8 +49,8 @@ void dm_dump_all(void)  	root = dm_root();  	if (root) { -		printf(" Class    index  Probed  Driver      Name\n"); -		printf("-----------------------------------------\n"); +		printf(" Class    index  Probed  Driver                Name\n"); +		printf("-----------------------------------------------------------\n");  		show_devices(root, -1, 0);  	}  } diff --git a/drivers/misc/altera_sysid.c b/drivers/misc/altera_sysid.c index 883b2a35e07..eff33f7343d 100644 --- a/drivers/misc/altera_sysid.c +++ b/drivers/misc/altera_sysid.c @@ -35,7 +35,7 @@ void display_sysid(void)  	if (ret)  		return;  	ret = misc_read(dev, 0, &sysid, sizeof(sysid)); -	if (ret) +	if (ret < 0)  		return;  	stamp = sysid[1]; diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c index 190505c11c7..2dcdb3d8d61 100644 --- a/drivers/misc/cros_ec.c +++ b/drivers/misc/cros_ec.c @@ -13,6 +13,8 @@   * is not reset.   */ +#define LOG_CATEGORY UCLASS_CROS_EC +  #include <common.h>  #include <command.h>  #include <dm.h> @@ -41,6 +43,54 @@ enum {  	CROS_EC_CMD_HASH_TIMEOUT_MS = 2000,  }; +#define INVALID_HCMD 0xFF + +/* + * Map UHEPI masks to non UHEPI commands in order to support old EC FW + * which does not support UHEPI command. + */ +static const struct { +	u8 set_cmd; +	u8 clear_cmd; +	u8 get_cmd; +} event_map[] = { +	[EC_HOST_EVENT_MAIN] = { +		INVALID_HCMD, EC_CMD_HOST_EVENT_CLEAR, +		INVALID_HCMD, +	}, +	[EC_HOST_EVENT_B] = { +		INVALID_HCMD, EC_CMD_HOST_EVENT_CLEAR_B, +		EC_CMD_HOST_EVENT_GET_B, +	}, +	[EC_HOST_EVENT_SCI_MASK] = { +		EC_CMD_HOST_EVENT_SET_SCI_MASK, INVALID_HCMD, +		EC_CMD_HOST_EVENT_GET_SCI_MASK, +	}, +	[EC_HOST_EVENT_SMI_MASK] = { +		EC_CMD_HOST_EVENT_SET_SMI_MASK, INVALID_HCMD, +		EC_CMD_HOST_EVENT_GET_SMI_MASK, +	}, +	[EC_HOST_EVENT_ALWAYS_REPORT_MASK] = { +		INVALID_HCMD, INVALID_HCMD, INVALID_HCMD, +	}, +	[EC_HOST_EVENT_ACTIVE_WAKE_MASK] = { +		EC_CMD_HOST_EVENT_SET_WAKE_MASK, INVALID_HCMD, +		EC_CMD_HOST_EVENT_GET_WAKE_MASK, +	}, +	[EC_HOST_EVENT_LAZY_WAKE_MASK_S0IX] = { +		EC_CMD_HOST_EVENT_SET_WAKE_MASK, INVALID_HCMD, +		EC_CMD_HOST_EVENT_GET_WAKE_MASK, +	}, +	[EC_HOST_EVENT_LAZY_WAKE_MASK_S3] = { +		EC_CMD_HOST_EVENT_SET_WAKE_MASK, INVALID_HCMD, +		EC_CMD_HOST_EVENT_GET_WAKE_MASK, +	}, +	[EC_HOST_EVENT_LAZY_WAKE_MASK_S5] = { +		EC_CMD_HOST_EVENT_SET_WAKE_MASK, INVALID_HCMD, +		EC_CMD_HOST_EVENT_GET_WAKE_MASK, +	}, +}; +  void cros_ec_dump_data(const char *name, int cmd, const uint8_t *data, int len)  {  #ifdef DEBUG @@ -227,7 +277,7 @@ static int send_command_proto3(struct cros_ec_dev *cdev,  	return handle_proto3_response(cdev, dinp, din_len);  } -static int send_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, +static int send_command(struct cros_ec_dev *dev, uint cmd, int cmd_version,  			const void *dout, int dout_len,  			uint8_t **dinp, int din_len)  { @@ -330,7 +380,7 @@ static int ec_command_inptr(struct udevice *dev, uint8_t cmd,   * @param din_len       Maximum size of response in bytes   * @return number of bytes in response, or -ve on error   */ -static int ec_command(struct udevice *dev, uint8_t cmd, int cmd_version, +static int ec_command(struct udevice *dev, uint cmd, int cmd_version,  		      const void *dout, int dout_len,  		      void *din, int din_len)  { @@ -365,10 +415,14 @@ int cros_ec_scan_keyboard(struct udevice *dev, struct mbkp_keyscan *scan)  int cros_ec_read_id(struct udevice *dev, char *id, int maxlen)  {  	struct ec_response_get_version *r; +	int ret; -	if (ec_command_inptr(dev, EC_CMD_GET_VERSION, 0, NULL, 0, -			(uint8_t **)&r, sizeof(*r)) != sizeof(*r)) +	ret = ec_command_inptr(dev, EC_CMD_GET_VERSION, 0, NULL, 0, +			       (uint8_t **)&r, sizeof(*r)); +	if (ret != sizeof(*r)) { +		log_err("Got rc %d, expected %d\n", ret, sizeof(*r));  		return -1; +	}  	if (maxlen > (int)sizeof(r->version_string_ro))  		maxlen = sizeof(r->version_string_ro); @@ -381,6 +435,7 @@ int cros_ec_read_id(struct udevice *dev, char *id, int maxlen)  		memcpy(id, r->version_string_rw, maxlen);  		break;  	default: +		log_err("Invalid EC image %d\n", r->current_image);  		return -1;  	} @@ -563,6 +618,36 @@ int cros_ec_info(struct udevice *dev, struct ec_response_mkbp_info *info)  	return 0;  } +int cros_ec_get_event_mask(struct udevice *dev, uint type, uint32_t *mask) +{ +	struct ec_response_host_event_mask rsp; +	int ret; + +	ret = ec_command(dev, type, 0, NULL, 0, &rsp, sizeof(rsp)); +	if (ret < 0) +		return ret; +	else if (ret != sizeof(rsp)) +		return -EINVAL; + +	*mask = rsp.mask; + +	return 0; +} + +int cros_ec_set_event_mask(struct udevice *dev, uint type, uint32_t mask) +{ +	struct ec_params_host_event_mask req; +	int ret; + +	req.mask = mask; + +	ret = ec_command(dev, type, 0, &req, sizeof(req), NULL, 0); +	if (ret < 0) +		return ret; + +	return 0; +} +  int cros_ec_get_host_events(struct udevice *dev, uint32_t *events_ptr)  {  	struct ec_response_host_event_mask *resp; @@ -616,6 +701,17 @@ int cros_ec_flash_protect(struct udevice *dev, uint32_t set_mask,  	return 0;  } +int cros_ec_entering_mode(struct udevice *dev, int mode) +{ +	int rc; + +	rc = ec_command(dev, EC_CMD_ENTERING_MODE, 0, &mode, sizeof(mode), +			NULL, 0); +	if (rc) +		return -1; +	return 0; +} +  static int cros_ec_check_version(struct udevice *dev)  {  	struct cros_ec_dev *cdev = dev_get_uclass_priv(dev); @@ -650,16 +746,14 @@ static int cros_ec_check_version(struct udevice *dev)  	cdev->protocol_version = 3;  	req.in_data = 0;  	if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req), -			     (uint8_t **)&resp, sizeof(*resp)) > 0) { +			     (uint8_t **)&resp, sizeof(*resp)) > 0)  		return 0; -	}  	/* Try sending a version 2 packet */  	cdev->protocol_version = 2;  	if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req), -			     (uint8_t **)&resp, sizeof(*resp)) > 0) { +			     (uint8_t **)&resp, sizeof(*resp)) > 0)  		return 0; -	}  	/*  	 * Fail if we're still here, since the EC doesn't understand any @@ -822,6 +916,9 @@ int cros_ec_flash_write(struct udevice *dev, const uint8_t *data,  	uint32_t end, off;  	int ret; +	if (!burst) +		return -EINVAL; +  	/*  	 * TODO: round up to the nearest multiple of write size.  Can get away  	 * without that on link right now because its write size is 4 bytes. @@ -845,6 +942,35 @@ int cros_ec_flash_write(struct udevice *dev, const uint8_t *data,  }  /** + * Run verification on a slot + * + * @param me     CrosEc instance + * @param region Region to run verification on + * @return 0 if success or not applicable. Non-zero if verification failed. + */ +int cros_ec_efs_verify(struct udevice *dev, enum ec_flash_region region) +{ +	struct ec_params_efs_verify p; +	int rv; + +	log_info("EFS: EC is verifying updated image...\n"); +	p.region = region; + +	rv = ec_command(dev, EC_CMD_EFS_VERIFY, 0, &p, sizeof(p), NULL, 0); +	if (rv >= 0) { +		log_info("EFS: Verification success\n"); +		return 0; +	} +	if (rv == -EC_RES_INVALID_COMMAND) { +		log_info("EFS: EC doesn't support EFS_VERIFY command\n"); +		return 0; +	} +	log_info("EFS: Verification failed\n"); + +	return rv; +} + +/**   * Read a single block from the flash   *   * Read a block of data from the EC flash. The size must not exceed the flash @@ -934,15 +1060,17 @@ int cros_ec_read_nvdata(struct udevice *dev, uint8_t *block, int size)  	struct ec_params_vbnvcontext p;  	int len; -	if (size != EC_VBNV_BLOCK_SIZE) +	if (size != EC_VBNV_BLOCK_SIZE && size != EC_VBNV_BLOCK_SIZE_V2)  		return -EINVAL;  	p.op = EC_VBNV_CONTEXT_OP_READ;  	len = ec_command(dev, EC_CMD_VBNV_CONTEXT, EC_VER_VBNV_CONTEXT, -			&p, sizeof(p), block, EC_VBNV_BLOCK_SIZE); -	if (len < EC_VBNV_BLOCK_SIZE) +			 &p, sizeof(uint32_t) + size, block, size); +	if (len != size) { +		log_err("Expected %d bytes, got %d\n", size, len);  		return -EIO; +	}  	return 0;  } @@ -952,19 +1080,33 @@ int cros_ec_write_nvdata(struct udevice *dev, const uint8_t *block, int size)  	struct ec_params_vbnvcontext p;  	int len; -	if (size != EC_VBNV_BLOCK_SIZE) +	if (size != EC_VBNV_BLOCK_SIZE && size != EC_VBNV_BLOCK_SIZE_V2)  		return -EINVAL;  	p.op = EC_VBNV_CONTEXT_OP_WRITE; -	memcpy(p.block, block, sizeof(p.block)); +	memcpy(p.block, block, size);  	len = ec_command_inptr(dev, EC_CMD_VBNV_CONTEXT, EC_VER_VBNV_CONTEXT, -			&p, sizeof(p), NULL, 0); +			&p, sizeof(uint32_t) + size, NULL, 0);  	if (len < 0)  		return -1;  	return 0;  } +int cros_ec_battery_cutoff(struct udevice *dev, uint8_t flags) +{ +	struct ec_params_battery_cutoff p; +	int len; + +	p.flags = flags; +	len = ec_command(dev, EC_CMD_BATTERY_CUT_OFF, 1, &p, sizeof(p), +			 NULL, 0); + +	if (len < 0) +		return -1; +	return 0; +} +  int cros_ec_set_ldo(struct udevice *dev, uint8_t index, uint8_t state)  {  	struct ec_params_ldo_set params; @@ -1139,9 +1281,209 @@ int cros_ec_i2c_tunnel(struct udevice *dev, int port, struct i2c_msg *in,  	return 0;  } +int cros_ec_check_feature(struct udevice *dev, int feature) +{ +	struct ec_response_get_features r; +	int rv; + +	rv = ec_command(dev, EC_CMD_GET_FEATURES, 0, &r, sizeof(r), NULL, 0); +	if (rv) +		return rv; + +	if (feature >= 8 * sizeof(r.flags)) +		return -1; + +	return r.flags[feature / 32] & EC_FEATURE_MASK_0(feature); +} + +/* + * Query the EC for specified mask indicating enabled events. + * The EC maintains separate event masks for SMI, SCI and WAKE. + */ +static int cros_ec_uhepi_cmd(struct udevice *dev, uint mask, uint action, +			     uint64_t *value) +{ +	int ret; +	struct ec_params_host_event req; +	struct ec_response_host_event rsp; + +	req.action = action; +	req.mask_type = mask; +	if (action != EC_HOST_EVENT_GET) +		req.value = *value; +	else +		*value = 0; +	ret = ec_command(dev, EC_CMD_HOST_EVENT, 0, &req, sizeof(req), &rsp, +			 sizeof(rsp)); + +	if (action != EC_HOST_EVENT_GET) +		return ret; +	if (ret == 0) +		*value = rsp.value; + +	return ret; +} + +static int cros_ec_handle_non_uhepi_cmd(struct udevice *dev, uint hcmd, +					uint action, uint64_t *value) +{ +	int ret = -1; +	struct ec_params_host_event_mask req; +	struct ec_response_host_event_mask rsp; + +	if (hcmd == INVALID_HCMD) +		return ret; + +	if (action != EC_HOST_EVENT_GET) +		req.mask = (uint32_t)*value; +	else +		*value = 0; + +	ret = ec_command(dev, hcmd, 0, &req, sizeof(req), &rsp, sizeof(rsp)); +	if (action != EC_HOST_EVENT_GET) +		return ret; +	if (ret == 0) +		*value = rsp.mask; + +	return ret; +} + +bool cros_ec_is_uhepi_supported(struct udevice *dev) +{ +#define UHEPI_SUPPORTED 1 +#define UHEPI_NOT_SUPPORTED 2 +	static int uhepi_support; + +	if (!uhepi_support) { +		uhepi_support = cros_ec_check_feature(dev, +			EC_FEATURE_UNIFIED_WAKE_MASKS) > 0 ? UHEPI_SUPPORTED : +			UHEPI_NOT_SUPPORTED; +		log_debug("Chrome EC: UHEPI %s\n", +			  uhepi_support == UHEPI_SUPPORTED ? "supported" : +			  "not supported"); +	} +	return uhepi_support == UHEPI_SUPPORTED; +} + +static int cros_ec_get_mask(struct udevice *dev, uint type) +{ +	u64 value = 0; + +	if (cros_ec_is_uhepi_supported(dev)) { +		cros_ec_uhepi_cmd(dev, type, EC_HOST_EVENT_GET, &value); +	} else { +		assert(type < ARRAY_SIZE(event_map)); +		cros_ec_handle_non_uhepi_cmd(dev, event_map[type].get_cmd, +					     EC_HOST_EVENT_GET, &value); +	} +	return value; +} + +static int cros_ec_clear_mask(struct udevice *dev, uint type, u64 mask) +{ +	if (cros_ec_is_uhepi_supported(dev)) +		return cros_ec_uhepi_cmd(dev, type, EC_HOST_EVENT_CLEAR, &mask); + +	assert(type < ARRAY_SIZE(event_map)); + +	return cros_ec_handle_non_uhepi_cmd(dev, event_map[type].clear_cmd, +					    EC_HOST_EVENT_CLEAR, &mask); +} + +uint64_t cros_ec_get_events_b(struct udevice *dev) +{ +	return cros_ec_get_mask(dev, EC_HOST_EVENT_B); +} + +int cros_ec_clear_events_b(struct udevice *dev, uint64_t mask) +{ +	log_debug("Chrome EC: clear events_b mask to 0x%016llx\n", mask); + +	return cros_ec_clear_mask(dev, EC_HOST_EVENT_B, mask); +} + +int cros_ec_read_limit_power(struct udevice *dev, int *limit_powerp) +{ +	struct ec_params_charge_state p; +	struct ec_response_charge_state r; +	int ret; + +	p.cmd = CHARGE_STATE_CMD_GET_PARAM; +	p.get_param.param = CS_PARAM_LIMIT_POWER; +	ret = ec_command(dev, EC_CMD_CHARGE_STATE, 0, &p, sizeof(p), +			 &r, sizeof(r)); + +	/* +	 * If our EC doesn't support the LIMIT_POWER parameter, assume that +	 * LIMIT_POWER is not requested. +	 */ +	if (ret == -EC_RES_INVALID_PARAM || ret == -EC_RES_INVALID_COMMAND) { +		log_warning("PARAM_LIMIT_POWER not supported by EC\n"); +		return -ENOSYS; +	} + +	if (ret != sizeof(r.get_param)) +		return -EINVAL; + +	*limit_powerp = r.get_param.value; +	return 0; +} + +int cros_ec_config_powerbtn(struct udevice *dev, uint32_t flags) +{ +	struct ec_params_config_power_button params; +	int ret; + +	params.flags = flags; +	ret = ec_command(dev, EC_CMD_CONFIG_POWER_BUTTON, 0, +			 ¶ms, sizeof(params), NULL, 0); +	if (ret < 0) +		return ret; + +	return 0; +} + +int cros_ec_get_lid_shutdown_mask(struct udevice *dev) +{ +	u32 mask; +	int ret; + +	ret = cros_ec_get_event_mask(dev, EC_CMD_HOST_EVENT_GET_SMI_MASK, +				     &mask); +	if (ret < 0) +		return ret; + +	return !!(mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED)); +} + +int cros_ec_set_lid_shutdown_mask(struct udevice *dev, int enable) +{ +	u32 mask; +	int ret; + +	ret = cros_ec_get_event_mask(dev, EC_CMD_HOST_EVENT_GET_SMI_MASK, +				     &mask); +	if (ret < 0) +		return ret; + +	// Set lid close event state in the EC SMI event mask +	if (enable) +		mask |= EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED); +	else +		mask &= ~EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED); + +	ret = cros_ec_set_event_mask(dev, EC_CMD_HOST_EVENT_SET_SMI_MASK, mask); +	if (ret < 0) +		return ret; + +	printf("EC: %sabled lid close event\n", enable ? "en" : "dis"); +	return 0; +} +  UCLASS_DRIVER(cros_ec) = {  	.id		= UCLASS_CROS_EC,  	.name		= "cros_ec",  	.per_device_auto_alloc_size = sizeof(struct cros_ec_dev),  	.post_bind	= dm_scan_fdt_dev, +	.flags		= DM_UC_FLAG_ALLOC_PRIV_DMA,  }; diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c index d741554d8a6..429f1a9b269 100644 --- a/drivers/misc/cros_ec_sandbox.c +++ b/drivers/misc/cros_ec_sandbox.c @@ -74,7 +74,7 @@ struct ec_keymatrix_entry {   * @recovery_req: Keyboard recovery requested   */  struct ec_state { -	uint8_t vbnv_context[EC_VBNV_BLOCK_SIZE]; +	u8 vbnv_context[EC_VBNV_BLOCK_SIZE_V2];  	struct fdt_cros_ec ec_config;  	uint8_t *flash_data;  	int flash_data_len; diff --git a/drivers/misc/misc_sandbox.c b/drivers/misc/misc_sandbox.c index e4164f76fba..f7c5b2e25fa 100644 --- a/drivers/misc/misc_sandbox.c +++ b/drivers/misc/misc_sandbox.c @@ -20,7 +20,7 @@ int misc_sandbox_read(struct udevice *dev, int offset, void *buf, int size)  	memcpy(buf, priv->mem + offset, size); -	return 0; +	return size;  }  int misc_sandbox_write(struct udevice *dev, int offset, const void *buf, @@ -30,7 +30,7 @@ int misc_sandbox_write(struct udevice *dev, int offset, const void *buf,  	memcpy(priv->mem + offset, buf, size); -	return 0; +	return size;  }  int misc_sandbox_ioctl(struct udevice *dev, unsigned long request, void *buf) diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c index 8a213c9e270..2520c6a38ed 100644 --- a/drivers/misc/rockchip-efuse.c +++ b/drivers/misc/rockchip-efuse.c @@ -65,7 +65,7 @@ static int dump_efuses(cmd_tbl_t *cmdtp, int flag,  	}  	ret = misc_read(dev, 0, &fuses, sizeof(fuses)); -	if (ret) { +	if (ret < 0) {  		printf("%s: misc_read failed\n", __func__);  		return 0;  	} diff --git a/drivers/misc/stm32mp_fuse.c b/drivers/misc/stm32mp_fuse.c index 2d661351a17..33943a231b1 100644 --- a/drivers/misc/stm32mp_fuse.c +++ b/drivers/misc/stm32mp_fuse.c @@ -29,6 +29,9 @@ int fuse_read(u32 bank, u32 word, u32 *val)  			return ret;  		ret = misc_read(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET,  				val, 4); +		if (ret < 0) +			return ret; +		ret = 0;  		break;  	default: @@ -54,6 +57,9 @@ int fuse_prog(u32 bank, u32 word, u32 val)  			return ret;  		ret = misc_write(dev, word * 4 + STM32_BSEC_OTP_OFFSET,  				 &val, 4); +		if (ret < 0) +			return ret; +		ret = 0;  		break;  	default: @@ -78,6 +84,9 @@ int fuse_sense(u32 bank, u32 word, u32 *val)  		if (ret)  			return ret;  		ret = misc_read(dev, word * 4 + STM32_BSEC_OTP_OFFSET, val, 4); +		if (ret < 0) +			return ret; +		ret = 0;  		break;  	default: @@ -103,6 +112,9 @@ int fuse_override(u32 bank, u32 word, u32 val)  			return ret;  		ret = misc_write(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET,  				 &val, 4); +		if (ret < 0) +			return ret; +		ret = 0;  		break;  	default: diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c index 7fef754c634..7b9891cb981 100644 --- a/drivers/mtd/spi/sandbox.c +++ b/drivers/mtd/spi/sandbox.c @@ -57,6 +57,8 @@ static const char *sandbox_sf_state_name(enum sandbox_sf_state state)  /* Bits for the status register */  #define STAT_WIP	(1 << 0)  #define STAT_WEL	(1 << 1) +#define STAT_BP_SHIFT	2 +#define STAT_BP_MASK	(7 << STAT_BP_SHIFT)  /* Assume all SPI flashes have 3 byte addresses since they do atm */  #define SF_ADDR_LEN	3 @@ -102,6 +104,14 @@ struct sandbox_spi_flash_plat_data {  	int cs;  }; +void sandbox_sf_set_block_protect(struct udevice *dev, int bp_mask) +{ +	struct sandbox_spi_flash *sbsf = dev_get_priv(dev); + +	sbsf->status &= ~STAT_BP_MASK; +	sbsf->status |= bp_mask << STAT_BP_SHIFT; +} +  /**   * This is a very strange probe function. If it has platform data (which may   * have come from the device tree) then this function gets the filename and diff --git a/drivers/mtd/spi/sf-uclass.c b/drivers/mtd/spi/sf-uclass.c index 662525f016f..719a2fd23ae 100644 --- a/drivers/mtd/spi/sf-uclass.c +++ b/drivers/mtd/spi/sf-uclass.c @@ -28,6 +28,15 @@ int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len)  	return log_ret(sf_get_ops(dev)->erase(dev, offset, len));  } +int spl_flash_get_sw_write_prot(struct udevice *dev) +{ +	struct dm_spi_flash_ops *ops = sf_get_ops(dev); + +	if (!ops->get_sw_write_prot) +		return -ENOSYS; +	return log_ret(ops->get_sw_write_prot(dev)); +} +  /*   * TODO(sjg@chromium.org): This is an old-style function. We should remove   * it when all SPI flash drivers use dm diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index 26f5c7c995e..46a50444175 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -170,6 +170,9 @@ int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len,  /* Flash erase(sectors) operation, support all possible erase commands */  int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len); +/* Get software write-protect value (BP bits) */ +int spi_flash_cmd_get_sw_write_prot(struct spi_flash *flash); +  /* Lock stmicro spi flash region */  int stm_lock(struct spi_flash *flash, u32 ofs, size_t len); diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index 94fde2ae7a3..5a2e932de8f 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -124,6 +124,13 @@ static int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len)  	return spi_flash_cmd_erase_ops(flash, offset, len);  } +static int spi_flash_std_get_sw_write_prot(struct udevice *dev) +{ +	struct spi_flash *flash = dev_get_uclass_priv(dev); + +	return spi_flash_cmd_get_sw_write_prot(flash); +} +  static int spi_flash_std_probe(struct udevice *dev)  {  	struct spi_slave *slave = dev_get_parent_priv(dev); @@ -141,6 +148,7 @@ static const struct dm_spi_flash_ops spi_flash_std_ops = {  	.read = spi_flash_std_read,  	.write = spi_flash_std_write,  	.erase = spi_flash_std_erase, +	.get_sw_write_prot = spi_flash_std_get_sw_write_prot,  };  static const struct udevice_id spi_flash_std_ids[] = { diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index a87bacd4ac7..0c2392f28a4 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -110,6 +110,18 @@ static int write_cr(struct spi_flash *flash, u8 wc)  }  #endif +int spi_flash_cmd_get_sw_write_prot(struct spi_flash *flash) +{ +	u8 status; +	int ret; + +	ret = read_sr(flash, &status); +	if (ret) +		return ret; + +	return (status >> 2) & 7; +} +  #ifdef CONFIG_SPI_FLASH_BAR  /*   * This "clean_bar" is necessary in a situation when one was accessing diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 0c52337f33a..2cf55cb743d 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -774,16 +774,19 @@ int pci_bind_bus_devices(struct udevice *bus)  			found_multi = false;  		if (PCI_FUNC(bdf) && !found_multi)  			continue; +  		/* Check only the first access, we don't expect problems */ -		ret = pci_bus_read_config(bus, bdf, PCI_HEADER_TYPE, -					  &header_type, PCI_SIZE_8); +		ret = pci_bus_read_config(bus, bdf, PCI_VENDOR_ID, &vendor, +					  PCI_SIZE_16);  		if (ret)  			goto error; -		pci_bus_read_config(bus, bdf, PCI_VENDOR_ID, &vendor, -				    PCI_SIZE_16); +  		if (vendor == 0xffff || vendor == 0x0000)  			continue; +		pci_bus_read_config(bus, bdf, PCI_HEADER_TYPE, +				    &header_type, PCI_SIZE_8); +  		if (!PCI_FUNC(bdf))  			found_multi = header_type & 0x80; diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index b84255bd274..2bc289a74cc 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -15,6 +15,8 @@  DECLARE_GLOBAL_DATA_PTR; +#define SPI_DEFAULT_SPEED_HZ 100000 +  static int spi_set_speed_mode(struct udevice *bus, int speed, int mode)  {  	struct dm_spi_ops *ops; @@ -58,7 +60,7 @@ int dm_spi_claim_bus(struct udevice *dev)  			speed = spi->max_hz;  	}  	if (!speed) -		speed = 100000; +		speed = SPI_DEFAULT_SPEED_HZ;  	if (speed != slave->speed) {  		int ret = spi_set_speed_mode(bus, speed, slave->mode); @@ -300,7 +302,13 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,  		}  		plat = dev_get_parent_platdata(dev);  		plat->cs = cs; -		plat->max_hz = speed; +		if (speed) { +			plat->max_hz = speed; +		} else { +			printf("Warning: SPI speed fallback to %u kHz\n", +			       SPI_DEFAULT_SPEED_HZ / 1000); +			plat->max_hz = SPI_DEFAULT_SPEED_HZ; +		}  		plat->mode = mode;  		created = true;  	} else if (ret) { @@ -374,7 +382,8 @@ int spi_slave_ofdata_to_platdata(struct udevice *dev,  	int value;  	plat->cs = dev_read_u32_default(dev, "reg", -1); -	plat->max_hz = dev_read_u32_default(dev, "spi-max-frequency", 0); +	plat->max_hz = dev_read_u32_default(dev, "spi-max-frequency", +					    SPI_DEFAULT_SPEED_HZ);  	if (dev_read_bool(dev, "spi-cpol"))  		mode |= SPI_CPOL;  	if (dev_read_bool(dev, "spi-cpha")) diff --git a/drivers/tpm/tpm_tis_sandbox.c b/drivers/tpm/tpm_tis_sandbox.c index 79517f015af..3336f559e57 100644 --- a/drivers/tpm/tpm_tis_sandbox.c +++ b/drivers/tpm/tpm_tis_sandbox.c @@ -187,9 +187,11 @@ static int sandbox_tpm_xfer(struct udevice *dev, const uint8_t *sendbuf,  	code = get_unaligned_be32(sendbuf + sizeof(uint16_t) +  				  sizeof(uint32_t)); +#ifdef DEBUG  	printf("tpm: %zd bytes, recv_len %zd, cmd = %x\n", send_size,  	       *recv_len, code);  	print_buffer(0, sendbuf, 1, send_size, 0); +#endif  	switch (code) {  	case TPM_CMD_GET_CAPABILITY:  		type = get_unaligned_be32(sendbuf + 14); @@ -306,6 +308,10 @@ static int sandbox_tpm_xfer(struct udevice *dev, const uint8_t *sendbuf,  		printf("Unknown tpm command %02x\n", code);  		return -ENOSYS;  	} +#ifdef DEBUG +	printf("tpm: rx recv_len %zd\n", *recv_len); +	print_buffer(0, recvbuf, 1, *recv_len, 0); +#endif  	return 0;  } diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 1874887f2f3..d7568bc79a5 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -344,7 +344,7 @@ static void vidconsole_escape_char(struct udevice *dev, char ch)  			switch (val) {  			case 0:  				/* all attributes off */ -				video_set_default_colors(vid_priv); +				video_set_default_colors(dev->parent, false);  				break;  			case 1:  				/* bold */ diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c index 44dfa71b6f4..b6551b69d3a 100644 --- a/drivers/video/video-uclass.c +++ b/drivers/video/video-uclass.c @@ -115,18 +115,29 @@ int video_clear(struct udevice *dev)  	return 0;  } -void video_set_default_colors(struct video_priv *priv) +void video_set_default_colors(struct udevice *dev, bool invert)  { +	struct video_priv *priv = dev_get_uclass_priv(dev); +	int fore, back; +  #ifdef CONFIG_SYS_WHITE_ON_BLACK  	/* White is used when switching to bold, use light gray here */ -	priv->fg_col_idx = VID_LIGHT_GRAY; -	priv->colour_fg = vid_console_color(priv, VID_LIGHT_GRAY); -	priv->colour_bg = vid_console_color(priv, VID_BLACK); +	fore = VID_LIGHT_GRAY; +	back = VID_BLACK;  #else -	priv->fg_col_idx = VID_BLACK; -	priv->colour_fg = vid_console_color(priv, VID_BLACK); -	priv->colour_bg = vid_console_color(priv, VID_WHITE); +	fore = VID_BLACK; +	back = VID_WHITE;  #endif +	if (invert) { +		int temp; + +		temp = fore; +		fore = back; +		back = temp; +	} +	priv->fg_col_idx = fore; +	priv->colour_fg = vid_console_color(priv, fore); +	priv->colour_bg = vid_console_color(priv, back);  }  /* Flush video activity to the caches */ @@ -219,7 +230,7 @@ static int video_post_probe(struct udevice *dev)  	priv->fb_size = priv->line_length * priv->ysize;  	/* Set up colors  */ -	video_set_default_colors(priv); +	video_set_default_colors(dev, false);  	if (!CONFIG_IS_ENABLED(NO_FB_CLEAR))  		video_clear(dev); | 
