From 976d0fc0ba4df2d3675753d98caac7bbded7955f Mon Sep 17 00:00:00 2001 From: Edward O'Callaghan Date: Mon, 23 Nov 2020 12:07:30 +1100 Subject: wbsio_spi.c: Move singleton state into spi master state tracker Make use of the reneterent framework by moving singleton static state out of the global life-time and into a per-spi_master basis. This allows for the wbsio_spi master to be reneterent and its internal state's life-time to be correctly handled by Flashrom's core dispatch logic. BUG=none TEST=builds Change-Id: Ic97fa41daf26f27b68ced11ddc2a4da91d18f68e Signed-off-by: Edward O'Callaghan Reviewed-on: https://review.coreboot.org/c/flashrom/+/47854 Reviewed-by: Sam McNally Tested-by: build bot (Jenkins) --- wbsio_spi.c | 49 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 12 deletions(-) (limited to 'wbsio_spi.c') diff --git a/wbsio_spi.c b/wbsio_spi.c index 26e3bb92c..632ff72ae 100644 --- a/wbsio_spi.c +++ b/wbsio_spi.c @@ -16,6 +16,8 @@ #if defined(__i386__) || defined(__x86_64__) +#include + #include "flash.h" #include "chipdrivers.h" #include "programmer.h" @@ -25,7 +27,9 @@ #define WBSIO_PORT1 0x2e #define WBSIO_PORT2 0x4e -static uint16_t wbsio_spibase = 0; +struct wbsio_spi_data { + uint16_t spibase; +}; static uint16_t wbsio_get_spibase(uint16_t port) { @@ -87,10 +91,13 @@ static int wbsio_spi_send_command(const struct flashctx *flash, unsigned int wri msg_pspew("%s:", __func__); + const struct wbsio_spi_data *data = + (const struct wbsio_spi_data *)flash->mst->spi.data; + if (1 == writecnt && 0 == readcnt) { mode = 0x10; } else if (2 == writecnt && 0 == readcnt) { - OUTB(writearr[1], wbsio_spibase + 4); + OUTB(writearr[1], data->spibase + 4); msg_pspew(" data=0x%02x", writearr[1]); mode = 0x20; } else if (1 == writecnt && 2 == readcnt) { @@ -98,28 +105,28 @@ static int wbsio_spi_send_command(const struct flashctx *flash, unsigned int wri } else if (4 == writecnt && 0 == readcnt) { msg_pspew(" addr=0x%02x", (writearr[1] & 0x0f)); for (i = 2; i < writecnt; i++) { - OUTB(writearr[i], wbsio_spibase + i); + OUTB(writearr[i], data->spibase + i); msg_pspew("%02x", writearr[i]); } mode = 0x40 | (writearr[1] & 0x0f); } else if (5 == writecnt && 0 == readcnt) { msg_pspew(" addr=0x%02x", (writearr[1] & 0x0f)); for (i = 2; i < 4; i++) { - OUTB(writearr[i], wbsio_spibase + i); + OUTB(writearr[i], data->spibase + i); msg_pspew("%02x", writearr[i]); } - OUTB(writearr[i], wbsio_spibase + i); + OUTB(writearr[i], data->spibase + i); msg_pspew(" data=0x%02x", writearr[i]); mode = 0x50 | (writearr[1] & 0x0f); } else if (8 == writecnt && 0 == readcnt) { msg_pspew(" addr=0x%02x", (writearr[1] & 0x0f)); for (i = 2; i < 4; i++) { - OUTB(writearr[i], wbsio_spibase + i); + OUTB(writearr[i], data->spibase + i); msg_pspew("%02x", writearr[i]); } msg_pspew(" data=0x"); for (; i < writecnt; i++) { - OUTB(writearr[i], wbsio_spibase + i); + OUTB(writearr[i], data->spibase + i); msg_pspew("%02x", writearr[i]); } mode = 0x60 | (writearr[1] & 0x0f); @@ -133,7 +140,7 @@ static int wbsio_spi_send_command(const struct flashctx *flash, unsigned int wri } else if (4 == writecnt && readcnt >= 1 && readcnt <= 4) { msg_pspew(" addr=0x%02x", (writearr[1] & 0x0f)); for (i = 2; i < writecnt; i++) { - OUTB(writearr[i], wbsio_spibase + i); + OUTB(writearr[i], data->spibase + i); msg_pspew("%02x", writearr[i]); } mode = ((7 + readcnt) << 4) | (writearr[1] & 0x0f); @@ -147,8 +154,8 @@ static int wbsio_spi_send_command(const struct flashctx *flash, unsigned int wri return SPI_INVALID_LENGTH; } - OUTB(writearr[0], wbsio_spibase); - OUTB(mode, wbsio_spibase + 1); + OUTB(writearr[0], data->spibase); + OUTB(mode, data->spibase + 1); programmer_delay(10); if (!readcnt) @@ -156,7 +163,7 @@ static int wbsio_spi_send_command(const struct flashctx *flash, unsigned int wri msg_pspew("%s: returning data =", __func__); for (i = 0; i < readcnt; i++) { - readarr[i] = INB(wbsio_spibase + 4 + i); + readarr[i] = INB(data->spibase + 4 + i); msg_pspew(" 0x%02x", readarr[i]); } msg_pspew("\n"); @@ -170,7 +177,7 @@ static int wbsio_spi_read(struct flashctx *flash, uint8_t *buf, return 0; } -static const struct spi_master spi_master_wbsio = { +static struct spi_master spi_master_wbsio = { .max_data_read = MAX_DATA_UNSPECIFIED, .max_data_write = MAX_DATA_UNSPECIFIED, .command = wbsio_spi_send_command, @@ -180,8 +187,16 @@ static const struct spi_master spi_master_wbsio = { .write_aai = spi_chip_write_1, }; +static int wbsio_spi_shutdown(void *data) +{ + free(data); + return 0; +} + int wbsio_check_for_spi(void) { + uint16_t wbsio_spibase = 0; + if (0 == (wbsio_spibase = wbsio_get_spibase(WBSIO_PORT1))) if (0 == (wbsio_spibase = wbsio_get_spibase(WBSIO_PORT2))) return 1; @@ -191,6 +206,16 @@ int wbsio_check_for_spi(void) msg_pdbg("%s: Winbond saved on 4 register bits so max chip size is " "1024 kB!\n", __func__); max_rom_decode.spi = 1024 * 1024; + + struct wbsio_spi_data * data = calloc(1, sizeof(struct wbsio_spi_data)); + if (!data) { + msg_perr("Unable to allocate space for extra SPI master data.\n"); + return SPI_GENERIC_ERROR; + } + data->spibase = wbsio_spibase; + + register_shutdown(wbsio_spi_shutdown, data); + spi_master_wbsio.data = data; register_spi_master(&spi_master_wbsio); return 0; -- cgit v1.2.3