diff options
author | Aaron Durbin <adurbin@chromium.org> | 2018-04-19 21:15:25 -0600 |
---|---|---|
committer | Aaron Durbin <adurbin@chromium.org> | 2018-04-23 20:58:58 +0000 |
commit | 851dde8255efda7ecf9b37a3b7b22f4edab8881f (patch) | |
tree | 10a4d241f9af25db1fb9c71b696dfecb7ca5cf44 /src/drivers | |
parent | 6c2b10e98933569f028d2ee78efb4cc660d2f9ac (diff) |
drivers/spi: reduce confusion in the API
Julius brought up confusion about the current spi api in [1]. In order
alleviate the confusion stemming from supporting x86 spi flash
controllers:
- Remove spi_xfer_two_vectors() which was fusing transactions to
accomodate the limitations of the spi controllers themselves.
- Add spi_flash_vector_helper() for the x86 spi flash controllers to
utilize in validating driver/controller current assumptions.
- Remove the xfer() callback in the x86 spi flash drivers which
will trigger an error as these controllers can't support the api.
[1] https://mail.coreboot.org/pipermail/coreboot/2018-April/086561.html
Change-Id: Id88adc6ad5234c29a739d43521c5f344bb7d3217
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: https://review.coreboot.org/25745
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
Diffstat (limited to 'src/drivers')
-rw-r--r-- | src/drivers/spi/spi-generic.c | 53 | ||||
-rw-r--r-- | src/drivers/spi/spi_flash.c | 48 |
2 files changed, 48 insertions, 53 deletions
diff --git a/src/drivers/spi/spi-generic.c b/src/drivers/spi/spi-generic.c index 1fcc05d4f3..6d7fcdc021 100644 --- a/src/drivers/spi/spi-generic.c +++ b/src/drivers/spi/spi-generic.c @@ -146,56 +146,3 @@ int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) return 0; } - -static int spi_xfer_combine_two_vectors(const struct spi_slave *slave, - struct spi_op *v1, struct spi_op *v2) -{ - struct spi_op op = { - .dout = v1->dout, .bytesout = v1->bytesout, - .din = v2->din, .bytesin = v2->bytesin, - }; - int ret; - - /* - * Combine two vectors only if: - * v1 has non-NULL dout and NULL din and - * v2 has non-NULL din and NULL dout and - * - * In all other cases, do not combine the two vectors. - */ - if ((!v1->dout || v1->din) || (v2->dout || !v2->din)) - return -1; - - ret = spi_xfer_single_op(slave, &op); - v1->status = v2->status = op.status; - - return ret; -} - -/* - * Helper function to allow chipsets to combine two vectors if possible. This - * function can only handle upto 2 vectors. - * - * Two vectors are combined if first vector has a non-NULL dout and NULL din and - * second vector has a non-NULL din and NULL dout. Otherwise, each vector is - * operated upon one at a time. - * - * Returns 0 on success and non-zero on failure. - */ -int spi_xfer_two_vectors(const struct spi_slave *slave, - struct spi_op vectors[], size_t count) -{ - int ret; - - assert (count <= 2); - - if (count == 2) { - ret = spi_xfer_combine_two_vectors(slave, &vectors[0], - &vectors[1]); - - if (!ret || (vectors[0].status != SPI_OP_NOT_EXECUTED)) - return ret; - } - - return spi_xfer_vector_default(slave, vectors, count); -} diff --git a/src/drivers/spi/spi_flash.c b/src/drivers/spi/spi_flash.c index f0f119addb..9cb10855fa 100644 --- a/src/drivers/spi/spi_flash.c +++ b/src/drivers/spi/spi_flash.c @@ -519,3 +519,51 @@ int spi_flash_ctrlr_protect_region(const struct spi_flash *flash, return -1; } + +int spi_flash_vector_helper(const struct spi_slave *slave, + struct spi_op vectors[], size_t count, + int (*func)(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin)) +{ + int ret; + void *din; + size_t bytes_in; + + if (count < 1 || count > 2) + return -1; + + /* SPI flash commands always have a command first... */ + if (!vectors[0].dout || !vectors[0].bytesout) + return -1; + /* And not read any data during the command. */ + if (vectors[0].din || vectors[0].bytesin) + return -1; + + if (count == 2) { + /* If response bytes requested ensure the buffer is valid. */ + if (vectors[1].bytesin && !vectors[1].din) + return -1; + /* No sends can accompany a receive. */ + if (vectors[1].dout || vectors[1].bytesout) + return -1; + din = vectors[1].din; + bytes_in = vectors[1].bytesin; + } else { + din = NULL; + bytes_in = 0; + } + + ret = func(slave, vectors[0].dout, vectors[0].bytesout, din, bytes_in); + + if (ret) { + vectors[0].status = SPI_OP_FAILURE; + if (count == 2) + vectors[1].status = SPI_OP_FAILURE; + } else { + vectors[0].status = SPI_OP_SUCCESS; + if (count == 2) + vectors[1].status = SPI_OP_SUCCESS; + } + + return ret; +} |