From 6273472a89c28a088313a6303aa3b5b7904f539e Mon Sep 17 00:00:00 2001 From: Anastasia Klimchuk Date: Wed, 26 May 2021 12:50:59 +1000 Subject: 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 Reviewed-on: https://review.coreboot.org/c/flashrom/+/54993 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons Reviewed-by: Edward O'Callaghan --- developerbox_spi.c | 55 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/developerbox_spi.c b/developerbox_spi.c index e74189045..e4ab6f6fd 100644 --- a/developerbox_spi.c +++ b/developerbox_spi.c @@ -60,15 +60,18 @@ const struct dev_entry devs_developerbox_spi[] = { {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 @@ static int cp210x_gpio_get(void) 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_gpio_set(uint8_t val, uint8_t mask) 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 @@ static const struct bitbang_spi_master bitbang_spi_master_cp210x = { .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 @@ int developerbox_spi_init(void) 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; } -- cgit v1.2.3