[coreboot-gerrit] New patch to review for coreboot: spi: Pass pointer to spi_slave structure in spi_setup_slave

Furquan Shaikh (furquan@google.com) gerrit at coreboot.org
Thu Dec 1 17:08:01 CET 2016


Furquan Shaikh (furquan at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17683

-gerrit

commit 139a0a26145ebf34604cc310f5b2df334d673000
Author: Furquan Shaikh <furquan at chromium.org>
Date:   Thu Dec 1 01:02:44 2016 -0800

    spi: Pass pointer to spi_slave structure in spi_setup_slave
    
    For spi_setup_slave, instead of making the platform driver return a
    pointer to spi_slave structure, pass in a structure pointer that can be
    filled in by the driver as required. This removes the need for platform
    drivers to maintain a slave structure in data/CAR section.
    
    BUG=chrome-os-partner:59832
    BRANCH=None
    TEST=Compiles successfully
    
    Change-Id: Ia15a4f88ef4dcfdf616bb1c22261e7cb642a7573
    Signed-off-by: Furquan Shaikh <furquan at chromium.org>
---
 src/drivers/spi/spi_flash.c                | 11 ++++---
 src/drivers/spi/tpm/tis.c                  | 10 +++++--
 src/ec/google/chromeec/ec_spi.c            | 14 +++++----
 src/include/spi-generic.h                  |  7 +++--
 src/soc/broadcom/cygnus/spi.c              | 18 ++++++------
 src/soc/imgtec/pistachio/spi.c             | 46 ++++++++++++++++++------------
 src/soc/intel/apollolake/spi.c             |  9 ++----
 src/soc/intel/baytrail/spi.c               | 13 ++-------
 src/soc/intel/braswell/spi.c               | 13 ++-------
 src/soc/intel/broadwell/spi.c              | 13 ++-------
 src/soc/intel/fsp_baytrail/spi.c           | 13 ++-------
 src/soc/intel/fsp_broadwell_de/spi.c       | 13 ++-------
 src/soc/intel/skylake/flash_controller.c   |  9 ++----
 src/soc/marvell/armada38x/spi.c            |  8 ++----
 src/soc/marvell/bg4cd/spi.c                |  4 +--
 src/soc/mediatek/mt8173/spi.c              | 22 +++++++-------
 src/soc/nvidia/tegra124/spi.c              |  9 ++++--
 src/soc/nvidia/tegra210/spi.c              |  9 ++++--
 src/soc/qualcomm/ipq40xx/include/soc/spi.h |  5 ----
 src/soc/qualcomm/ipq40xx/spi.c             | 34 +++++++++++++++++-----
 src/soc/qualcomm/ipq806x/include/soc/spi.h |  5 ----
 src/soc/qualcomm/ipq806x/spi.c             | 32 +++++++++++++++++----
 src/soc/rockchip/common/spi.c              | 18 ++++++------
 src/soc/samsung/exynos5420/spi.c           | 13 ++++++---
 src/southbridge/amd/agesa/hudson/spi.c     | 14 +++------
 src/southbridge/amd/cimx/sb800/spi.c       | 14 +++------
 src/southbridge/amd/sb700/spi.c            | 14 +++------
 src/southbridge/intel/common/spi.c         | 13 ++-------
 src/southbridge/intel/fsp_rangeley/spi.c   | 13 ++-------
 29 files changed, 191 insertions(+), 225 deletions(-)

diff --git a/src/drivers/spi/spi_flash.c b/src/drivers/spi/spi_flash.c
index 54a7c11..16ebc9c 100644
--- a/src/drivers/spi/spi_flash.c
+++ b/src/drivers/spi/spi_flash.c
@@ -313,25 +313,24 @@ static struct spi_flash *__spi_flash_probe(struct spi_slave *spi)
 
 struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs)
 {
-	struct spi_slave *spi;
+	struct spi_slave spi;
 	struct spi_flash *flash;
 
-	spi = spi_setup_slave(bus, cs);
-	if (!spi) {
+	if (spi_setup_slave(bus, cs, &spi)) {
 		printk(BIOS_WARNING, "SF: Failed to set up slave\n");
 		return NULL;
 	}
 
 	/* Try special programmer probe if any (without force). */
-	flash = spi_flash_programmer_probe(spi, 0);
+	flash = spi_flash_programmer_probe(&spi, 0);
 
 	/* If flash is not found, try generic spi flash probe. */
 	if (!flash)
-		flash = __spi_flash_probe(spi);
+		flash = __spi_flash_probe(&spi);
 
 	/* If flash is not yet found, force special programmer probe if any. */
 	if (!flash)
-		flash = spi_flash_programmer_probe(spi, 1);
+		flash = spi_flash_programmer_probe(&spi, 1);
 
 	/* Give up -- nothing more to try if flash is not found. */
 	if (!flash) {
diff --git a/src/drivers/spi/tpm/tis.c b/src/drivers/spi/tpm/tis.c
index 055525b..d3c727c 100644
--- a/src/drivers/spi/tpm/tis.c
+++ b/src/drivers/spi/tpm/tis.c
@@ -58,10 +58,16 @@ int tis_close(void)
 
 int tis_init(void)
 {
+	struct spi_slave spi;
 	struct tpm2_info info;
 
-	if (tpm2_init(spi_setup_slave(CONFIG_DRIVER_TPM_SPI_BUS,
-				      CONFIG_DRIVER_TPM_SPI_CHIP))) {
+	if (spi_setup_slave(CONFIG_DRIVER_TPM_SPI_BUS,
+			    CONFIG_DRIVER_TPM_SPI_CHIP, &spi)) {
+		printk(BIOS_ERR, "Failed to setup TPM SPI slave\n");
+		return -1;
+	}
+
+	if (tpm2_init(&spi)) {
 		printk(BIOS_ERR, "Failed to initialize TPM SPI interface\n");
 		return -1;
 	}
diff --git a/src/ec/google/chromeec/ec_spi.c b/src/ec/google/chromeec/ec_spi.c
index a0049c6..810979e 100644
--- a/src/ec/google/chromeec/ec_spi.c
+++ b/src/ec/google/chromeec/ec_spi.c
@@ -101,13 +101,17 @@ out:
 
 int google_chromeec_command(struct chromeec_command *cec_command)
 {
-	static struct spi_slave *slave = NULL;
-	if (!slave) {
-		slave = spi_setup_slave(CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS,
-					CONFIG_EC_GOOGLE_CHROMEEC_SPI_CHIP);
+	static int done = 0;
+	static struct spi_slave slave;
+
+	if (!done) {
+		if (spi_setup_slave(CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS,
+				    CONFIG_EC_GOOGLE_CHROMEEC_SPI_CHIP, &slave))
+			return -1;
 		stopwatch_init(&cs_cooldown_sw);
+		done = 1;
 	}
-	return crosec_command_proto(cec_command, crosec_spi_io, slave);
+	return crosec_command_proto(cec_command, crosec_spi_io, &slave);
 }
 
 #ifndef __PRE_RAM__
diff --git a/src/include/spi-generic.h b/src/include/spi-generic.h
index 7c53611..c8b209d 100644
--- a/src/include/spi-generic.h
+++ b/src/include/spi-generic.h
@@ -48,11 +48,12 @@ void spi_init(void);
  *
  *   bus:     Bus ID of the slave chip.
  *   cs:      Chip select ID of the slave chip on the specified bus.
+ *   slave:   Pointer to slave structure that needs to be initialized.
  *
- * Returns: A spi_slave reference that can be used in subsequent SPI
- * calls, or NULL if one or more of the parameters are not supported.
+ * Returns:
+ * 0 on success, -1 on error
  */
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs);
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave);
 
 /*-----------------------------------------------------------------------
  * Claim the bus and prepare it for communication with a given slave.
diff --git a/src/soc/broadcom/cygnus/spi.c b/src/soc/broadcom/cygnus/spi.c
index 13b6976..810f2c2 100644
--- a/src/soc/broadcom/cygnus/spi.c
+++ b/src/soc/broadcom/cygnus/spi.c
@@ -76,9 +76,6 @@
 
 /* QSPI private data */
 struct qspi_priv {
-	/* Slave entry */
-	struct spi_slave slave;
-
 	/* Specified SPI parameters */
 	unsigned int max_hz;
 	unsigned int spi_mode;
@@ -94,16 +91,19 @@ struct qspi_priv {
 
 static struct qspi_priv qspi_slave;
 
-/* Macro to get the private data */
-#define to_qspi_slave(s) container_of(s, struct qspi_priv, slave)
+static struct qspi_priv *to_qspi_slave(const struct spi_slave *slave)
+{
+	return &qspi_slave;
+}
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
 {
 	struct qspi_priv *priv = &qspi_slave;
 	unsigned int spbr;
 
-	priv->slave.bus = bus;
-	priv->slave.cs = cs;
+	slave->bus = bus;
+	slave->cs = cs;
+
 	priv->max_hz = QSPI_MAX_HZ;
 	priv->spi_mode = QSPI_MODE;
 	priv->reg = (void *)(IPROC_QSPI_BASE);
@@ -129,7 +129,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
 	       (8 << 2) |		/* 8 bits per word */
 	       (priv->spi_mode & 3));	/* mode: CPOL / CPHA */
 
-	return &priv->slave;
+	return 0;
 }
 
 static int mspi_enable(struct qspi_priv *priv)
diff --git a/src/soc/imgtec/pistachio/spi.c b/src/soc/imgtec/pistachio/spi.c
index 9664989..2dd3ecd 100644
--- a/src/soc/imgtec/pistachio/spi.c
+++ b/src/soc/imgtec/pistachio/spi.c
@@ -26,7 +26,6 @@
 #define IMGTEC_SPI_MAX_TRANSFER_SIZE   ((1 << 16) - 1)
 
 struct img_spi_slave {
-	struct spi_slave slave;
 	/* SPIM instance device parameters */
 	struct spim_device_parameters device_parameters;
 	/* SPIM instance base address */
@@ -55,13 +54,20 @@ static int wait_status(u32 reg, u32 shift)
 	return SPIM_OK;
 }
 
+static struct img_spi_slave *get_img_slave(const struct spi_slave *slave)
+{
+	return img_spi_slaves + slave->bus * SPIM_NUM_PORTS_PER_BLOCK +
+		slave->cs;
+}
+
 /* Transmitter function. Fills TX FIFO with data before enabling SPIM */
 static int transmitdata(const struct spi_slave *slave, u8 *buffer, u32 size)
 {
 	u32 blocksize, base, write_data;
 	int ret;
+	struct img_spi_slave *img_slave = get_img_slave(slave);
 
-	base = container_of(slave, struct img_spi_slave, slave)->base;
+	base = img_slave->base;
 	while (size) {
 		/* Wait until FIFO empty */
 		write32(base + SPFI_INT_CLEAR_REG_OFFSET, SPFI_SDE_MASK);
@@ -97,8 +103,9 @@ static int receivedata(const struct spi_slave *slave, u8 *buffer, u32 size)
 {
 	u32 read_data, base;
 	int ret;
+	struct img_spi_slave *img_slave = get_img_slave(slave);
 
-	base = container_of(slave, struct img_spi_slave, slave)->base;
+	base = img_slave->base;
 	/*
 	 * Do 32bit reads first. Clear status GDEX32BIT here so that the first
 	 * status reg. read gets the actual bit state
@@ -141,10 +148,10 @@ static void  setparams(const struct spi_slave *slave, u32 port,
 			struct spim_device_parameters *params)
 {
 	u32 spim_parameters, port_state, base;
+	struct img_spi_slave *img_slave = get_img_slave(slave);
 
+	base = img_slave->base;
 	spim_parameters = 0;
-
-	base = container_of(slave, struct img_spi_slave, slave)->base;
 	port_state = read32(base + SPFI_PORT_STATE_REG_OFFSET);
 	port_state &= ~((SPIM_PORT0_MASK>>port)|SPFI_PORT_SELECT_MASK);
 	port_state |= params->cs_idle_level<<(SPIM_CS0_IDLE_SHIFT-port);
@@ -246,7 +253,9 @@ static u32 control_reg_setup(struct spim_buffer *first,
 static int check_buffers(const struct spi_slave *slave, struct spim_buffer *first,
 				struct spim_buffer *second){
 
-	if (!(container_of(slave, struct img_spi_slave, slave)->initialised))
+	struct img_spi_slave *img_slave = get_img_slave(slave);
+
+	if (!(img_slave->initialised))
 		return -SPIM_API_NOT_INITIALISED;
 	/*
 	 * First operation must always be defined
@@ -327,8 +336,9 @@ static int spim_io(const struct spi_slave *slave, struct spim_buffer *first,
 	u32 reg, base;
 	int i, trans_count, ret;
 	struct spim_buffer *transaction[2];
+	struct img_spi_slave *img_slave = get_img_slave(slave);
 
-	base = container_of(slave, struct img_spi_slave, slave)->base;
+	base = img_slave->base;
 
 	ret = check_buffers(slave, first, second);
 	if (ret)
@@ -408,11 +418,9 @@ void spi_init(void)
 }
 
 /* Set up communications parameters for a SPI slave. */
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
 {
-
 	struct img_spi_slave *img_slave = NULL;
-	struct spi_slave *slave;
 	struct spim_device_parameters *device_parameters;
 	u32 base;
 
@@ -426,21 +434,21 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
 	default:
 		printk(BIOS_ERR, "%s: Error: unsupported bus.\n",
 				__func__);
-		return NULL;
+		return -1;
 	}
 	if (cs > SPIM_DEVICE4) {
 		printk(BIOS_ERR, "%s: Error: unsupported chipselect.\n",
 				__func__);
-		return NULL;
+		return -1;
 	}
 
-	img_slave = img_spi_slaves + bus * SPIM_NUM_PORTS_PER_BLOCK + cs;
-	slave = &(img_slave->slave);
+	slave->bus = bus;
+	slave->cs = cs;
+
+	img_slave = get_img_slave(slave);
 	device_parameters = &(img_slave->device_parameters);
 
 	img_slave->base = base;
-	slave->bus = bus;
-	slave->cs = cs;
 
 	device_parameters->bitrate = 64;
 	device_parameters->cs_setup = 0;
@@ -451,7 +459,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
 	device_parameters->data_idle_level = 0;
 	img_slave->initialised = IMG_FALSE;
 
-	return slave;
+	return 0;
 }
 
 /* Claim the bus and prepare it for communication */
@@ -465,7 +473,7 @@ int spi_claim_bus(const struct spi_slave *slave)
 				__func__);
 		return -SPIM_API_NOT_INITIALISED;
 	}
-	img_slave = container_of(slave, struct img_spi_slave, slave);
+	img_slave = get_img_slave(slave);
 	if (img_slave->initialised)
 		return SPIM_OK;
 	/* Check device parameters */
@@ -495,7 +503,7 @@ void spi_release_bus(const struct spi_slave *slave)
 				__func__);
 		return;
 	}
-	img_slave = container_of(slave, struct img_spi_slave, slave);
+	img_slave = get_img_slave(slave);
 	img_slave->initialised = IMG_FALSE;
 	/* Soft reset peripheral internals */
 	write32(img_slave->base + SPFI_CONTROL_REG_OFFSET,
diff --git a/src/soc/intel/apollolake/spi.c b/src/soc/intel/apollolake/spi.c
index 6e873f4..ca56702 100644
--- a/src/soc/intel/apollolake/spi.c
+++ b/src/soc/intel/apollolake/spi.c
@@ -344,7 +344,6 @@ static int nuclear_spi_status(const struct spi_flash *flash, uint8_t *reg)
 	return ret;
 }
 
-static struct spi_slave boot_spi CAR_GLOBAL;
 static struct spi_flash boot_flash CAR_GLOBAL;
 
 /*
@@ -391,20 +390,18 @@ struct spi_flash *spi_flash_programmer_probe(struct spi_slave *spi, int force)
 	return flash;
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
 {
 	BOILERPLATE_CREATE_CTX(ctx);
 
 	/* This is special hardware. We expect bus 0 and CS line 0 here. */
 	if ((bus != 0) || (cs != 0))
-		return NULL;
-
-	struct spi_slave *slave = car_get_var_ptr(&boot_spi);
+		return -1;
 
 	slave->bus = bus;
 	slave->cs = cs;
 
-	return slave;
+	return 0;
 }
 
 int spi_read_status(uint8_t *status)
diff --git a/src/soc/intel/baytrail/spi.c b/src/soc/intel/baytrail/spi.c
index 13f8806..b4f95aa 100644
--- a/src/soc/intel/baytrail/spi.c
+++ b/src/soc/intel/baytrail/spi.c
@@ -260,20 +260,11 @@ static void ich_set_bbar(uint32_t minaddr)
 	writel_(ichspi_bbar, cntlr.bbar);
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
 {
-	ich_spi_slave *slave = malloc(sizeof(*slave));
-
-	if (!slave) {
-		printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n");
-		return NULL;
-	}
-
-	memset(slave, 0, sizeof(*slave));
-
 	slave->bus = bus;
 	slave->cs = cs;
-	return slave;
+	return 0;
 }
 
 static ich9_spi_regs *spi_regs(void)
diff --git a/src/soc/intel/braswell/spi.c b/src/soc/intel/braswell/spi.c
index 34e031b..4236e6f 100644
--- a/src/soc/intel/braswell/spi.c
+++ b/src/soc/intel/braswell/spi.c
@@ -229,20 +229,11 @@ static void read_reg(void *src, void *value, uint32_t size)
 	}
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
 {
-	ich_spi_slave *slave = malloc(sizeof(*slave));
-
-	if (!slave) {
-		printk(BIOS_ERR, "ICH SPI: Bad allocation\n");
-		return NULL;
-	}
-
-	memset(slave, 0, sizeof(*slave));
-
 	slave->bus = bus;
 	slave->cs = cs;
-	return slave;
+	return 0;
 }
 
 static ich9_spi_regs *spi_regs(void)
diff --git a/src/soc/intel/broadwell/spi.c b/src/soc/intel/broadwell/spi.c
index 6aa7dd3..5220970 100644
--- a/src/soc/intel/broadwell/spi.c
+++ b/src/soc/intel/broadwell/spi.c
@@ -259,20 +259,11 @@ static void ich_set_bbar(uint32_t minaddr)
 	writel_(ichspi_bbar, cntlr.bbar);
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
 {
-	ich_spi_slave *slave = malloc(sizeof(*slave));
-
-	if (!slave) {
-		printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n");
-		return NULL;
-	}
-
-	memset(slave, 0, sizeof(*slave));
-
 	slave->bus = bus;
 	slave->cs = cs;
-	return slave;
+	return 0;
 }
 
 void spi_init(void)
diff --git a/src/soc/intel/fsp_baytrail/spi.c b/src/soc/intel/fsp_baytrail/spi.c
index 232366c..06b160c 100644
--- a/src/soc/intel/fsp_baytrail/spi.c
+++ b/src/soc/intel/fsp_baytrail/spi.c
@@ -249,20 +249,11 @@ static void read_reg(const void *src, void *value, uint32_t size)
 	}
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
 {
-	ich_spi_slave *slave = malloc(sizeof(*slave));
-
-	if (!slave) {
-		printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n");
-		return NULL;
-	}
-
-	memset(slave, 0, sizeof(*slave));
-
 	slave->bus = bus;
 	slave->cs = cs;
-	return slave;
+	return 0;
 }
 
 static ich9_spi_regs *spi_regs(void)
