mirror of
				https://review.coreboot.org/flashrom.git
				synced 2025-10-31 13:20:42 +01:00 
			
		
		
		
	pickit2_spi.c: Refactor singleton states into reentrant pattern
Move global singleton states into a struct and store within the spi_master data field for the life-time of the driver. This is one of the steps on the way to move spi_master data memory management behind the initialisation API, for more context see other patches under the same topic "register_master_api". TEST=builds BUG=b:185191942 Change-Id: Ibacc4738bee02c371c41583d321e0337128ad18a Signed-off-by: Anastasia Klimchuk <aklm@chromium.org> Reviewed-on: https://review.coreboot.org/c/flashrom/+/52774 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Nico Huber <nico.h@gmx.de> Reviewed-by: Edward O'Callaghan <quasisec@chromium.org> Reviewed-by: Angel Pons <th3fanbus@gmail.com>
This commit is contained in:
		 Anastasia Klimchuk
					Anastasia Klimchuk
				
			
				
					committed by
					
						 Nico Huber
						Nico Huber
					
				
			
			
				
	
			
			
			 Nico Huber
						Nico Huber
					
				
			
						parent
						
							e4261e3425
						
					
				
				
					commit
					4a9a66f7c8
				
			| @@ -52,7 +52,9 @@ const struct dev_entry devs_pickit2_spi[] = { | |||||||
| 	{0} | 	{0} | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static libusb_device_handle *pickit2_handle; | struct pickit2_spi_data { | ||||||
|  | 	libusb_device_handle *pickit2_handle; | ||||||
|  | }; | ||||||
|  |  | ||||||
| /* Default USB transaction timeout in ms */ | /* Default USB transaction timeout in ms */ | ||||||
| #define DFLT_TIMEOUT            10000 | #define DFLT_TIMEOUT            10000 | ||||||
| @@ -89,7 +91,7 @@ static libusb_device_handle *pickit2_handle; | |||||||
| #define SCR_VDD_OFF             0xFE | #define SCR_VDD_OFF             0xFE | ||||||
| #define SCR_VDD_ON              0xFF | #define SCR_VDD_ON              0xFF | ||||||
|  |  | ||||||
| static int pickit2_get_firmware_version(void) | static int pickit2_get_firmware_version(libusb_device_handle *pickit2_handle) | ||||||
| { | { | ||||||
| 	int ret; | 	int ret; | ||||||
| 	uint8_t command[CMD_LENGTH] = {CMD_GET_VERSION, CMD_END_OF_BUFFER}; | 	uint8_t command[CMD_LENGTH] = {CMD_GET_VERSION, CMD_END_OF_BUFFER}; | ||||||
| @@ -113,7 +115,7 @@ static int pickit2_get_firmware_version(void) | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int pickit2_set_spi_voltage(int millivolt) | static int pickit2_set_spi_voltage(libusb_device_handle *pickit2_handle, int millivolt) | ||||||
| { | { | ||||||
| 	double voltage_selector; | 	double voltage_selector; | ||||||
| 	switch (millivolt) { | 	switch (millivolt) { | ||||||
| @@ -172,7 +174,7 @@ static const struct pickit2_spispeeds spispeeds[] = { | |||||||
| 	{ NULL,		0x0 }, | 	{ NULL,		0x0 }, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static int pickit2_set_spi_speed(unsigned int spispeed_idx) | static int pickit2_set_spi_speed(libusb_device_handle *pickit2_handle, unsigned int spispeed_idx) | ||||||
| { | { | ||||||
| 	msg_pdbg("SPI speed is %sHz\n", spispeeds[spispeed_idx].name); | 	msg_pdbg("SPI speed is %sHz\n", spispeeds[spispeed_idx].name); | ||||||
|  |  | ||||||
| @@ -198,6 +200,7 @@ static int pickit2_set_spi_speed(unsigned int spispeed_idx) | |||||||
| static int pickit2_spi_send_command(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt, | static int pickit2_spi_send_command(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt, | ||||||
| 				     const unsigned char *writearr, unsigned char *readarr) | 				     const unsigned char *writearr, unsigned char *readarr) | ||||||
| { | { | ||||||
|  | 	struct pickit2_spi_data *pickit2_data = flash->mst->spi.data; | ||||||
|  |  | ||||||
| 	/* Maximum number of bytes per transaction (including command overhead) is 64. Lets play it safe | 	/* Maximum number of bytes per transaction (including command overhead) is 64. Lets play it safe | ||||||
| 	 * and always assume the worst case scenario of 20 bytes command overhead. | 	 * and always assume the worst case scenario of 20 bytes command overhead. | ||||||
| @@ -255,7 +258,8 @@ static int pickit2_spi_send_command(const struct flashctx *flash, unsigned int w | |||||||
| 	buf[i++] = CMD_END_OF_BUFFER; | 	buf[i++] = CMD_END_OF_BUFFER; | ||||||
|  |  | ||||||
| 	int transferred; | 	int transferred; | ||||||
| 	int ret = libusb_interrupt_transfer(pickit2_handle, ENDPOINT_OUT, buf, CMD_LENGTH, &transferred, DFLT_TIMEOUT); | 	int ret = libusb_interrupt_transfer(pickit2_data->pickit2_handle, | ||||||
|  | 					ENDPOINT_OUT, buf, CMD_LENGTH, &transferred, DFLT_TIMEOUT); | ||||||
|  |  | ||||||
| 	if (ret != 0) { | 	if (ret != 0) { | ||||||
| 		msg_perr("Send SPI failed!\n"); | 		msg_perr("Send SPI failed!\n"); | ||||||
| @@ -264,7 +268,8 @@ static int pickit2_spi_send_command(const struct flashctx *flash, unsigned int w | |||||||
|  |  | ||||||
| 	if (readcnt) { | 	if (readcnt) { | ||||||
| 		int length = 0; | 		int length = 0; | ||||||
| 		ret = libusb_interrupt_transfer(pickit2_handle, ENDPOINT_IN, buf, CMD_LENGTH, &length, DFLT_TIMEOUT); | 		ret = libusb_interrupt_transfer(pickit2_data->pickit2_handle, | ||||||
|  | 					ENDPOINT_IN, buf, CMD_LENGTH, &length, DFLT_TIMEOUT); | ||||||
|  |  | ||||||
| 		if (length == 0 || ret != 0) { | 		if (length == 0 || ret != 0) { | ||||||
| 			msg_perr("Receive SPI failed\n"); | 			msg_perr("Receive SPI failed\n"); | ||||||
| @@ -335,7 +340,7 @@ static int parse_voltage(char *voltage) | |||||||
| 	return millivolt; | 	return millivolt; | ||||||
| } | } | ||||||
|  |  | ||||||
| static const struct spi_master spi_master_pickit2 = { | static struct spi_master spi_master_pickit2 = { | ||||||
| 	.max_data_read	= 40, | 	.max_data_read	= 40, | ||||||
| 	.max_data_write	= 40, | 	.max_data_write	= 40, | ||||||
| 	.command	= pickit2_spi_send_command, | 	.command	= pickit2_spi_send_command, | ||||||
| @@ -347,6 +352,8 @@ static const struct spi_master spi_master_pickit2 = { | |||||||
|  |  | ||||||
| static int pickit2_shutdown(void *data) | static int pickit2_shutdown(void *data) | ||||||
| { | { | ||||||
|  | 	struct pickit2_spi_data *pickit2_data = data; | ||||||
|  |  | ||||||
| 	/* Set all pins to float and turn voltages off */ | 	/* Set all pins to float and turn voltages off */ | ||||||
| 	uint8_t command[CMD_LENGTH] = { | 	uint8_t command[CMD_LENGTH] = { | ||||||
| 		CMD_EXEC_SCRIPT, | 		CMD_EXEC_SCRIPT, | ||||||
| @@ -363,18 +370,21 @@ static int pickit2_shutdown(void *data) | |||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	int transferred; | 	int transferred; | ||||||
| 	int ret = libusb_interrupt_transfer(pickit2_handle, ENDPOINT_OUT, command, CMD_LENGTH, &transferred, DFLT_TIMEOUT); | 	int ret = libusb_interrupt_transfer(pickit2_data->pickit2_handle, | ||||||
|  | 					ENDPOINT_OUT, command, CMD_LENGTH, &transferred, DFLT_TIMEOUT); | ||||||
|  |  | ||||||
| 	if (ret != 0) { | 	if (ret != 0) { | ||||||
| 		msg_perr("Command Shutdown failed!\n"); | 		msg_perr("Command Shutdown failed!\n"); | ||||||
| 		ret = 1; | 		ret = 1; | ||||||
| 	} | 	} | ||||||
| 	if (libusb_release_interface(pickit2_handle, 0) != 0) { | 	if (libusb_release_interface(pickit2_data->pickit2_handle, 0) != 0) { | ||||||
| 		msg_perr("Could not release USB interface!\n"); | 		msg_perr("Could not release USB interface!\n"); | ||||||
| 		ret = 1; | 		ret = 1; | ||||||
| 	} | 	} | ||||||
| 	libusb_close(pickit2_handle); | 	libusb_close(pickit2_data->pickit2_handle); | ||||||
| 	libusb_exit(NULL); | 	libusb_exit(NULL); | ||||||
|  |  | ||||||
|  | 	free(data); | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -397,7 +407,8 @@ int pickit2_spi_init(void) | |||||||
| 		CMD_END_OF_BUFFER | 		CMD_END_OF_BUFFER | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|  | 	libusb_device_handle *pickit2_handle; | ||||||
|  | 	struct pickit2_spi_data *pickit2_data; | ||||||
| 	int spispeed_idx = 0; | 	int spispeed_idx = 0; | ||||||
| 	char *spispeed = extract_programmer_param("spispeed"); | 	char *spispeed = extract_programmer_param("spispeed"); | ||||||
| 	if (spispeed != NULL) { | 	if (spispeed != NULL) { | ||||||
| @@ -458,16 +469,26 @@ int pickit2_spi_init(void) | |||||||
| 		return 1; | 		return 1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (pickit2_get_firmware_version()) | 	pickit2_data = calloc(1, sizeof(*pickit2_data)); | ||||||
|  | 	if (!pickit2_data) { | ||||||
|  | 		msg_perr("Unable to allocate space for SPI master data\n"); | ||||||
|  | 		libusb_close(pickit2_handle); | ||||||
|  | 		libusb_exit(NULL); | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | 	pickit2_data->pickit2_handle = pickit2_handle; | ||||||
|  | 	spi_master_pickit2.data = pickit2_data; | ||||||
|  |  | ||||||
|  | 	if (pickit2_get_firmware_version(pickit2_handle)) | ||||||
| 		goto init_err_cleanup_exit; | 		goto init_err_cleanup_exit; | ||||||
|  |  | ||||||
| 	/* Command Set SPI Speed */ | 	/* Command Set SPI Speed */ | ||||||
| 	if (pickit2_set_spi_speed(spispeed_idx)) | 	if (pickit2_set_spi_speed(pickit2_handle, spispeed_idx)) | ||||||
| 		goto init_err_cleanup_exit; | 		goto init_err_cleanup_exit; | ||||||
|  |  | ||||||
| 	/* Command Set SPI Voltage */ | 	/* Command Set SPI Voltage */ | ||||||
| 	msg_pdbg("Setting voltage to %i mV.\n", millivolt); | 	msg_pdbg("Setting voltage to %i mV.\n", millivolt); | ||||||
| 	if (pickit2_set_spi_voltage(millivolt) != 0) | 	if (pickit2_set_spi_voltage(pickit2_handle, millivolt) != 0) | ||||||
| 		goto init_err_cleanup_exit; | 		goto init_err_cleanup_exit; | ||||||
|  |  | ||||||
| 	/* Perform basic setup. | 	/* Perform basic setup. | ||||||
| @@ -478,13 +499,13 @@ int pickit2_spi_init(void) | |||||||
| 		goto init_err_cleanup_exit; | 		goto init_err_cleanup_exit; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (register_shutdown(pickit2_shutdown, NULL)) | 	if (register_shutdown(pickit2_shutdown, pickit2_data)) | ||||||
| 		goto init_err_cleanup_exit; | 		goto init_err_cleanup_exit; | ||||||
| 	register_spi_master(&spi_master_pickit2); | 	register_spi_master(&spi_master_pickit2); | ||||||
|  |  | ||||||
| 	return 0; | 	return 0; | ||||||
|  |  | ||||||
| init_err_cleanup_exit: | init_err_cleanup_exit: | ||||||
| 	pickit2_shutdown(NULL); | 	pickit2_shutdown(pickit2_data); | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user