From eefffb42f6659c9510105f3e4ebf2a8499d56936 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 7 Mar 2019 16:54:21 +0100 Subject: spi: work around clang bug in SPI_BPW_RANGE_MASK() Clang-8 evaluates both sides of a ?: expression to check for valid arithmetic even in the side that is never taken. This results in a build warning: drivers/spi/spi-sh-msiof.c:1052:24: error: shift count >= width of type [-Werror,-Wshift-count-overflow] .bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32), ^~~~~~~~~~~~~~~~~~~~~~~~~ Change the implementation to use the GENMASK() macro that does what we want here but does not have a problem with the shift count overflow. Link: https://bugs.llvm.org/show_bug.cgi?id=38789 Signed-off-by: Arnd Bergmann Signed-off-by: Mark Brown --- include/linux/spi/spi.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 662b336aa2e4..b27386450089 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -444,8 +444,7 @@ struct spi_controller { /* bitmask of supported bits_per_word for transfers */ u32 bits_per_word_mask; #define SPI_BPW_MASK(bits) BIT((bits) - 1) -#define SPI_BIT_MASK(bits) (((bits) == 32) ? ~0U : (BIT(bits) - 1)) -#define SPI_BPW_RANGE_MASK(min, max) (SPI_BIT_MASK(max) - SPI_BIT_MASK(min - 1)) +#define SPI_BPW_RANGE_MASK(min, max) GENMASK((min) - 1, (max) - 1) /* limits on transfer speed */ u32 min_speed_hz; -- cgit v1.2.3-71-gd317 From 6d85028134d3f4f946924e2f9f0aaff47d9de840 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 13 Mar 2019 22:00:34 +0100 Subject: spi: fix SPI_BPW_RANGE_MASK() regression Geert points out that I confused the min/max arguments that are reversed between SPI_BPW_RANGE_MASK() and GENMASK(). This time I have verified the result of the macro after fixing the arguments. Cc: Geert Uytterhoeven Fixes: eefffb42f665 ("spi: work around clang bug in SPI_BPW_RANGE_MASK()") Signed-off-by: Arnd Bergmann Reviewed-by: Geert Uytterhoeven Signed-off-by: Mark Brown --- include/linux/spi/spi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index b27386450089..a0975cf76cf6 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -444,7 +444,7 @@ struct spi_controller { /* bitmask of supported bits_per_word for transfers */ u32 bits_per_word_mask; #define SPI_BPW_MASK(bits) BIT((bits) - 1) -#define SPI_BPW_RANGE_MASK(min, max) GENMASK((min) - 1, (max) - 1) +#define SPI_BPW_RANGE_MASK(min, max) GENMASK((max) - 1, (min) - 1) /* limits on transfer speed */ u32 min_speed_hz; -- cgit v1.2.3-71-gd317 From 37821a82e6789eaaa81dd32a67edc3511ebfd5aa Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 19 Mar 2019 17:48:42 +0200 Subject: spi: pxa2xx: Introduce DMA burst size support Some masters may have different DMA burst size than hard coded default. In such case respect the value given by DMA burst size provided via platform data. Signed-off-by: Andy Shevchenko Tested-by: Jarkko Nikula Reviewed-by: Jarkko Nikula Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx-dma.c | 4 +++- drivers/spi/spi-pxa2xx-pci.c | 4 ++++ drivers/spi/spi-pxa2xx.c | 1 + include/linux/spi/pxa2xx_spi.h | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/spi/spi-pxa2xx-dma.c b/drivers/spi/spi-pxa2xx-dma.c index 15592598273e..e5c26c1779ab 100644 --- a/drivers/spi/spi-pxa2xx-dma.c +++ b/drivers/spi/spi-pxa2xx-dma.c @@ -239,13 +239,15 @@ int pxa2xx_spi_set_dma_burst_and_threshold(struct chip_data *chip, u32 *threshold) { struct pxa2xx_spi_chip *chip_info = spi->controller_data; + struct driver_data *drv_data = spi_controller_get_devdata(spi->controller); + u32 dma_burst_size = drv_data->controller_info->dma_burst_size; /* * If the DMA burst size is given in chip_info we use that, * otherwise we use the default. Also we use the default FIFO * thresholds for now. */ - *burst_code = chip_info ? chip_info->dma_burst_size : 1; + *burst_code = chip_info ? chip_info->dma_burst_size : dma_burst_size; *threshold = SSCR1_RxTresh(RX_THRESH_DFLT) | SSCR1_TxTresh(TX_THRESH_DFLT); diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c index 4b162fdca35f..d456c5251b5d 100644 --- a/drivers/spi/spi-pxa2xx-pci.c +++ b/drivers/spi/spi-pxa2xx-pci.c @@ -34,6 +34,8 @@ struct pxa_spi_info { void *tx_param; void *rx_param; + int dma_burst_size; + int (*setup)(struct pci_dev *pdev, struct pxa_spi_info *c); }; @@ -132,6 +134,7 @@ static int mrfld_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c) rx->dma_dev = &dma_dev->dev; c->dma_filter = lpss_dma_filter; + c->dma_burst_size = 8; return 0; } @@ -222,6 +225,7 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, spi_pdata.tx_param = c->tx_param; spi_pdata.rx_param = c->rx_param; spi_pdata.enable_dma = c->rx_param && c->tx_param; + spi_pdata.dma_burst_size = c->dma_burst_size ? c->dma_burst_size : 1; ssp = &spi_pdata.ssp; ssp->phys_base = pci_resource_start(dev, 0); diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index b6ddba833d02..461c6b796b8f 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1564,6 +1564,7 @@ pxa2xx_spi_init_pdata(struct platform_device *pdev) pdata->is_slave = of_property_read_bool(pdev->dev.of_node, "spi-slave"); pdata->num_chipselect = 1; pdata->enable_dma = true; + pdata->dma_burst_size = 1; return pdata; } diff --git a/include/linux/spi/pxa2xx_spi.h b/include/linux/spi/pxa2xx_spi.h index c1c59473cef9..6005f0126631 100644 --- a/include/linux/spi/pxa2xx_spi.h +++ b/include/linux/spi/pxa2xx_spi.h @@ -25,6 +25,7 @@ struct dma_chan; struct pxa2xx_spi_controller { u16 num_chipselect; u8 enable_dma; + u8 dma_burst_size; bool is_slave; /* DMA engine specific config */ -- cgit v1.2.3-71-gd317 From 46109648052fe778c75f199d72255c899578d6f7 Mon Sep 17 00:00:00 2001 From: Naga Sureshkumar Relli Date: Mon, 1 Apr 2019 13:29:00 +0530 Subject: spi: spi-mem: export spi_mem_default_supports_op() Export spi_mem_default_supports_op(), so that controller drivers can use this. spi-mem driver already exports this using EXPORT_SYMBOL, but not declared it in spi-mem.h. This patch declares spi_mem_default_supports_op() in spi-mem.h and also removes the static from the function prototype. Signed-off-by: Naga Sureshkumar Relli Signed-off-by: Mark Brown --- drivers/spi/spi-mem.c | 4 ++-- include/linux/spi/spi-mem.h | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index a4d8d19ecff9..3397fd10cf8d 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -135,8 +135,8 @@ static int spi_check_buswidth_req(struct spi_mem *mem, u8 buswidth, bool tx) return -ENOTSUPP; } -static bool spi_mem_default_supports_op(struct spi_mem *mem, - const struct spi_mem_op *op) +bool spi_mem_default_supports_op(struct spi_mem *mem, + const struct spi_mem_op *op) { if (spi_check_buswidth_req(mem, op->cmd.buswidth, true)) return false; diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index 3703d0dcac2e..c845cd6e22ba 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h @@ -341,6 +341,9 @@ int spi_mem_driver_register_with_owner(struct spi_mem_driver *drv, void spi_mem_driver_unregister(struct spi_mem_driver *drv); +bool spi_mem_default_supports_op(struct spi_mem *mem, + const struct spi_mem_op *op); + #define spi_mem_driver_register(__drv) \ spi_mem_driver_register_with_owner(__drv, THIS_MODULE) -- cgit v1.2.3-71-gd317 From 45beec3519983cb11768cd3ee350f44975bf4cea Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Tue, 2 Apr 2019 21:01:32 -0700 Subject: spi: bitbang: Introduce spi_bitbang_init() Move all of the code doing struct spi_bitbang initialization, so that it can be paired with devm_spi_register_master() in order to avoid having to call spi_bitbang_stop() explicitly. Signed-off-by: Andrey Smirnov Cc: Mark Brown Cc: Chris Healy Cc: linux-spi@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Mark Brown --- drivers/spi/spi-bitbang.c | 66 ++++++++++++++++++++++++----------------- include/linux/spi/spi_bitbang.h | 1 + 2 files changed, 40 insertions(+), 27 deletions(-) (limited to 'include/linux') diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index dd9a8c54a693..4243e53f9f7b 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c @@ -335,6 +335,42 @@ static void spi_bitbang_set_cs(struct spi_device *spi, bool enable) /*----------------------------------------------------------------------*/ +int spi_bitbang_init(struct spi_bitbang *bitbang) +{ + struct spi_master *master = bitbang->master; + + if (!master || !bitbang->chipselect) + return -EINVAL; + + mutex_init(&bitbang->lock); + + if (!master->mode_bits) + master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags; + + if (master->transfer || master->transfer_one_message) + return -EINVAL; + + master->prepare_transfer_hardware = spi_bitbang_prepare_hardware; + master->unprepare_transfer_hardware = spi_bitbang_unprepare_hardware; + master->transfer_one = spi_bitbang_transfer_one; + master->set_cs = spi_bitbang_set_cs; + + if (!bitbang->txrx_bufs) { + bitbang->use_dma = 0; + bitbang->txrx_bufs = spi_bitbang_bufs; + if (!master->setup) { + if (!bitbang->setup_transfer) + bitbang->setup_transfer = + spi_bitbang_setup_transfer; + master->setup = spi_bitbang_setup; + master->cleanup = spi_bitbang_cleanup; + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(spi_bitbang_init); + /** * spi_bitbang_start - start up a polled/bitbanging SPI master driver * @bitbang: driver handle @@ -368,33 +404,9 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) struct spi_master *master = bitbang->master; int ret; - if (!master || !bitbang->chipselect) - return -EINVAL; - - mutex_init(&bitbang->lock); - - if (!master->mode_bits) - master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags; - - if (master->transfer || master->transfer_one_message) - return -EINVAL; - - master->prepare_transfer_hardware = spi_bitbang_prepare_hardware; - master->unprepare_transfer_hardware = spi_bitbang_unprepare_hardware; - master->transfer_one = spi_bitbang_transfer_one; - master->set_cs = spi_bitbang_set_cs; - - if (!bitbang->txrx_bufs) { - bitbang->use_dma = 0; - bitbang->txrx_bufs = spi_bitbang_bufs; - if (!master->setup) { - if (!bitbang->setup_transfer) - bitbang->setup_transfer = - spi_bitbang_setup_transfer; - master->setup = spi_bitbang_setup; - master->cleanup = spi_bitbang_cleanup; - } - } + ret = spi_bitbang_init(bitbang); + if (ret) + return ret; /* driver may get busy before register() returns, especially * if someone registered boardinfo for devices diff --git a/include/linux/spi/spi_bitbang.h b/include/linux/spi/spi_bitbang.h index b7e021b274dc..4444c2a992cb 100644 --- a/include/linux/spi/spi_bitbang.h +++ b/include/linux/spi/spi_bitbang.h @@ -44,6 +44,7 @@ extern int spi_bitbang_setup_transfer(struct spi_device *spi, /* start or stop queue processing */ extern int spi_bitbang_start(struct spi_bitbang *spi); +extern int spi_bitbang_init(struct spi_bitbang *spi); extern void spi_bitbang_stop(struct spi_bitbang *spi); #endif /* __SPI_BITBANG_H */ -- cgit v1.2.3-71-gd317 From f1ca9992ced71029735784de138f53446363087f Mon Sep 17 00:00:00 2001 From: Sowjanya Komatineni Date: Thu, 4 Apr 2019 17:14:16 -0700 Subject: spi: add a method for configuring CS timing This patch creates set_cs_timing SPI master optional method for SPI masters to implement configuring CS timing if applicable. This patch also creates spi_cs_timing accessory for SPI clients to use for requesting SPI master controllers to configure device requested CS setup time, hold time and inactive delay. Signed-off-by: Sowjanya Komatineni Signed-off-by: Mark Brown --- drivers/spi/spi.c | 15 +++++++++++++++ include/linux/spi/spi.h | 15 +++++++++++++++ 2 files changed, 30 insertions(+) (limited to 'include/linux') diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index fd1372fe0505..bf4027b54a19 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -2995,6 +2995,21 @@ int spi_setup(struct spi_device *spi) } EXPORT_SYMBOL_GPL(spi_setup); +/** + * spi_set_cs_timing - configure CS setup, hold, and inactive delays + * @spi: the device that requires specific CS timing configuration + * @setup: CS setup time in terms of clock count + * @hold: CS hold time in terms of clock count + * @inactive_dly: CS inactive delay between transfers in terms of clock count + */ +void spi_set_cs_timing(struct spi_device *spi, u8 setup, u8 hold, + u8 inactive_dly) +{ + if (spi->controller->set_cs_timing) + spi->controller->set_cs_timing(spi, setup, hold, inactive_dly); +} +EXPORT_SYMBOL_GPL(spi_set_cs_timing); + static int __spi_validate(struct spi_device *spi, struct spi_message *message) { struct spi_controller *ctlr = spi->controller; diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index a0975cf76cf6..589f9dc9ac2b 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -330,6 +330,9 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * must fail if an unrecognized or unsupported mode is requested. * It's always safe to call this unless transfers are pending on * the device whose settings are being modified. + * @set_cs_timing: optional hook for SPI devices to request SPI master + * controller for configuring specific CS setup time, hold time and inactive + * delay interms of clock counts * @transfer: adds a message to the controller's transfer queue. * @cleanup: frees controller-specific state * @can_dma: determine whether this controller supports DMA @@ -363,6 +366,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * @unprepare_transfer_hardware: there are currently no more messages on the * queue so the subsystem notifies the driver that it may relax the * hardware by issuing this call + * * @set_cs: set the logic level of the chip select line. May be called * from interrupt context. * @prepare_message: set up the controller to transfer a single message, @@ -488,6 +492,17 @@ struct spi_controller { */ int (*setup)(struct spi_device *spi); + /* + * set_cs_timing() method is for SPI controllers that supports + * configuring CS timing. + * + * This hook allows SPI client drivers to request SPI controllers + * to configure specific CS timing through spi_set_cs_timing() after + * spi_setup(). + */ + void (*set_cs_timing)(struct spi_device *spi, u8 setup_clk_cycles, + u8 hold_clk_cycles, u8 inactive_clk_cycles); + /* bidirectional bulk transfers * * + The transfer() method may not sleep; its main role is -- cgit v1.2.3-71-gd317 From 72e6841608b9ce7e04515ed43693b2878936c93a Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Mon, 8 Apr 2019 22:39:49 +0800 Subject: spi: spi-mem: Fix build error without CONFIG_SPI_MEM When building with CONFIG_SPI_MEM is not set gc warns this: drivers/spi/spi-zynq-qspi.o: In function `zynq_qspi_supports_op': spi-zynq-qspi.c:(.text+0x1da): undefined reference to `spi_mem_default_supports_op' Fixes: 67dca5e580f1 ("spi: spi-mem: Add support for Zynq QSPI controller") Signed-off-by: YueHaibing Signed-off-by: Mark Brown --- include/linux/spi/spi-mem.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index c845cd6e22ba..1941b845aa15 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h @@ -295,6 +295,10 @@ int spi_controller_dma_map_mem_op_data(struct spi_controller *ctlr, void spi_controller_dma_unmap_mem_op_data(struct spi_controller *ctlr, const struct spi_mem_op *op, struct sg_table *sg); + +bool spi_mem_default_supports_op(struct spi_mem *mem, + const struct spi_mem_op *op); + #else static inline int spi_controller_dma_map_mem_op_data(struct spi_controller *ctlr, @@ -310,6 +314,13 @@ spi_controller_dma_unmap_mem_op_data(struct spi_controller *ctlr, struct sg_table *sg) { } + +bool spi_mem_default_supports_op(struct spi_mem *mem, + const struct spi_mem_op *op) +{ + return false; +} + #endif /* CONFIG_SPI_MEM */ int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op); @@ -341,9 +352,6 @@ int spi_mem_driver_register_with_owner(struct spi_mem_driver *drv, void spi_mem_driver_unregister(struct spi_mem_driver *drv); -bool spi_mem_default_supports_op(struct spi_mem *mem, - const struct spi_mem_op *op); - #define spi_mem_driver_register(__drv) \ spi_mem_driver_register_with_owner(__drv, THIS_MODULE) -- cgit v1.2.3-71-gd317 From b5881b153bc81d63a5a7e82a35e8a4bdbe1f8c73 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Wed, 10 Apr 2019 21:18:28 +0800 Subject: spi: spi-mem: Make spi_mem_default_supports_op() static inline Stub helper spi_mem_default_supports_op() should be set to static inline Signed-off-by: YueHaibing Signed-off-by: Mark Brown --- include/linux/spi/spi-mem.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index 1941b845aa15..af9ff2f0f1b2 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h @@ -315,6 +315,7 @@ spi_controller_dma_unmap_mem_op_data(struct spi_controller *ctlr, { } +static inline bool spi_mem_default_supports_op(struct spi_mem *mem, const struct spi_mem_op *op) { -- cgit v1.2.3-71-gd317 From 937e6d756422637eeb212c645ded69569a67fabc Mon Sep 17 00:00:00 2001 From: Sowjanya Komatineni Date: Mon, 15 Apr 2019 14:30:27 -0700 Subject: spi: expand mode support This patch changes mode and mode_bits from u16 to u32 to allow more mode configurations. Signed-off-by: Sowjanya Komatineni Signed-off-by: Mark Brown --- include/linux/spi/spi.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 589f9dc9ac2b..053abd22ad31 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -143,7 +143,7 @@ struct spi_device { u32 max_speed_hz; u8 chip_select; u8 bits_per_word; - u16 mode; + u32 mode; #define SPI_CPHA 0x01 /* clock phase */ #define SPI_CPOL 0x02 /* clock polarity */ #define SPI_MODE_0 (0|0) /* (original MicroWire) */ @@ -443,7 +443,7 @@ struct spi_controller { u16 dma_alignment; /* spi_device.mode flags understood by this controller driver */ - u16 mode_bits; + u32 mode_bits; /* bitmask of supported bits_per_word for transfers */ u32 bits_per_word_mask; @@ -1291,7 +1291,7 @@ struct spi_board_info { /* mode becomes spi_device.mode, and is essential for chips * where the default of SPI_CS_HIGH = 0 is wrong. */ - u16 mode; + u32 mode; /* ... may need additional spi_device chip config data here. * avoid stuff protocol drivers can set; but include stuff -- cgit v1.2.3-71-gd317 From 1dfbf334f12361ebe6269c5918328b755ee960c7 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sat, 20 Apr 2019 13:05:59 +0200 Subject: spi: ep93xx: Convert to use CS GPIO descriptors This converts the EP93xx SPI master driver to use GPIO descriptors for chip select handling. EP93xx was using platform data to pass in GPIO lines, by converting all board files to use GPIO descriptor tables the core will look up the GPIO lines from the SPI device in the same manner as for device tree. Signed-off-by: Linus Walleij Signed-off-by: Mark Brown --- arch/arm/mach-ep93xx/edb93xx.c | 13 +++++++++---- arch/arm/mach-ep93xx/simone.c | 11 +++++++---- arch/arm/mach-ep93xx/ts72xx.c | 25 +++++++++++++++++-------- arch/arm/mach-ep93xx/vision_ep9307.c | 15 +++++++++------ drivers/spi/spi-ep93xx.c | 32 ++++++-------------------------- include/linux/platform_data/spi-ep93xx.h | 4 ---- 6 files changed, 48 insertions(+), 52 deletions(-) (limited to 'include/linux') diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c index 8e89ec8b6f0f..34e18e9556d9 100644 --- a/arch/arm/mach-ep93xx/edb93xx.c +++ b/arch/arm/mach-ep93xx/edb93xx.c @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -105,13 +106,16 @@ static struct spi_board_info edb93xx_spi_board_info[] __initdata = { }, }; -static int edb93xx_spi_chipselects[] __initdata = { - EP93XX_GPIO_LINE_EGPIO6, +static struct gpiod_lookup_table edb93xx_spi_cs_gpio_table = { + .dev_id = "ep93xx-spi.0", + .table = { + GPIO_LOOKUP("A", 6, "cs", GPIO_ACTIVE_LOW), + { }, + }, }; static struct ep93xx_spi_info edb93xx_spi_info __initdata = { - .chipselect = edb93xx_spi_chipselects, - .num_chipselect = ARRAY_SIZE(edb93xx_spi_chipselects), + /* Intentionally left blank */ }; static void __init edb93xx_register_spi(void) @@ -123,6 +127,7 @@ static void __init edb93xx_register_spi(void) else if (machine_is_edb9315a()) edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_EGPIO14; + gpiod_add_lookup_table(&edb93xx_spi_cs_gpio_table); ep93xx_register_spi(&edb93xx_spi_info, edb93xx_spi_board_info, ARRAY_SIZE(edb93xx_spi_board_info)); } diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c index 80ccb984d521..f0f38c0dba52 100644 --- a/arch/arm/mach-ep93xx/simone.c +++ b/arch/arm/mach-ep93xx/simone.c @@ -77,13 +77,15 @@ static struct spi_board_info simone_spi_devices[] __initdata = { * low between multi-message command blocks. From v1.4, it uses a GPIO instead. * v1.3 parts will still work, since the signal on SFRMOUT is automatic. */ -static int simone_spi_chipselects[] __initdata = { - EP93XX_GPIO_LINE_EGPIO1, +static struct gpiod_lookup_table simone_spi_cs_gpio_table = { + .dev_id = "ep93xx-spi.0", + .table = { + GPIO_LOOKUP("A", 1, "cs", GPIO_ACTIVE_LOW), + { }, + }, }; static struct ep93xx_spi_info simone_spi_info __initdata = { - .chipselect = simone_spi_chipselects, - .num_chipselect = ARRAY_SIZE(simone_spi_chipselects), .use_dma = 1, }; @@ -113,6 +115,7 @@ static void __init simone_init_machine(void) ep93xx_register_i2c(simone_i2c_board_info, ARRAY_SIZE(simone_i2c_board_info)); gpiod_add_lookup_table(&simone_mmc_spi_gpio_table); + gpiod_add_lookup_table(&simone_spi_cs_gpio_table); ep93xx_register_spi(&simone_spi_info, simone_spi_devices, ARRAY_SIZE(simone_spi_devices)); simone_register_audio(); diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c index 85b74ac943f0..a3a20c83c6b8 100644 --- a/arch/arm/mach-ep93xx/ts72xx.c +++ b/arch/arm/mach-ep93xx/ts72xx.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -269,13 +270,15 @@ static struct spi_board_info bk3_spi_board_info[] __initdata = { * The all work is performed automatically by !SPI_FRAME (SFRM1) and * goes through CPLD */ -static int bk3_spi_chipselects[] __initdata = { - EP93XX_GPIO_LINE_F(3), +static struct gpiod_lookup_table bk3_spi_cs_gpio_table = { + .dev_id = "ep93xx-spi.0", + .table = { + GPIO_LOOKUP("F", 3, "cs", GPIO_ACTIVE_LOW), + { }, + }, }; static struct ep93xx_spi_info bk3_spi_master __initdata = { - .chipselect = bk3_spi_chipselects, - .num_chipselect = ARRAY_SIZE(bk3_spi_chipselects), .use_dma = 1, }; @@ -316,13 +319,17 @@ static struct spi_board_info ts72xx_spi_devices[] __initdata = { }, }; -static int ts72xx_spi_chipselects[] __initdata = { - EP93XX_GPIO_LINE_F(2), /* DIO_17 */ +static struct gpiod_lookup_table ts72xx_spi_cs_gpio_table = { + .dev_id = "ep93xx-spi.0", + .table = { + /* DIO_17 */ + GPIO_LOOKUP("F", 2, "cs", GPIO_ACTIVE_LOW), + { }, + }, }; static struct ep93xx_spi_info ts72xx_spi_info __initdata = { - .chipselect = ts72xx_spi_chipselects, - .num_chipselect = ARRAY_SIZE(ts72xx_spi_chipselects), + /* Intentionally left blank */ }; static void __init ts72xx_init_machine(void) @@ -339,6 +346,7 @@ static void __init ts72xx_init_machine(void) if (board_is_ts7300()) platform_device_register(&ts73xx_fpga_device); #endif + gpiod_add_lookup_table(&ts72xx_spi_cs_gpio_table); ep93xx_register_spi(&ts72xx_spi_info, ts72xx_spi_devices, ARRAY_SIZE(ts72xx_spi_devices)); } @@ -398,6 +406,7 @@ static void __init bk3_init_machine(void) ep93xx_register_eth(&ts72xx_eth_data, 1); + gpiod_add_lookup_table(&bk3_spi_cs_gpio_table); ep93xx_register_spi(&bk3_spi_master, bk3_spi_board_info, ARRAY_SIZE(bk3_spi_board_info)); diff --git a/arch/arm/mach-ep93xx/vision_ep9307.c b/arch/arm/mach-ep93xx/vision_ep9307.c index 767ee64628dc..f95a644769e4 100644 --- a/arch/arm/mach-ep93xx/vision_ep9307.c +++ b/arch/arm/mach-ep93xx/vision_ep9307.c @@ -245,15 +245,17 @@ static struct spi_board_info vision_spi_board_info[] __initdata = { }, }; -static int vision_spi_chipselects[] __initdata = { - EP93XX_GPIO_LINE_EGPIO6, - EP93XX_GPIO_LINE_EGPIO7, - EP93XX_GPIO_LINE_G(2), +static struct gpiod_lookup_table vision_spi_cs_gpio_table = { + .dev_id = "ep93xx-spi.0", + .table = { + GPIO_LOOKUP_IDX("A", 6, "cs", 0, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("A", 7, "cs", 1, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("G", 2, "cs", 2, GPIO_ACTIVE_LOW), + { }, + }, }; static struct ep93xx_spi_info vision_spi_master __initdata = { - .chipselect = vision_spi_chipselects, - .num_chipselect = ARRAY_SIZE(vision_spi_chipselects), .use_dma = 1, }; @@ -295,6 +297,7 @@ static void __init vision_init_machine(void) ep93xx_register_i2c(vision_i2c_info, ARRAY_SIZE(vision_i2c_info)); gpiod_add_lookup_table(&vision_spi_mmc_gpio_table); + gpiod_add_lookup_table(&vision_spi_cs_gpio_table); ep93xx_register_spi(&vision_spi_master, vision_spi_board_info, ARRAY_SIZE(vision_spi_board_info)); vision_register_i2s(); diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index 79fc3940245a..47e39251bad9 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -676,6 +675,7 @@ static int ep93xx_spi_probe(struct platform_device *pdev) if (!master) return -ENOMEM; + master->use_gpio_descriptors = true; master->prepare_transfer_hardware = ep93xx_spi_prepare_hardware; master->unprepare_transfer_hardware = ep93xx_spi_unprepare_hardware; master->prepare_message = ep93xx_spi_prepare_message; @@ -683,31 +683,11 @@ static int ep93xx_spi_probe(struct platform_device *pdev) master->bus_num = pdev->id; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); - - master->num_chipselect = info->num_chipselect; - master->cs_gpios = devm_kcalloc(&master->dev, - master->num_chipselect, sizeof(int), - GFP_KERNEL); - if (!master->cs_gpios) { - error = -ENOMEM; - goto fail_release_master; - } - - for (i = 0; i < master->num_chipselect; i++) { - master->cs_gpios[i] = info->chipselect[i]; - - if (!gpio_is_valid(master->cs_gpios[i])) - continue; - - error = devm_gpio_request_one(&pdev->dev, master->cs_gpios[i], - GPIOF_OUT_INIT_HIGH, - "ep93xx-spi"); - if (error) { - dev_err(&pdev->dev, "could not request cs gpio %d\n", - master->cs_gpios[i]); - goto fail_release_master; - } - } + /* + * The SPI core will count the number of GPIO descriptors to figure + * out the number of chip selects available on the platform. + */ + master->num_chipselect = 0; platform_set_drvdata(pdev, master); diff --git a/include/linux/platform_data/spi-ep93xx.h b/include/linux/platform_data/spi-ep93xx.h index eb16c6739ac2..b439f2a896e0 100644 --- a/include/linux/platform_data/spi-ep93xx.h +++ b/include/linux/platform_data/spi-ep93xx.h @@ -6,13 +6,9 @@ struct spi_device; /** * struct ep93xx_spi_info - EP93xx specific SPI descriptor - * @chipselect: array of gpio numbers to use as chip selects - * @num_chipselect: ARRAY_SIZE(chipselect) * @use_dma: use DMA for the transfers */ struct ep93xx_spi_info { - int *chipselect; - int num_chipselect; bool use_dma; }; -- cgit v1.2.3-71-gd317