diff --git a/src/soc/intel/fsp_broadwell_de/spi.c b/src/soc/intel/fsp_broadwell_de/spi.c
index c38fbce..8af5686 100644
--- a/src/soc/intel/fsp_broadwell_de/spi.c
+++ b/src/soc/intel/fsp_broadwell_de/spi.c
@@ -259,20 +259,11 @@ static void ich_set_bbar(uint32_t minaddr)
 	writel_(ichspi_bbar, cntlr.bbar);
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave * slave)
 {
-	ich_spi_slave *slave = malloc(sizeof(*slave));
-
-	if (!slave) {
-		printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n");
-		return NULL;
-	}
-
-	memset(slave, 0, sizeof(*slave));
-
 	slave->bus = bus;
 	slave->cs = cs;
-	return slave;
+	return 0;
 }
 
 void spi_init(void)
diff --git a/src/soc/intel/skylake/flash_controller.c b/src/soc/intel/skylake/flash_controller.c
index 8aee796..734d9d3 100644
--- a/src/soc/intel/skylake/flash_controller.c
+++ b/src/soc/intel/skylake/flash_controller.c
@@ -342,7 +342,6 @@ int pch_hwseq_read_status(const struct spi_flash *flash, u8 *reg)
 	return 0;
 }
 
-static struct spi_slave boot_spi CAR_GLOBAL;
 static struct spi_flash boot_flash CAR_GLOBAL;
 
 struct spi_flash *spi_flash_programmer_probe(struct spi_slave *spi, int force)
