From 810e2cde30035d0de691805041ffeeff57f68027 Mon Sep 17 00:00:00 2001 From: Furquan Shaikh Date: Mon, 5 Dec 2016 20:32:24 -0800 Subject: [PATCH] spi_flash: Make a deep copy of spi_slave structure Commit 36b81af (spi: Pass pointer to spi_slave structure in spi_setup_slave) changes the way spi_setup_slave handles the spi_slave structure. Instead of expecting spi controller drivers to maintain spi_slave structure in CAR_GLOBAL/data section, caller is expected to manage the spi_slave structure. This requires that spi_flash drivers maintain spi_slave structure and flash probe function needs to make a copy of the passed in spi_slave structure. This change fixes the regression on Lenovo X230 and other mainboards. Change-Id: I0ad971eecaf3bfe301e9f95badc043193cc27cab Signed-off-by: Furquan Shaikh Reviewed-on: https://review.coreboot.org/17728 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin Reviewed-by: Paul Menzel Reviewed-by: Iru Cai --- src/drivers/spi/adesto.c | 7 +++--- src/drivers/spi/amic.c | 7 +++--- src/drivers/spi/atmel.c | 8 ++++--- src/drivers/spi/eon.c | 7 +++--- src/drivers/spi/gigadevice.c | 7 +++--- src/drivers/spi/macronix.c | 7 +++--- src/drivers/spi/spansion.c | 7 +++--- src/drivers/spi/spi_flash.c | 22 +++++++++---------- src/drivers/spi/spi_flash_internal.h | 6 +++--- src/drivers/spi/sst.c | 25 +++++++++++----------- src/drivers/spi/stmicro.c | 7 +++--- src/drivers/spi/winbond.c | 7 +++--- src/include/spi_flash.h | 3 ++- src/soc/intel/apollolake/spi.c | 3 ++- src/soc/intel/skylake/flash_controller.c | 4 ++-- src/soc/mediatek/mt8173/flash_controller.c | 6 ++++-- src/southbridge/intel/common/spi.c | 6 +++--- 17 files changed, 77 insertions(+), 62 deletions(-) diff --git a/src/drivers/spi/adesto.c b/src/drivers/spi/adesto.c index 91bb774e36..52a74f97bd 100644 --- a/src/drivers/spi/adesto.c +++ b/src/drivers/spi/adesto.c @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -108,13 +109,13 @@ static int adesto_write(const struct spi_flash *flash, u32 offset, size_t len, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len); #endif - ret = spi_flash_cmd(flash->spi, CMD_AT25DF_WREN, NULL, 0); + ret = spi_flash_cmd(&flash->spi, CMD_AT25DF_WREN, NULL, 0); if (ret < 0) { printk(BIOS_WARNING, "SF: Enabling Write failed\n"); goto out; } - ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), + ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), buf + actual, chunk_len); if (ret < 0) { printk(BIOS_WARNING, "SF: adesto Page Program failed\n"); @@ -165,7 +166,7 @@ struct spi_flash *spi_flash_probe_adesto(struct spi_slave *spi, u8 *idcode) } stm->params = params; - stm->flash.spi = spi; + memcpy(&stm->flash.spi, spi, sizeof(*spi)); stm->flash.name = params->name; /* Assuming power-of-two page size initially. */ diff --git a/src/drivers/spi/amic.c b/src/drivers/spi/amic.c index 4f3002c73b..42f7cfa120 100644 --- a/src/drivers/spi/amic.c +++ b/src/drivers/spi/amic.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "spi_flash_internal.h" @@ -90,13 +91,13 @@ static int amic_write(const struct spi_flash *flash, u32 offset, size_t len, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len); #endif - ret = spi_flash_cmd(flash->spi, CMD_A25_WREN, NULL, 0); + ret = spi_flash_cmd(&flash->spi, CMD_A25_WREN, NULL, 0); if (ret < 0) { printk(BIOS_WARNING, "SF: Enabling Write failed\n"); goto out; } - ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), + ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), buf + actual, chunk_len); if (ret < 0) { printk(BIOS_WARNING, "SF: AMIC Page Program failed\n"); @@ -147,7 +148,7 @@ struct spi_flash *spi_flash_probe_amic(struct spi_slave *spi, u8 *idcode) } amic->params = params; - amic->flash.spi = spi; + memcpy(&amic->flash.spi, spi, sizeof(*spi)); amic->flash.name = params->name; /* Assuming power-of-two page size initially. */ diff --git a/src/drivers/spi/atmel.c b/src/drivers/spi/atmel.c index e53889205d..feb1a6d1fd 100644 --- a/src/drivers/spi/atmel.c +++ b/src/drivers/spi/atmel.c @@ -10,6 +10,8 @@ #include #include #include +#include + #include "spi_flash_internal.h" /* M25Pxx-specific commands */ @@ -135,13 +137,13 @@ static int atmel_write(const struct spi_flash *flash, u32 offset, size_t len, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len); #endif - ret = spi_flash_cmd(flash->spi, CMD_AT25_WREN, NULL, 0); + ret = spi_flash_cmd(&flash->spi, CMD_AT25_WREN, NULL, 0); if (ret < 0) { printk(BIOS_WARNING, "SF: Enabling Write failed\n"); goto out; } - ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), + ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), buf + actual, chunk_len); if (ret < 0) { printk(BIOS_WARNING, "SF: Atmel Page Program failed\n"); @@ -192,7 +194,7 @@ struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode) } stm->params = params; - stm->flash.spi = spi; + memcpy(&stm->flash.spi, spi, sizeof(*spi)); stm->flash.name = params->name; /* Assuming power-of-two page size initially. */ diff --git a/src/drivers/spi/eon.c b/src/drivers/spi/eon.c index 64307664de..f6db9e377c 100644 --- a/src/drivers/spi/eon.c +++ b/src/drivers/spi/eon.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "spi_flash_internal.h" @@ -96,7 +97,7 @@ static int eon_write(const struct spi_flash *flash, chunk_len = min(len - actual, page_size - byte_addr); chunk_len = spi_crop_chunk(sizeof(cmd), chunk_len); - ret = spi_flash_cmd(flash->spi, CMD_EN25_WREN, NULL, 0); + ret = spi_flash_cmd(&flash->spi, CMD_EN25_WREN, NULL, 0); if (ret < 0) { printk(BIOS_WARNING, "SF: Enabling Write failed\n"); goto out; @@ -113,7 +114,7 @@ static int eon_write(const struct spi_flash *flash, buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len); #endif - ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), + ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), buf + actual, chunk_len); if (ret < 0) { printk(BIOS_WARNING, "SF: EON Page Program failed\n"); @@ -164,7 +165,7 @@ struct spi_flash *spi_flash_probe_eon(struct spi_slave *spi, u8 *idcode) } eon->params = params; - eon->flash.spi = spi; + memcpy(&eon->flash.spi, spi, sizeof(*spi)); eon->flash.name = params->name; eon->flash.internal_write = eon_write; diff --git a/src/drivers/spi/gigadevice.c b/src/drivers/spi/gigadevice.c index 3146a97167..84d19a6073 100644 --- a/src/drivers/spi/gigadevice.c +++ b/src/drivers/spi/gigadevice.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "spi_flash_internal.h" @@ -137,7 +138,7 @@ static int gigadevice_write(const struct spi_flash *flash, u32 offset, chunk_len = min(len - actual, page_size - byte_addr); chunk_len = spi_crop_chunk(sizeof(cmd), chunk_len); - ret = spi_flash_cmd(flash->spi, CMD_GD25_WREN, NULL, 0); + ret = spi_flash_cmd(&flash->spi, CMD_GD25_WREN, NULL, 0); if (ret < 0) { printk(BIOS_WARNING, "SF gigadevice.c: Enabling Write failed\n"); @@ -155,7 +156,7 @@ static int gigadevice_write(const struct spi_flash *flash, u32 offset, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len); #endif - ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), + ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), buf + actual, chunk_len); if (ret < 0) { printk(BIOS_WARNING, @@ -205,7 +206,7 @@ struct spi_flash *spi_flash_probe_gigadevice(struct spi_slave *spi, u8 *idcode) } stm.params = params; - stm.flash.spi = spi; + memcpy(&stm.flash.spi, spi, sizeof(*spi)); stm.flash.name = params->name; /* Assuming power-of-two page size initially. */ diff --git a/src/drivers/spi/macronix.c b/src/drivers/spi/macronix.c index 799cc97c8b..0e3d028b9c 100644 --- a/src/drivers/spi/macronix.c +++ b/src/drivers/spi/macronix.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "spi_flash_internal.h" @@ -175,13 +176,13 @@ static int macronix_write(const struct spi_flash *flash, u32 offset, size_t len, buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len); #endif - ret = spi_flash_cmd(flash->spi, CMD_MX25XX_WREN, NULL, 0); + ret = spi_flash_cmd(&flash->spi, CMD_MX25XX_WREN, NULL, 0); if (ret < 0) { printk(BIOS_WARNING, "SF: Enabling Write failed\n"); break; } - ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), + ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), buf + actual, chunk_len); if (ret < 0) { printk(BIOS_WARNING, "SF: Macronix Page Program failed\n"); @@ -224,7 +225,7 @@ struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode) } mcx.params = params; - mcx.flash.spi = spi; + memcpy(&mcx.flash.spi, spi, sizeof(*spi)); mcx.flash.name = params->name; mcx.flash.internal_write = macronix_write; diff --git a/src/drivers/spi/spansion.c b/src/drivers/spi/spansion.c index 95b1bafe05..091f7ae460 100644 --- a/src/drivers/spi/spansion.c +++ b/src/drivers/spi/spansion.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "spi_flash_internal.h" @@ -230,13 +231,13 @@ static int spansion_write(const struct spi_flash *flash, u32 offset, size_t len, buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len); #endif - ret = spi_flash_cmd(flash->spi, CMD_S25FLXX_WREN, NULL, 0); + ret = spi_flash_cmd(&flash->spi, CMD_S25FLXX_WREN, NULL, 0); if (ret < 0) { printk(BIOS_WARNING, "SF: Enabling Write failed\n"); break; } - ret = spi_flash_cmd_write(flash->spi, cmd, 4, + ret = spi_flash_cmd_write(&flash->spi, cmd, 4, buf + actual, chunk_len); if (ret < 0) { printk(BIOS_WARNING, "SF: SPANSION Page Program failed\n"); @@ -283,7 +284,7 @@ struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode) spsn = &spsn_flash; spsn->params = params; - spsn->flash.spi = spi; + memcpy(&spsn->flash.spi, spi, sizeof(*spi)); spsn->flash.name = params->name; spsn->flash.internal_write = spansion_write; diff --git a/src/drivers/spi/spi_flash.c b/src/drivers/spi/spi_flash.c index b51a1e5ce8..3b4272b709 100644 --- a/src/drivers/spi/spi_flash.c +++ b/src/drivers/spi/spi_flash.c @@ -77,7 +77,7 @@ done: return ret; } -int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len) +int spi_flash_cmd(const struct spi_slave *spi, u8 cmd, void *response, size_t len) { int ret = do_spi_flash_cmd(spi, &cmd, sizeof(cmd), response, len); if (ret) @@ -86,7 +86,7 @@ int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len) return ret; } -static int spi_flash_cmd_read(struct spi_slave *spi, const u8 *cmd, +static int spi_flash_cmd_read(const struct spi_slave *spi, const u8 *cmd, size_t cmd_len, void *data, size_t data_len) { int ret = do_spi_flash_cmd(spi, cmd, cmd_len, data, data_len); @@ -101,8 +101,8 @@ static int spi_flash_cmd_read(struct spi_slave *spi, const u8 *cmd, /* TODO: This code is quite possibly broken and overflowing stacks. Fix ASAP! */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstack-usage=" -int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len, - const void *data, size_t data_len) +int spi_flash_cmd_write(const struct spi_slave *spi, const u8 *cmd, + size_t cmd_len, const void *data, size_t data_len) { int ret; u8 buff[cmd_len + data_len]; @@ -119,7 +119,7 @@ int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len, } #pragma GCC diagnostic pop -static int spi_flash_cmd_read_array(struct spi_slave *spi, u8 *cmd, +static int spi_flash_cmd_read_array(const struct spi_slave *spi, u8 *cmd, size_t cmd_len, u32 offset, size_t len, void *data) { @@ -135,7 +135,7 @@ int spi_flash_cmd_read_fast(const struct spi_flash *flash, u32 offset, cmd[0] = CMD_READ_ARRAY_FAST; cmd[4] = 0x00; - return spi_flash_cmd_read_array(flash->spi, cmd, sizeof(cmd), + return spi_flash_cmd_read_array(&flash->spi, cmd, sizeof(cmd), offset, len, data); } @@ -145,14 +145,14 @@ int spi_flash_cmd_read_slow(const struct spi_flash *flash, u32 offset, u8 cmd[4]; cmd[0] = CMD_READ_ARRAY_SLOW; - return spi_flash_cmd_read_array(flash->spi, cmd, sizeof(cmd), + return spi_flash_cmd_read_array(&flash->spi, cmd, sizeof(cmd), offset, len, data); } int spi_flash_cmd_poll_bit(const struct spi_flash *flash, unsigned long timeout, u8 cmd, u8 poll_bit) { - struct spi_slave *spi = flash->spi; + const struct spi_slave *spi = &flash->spi; int ret; u8 status; struct mono_time current, end; @@ -205,11 +205,11 @@ int spi_flash_cmd_erase(const struct spi_flash *flash, u32 offset, size_t len) printk(BIOS_SPEW, "SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1], cmd[2], cmd[3], offset); #endif - ret = spi_flash_cmd(flash->spi, CMD_WRITE_ENABLE, NULL, 0); + ret = spi_flash_cmd(&flash->spi, CMD_WRITE_ENABLE, NULL, 0); if (ret) goto out; - ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), NULL, 0); + ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), NULL, 0); if (ret) goto out; @@ -226,7 +226,7 @@ out: int spi_flash_cmd_status(const struct spi_flash *flash, u8 *reg) { - return spi_flash_cmd(flash->spi, flash->status_cmd, reg, sizeof(*reg)); + return spi_flash_cmd(&flash->spi, flash->status_cmd, reg, sizeof(*reg)); } /* diff --git a/src/drivers/spi/spi_flash_internal.h b/src/drivers/spi/spi_flash_internal.h index c75839357e..9b517238b2 100644 --- a/src/drivers/spi/spi_flash_internal.h +++ b/src/drivers/spi/spi_flash_internal.h @@ -32,7 +32,7 @@ #define STATUS_WIP 0x01 /* Send a single-byte command to the device and read the response */ -int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len); +int spi_flash_cmd(const struct spi_slave *spi, u8 cmd, void *response, size_t len); int spi_flash_cmd_read_fast(const struct spi_flash *flash, u32 offset, size_t len, void *data); @@ -44,8 +44,8 @@ int spi_flash_cmd_read_slow(const struct spi_flash *flash, u32 offset, * Send a multi-byte command to the device followed by (optional) * data. Used for programming the flash array, etc. */ -int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len, - const void *data, size_t data_len); +int spi_flash_cmd_write(const struct spi_slave *spi, const u8 *cmd, + size_t cmd_len, const void *data, size_t data_len); /* Send a command to the device and wait for some bit to clear itself. */ int spi_flash_cmd_poll_bit(const struct spi_flash *flash, unsigned long timeout, diff --git a/src/drivers/spi/sst.c b/src/drivers/spi/sst.c index 940d894396..70999a6652 100644 --- a/src/drivers/spi/sst.c +++ b/src/drivers/spi/sst.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "spi_flash_internal.h" @@ -109,7 +110,7 @@ static const struct sst_spi_flash_params sst_spi_flash_table[] = { static int sst_enable_writing(const struct spi_flash *flash) { - int ret = spi_flash_cmd(flash->spi, CMD_SST_WREN, NULL, 0); + int ret = spi_flash_cmd(&flash->spi, CMD_SST_WREN, NULL, 0); if (ret) printk(BIOS_WARNING, "SF: Enabling Write failed\n"); return ret; @@ -118,7 +119,7 @@ sst_enable_writing(const struct spi_flash *flash) static int sst_enable_writing_status(const struct spi_flash *flash) { - int ret = spi_flash_cmd(flash->spi, CMD_SST_EWSR, NULL, 0); + int ret = spi_flash_cmd(&flash->spi, CMD_SST_EWSR, NULL, 0); if (ret) printk(BIOS_WARNING, "SF: Enabling Write Status failed\n"); return ret; @@ -127,7 +128,7 @@ sst_enable_writing_status(const struct spi_flash *flash) static int sst_disable_writing(const struct spi_flash *flash) { - int ret = spi_flash_cmd(flash->spi, CMD_SST_WRDI, NULL, 0); + int ret = spi_flash_cmd(&flash->spi, CMD_SST_WRDI, NULL, 0); if (ret) printk(BIOS_WARNING, "SF: Disabling Write failed\n"); return ret; @@ -146,14 +147,14 @@ sst_byte_write(const struct spi_flash *flash, u32 offset, const void *buf) #if CONFIG_DEBUG_SPI_FLASH printk(BIOS_SPEW, "BP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n", - spi_w8r8(flash->spi, CMD_SST_RDSR), buf, cmd[0], offset); + spi_w8r8(&flash->spi, CMD_SST_RDSR), buf, cmd[0], offset); #endif ret = sst_enable_writing(flash); if (ret) return ret; - ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), buf, 1); + ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), buf, 1); if (ret) return ret; @@ -205,13 +206,13 @@ static int sst_write_256(const struct spi_flash *flash, u32 offset, size_t len, buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len); #endif - ret = spi_flash_cmd(flash->spi, CMD_SST_WREN, NULL, 0); + ret = spi_flash_cmd(&flash->spi, CMD_SST_WREN, NULL, 0); if (ret < 0) { printk(BIOS_WARNING, "SF: Enabling Write failed\n"); break; } - ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), + ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), buf + actual, chunk_len); if (ret < 0) { printk(BIOS_WARNING, "SF: SST Page Program failed\n"); @@ -263,11 +264,11 @@ static int sst_write_ai(const struct spi_flash *flash, u32 offset, size_t len, for (; actual < len - 1; actual += 2) { #if CONFIG_DEBUG_SPI_FLASH printk(BIOS_SPEW, "WP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n", - spi_w8r8(flash->spi, CMD_SST_RDSR), buf + actual, cmd[0], + spi_w8r8(&flash->spi, CMD_SST_RDSR), buf + actual, cmd[0], offset); #endif - ret = spi_flash_cmd_write(flash->spi, cmd, cmd_len, + ret = spi_flash_cmd_write(&flash->spi, cmd, cmd_len, buf + actual, 2); if (ret) { printk(BIOS_WARNING, "SF: SST word program failed\n"); @@ -310,11 +311,11 @@ sst_unlock(const struct spi_flash *flash) cmd = CMD_SST_WRSR; status = 0; - ret = spi_flash_cmd_write(flash->spi, &cmd, 1, &status, 1); + ret = spi_flash_cmd_write(&flash->spi, &cmd, 1, &status, 1); if (ret) printk(BIOS_WARNING, "SF: Unable to set status byte\n"); - printk(BIOS_INFO, "SF: SST: status = %x\n", spi_w8r8(flash->spi, CMD_SST_RDSR)); + printk(BIOS_INFO, "SF: SST: status = %x\n", spi_w8r8(&flash->spi, CMD_SST_RDSR)); return ret; } @@ -344,7 +345,7 @@ spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode) } stm->params = params; - stm->flash.spi = spi; + memcpy(&stm->flash.spi, spi, sizeof(*spi)); stm->flash.name = params->name; stm->flash.internal_write = params->write; diff --git a/src/drivers/spi/stmicro.c b/src/drivers/spi/stmicro.c index 56181628c6..93d545f396 100644 --- a/src/drivers/spi/stmicro.c +++ b/src/drivers/spi/stmicro.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "spi_flash_internal.h" @@ -204,13 +205,13 @@ static int stmicro_write(const struct spi_flash *flash, buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len); #endif - ret = spi_flash_cmd(flash->spi, CMD_M25PXX_WREN, NULL, 0); + ret = spi_flash_cmd(&flash->spi, CMD_M25PXX_WREN, NULL, 0); if (ret < 0) { printk(BIOS_WARNING, "SF: Enabling Write failed\n"); goto out; } - ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), + ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), buf + actual, chunk_len); if (ret < 0) { printk(BIOS_WARNING, "SF: STMicro Page Program failed\n"); @@ -268,7 +269,7 @@ struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode) } stm.params = params; - stm.flash.spi = spi; + memcpy(&stm.flash.spi, spi, sizeof(*spi)); stm.flash.name = params->name; stm.flash.internal_write = stmicro_write; diff --git a/src/drivers/spi/winbond.c b/src/drivers/spi/winbond.c index c6af2acc64..74c6e81185 100644 --- a/src/drivers/spi/winbond.c +++ b/src/drivers/spi/winbond.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "spi_flash_internal.h" @@ -166,13 +167,13 @@ static int winbond_write(const struct spi_flash *flash, u32 offset, size_t len, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len); #endif - ret = spi_flash_cmd(flash->spi, CMD_W25_WREN, NULL, 0); + ret = spi_flash_cmd(&flash->spi, CMD_W25_WREN, NULL, 0); if (ret < 0) { printk(BIOS_WARNING, "SF: Enabling Write failed\n"); goto out; } - ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), + ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), buf + actual, chunk_len); if (ret < 0) { printk(BIOS_WARNING, "SF: Winbond Page Program failed\n"); @@ -218,7 +219,7 @@ struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode) } stm.params = params; - stm.flash.spi = spi; + memcpy(&stm.flash.spi, spi, sizeof(*spi)); stm.flash.name = params->name; /* Assuming power-of-two page size initially. */ diff --git a/src/include/spi_flash.h b/src/include/spi_flash.h index 8fec4849c7..5a9237869f 100644 --- a/src/include/spi_flash.h +++ b/src/include/spi_flash.h @@ -17,6 +17,7 @@ #include #include +#include #include /* SPI Flash opcodes */ @@ -24,7 +25,7 @@ #define SPI_OPCODE_FAST_READ 0x0b struct spi_flash { - struct spi_slave *spi; + struct spi_slave spi; const char *name; u32 size; u32 sector_size; diff --git a/src/soc/intel/apollolake/spi.c b/src/soc/intel/apollolake/spi.c index 8992fa55ca..f9c17cdc2a 100644 --- a/src/soc/intel/apollolake/spi.c +++ b/src/soc/intel/apollolake/spi.c @@ -352,7 +352,8 @@ struct spi_flash *spi_flash_programmer_probe(struct spi_slave *spi, int force) flash_bits = read_spi_sfdp_param(ctx, 0x04); flash->size = (flash_bits >> 3) + 1; - flash->spi = spi; + memcpy(&flash->spi, spi, sizeof(*spi)); + flash->name = "Apollolake hardware sequencer"; /* Can erase both 4 KiB and 64 KiB chunks. Declare the smaller size. */ diff --git a/src/soc/intel/skylake/flash_controller.c b/src/soc/intel/skylake/flash_controller.c index e0ac93da03..994aec6b5d 100644 --- a/src/soc/intel/skylake/flash_controller.c +++ b/src/soc/intel/skylake/flash_controller.c @@ -191,7 +191,7 @@ int pch_hwseq_erase(const struct spi_flash *flash, u32 offset, size_t len) len, start); out: - spi_release_bus(flash->spi); + spi_release_bus(&flash->spi); return ret; } @@ -335,7 +335,7 @@ struct spi_flash *spi_flash_programmer_probe(struct spi_slave *spi, int force) /* Ensure writes can take place to the flash. */ spi_init(); - flash->spi = spi; + memcpy(&flash->spi, spi, sizeof(*spi)); flash->name = "Opaque HW-sequencing"; flash->internal_write = pch_hwseq_write; diff --git a/src/soc/mediatek/mt8173/flash_controller.c b/src/soc/mediatek/mt8173/flash_controller.c index 3799c6ac10..2aee66834f 100644 --- a/src/soc/mediatek/mt8173/flash_controller.c +++ b/src/soc/mediatek/mt8173/flash_controller.c @@ -236,12 +236,13 @@ static int nor_erase(const struct spi_flash *flash, u32 offset, size_t len) struct spi_flash *spi_flash_programmer_probe(struct spi_slave *spi, int force) { static struct spi_flash flash = {0}; + static int done = 0; - if (flash.spi) + if (done) return &flash; write32(&mt8173_nor->wrprot, SFLASH_COMMAND_ENABLE); - flash.spi = spi; + memcpy(&flash.spi, spi, sizeof(*spi)); flash.name = "mt8173 flash controller"; flash.internal_write = nor_write; flash.internal_erase = nor_erase; @@ -250,5 +251,6 @@ struct spi_flash *spi_flash_programmer_probe(struct spi_slave *spi, int force) flash.sector_size = 0x1000; flash.erase_cmd = SECTOR_ERASE_CMD; flash.size = CONFIG_ROM_SIZE; + done = 1; return &flash; } diff --git a/src/southbridge/intel/common/spi.c b/src/southbridge/intel/common/spi.c index 42a2a748de..c58f402195 100644 --- a/src/southbridge/intel/common/spi.c +++ b/src/southbridge/intel/common/spi.c @@ -733,7 +733,7 @@ static int ich_hwseq_erase(const struct spi_flash *flash, u32 offset, return -1; } - ret = spi_claim_bus(flash->spi); + ret = spi_claim_bus(&flash->spi); if (ret) { printk(BIOS_ERR, "SF: Unable to claim SPI bus\n"); return ret; @@ -766,7 +766,7 @@ static int ich_hwseq_erase(const struct spi_flash *flash, u32 offset, printk(BIOS_DEBUG, "SF: Successfully erased %zu bytes @ %#x\n", len, start); out: - spi_release_bus(flash->spi); + spi_release_bus(&flash->spi); return ret; } @@ -921,7 +921,7 @@ struct spi_flash *spi_flash_programmer_probe(struct spi_slave *spi, int force) return NULL; } - flash->spi = spi; + memcpy(&flash->spi, spi, sizeof(*spi)); flash->name = "Opaque HW-sequencing"; flash->internal_write = ich_hwseq_write;