Edward O'Callaghan has submitted this change. ( https://review.coreboot.org/c/flashrom/+/54993 )
Change subject: developerbox_spi.c: Refactor singleton states into reentrant pattern ......................................................................
developerbox_spi.c: Refactor singleton states into reentrant pattern
Move global singleton states into a struct and store within the bitbang_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".
BUG=b:185191942 TEST=builds
Change-Id: I84bf0cffa4a14e58103bdb1e7e65ec2475344f12 Signed-off-by: Anastasia Klimchuk aklm@chromium.org Reviewed-on: https://review.coreboot.org/c/flashrom/+/54993 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Angel Pons th3fanbus@gmail.com Reviewed-by: Edward O'Callaghan quasisec@chromium.org --- M developerbox_spi.c 1 file changed, 39 insertions(+), 16 deletions(-)
Approvals: build bot (Jenkins): Verified Angel Pons: Looks good to me, approved Edward O'Callaghan: Looks good to me, approved
diff --git a/developerbox_spi.c b/developerbox_spi.c index e741890..e4ab6f6 100644 --- a/developerbox_spi.c +++ b/developerbox_spi.c @@ -60,15 +60,18 @@ {0}, };
-static struct libusb_context *usb_ctx; -static libusb_device_handle *cp210x_handle; +struct devbox_spi_data { + struct libusb_context *usb_ctx; + libusb_device_handle *cp210x_handle; +};
-static int cp210x_gpio_get(void) +static int cp210x_gpio_get(void *spi_data) { int res; uint8_t gpio; + struct devbox_spi_data *data = spi_data;
- res = libusb_control_transfer(cp210x_handle, REQTYPE_DEVICE_TO_HOST, + res = libusb_control_transfer(data->cp210x_handle, REQTYPE_DEVICE_TO_HOST, CP210X_VENDOR_SPECIFIC, CP210X_READ_LATCH, 0, &gpio, 1, 0); if (res < 0) { @@ -79,15 +82,16 @@ return gpio; }
-static void cp210x_gpio_set(uint8_t val, uint8_t mask) +static void cp210x_gpio_set(uint8_t val, uint8_t mask, void *spi_data) { int res; uint16_t gpio; + struct devbox_spi_data *data = spi_data;
gpio = ((val & 0xf) << 8) | (mask & 0xf);
/* Set relay state on the card */ - res = libusb_control_transfer(cp210x_handle, REQTYPE_HOST_TO_DEVICE, + res = libusb_control_transfer(data->cp210x_handle, REQTYPE_HOST_TO_DEVICE, CP210X_VENDOR_SPECIFIC, CP210X_WRITE_LATCH, gpio, NULL, 0, 0); if (res < 0) @@ -96,28 +100,29 @@
static void cp210x_bitbang_set_cs(int val, void *spi_data) { - cp210x_gpio_set(val << DEVELOPERBOX_SPI_CS, 1 << DEVELOPERBOX_SPI_CS); + cp210x_gpio_set(val << DEVELOPERBOX_SPI_CS, 1 << DEVELOPERBOX_SPI_CS, spi_data); }
static void cp210x_bitbang_set_sck(int val, void *spi_data) { - cp210x_gpio_set(val << DEVELOPERBOX_SPI_SCK, 1 << DEVELOPERBOX_SPI_SCK); + cp210x_gpio_set(val << DEVELOPERBOX_SPI_SCK, 1 << DEVELOPERBOX_SPI_SCK, spi_data); }
static void cp210x_bitbang_set_mosi(int val, void *spi_data) { - cp210x_gpio_set(val << DEVELOPERBOX_SPI_MOSI, 1 << DEVELOPERBOX_SPI_MOSI); + cp210x_gpio_set(val << DEVELOPERBOX_SPI_MOSI, 1 << DEVELOPERBOX_SPI_MOSI, spi_data); }
static int cp210x_bitbang_get_miso(void *spi_data) { - return !!(cp210x_gpio_get() & (1 << DEVELOPERBOX_SPI_MISO)); + return !!(cp210x_gpio_get(spi_data) & (1 << DEVELOPERBOX_SPI_MISO)); }
static void cp210x_bitbang_set_sck_set_mosi(int sck, int mosi, void *spi_data) { cp210x_gpio_set(sck << DEVELOPERBOX_SPI_SCK | mosi << DEVELOPERBOX_SPI_MOSI, - 1 << DEVELOPERBOX_SPI_SCK | 1 << DEVELOPERBOX_SPI_MOSI); + 1 << DEVELOPERBOX_SPI_SCK | 1 << DEVELOPERBOX_SPI_MOSI, + spi_data); }
static const struct bitbang_spi_master bitbang_spi_master_cp210x = { @@ -128,16 +133,22 @@ .set_sck_set_mosi = cp210x_bitbang_set_sck_set_mosi, };
-static int developerbox_spi_shutdown(void *data) +static int developerbox_spi_shutdown(void *spi_data) { - libusb_close(cp210x_handle); - libusb_exit(usb_ctx); + struct devbox_spi_data *data = spi_data;
+ libusb_close(data->cp210x_handle); + libusb_exit(data->usb_ctx); + + free(data); return 0; }
int developerbox_spi_init(void) { + struct libusb_context *usb_ctx; + libusb_device_handle *cp210x_handle; + libusb_init(&usb_ctx); if (!usb_ctx) { msg_perr("Could not initialize libusb!\n"); @@ -155,15 +166,27 @@ goto err_exit; }
- if (register_shutdown(developerbox_spi_shutdown, NULL)) + struct devbox_spi_data *data = calloc(1, sizeof(*data)); + if (!data) { + msg_perr("Unable to allocate space for SPI master data\n"); goto err_exit; + } + data->usb_ctx = usb_ctx; + data->cp210x_handle = cp210x_handle;
- if (register_spi_bitbang_master(&bitbang_spi_master_cp210x, NULL)) + if (register_shutdown(developerbox_spi_shutdown, data)) { + free(data); goto err_exit; + } + + if (register_spi_bitbang_master(&bitbang_spi_master_cp210x, data)) + return 1; /* shutdown function does the cleanup */
return 0;
err_exit: + if (cp210x_handle) + libusb_close(cp210x_handle); libusb_exit(usb_ctx); return 1; }