@@ -370,18 +369,16 @@ struct spi_flash *spi_flash_programmer_probe(struct spi_slave *spi, int force)
 	return flash;
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
 {
 	/* This is special hardware. We expect bus 0 and CS line 0 here. */
 	if ((bus != 0) || (cs != 0))
-		return NULL;
-
-	struct spi_slave *slave = car_get_var_ptr(&boot_spi);
+		return -1;
 
 	slave->bus = bus;
 	slave->cs = cs;
 
-	return slave;
+	return 0;
 }
 
 int spi_flash_get_fpr_info(struct fpr_info *info)
diff --git a/src/soc/marvell/armada38x/spi.c b/src/soc/marvell/armada38x/spi.c
index 9a0b963..b628170 100644
--- a/src/soc/marvell/armada38x/spi.c
+++ b/src/soc/marvell/armada38x/spi.c
@@ -153,8 +153,6 @@ static MV_SPI_TYPE_INFO spi_types[] = { {.en16_bit = MV_TRUE,
 param define end
 *******************************************************************************/
 
-static struct spi_slave s_spi;
-
 static int mv_spi_baud_rate_set(unsigned char spi_id,
 			unsigned int serial_baud_rate);
 static void mv_spi_cs_deassert(unsigned char spi_id);
@@ -444,14 +442,12 @@ static int mrvl_spi_xfer(const struct spi_slave *slave,
 	return 0;
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
 {
-	struct spi_slave *slave = &s_spi;
-
 	slave->bus = bus;
 	slave->cs = cs;
 	mv_spi_sys_init(bus, cs, CONFIG_SF_DEFAULT_SPEED);
-	return slave;
+	return 0;
 }
 
 int spi_claim_bus(const struct spi_slave *slave)
diff --git a/src/soc/marvell/bg4cd/spi.c b/src/soc/marvell/bg4cd/spi.c
index 9a999b0..54161bc 100644
--- a/src/soc/marvell/bg4cd/spi.c
+++ b/src/soc/marvell/bg4cd/spi.c
@@ -15,9 +15,9 @@
 #include <stddef.h>
 #include <spi-generic.h>
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
 {
-	return NULL;
+	return -1;
 }
 
 int spi_claim_bus(const struct spi_slave *slave)
diff --git a/src/soc/mediatek/mt8173/spi.c b/src/soc/mediatek/mt8173/spi.c
index f60de6c..d02f02d 100644
--- a/src/soc/mediatek/mt8173/spi.c
+++ b/src/soc/mediatek/mt8173/spi.c
@@ -47,9 +47,6 @@ enum {
 
 static struct mtk_spi_bus spi_bus[1] = {
 	{
-		.slave = {
-			.bus = 0,
-		},
 		.regs = (void *)SPI_BASE,
 		.state = MTK_SPI_IDLE,
 	}
@@ -57,7 +54,8 @@ static struct mtk_spi_bus spi_bus[1] = {
 
 static inline struct mtk_spi_bus *to_mtk_spi(const struct spi_slave *slave)
 {
-	return container_of(slave, struct mtk_spi_bus, slave);
+	assert(slave->bus >= ARRAY_SIZE(spi_bus));
+	return &spi_bus[slave->bus];
 }
 
 static void spi_sw_reset(struct mtk_spi_regs *regs)
@@ -162,24 +160,26 @@ static void mtk_spi_dump_data(const char *name, const uint8_t *data,
 #endif
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
 {
 	struct mtk_spi_bus *eslave;
-	static struct spi_slave slave;
 
 	switch (bus) {
 	case CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS:
-		eslave = &spi_bus[bus];
+		slave->bus = bus;
+		slave->cs = cs;
+		eslave = to_mtk_spi(slave);
 		assert(read32(&eslave->regs->spi_cfg0_reg) != 0);
 		spi_sw_reset(eslave->regs);
-		return &eslave->slave;
+		return 0;
 	case CONFIG_BOOT_DEVICE_SPI_FLASH_BUS:
-		slave.bus = bus;
-		slave.cs = cs;
-		return &slave;
+		slave->bus = bus;
+		slave->cs = cs;
+		return 0;
 	default:
 		die ("wrong bus number.\n");
 	};
+	return -1;
 }
 
 int spi_claim_bus(const struct spi_slave *slave)
diff --git a/src/soc/nvidia/tegra124/spi.c b/src/soc/nvidia/tegra124/spi.c
index 71b8735..d5b2915 100644
--- a/src/soc/nvidia/tegra124/spi.c
+++ b/src/soc/nvidia/tegra124/spi.c
@@ -811,11 +811,14 @@ int spi_xfer(const struct spi_slave *slave, const void *dout, size_t out_bytes,
 	return ret;
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
 {
 	struct tegra_spi_channel *channel = to_tegra_spi(bus);
 	if (!channel)
-		return NULL;
+		return -1;
 
-	return &channel->slave;
+	slave->bus = channel->slave.bus;
+	slave->cs = channel->slave.cs;
+
+	return 0;
 }
diff --git a/src/soc/nvidia/tegra210/spi.c b/src/soc/nvidia/tegra210/spi.c
index df3b8a1..cecf573 100644
--- a/src/soc/nvidia/tegra210/spi.c
+++ b/src/soc/nvidia/tegra210/spi.c
@@ -847,11 +847,14 @@ int spi_xfer(const struct spi_slave *slave, const void *dout, size_t out_bytes,
 	return ret;
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
 {
 	struct tegra_spi_channel *channel = to_tegra_spi(bus);
 	if (!channel)
-		return NULL;
+		return -1;
 
-	return &channel->slave;
+	slave->cs = channel->slave.cs;
+	slave->bus = channel->slave.bus;
+
+	return 0;
 }
diff --git a/src/soc/qualcomm/ipq40xx/include/soc/spi.h b/src/soc/qualcomm/ipq40xx/include/soc/spi.h
index 8ef1fbf..b91e6ca 100644
--- a/src/soc/qualcomm/ipq40xx/include/soc/spi.h
+++ b/src/soc/qualcomm/ipq40xx/include/soc/spi.h
@@ -186,9 +186,4 @@ struct ipq_spi_slave {
 	int allocated;
 };
 
-static inline struct ipq_spi_slave *to_ipq_spi(const struct spi_slave *slave)
-{
-	return container_of(slave, struct ipq_spi_slave, slave);
-}
-
 #endif /* _IPQ40XX_SPI_H_ */
diff --git a/src/soc/qualcomm/ipq40xx/spi.c b/src/soc/qualcomm/ipq40xx/spi.c
index 871f24b..cda3bea 100644
--- a/src/soc/qualcomm/ipq40xx/spi.c
+++ b/src/soc/qualcomm/ipq40xx/spi.c
@@ -207,7 +207,26 @@ void spi_init(void)
 	memset(spi_slave_pool, 0, sizeof(spi_slave_pool));
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+static struct ipq_spi_slave *to_ipq_spi(const struct spi_slave *slave)
+{
+	struct ipq_spi_slave *ds;
+	size_t i;
+
+	for (i = 0; i < ARRAY_SIZE(spi_slave_pool); i++) {
+		ds = spi_slave_pool + i;
+
+		if (!ds->allocated)
+			continue;
+
+		if ((ds->slave.bus == slave->bus) &&
+		    (ds->slave.cs == slave->cs))
+			return ds;
+	}
+
+	return NULL;
+}
+
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
 {
 	struct ipq_spi_slave *ds = NULL;
 	int i;
@@ -218,16 +237,17 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
 		printk(BIOS_ERR,
 			"SPI error: unsupported bus %d (Supported busses 0, 1 and 2) "
                         "or chipselect\n", bus);
-		return NULL;
+		return -1;
 	}
 
 	for (i = 0; i < ARRAY_SIZE(spi_slave_pool); i++) {
 		if (spi_slave_pool[i].allocated)
 			continue;
 		ds = spi_slave_pool + i;
-		ds->slave.bus	= bus;
-		ds->slave.cs	= cs;
-		ds->regs	= &spi_reg[bus];
+
+		ds->slave.bus = slave->bus = bus;
+		ds->slave.cs = slave->cs = cs;
+		ds->regs = &spi_reg[bus];
 
 		/*
 		 * TODO(vbendeb):
@@ -238,11 +258,11 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
 		ds->mode = SPI_MODE3;
 		ds->allocated = 1;
 
-		return &ds->slave;
+		return 0;
 	}
 
 	printk(BIOS_ERR, "SPI error: all %d pools busy\n", i);
-	return NULL;
+	return -1;
 }
 
 /*
diff --git a/src/soc/qualcomm/ipq806x/include/soc/spi.h b/src/soc/qualcomm/ipq806x/include/soc/spi.h
index 5dedcda..98a15b8 100644
--- a/src/soc/qualcomm/ipq806x/include/soc/spi.h
+++ b/src/soc/qualcomm/ipq806x/include/soc/spi.h
@@ -271,9 +271,4 @@ struct ipq_spi_slave {
 	int allocated;
 };
 
-static inline struct ipq_spi_slave *to_ipq_spi(const struct spi_slave *slave)
-{
-	return container_of(slave, struct ipq_spi_slave, slave);
-}
-
 #endif /* _IPQ806X_SPI_H_ */
diff --git a/src/soc/qualcomm/ipq806x/spi.c b/src/soc/qualcomm/ipq806x/spi.c
index d1af720..81dc508 100644
--- a/src/soc/qualcomm/ipq806x/spi.c
+++ b/src/soc/qualcomm/ipq806x/spi.c
@@ -499,7 +499,26 @@ void spi_init()
 	memset(spi_slave_pool, 0, sizeof(spi_slave_pool));
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+static struct ipq_spi_slave *to_ipq_spi(const struct spi_slave *slave)
+{
+	struct ipq_spi_slave *ds;
+	size_t i;
+
+	for (i = 0; i < ARRAY_SIZE(spi_slave_pool); i++) {
+		ds = spi_slave_pool + i;
+
+		if (!ds->allocated)
+			continue;
+
+		if ((ds->slave.bus == slave->bus) &&
+		    (ds->slave.cs == slave->cs))
+			return ds;
+	}
+
+	return NULL;
+}
+
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
 {
 	struct ipq_spi_slave *ds = NULL;
 	int i;
@@ -521,9 +540,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
 		if (spi_slave_pool[i].allocated)
 			continue;
 		ds = spi_slave_pool + i;
-		ds->slave.bus	= bus;
-		ds->slave.cs	= cs;
-		ds->regs	= &spi_reg[bus];
+
+		ds->slave.bus = slave->bus = bus;
+		ds->slave.cs = slave->cs = cs;
+		ds->regs = &spi_reg[bus];
 
 		/*
 		 * TODO(vbendeb):
@@ -534,11 +554,11 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
 		ds->mode = GSBI_SPI_MODE_0;
 		ds->allocated = 1;
 
-		return &ds->slave;
+		return 0;
 	}
 
 	printk(BIOS_ERR, "SPI error: all %d pools busy\n", i);
-	return NULL;
+	return -1;
 }
 
 /*
diff --git a/src/soc/rockchip/common/spi.c b/src/soc/rockchip/common/spi.c
index c5e5018..216ac86 100644
--- a/src/soc/rockchip/common/spi.c
+++ b/src/soc/rockchip/common/spi.c
@@ -27,7 +27,6 @@
 #include <timer.h>
 
 struct rockchip_spi_slave {
-	struct spi_slave slave;
 	struct rockchip_spi *regs;
 };
 
@@ -37,30 +36,24 @@ struct rockchip_spi_slave {
 
 static struct rockchip_spi_slave rockchip_spi_slaves[] = {
 	{
-	 .slave = { .bus = 0, },
 	 .regs = (void *)SPI0_BASE,
 	},
 	{
-	 .slave = { .bus = 1, },
 	 .regs = (void *)SPI1_BASE,
 	},
 	{
-	 .slave = { .bus = 2, },
 	 .regs = (void *)SPI2_BASE,
 	},
 #ifdef SPI3_BASE
 	{
-	 .slave = { .bus = 3, },
 	 .regs = (void *)SPI3_BASE,
 	},
 #ifdef SPI4_BASE
 	{
-	 .slave = { .bus = 4, },
 	 .regs = (void *)SPI4_BASE,
 	},
 #ifdef SPI5_BASE
 	{
-	 .slave = { .bus = 5, },
 	 .regs = (void *)SPI5_BASE,
 	},
 #endif
@@ -70,13 +63,18 @@ static struct rockchip_spi_slave rockchip_spi_slaves[] = {
 
 static struct rockchip_spi_slave *to_rockchip_spi(const struct spi_slave *slave)
 {
-	return container_of(slave, struct rockchip_spi_slave, slave);
+	assert(slave->bus >= 0 && slave->bus < ARRAY_SIZE(rockchip_spi_slaves));
+	return &rockchip_spi_slaves[slave->bus];
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
 {
 	assert(bus >= 0 && bus < ARRAY_SIZE(rockchip_spi_slaves));
-	return &(rockchip_spi_slaves[bus].slave);
+
+	slave->bus = bus;
+	slave->cs = cs;
+
+	return 0;
 }
 
 static void spi_cs_activate(const struct spi_slave *slave)
diff --git a/src/soc/samsung/exynos5420/spi.c b/src/soc/samsung/exynos5420/spi.c
index 02f04df..c809bb3 100644
--- a/src/soc/samsung/exynos5420/spi.c
+++ b/src/soc/samsung/exynos5420/spi.c
@@ -60,7 +60,7 @@ static struct exynos_spi_slave exynos_spi_slaves[3] = {
 
 static inline struct exynos_spi_slave *to_exynos_spi(const struct spi_slave *slave)
 {
-	return container_of(slave, struct exynos_spi_slave, slave);
+	return &exynos_spi_slaves[slave->bus];
 }
 
 static void spi_sw_reset(struct exynos_spi *regs, int word)
@@ -117,15 +117,20 @@ static void exynos_spi_init(struct exynos_spi *regs)
 	spi_sw_reset(regs, 1);
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
 {
 	ASSERT(bus >= 0 && bus < 3);
-	struct exynos_spi_slave *eslave = &exynos_spi_slaves[bus];
+	struct exynos_spi_slave *eslave;
+
+	slave->bus = bus;
+	slave->cs = cs;
+
+	eslave = to_exynos_spi(slave);
 	if (!eslave->initialized) {
 		exynos_spi_init(eslave->regs);
 		eslave->initialized = 1;
 	}
-	return &eslave->slave;
+	return 0;
 }
 
 int spi_claim_bus(const struct spi_slave *slave)
diff --git a/src/southbridge/amd/agesa/hudson/spi.c b/src/southbridge/amd/agesa/hudson/spi.c
index 7bb0e3f..a8b3b2a 100644
--- a/src/southbridge/amd/agesa/hudson/spi.c
+++ b/src/southbridge/amd/agesa/hudson/spi.c
@@ -176,15 +176,9 @@ int chipset_volatile_group_end(const struct spi_flash *flash)
 	return 0;
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
 {
-	struct spi_slave *slave = malloc(sizeof(*slave));
-
-	if (!slave) {
-		return NULL;
-	}
-
-	memset(slave, 0, sizeof(*slave));
-
-	return slave;
+	slave->bus = bus;
+	slave->cs = cs;
+	return 0;
 }
diff --git a/src/southbridge/amd/cimx/sb800/spi.c b/src/southbridge/amd/cimx/sb800/spi.c
index 2522c2e..d331060 100644
--- a/src/southbridge/amd/cimx/sb800/spi.c
+++ b/src/southbridge/amd/cimx/sb800/spi.c
@@ -168,15 +168,9 @@ int chipset_volatile_group_end(const struct spi_flash *flash)
 	return 0;
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
 {
-	struct spi_slave *slave = malloc(sizeof(*slave));
-
-	if (!slave) {
-		return NULL;
-	}
-
-	memset(slave, 0, sizeof(*slave));
-
-	return slave;
+	slave->bus = bus;
+	slave->cs = cs;
+	return 0;
 }
diff --git a/src/southbridge/amd/sb700/spi.c b/src/southbridge/amd/sb700/spi.c
index 2b1ae2d..fca401c 100644
--- a/src/southbridge/amd/sb700/spi.c
+++ b/src/southbridge/amd/sb700/spi.c
@@ -76,17 +76,11 @@ void spi_release_bus(const struct spi_slave *slave)
 	/* Handled internally by the SB700 */
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
 {
-	struct spi_slave *slave = malloc(sizeof(*slave));
-
-	if (!slave) {
-		return NULL;
-	}
-
-	memset(slave, 0, sizeof(*slave));
-
-	return slave;
+	slave->bus = bus;
+	slave->cs = cs;
+	return 0;
 }
 
 int spi_xfer(const struct spi_slave *slave, const void *dout,
diff --git a/src/southbridge/intel/common/spi.c b/src/southbridge/intel/common/spi.c
index 2d36d38..7e0cc20 100644
--- a/src/southbridge/intel/common/spi.c
+++ b/src/southbridge/intel/common/spi.c
@@ -285,20 +285,11 @@ static void ich_set_bbar(uint32_t minaddr)
 	writel_(ichspi_bbar, cntlr.bbar);
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
 {
-	ich_spi_slave *slave = malloc(sizeof(*slave));
-
-	if (!slave) {
-		printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n");
-		return NULL;
-	}
-
-	memset(slave, 0, sizeof(*slave));
-
 	slave->bus = bus;
 	slave->cs = cs;
-	return slave;
+	return 0;
 }
 
 void spi_init(void)
diff --git a/src/southbridge/intel/fsp_rangeley/spi.c b/src/southbridge/intel/fsp_rangeley/spi.c
index 8a0fac2..de676a9 100644
--- a/src/southbridge/intel/fsp_rangeley/spi.c
+++ b/src/southbridge/intel/fsp_rangeley/spi.c
@@ -322,20 +322,11 @@ static void ich_set_bbar(uint32_t minaddr)
 	writel_(ichspi_bbar, cntlr.bbar);
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
 {
-	ich_spi_slave *slave = malloc(sizeof(*slave));
-
-	if (!slave) {
-		printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n");
-		return NULL;
-	}
-
-	memset(slave, 0, sizeof(*slave));
-
 	slave->bus = bus;
 	slave->cs = cs;
-	return slave;
+	return 0;
 }
 
 /*



More information about the coreboot-gerrit mailing list