From c8516869c49677bb1468e0e2e351bc05b815e4ef Mon Sep 17 00:00:00 2001 From: Steffen Trumtrar Date: Fri, 3 May 2019 11:33:54 +0200 Subject: 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 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 Reviewed-by: Frieder Schrempf Tested-by: Frieder Schrempf Signed-off-by: Mark Brown Signed-off-by: Steffen Trumtrar Signed-off-by: Sascha Hauer --- include/spi/spi.h | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'include/spi') diff --git a/include/spi/spi.h b/include/spi/spi.h index 6eeaf254c7..bdcda0bb60 100644 --- a/include/spi/spi.h +++ b/include/spi/spi.h @@ -2,8 +2,12 @@ #define __INCLUDE_SPI_H #include +#include +#include #include +struct spi_controller_mem_ops; + struct spi_board_info { char *name; int max_speed_hz; @@ -62,6 +66,7 @@ struct spi_device { struct device_d dev; struct spi_controller *controller; struct spi_controller *master; /* compatibility layer */ + struct spi_mem *mem; u32 max_speed_hz; u8 chip_select; u8 mode; @@ -109,6 +114,13 @@ struct spi_message; * @dev: device interface to this driver * @bus_num: board-specific (and often SOC-specific) identifier for a * given SPI controller. + * @mem_ops: optimized/dedicated operations for interactions with SPI + * memory. This field is optional and should only be implemented + * if the controller has native support for memory like operations. + * @max_transfer_size: function that returns the max transfer size for + * a &spi_device; may be %NULL, so the default %SIZE_MAX will be used. + * @max_message_size: function that returns the max message size for + * a &spi_device; may be %NULL, so the default %SIZE_MAX will be used. * @num_chipselect: chipselects are used to distinguish individual * SPI slaves, and are numbered from zero to num_chipselects. * each slave has a chipselect signal, but it's common that not @@ -144,6 +156,15 @@ struct spi_controller { */ s16 bus_num; + /* Optimized handlers for SPI memory-like operations */ + const struct spi_controller_mem_ops *mem_ops; + /* + * on some hardware transfer size may be constrained + * the limit may depend on device transfer settings + */ + size_t (*max_transfer_size)(struct spi_device *spi); + size_t (*max_message_size)(struct spi_device *spi); + /* chipselects will be integral to many controllers; some others * might use board-specific GPIOs. */ @@ -180,6 +201,40 @@ struct spi_controller { struct list_head list; }; +static inline void *spi_controller_get_devdata(struct spi_controller *ctlr) +{ + if (ctlr->dev->platform_data) + return ctlr->dev->platform_data; + else + return ERR_PTR(-EINVAL); +} + +static inline void spi_controller_set_devdata(struct spi_controller *ctlr, + void *data) +{ + ctlr->dev->platform_data = data; +} + +static inline size_t spi_max_message_size(struct spi_device *spi) +{ + struct spi_controller *ctrl = spi->controller; + if (!ctrl->max_transfer_size) + return SIZE_MAX; + return ctrl->max_transfer_size(spi); +} + +static inline size_t spi_max_transfer_size(struct spi_device *spi) +{ + struct spi_controller *ctrl = spi->controller; + size_t tr_max = SIZE_MAX; + size_t msg_max = spi_max_message_size(spi); + + if (ctrl->max_transfer_size) + tr_max = ctrl->max_transfer_size(spi); + + return min(tr_max, msg_max); +} + #define spi_master spi_controller #define spi_register_master(_ctrl) spi_register_controller(_ctrl) -- cgit v1.2.3