diff options
author | Steffen Trumtrar <s.trumtrar@pengutronix.de> | 2019-05-03 11:33:54 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2019-05-08 10:52:51 +0200 |
commit | c8516869c49677bb1468e0e2e351bc05b815e4ef (patch) | |
tree | 233230d051ce0166cbdbb75ccaad7d599f61ad9c /drivers/spi/spi.c | |
parent | 167a27b5354910b92c7a4654a44d72a3d167f0ab (diff) | |
download | barebox-c8516869c49677bb1468e0e2e351bc05b815e4ef.tar.gz barebox-c8516869c49677bb1468e0e2e351bc05b815e4ef.tar.xz |
spi: Extend the core to ease integration of SPI memory controllers
Sync with Linux v5.1-rc1.
This is the barebox adoption of the commit
commit c36ff266dc82f4ae797a6f3513c6ffa344f7f1c7
Author: Boris Brezillon <boris.brezillon@bootlin.com>
Date: Thu Apr 26 18:18:14 2018 +0200
spi: Extend the core to ease integration of SPI memory controllers
Some controllers are exposing high-level interfaces to access various
kind of SPI memories. Unfortunately they do not fit in the current
spi_controller model and usually have drivers placed in
drivers/mtd/spi-nor which are only supporting SPI NORs and not SPI
memories in general.
This is an attempt at defining a SPI memory interface which works for
all kinds of SPI memories (NORs, NANDs, SRAMs).
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Reviewed-by: Frieder Schrempf <frieder.schrempf@exceet.de>
Tested-by: Frieder Schrempf <frieder.schrempf@exceet.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/spi/spi.c')
-rw-r--r-- | drivers/spi/spi.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 7756304f19..d9311d4af5 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -19,6 +19,7 @@ */ #include <common.h> +#include <linux/spi/spi-mem.h> #include <spi/spi.h> #include <xfuncs.h> #include <malloc.h> @@ -58,6 +59,7 @@ struct spi_device *spi_new_device(struct spi_controller *ctrl, struct spi_board_info *chip) { struct spi_device *proxy; + struct spi_mem *mem; int status; /* Chipselects are numbered 0..max; validate. */ @@ -84,6 +86,15 @@ struct spi_device *spi_new_device(struct spi_controller *ctrl, proxy->dev.parent = ctrl->dev; proxy->master = proxy->controller = ctrl; + mem = xzalloc(sizeof *mem); + mem->spi = proxy; + + if (ctrl->mem_ops && ctrl->mem_ops->get_name) + mem->name = ctrl->mem_ops->get_name(mem); + else + mem->name = dev_name(&proxy->dev); + proxy->mem = mem; + /* drivers may modify this initial i/o setup */ status = ctrl->setup(proxy); if (status < 0) { @@ -194,6 +205,26 @@ static void scan_boardinfo(struct spi_controller *ctrl) static LIST_HEAD(spi_controller_list); +static int spi_controller_check_ops(struct spi_controller *ctlr) +{ + /* + * The controller may implement only the high-level SPI-memory like + * operations if it does not support regular SPI transfers, and this is + * valid use case. + * If ->mem_ops is NULL, we request that at least one of the + * ->transfer_xxx() method be implemented. + */ + if (ctlr->mem_ops) { + if (!ctlr->mem_ops->exec_op) + return -EINVAL; + } else if (!ctlr->transfer) { + return -EINVAL; + } + + return 0; +} + + /** * spi_register_ctrl - register SPI ctrl controller * @ctrl: initialized ctrl, originally from spi_alloc_ctrl() @@ -221,6 +252,14 @@ int spi_register_controller(struct spi_controller *ctrl) debug("%s: %s:%d\n", __func__, ctrl->dev->name, ctrl->dev->id); + /* + * Make sure all necessary hooks are implemented before registering + * the SPI controller. + */ + status = spi_controller_check_ops(ctrl); + if (status) + return status; + /* even if it's just one always-selected device, there must * be at least one chipselect */ |