diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-14 15:01:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-14 15:01:08 -0400 |
commit | 010b0e708e08727d38b82accb21832b63fe2c250 (patch) | |
tree | 29f110982a25675c02346320b2529ffd82aef244 | |
parent | 792adb90fa724ce07c0171cbc96b9215af4b1045 (diff) | |
parent | c1acb21b32a3bb601453764c9eac9fc8fbb3a81d (diff) |
Merge tag 'spi-v4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi updates from Mark Brown:
"Quite an active release for the SPI subsystem, lots of small updates
and fixes scattered about with highlights including:
- 3-wire support in the GPIO driver.
- support for setting a custom memory name in the memory mapped flash
drivers.
- support for extended mode in the Freescale DSPI controller.
- support for the non-standard integration with the Microsemi Ocelot
platform in the DesignWare driver.
- new driver for the SocioNext UniPhier"
* tag 'spi-v4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (47 commits)
spi: davinci: fix a NULL pointer dereference
spi: spi-mem: Constify spi_mem->name
mtd: m25p80: Call spi_mem_get_name() to let controller set a custom name
spi: spi-mem: Extend the SPI mem interface to set a custom memory name
spi: spi-mem: Fix a typo in the documentation of struct spi_mem
spi: uniphier: remove unnecessary include headers
spi: spi-gpio: add SPI_3WIRE support
spi: add flags parameter to txrx_word function pointers
spi: add SPI controller driver for UniPhier SoC
spi: add DT bindings for UniPhier SPI controller
spi: dw: document Microsemi integration
spi: img-spfi: Set device select bits for SPFI port state
spi: omap2-mcspi: remove several redundant variables
spi: dw-mmio: add MSCC Ocelot support
spi: dw: export dw_spi_set_cs
spi: spi-fsl-espi: Log fifo counters on error
spi: imx: Use the longuest possible burst size when in dynamic_burst
spi: imx: remove unnecessary check in spi_imx_can_dma
spi: imx: Use correct number of bytes per words
spi: imx: Use dynamic bursts only when bits_per_word is 8, 16 or 32
...
31 files changed, 1253 insertions, 674 deletions
diff --git a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.txt b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.txt index 204b311e0400..642d3fb1ef85 100644 --- a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.txt +++ b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.txt | |||
@@ -1,8 +1,10 @@ | |||
1 | Synopsys DesignWare AMBA 2.0 Synchronous Serial Interface. | 1 | Synopsys DesignWare AMBA 2.0 Synchronous Serial Interface. |
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | - compatible : "snps,dw-apb-ssi" | 4 | - compatible : "snps,dw-apb-ssi" or "mscc,<soc>-spi", where soc is "ocelot" or |
5 | - reg : The register base for the controller. | 5 | "jaguar2" |
6 | - reg : The register base for the controller. For "mscc,<soc>-spi", a second | ||
7 | register set is required (named ICPU_CFG:SPI_MST) | ||
6 | - interrupts : One interrupt, used by the controller. | 8 | - interrupts : One interrupt, used by the controller. |
7 | - #address-cells : <1>, as required by generic SPI binding. | 9 | - #address-cells : <1>, as required by generic SPI binding. |
8 | - #size-cells : <0>, also as required by generic SPI binding. | 10 | - #size-cells : <0>, also as required by generic SPI binding. |
diff --git a/Documentation/devicetree/bindings/spi/spi-rockchip.txt b/Documentation/devicetree/bindings/spi/spi-rockchip.txt index 6e3ffacbba32..a0edac12d8df 100644 --- a/Documentation/devicetree/bindings/spi/spi-rockchip.txt +++ b/Documentation/devicetree/bindings/spi/spi-rockchip.txt | |||
@@ -7,6 +7,7 @@ Required Properties: | |||
7 | 7 | ||
8 | - compatible: should be one of the following. | 8 | - compatible: should be one of the following. |
9 | "rockchip,rv1108-spi" for rv1108 SoCs. | 9 | "rockchip,rv1108-spi" for rv1108 SoCs. |
10 | "rockchip,px30-spi", "rockchip,rk3066-spi" for px30 SoCs. | ||
10 | "rockchip,rk3036-spi" for rk3036 SoCS. | 11 | "rockchip,rk3036-spi" for rk3036 SoCS. |
11 | "rockchip,rk3066-spi" for rk3066 SoCs. | 12 | "rockchip,rk3066-spi" for rk3066 SoCs. |
12 | "rockchip,rk3188-spi" for rk3188 SoCs. | 13 | "rockchip,rk3188-spi" for rk3188 SoCs. |
diff --git a/Documentation/devicetree/bindings/spi/spi-uniphier.txt b/Documentation/devicetree/bindings/spi/spi-uniphier.txt new file mode 100644 index 000000000000..504a4ecfc7b1 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/spi-uniphier.txt | |||
@@ -0,0 +1,22 @@ | |||
1 | Socionext UniPhier SPI controller driver | ||
2 | |||
3 | UniPhier SoCs have SCSSI which supports SPI single channel. | ||
4 | |||
5 | Required properties: | ||
6 | - compatible: should be "socionext,uniphier-scssi" | ||
7 | - reg: address and length of the spi master registers | ||
8 | - #address-cells: must be <1>, see spi-bus.txt | ||
9 | - #size-cells: must be <0>, see spi-bus.txt | ||
10 | - clocks: A phandle to the clock for the device. | ||
11 | - resets: A phandle to the reset control for the device. | ||
12 | |||
13 | Example: | ||
14 | |||
15 | spi0: spi@54006000 { | ||
16 | compatible = "socionext,uniphier-scssi"; | ||
17 | reg = <0x54006000 0x100>; | ||
18 | #address-cells = <1>; | ||
19 | #size-cells = <0>; | ||
20 | clocks = <&peri_clk 11>; | ||
21 | resets = <&peri_rst 11>; | ||
22 | }; | ||
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index fe260ccb2d7d..cbfafc453274 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c | |||
@@ -199,6 +199,9 @@ static int m25p_probe(struct spi_mem *spimem) | |||
199 | if (data && data->name) | 199 | if (data && data->name) |
200 | nor->mtd.name = data->name; | 200 | nor->mtd.name = data->name; |
201 | 201 | ||
202 | if (!nor->mtd.name) | ||
203 | nor->mtd.name = spi_mem_get_name(spimem); | ||
204 | |||
202 | /* For some (historical?) reason many platforms provide two different | 205 | /* For some (historical?) reason many platforms provide two different |
203 | * names in flash_platform_data: "name" and "type". Quite often name is | 206 | * names in flash_platform_data: "name" and "type". Quite often name is |
204 | * set to "m25p80" and then "type" provides a real chip name. | 207 | * set to "m25p80" and then "type" provides a real chip name. |
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index ad5d68e1dab7..671d078349cc 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -688,6 +688,19 @@ config SPI_TXX9 | |||
688 | help | 688 | help |
689 | SPI driver for Toshiba TXx9 MIPS SoCs | 689 | SPI driver for Toshiba TXx9 MIPS SoCs |
690 | 690 | ||
691 | config SPI_UNIPHIER | ||
692 | tristate "Socionext UniPhier SPI Controller" | ||
693 | depends on (ARCH_UNIPHIER || COMPILE_TEST) && OF | ||
694 | help | ||
695 | This enables a driver for the Socionext UniPhier SoC SCSSI SPI controller. | ||
696 | |||
697 | UniPhier SoCs have SCSSI and MCSSI SPI controllers. | ||
698 | Every UniPhier SoC has SCSSI which supports single channel. | ||
699 | Older UniPhier Pro4/Pro5 also has MCSSI which support multiple channels. | ||
700 | This driver supports SCSSI only. | ||
701 | |||
702 | If your SoC supports SCSSI, say Y here. | ||
703 | |||
691 | config SPI_XCOMM | 704 | config SPI_XCOMM |
692 | tristate "Analog Devices AD-FMCOMMS1-EBZ SPI-I2C-bridge driver" | 705 | tristate "Analog Devices AD-FMCOMMS1-EBZ SPI-I2C-bridge driver" |
693 | depends on I2C | 706 | depends on I2C |
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index cb1f4378b87c..a90d55970036 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile | |||
@@ -101,6 +101,7 @@ spi-thunderx-objs := spi-cavium.o spi-cavium-thunderx.o | |||
101 | obj-$(CONFIG_SPI_THUNDERX) += spi-thunderx.o | 101 | obj-$(CONFIG_SPI_THUNDERX) += spi-thunderx.o |
102 | obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi-topcliff-pch.o | 102 | obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi-topcliff-pch.o |
103 | obj-$(CONFIG_SPI_TXX9) += spi-txx9.o | 103 | obj-$(CONFIG_SPI_TXX9) += spi-txx9.o |
104 | obj-$(CONFIG_SPI_UNIPHIER) += spi-uniphier.o | ||
104 | obj-$(CONFIG_SPI_XCOMM) += spi-xcomm.o | 105 | obj-$(CONFIG_SPI_XCOMM) += spi-xcomm.o |
105 | obj-$(CONFIG_SPI_XILINX) += spi-xilinx.o | 106 | obj-$(CONFIG_SPI_XILINX) += spi-xilinx.o |
106 | obj-$(CONFIG_SPI_XLP) += spi-xlp.o | 107 | obj-$(CONFIG_SPI_XLP) += spi-xlp.o |
diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c index 0719bd484891..3f6b657394de 100644 --- a/drivers/spi/spi-ath79.c +++ b/drivers/spi/spi-ath79.c | |||
@@ -176,7 +176,7 @@ static void ath79_spi_cleanup(struct spi_device *spi) | |||
176 | } | 176 | } |
177 | 177 | ||
178 | static u32 ath79_spi_txrx_mode0(struct spi_device *spi, unsigned int nsecs, | 178 | static u32 ath79_spi_txrx_mode0(struct spi_device *spi, unsigned int nsecs, |
179 | u32 word, u8 bits) | 179 | u32 word, u8 bits, unsigned flags) |
180 | { | 180 | { |
181 | struct ath79_spi *sp = ath79_spidev_to_sp(spi); | 181 | struct ath79_spi *sp = ath79_spidev_to_sp(spi); |
182 | u32 ioc = sp->ioc_base; | 182 | u32 ioc = sp->ioc_base; |
diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index 3aa9e6e3dac8..f29176000b8d 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c | |||
@@ -49,22 +49,26 @@ | |||
49 | struct spi_bitbang_cs { | 49 | struct spi_bitbang_cs { |
50 | unsigned nsecs; /* (clock cycle time)/2 */ | 50 | unsigned nsecs; /* (clock cycle time)/2 */ |
51 | u32 (*txrx_word)(struct spi_device *spi, unsigned nsecs, | 51 | u32 (*txrx_word)(struct spi_device *spi, unsigned nsecs, |
52 | u32 word, u8 bits); | 52 | u32 word, u8 bits, unsigned flags); |
53 | unsigned (*txrx_bufs)(struct spi_device *, | 53 | unsigned (*txrx_bufs)(struct spi_device *, |
54 | u32 (*txrx_word)( | 54 | u32 (*txrx_word)( |
55 | struct spi_device *spi, | 55 | struct spi_device *spi, |
56 | unsigned nsecs, | 56 | unsigned nsecs, |
57 | u32 word, u8 bits), | 57 | u32 word, u8 bits, |
58 | unsigned, struct spi_transfer *); | 58 | unsigned flags), |
59 | unsigned, struct spi_transfer *, | ||
60 | unsigned); | ||
59 | }; | 61 | }; |
60 | 62 | ||
61 | static unsigned bitbang_txrx_8( | 63 | static unsigned bitbang_txrx_8( |
62 | struct spi_device *spi, | 64 | struct spi_device *spi, |
63 | u32 (*txrx_word)(struct spi_device *spi, | 65 | u32 (*txrx_word)(struct spi_device *spi, |
64 | unsigned nsecs, | 66 | unsigned nsecs, |
65 | u32 word, u8 bits), | 67 | u32 word, u8 bits, |
68 | unsigned flags), | ||
66 | unsigned ns, | 69 | unsigned ns, |
67 | struct spi_transfer *t | 70 | struct spi_transfer *t, |
71 | unsigned flags | ||
68 | ) { | 72 | ) { |
69 | unsigned bits = t->bits_per_word; | 73 | unsigned bits = t->bits_per_word; |
70 | unsigned count = t->len; | 74 | unsigned count = t->len; |
@@ -76,7 +80,7 @@ static unsigned bitbang_txrx_8( | |||
76 | 80 | ||
77 | if (tx) | 81 | if (tx) |
78 | word = *tx++; | 82 | word = *tx++; |
79 | word = txrx_word(spi, ns, word, bits); | 83 | word = txrx_word(spi, ns, word, bits, flags); |
80 | if (rx) | 84 | if (rx) |
81 | *rx++ = word; | 85 | *rx++ = word; |
82 | count -= 1; | 86 | count -= 1; |
@@ -88,9 +92,11 @@ static unsigned bitbang_txrx_16( | |||
88 | struct spi_device *spi, | 92 | struct spi_device *spi, |
89 | u32 (*txrx_word)(struct spi_device *spi, | 93 | u32 (*txrx_word)(struct spi_device *spi, |
90 | unsigned nsecs, | 94 | unsigned nsecs, |
91 | u32 word, u8 bits), | 95 | u32 word, u8 bits, |
96 | unsigned flags), | ||
92 | unsigned ns, | 97 | unsigned ns, |
93 | struct spi_transfer *t | 98 | struct spi_transfer *t, |
99 | unsigned flags | ||
94 | ) { | 100 | ) { |
95 | unsigned bits = t->bits_per_word; | 101 | unsigned bits = t->bits_per_word; |
96 | unsigned count = t->len; | 102 | unsigned count = t->len; |
@@ -102,7 +108,7 @@ static unsigned bitbang_txrx_16( | |||
102 | 108 | ||
103 | if (tx) | 109 | if (tx) |
104 | word = *tx++; | 110 | word = *tx++; |
105 | word = txrx_word(spi, ns, word, bits); | 111 | word = txrx_word(spi, ns, word, bits, flags); |
106 | if (rx) | 112 | if (rx) |
107 | *rx++ = word; | 113 | *rx++ = word; |
108 | count -= 2; | 114 | count -= 2; |
@@ -114,9 +120,11 @@ static unsigned bitbang_txrx_32( | |||
114 | struct spi_device *spi, | 120 | struct spi_device *spi, |
115 | u32 (*txrx_word)(struct spi_device *spi, | 121 | u32 (*txrx_word)(struct spi_device *spi, |
116 | unsigned nsecs, | 122 | unsigned nsecs, |
117 | u32 word, u8 bits), | 123 | u32 word, u8 bits, |
124 | unsigned flags), | ||
118 | unsigned ns, | 125 | unsigned ns, |
119 | struct spi_transfer *t | 126 | struct spi_transfer *t, |
127 | unsigned flags | ||
120 | ) { | 128 | ) { |
121 | unsigned bits = t->bits_per_word; | 129 | unsigned bits = t->bits_per_word; |
122 | unsigned count = t->len; | 130 | unsigned count = t->len; |
@@ -128,7 +136,7 @@ static unsigned bitbang_txrx_32( | |||
128 | 136 | ||
129 | if (tx) | 137 | if (tx) |
130 | word = *tx++; | 138 | word = *tx++; |
131 | word = txrx_word(spi, ns, word, bits); | 139 | word = txrx_word(spi, ns, word, bits, flags); |
132 | if (rx) | 140 | if (rx) |
133 | *rx++ = word; | 141 | *rx++ = word; |
134 | count -= 4; | 142 | count -= 4; |
@@ -235,8 +243,24 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
235 | { | 243 | { |
236 | struct spi_bitbang_cs *cs = spi->controller_state; | 244 | struct spi_bitbang_cs *cs = spi->controller_state; |
237 | unsigned nsecs = cs->nsecs; | 245 | unsigned nsecs = cs->nsecs; |
246 | struct spi_bitbang *bitbang; | ||
247 | |||
248 | bitbang = spi_master_get_devdata(spi->master); | ||
249 | if (bitbang->set_line_direction) { | ||
250 | int err; | ||
238 | 251 | ||
239 | return cs->txrx_bufs(spi, cs->txrx_word, nsecs, t); | 252 | err = bitbang->set_line_direction(spi, !!(t->tx_buf)); |
253 | if (err < 0) | ||
254 | return err; | ||
255 | } | ||
256 | |||
257 | if (spi->mode & SPI_3WIRE) { | ||
258 | unsigned flags; | ||
259 | |||
260 | flags = t->tx_buf ? SPI_MASTER_NO_RX : SPI_MASTER_NO_TX; | ||
261 | return cs->txrx_bufs(spi, cs->txrx_word, nsecs, t, flags); | ||
262 | } | ||
263 | return cs->txrx_bufs(spi, cs->txrx_word, nsecs, t, 0); | ||
240 | } | 264 | } |
241 | 265 | ||
242 | /*----------------------------------------------------------------------*/ | 266 | /*----------------------------------------------------------------------*/ |
diff --git a/drivers/spi/spi-butterfly.c b/drivers/spi/spi-butterfly.c index 22a31e4a1a11..1a3510215841 100644 --- a/drivers/spi/spi-butterfly.c +++ b/drivers/spi/spi-butterfly.c | |||
@@ -144,9 +144,9 @@ static void butterfly_chipselect(struct spi_device *spi, int value) | |||
144 | 144 | ||
145 | static u32 | 145 | static u32 |
146 | butterfly_txrx_word_mode0(struct spi_device *spi, unsigned nsecs, u32 word, | 146 | butterfly_txrx_word_mode0(struct spi_device *spi, unsigned nsecs, u32 word, |
147 | u8 bits) | 147 | u8 bits, unsigned flags) |
148 | { | 148 | { |
149 | return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits); | 149 | return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits); |
150 | } | 150 | } |
151 | 151 | ||
152 | /*----------------------------------------------------------------------*/ | 152 | /*----------------------------------------------------------------------*/ |
diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c index f3dad6fcdc35..7c88f74f7f47 100644 --- a/drivers/spi/spi-cadence.c +++ b/drivers/spi/spi-cadence.c | |||
@@ -319,7 +319,7 @@ static void cdns_spi_fill_tx_fifo(struct cdns_spi *xspi) | |||
319 | */ | 319 | */ |
320 | if (cdns_spi_read(xspi, CDNS_SPI_ISR) & | 320 | if (cdns_spi_read(xspi, CDNS_SPI_ISR) & |
321 | CDNS_SPI_IXR_TXFULL) | 321 | CDNS_SPI_IXR_TXFULL) |
322 | usleep_range(10, 20); | 322 | udelay(10); |
323 | 323 | ||
324 | if (xspi->txbuf) | 324 | if (xspi->txbuf) |
325 | cdns_spi_write(xspi, CDNS_SPI_TXD, *xspi->txbuf++); | 325 | cdns_spi_write(xspi, CDNS_SPI_TXD, *xspi->txbuf++); |
@@ -739,7 +739,7 @@ static int __maybe_unused cnds_runtime_resume(struct device *dev) | |||
739 | ret = clk_prepare_enable(xspi->ref_clk); | 739 | ret = clk_prepare_enable(xspi->ref_clk); |
740 | if (ret) { | 740 | if (ret) { |
741 | dev_err(dev, "Cannot enable device clock.\n"); | 741 | dev_err(dev, "Cannot enable device clock.\n"); |
742 | clk_disable(xspi->pclk); | 742 | clk_disable_unprepare(xspi->pclk); |
743 | return ret; | 743 | return ret; |
744 | } | 744 | } |
745 | return 0; | 745 | return 0; |
diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 577084bb911b..a02099c90c5c 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c | |||
@@ -217,7 +217,7 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value) | |||
217 | pdata = &dspi->pdata; | 217 | pdata = &dspi->pdata; |
218 | 218 | ||
219 | /* program delay transfers if tx_delay is non zero */ | 219 | /* program delay transfers if tx_delay is non zero */ |
220 | if (spicfg->wdelay) | 220 | if (spicfg && spicfg->wdelay) |
221 | spidat1 |= SPIDAT1_WDEL; | 221 | spidat1 |= SPIDAT1_WDEL; |
222 | 222 | ||
223 | /* | 223 | /* |
diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c index d25cc4037e23..e80f60ed6fdf 100644 --- a/drivers/spi/spi-dw-mmio.c +++ b/drivers/spi/spi-dw-mmio.c | |||
@@ -15,11 +15,13 @@ | |||
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/spi/spi.h> | 16 | #include <linux/spi/spi.h> |
17 | #include <linux/scatterlist.h> | 17 | #include <linux/scatterlist.h> |
18 | #include <linux/mfd/syscon.h> | ||
18 | #include <linux/module.h> | 19 | #include <linux/module.h> |
19 | #include <linux/of.h> | 20 | #include <linux/of.h> |
20 | #include <linux/of_gpio.h> | 21 | #include <linux/of_gpio.h> |
21 | #include <linux/of_platform.h> | 22 | #include <linux/of_platform.h> |
22 | #include <linux/property.h> | 23 | #include <linux/property.h> |
24 | #include <linux/regmap.h> | ||
23 | 25 | ||
24 | #include "spi-dw.h" | 26 | #include "spi-dw.h" |
25 | 27 | ||
@@ -28,10 +30,90 @@ | |||
28 | struct dw_spi_mmio { | 30 | struct dw_spi_mmio { |
29 | struct dw_spi dws; | 31 | struct dw_spi dws; |
30 | struct clk *clk; | 32 | struct clk *clk; |
33 | void *priv; | ||
31 | }; | 34 | }; |
32 | 35 | ||
36 | #define MSCC_CPU_SYSTEM_CTRL_GENERAL_CTRL 0x24 | ||
37 | #define OCELOT_IF_SI_OWNER_MASK GENMASK(5, 4) | ||
38 | #define OCELOT_IF_SI_OWNER_OFFSET 4 | ||
39 | #define MSCC_IF_SI_OWNER_SISL 0 | ||
40 | #define MSCC_IF_SI_OWNER_SIBM 1 | ||
41 | #define MSCC_IF_SI_OWNER_SIMC 2 | ||
42 | |||
43 | #define MSCC_SPI_MST_SW_MODE 0x14 | ||
44 | #define MSCC_SPI_MST_SW_MODE_SW_PIN_CTRL_MODE BIT(13) | ||
45 | #define MSCC_SPI_MST_SW_MODE_SW_SPI_CS(x) (x << 5) | ||
46 | |||
47 | struct dw_spi_mscc { | ||
48 | struct regmap *syscon; | ||
49 | void __iomem *spi_mst; | ||
50 | }; | ||
51 | |||
52 | /* | ||
53 | * The Designware SPI controller (referred to as master in the documentation) | ||
54 | * automatically deasserts chip select when the tx fifo is empty. The chip | ||
55 | * selects then needs to be either driven as GPIOs or, for the first 4 using the | ||
56 | * the SPI boot controller registers. the final chip select is an OR gate | ||
57 | * between the Designware SPI controller and the SPI boot controller. | ||
58 | */ | ||
59 | static void dw_spi_mscc_set_cs(struct spi_device *spi, bool enable) | ||
60 | { | ||
61 | struct dw_spi *dws = spi_master_get_devdata(spi->master); | ||
62 | struct dw_spi_mmio *dwsmmio = container_of(dws, struct dw_spi_mmio, dws); | ||
63 | struct dw_spi_mscc *dwsmscc = dwsmmio->priv; | ||
64 | u32 cs = spi->chip_select; | ||
65 | |||
66 | if (cs < 4) { | ||
67 | u32 sw_mode = MSCC_SPI_MST_SW_MODE_SW_PIN_CTRL_MODE; | ||
68 | |||
69 | if (!enable) | ||
70 | sw_mode |= MSCC_SPI_MST_SW_MODE_SW_SPI_CS(BIT(cs)); | ||
71 | |||
72 | writel(sw_mode, dwsmscc->spi_mst + MSCC_SPI_MST_SW_MODE); | ||
73 | } | ||
74 | |||
75 | dw_spi_set_cs(spi, enable); | ||
76 | } | ||
77 | |||
78 | static int dw_spi_mscc_init(struct platform_device *pdev, | ||
79 | struct dw_spi_mmio *dwsmmio) | ||
80 | { | ||
81 | struct dw_spi_mscc *dwsmscc; | ||
82 | struct resource *res; | ||
83 | |||
84 | dwsmscc = devm_kzalloc(&pdev->dev, sizeof(*dwsmscc), GFP_KERNEL); | ||
85 | if (!dwsmscc) | ||
86 | return -ENOMEM; | ||
87 | |||
88 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
89 | dwsmscc->spi_mst = devm_ioremap_resource(&pdev->dev, res); | ||
90 | if (IS_ERR(dwsmscc->spi_mst)) { | ||
91 | dev_err(&pdev->dev, "SPI_MST region map failed\n"); | ||
92 | return PTR_ERR(dwsmscc->spi_mst); | ||
93 | } | ||
94 | |||
95 | dwsmscc->syscon = syscon_regmap_lookup_by_compatible("mscc,ocelot-cpu-syscon"); | ||
96 | if (IS_ERR(dwsmscc->syscon)) | ||
97 | return PTR_ERR(dwsmscc->syscon); | ||
98 | |||
99 | /* Deassert all CS */ | ||
100 | writel(0, dwsmscc->spi_mst + MSCC_SPI_MST_SW_MODE); | ||
101 | |||
102 | /* Select the owner of the SI interface */ | ||
103 | regmap_update_bits(dwsmscc->syscon, MSCC_CPU_SYSTEM_CTRL_GENERAL_CTRL, | ||
104 | OCELOT_IF_SI_OWNER_MASK, | ||
105 | MSCC_IF_SI_OWNER_SIMC << OCELOT_IF_SI_OWNER_OFFSET); | ||
106 | |||
107 | dwsmmio->dws.set_cs = dw_spi_mscc_set_cs; | ||
108 | dwsmmio->priv = dwsmscc; | ||
109 | |||
110 | return 0; | ||
111 | } | ||
112 | |||
33 | static int dw_spi_mmio_probe(struct platform_device *pdev) | 113 | static int dw_spi_mmio_probe(struct platform_device *pdev) |
34 | { | 114 | { |
115 | int (*init_func)(struct platform_device *pdev, | ||
116 | struct dw_spi_mmio *dwsmmio); | ||
35 | struct dw_spi_mmio *dwsmmio; | 117 | struct dw_spi_mmio *dwsmmio; |
36 | struct dw_spi *dws; | 118 | struct dw_spi *dws; |
37 | struct resource *mem; | 119 | struct resource *mem; |
@@ -99,6 +181,13 @@ static int dw_spi_mmio_probe(struct platform_device *pdev) | |||
99 | } | 181 | } |
100 | } | 182 | } |
101 | 183 | ||
184 | init_func = device_get_match_data(&pdev->dev); | ||
185 | if (init_func) { | ||
186 | ret = init_func(pdev, dwsmmio); | ||
187 | if (ret) | ||
188 | goto out; | ||
189 | } | ||
190 | |||
102 | ret = dw_spi_add_host(&pdev->dev, dws); | 191 | ret = dw_spi_add_host(&pdev->dev, dws); |
103 | if (ret) | 192 | if (ret) |
104 | goto out; | 193 | goto out; |
@@ -123,6 +212,7 @@ static int dw_spi_mmio_remove(struct platform_device *pdev) | |||
123 | 212 | ||
124 | static const struct of_device_id dw_spi_mmio_of_match[] = { | 213 | static const struct of_device_id dw_spi_mmio_of_match[] = { |
125 | { .compatible = "snps,dw-apb-ssi", }, | 214 | { .compatible = "snps,dw-apb-ssi", }, |
215 | { .compatible = "mscc,ocelot-spi", .data = dw_spi_mscc_init}, | ||
126 | { /* end of table */} | 216 | { /* end of table */} |
127 | }; | 217 | }; |
128 | MODULE_DEVICE_TABLE(of, dw_spi_mmio_of_match); | 218 | MODULE_DEVICE_TABLE(of, dw_spi_mmio_of_match); |
diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index f693bfe95ab9..ac2eb89ef7a5 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c | |||
@@ -133,7 +133,7 @@ static inline void dw_spi_debugfs_remove(struct dw_spi *dws) | |||
133 | } | 133 | } |
134 | #endif /* CONFIG_DEBUG_FS */ | 134 | #endif /* CONFIG_DEBUG_FS */ |
135 | 135 | ||
136 | static void dw_spi_set_cs(struct spi_device *spi, bool enable) | 136 | void dw_spi_set_cs(struct spi_device *spi, bool enable) |
137 | { | 137 | { |
138 | struct dw_spi *dws = spi_controller_get_devdata(spi->controller); | 138 | struct dw_spi *dws = spi_controller_get_devdata(spi->controller); |
139 | struct chip_data *chip = spi_get_ctldata(spi); | 139 | struct chip_data *chip = spi_get_ctldata(spi); |
@@ -145,6 +145,7 @@ static void dw_spi_set_cs(struct spi_device *spi, bool enable) | |||
145 | if (!enable) | 145 | if (!enable) |
146 | dw_writel(dws, DW_SPI_SER, BIT(spi->chip_select)); | 146 | dw_writel(dws, DW_SPI_SER, BIT(spi->chip_select)); |
147 | } | 147 | } |
148 | EXPORT_SYMBOL_GPL(dw_spi_set_cs); | ||
148 | 149 | ||
149 | /* Return the max entries we can fill into tx fifo */ | 150 | /* Return the max entries we can fill into tx fifo */ |
150 | static inline u32 tx_max(struct dw_spi *dws) | 151 | static inline u32 tx_max(struct dw_spi *dws) |
@@ -485,6 +486,8 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) | |||
485 | dws->dma_inited = 0; | 486 | dws->dma_inited = 0; |
486 | dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR); | 487 | dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR); |
487 | 488 | ||
489 | spi_controller_set_devdata(master, dws); | ||
490 | |||
488 | ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dev_name(dev), | 491 | ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dev_name(dev), |
489 | master); | 492 | master); |
490 | if (ret < 0) { | 493 | if (ret < 0) { |
@@ -505,6 +508,9 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) | |||
505 | master->dev.of_node = dev->of_node; | 508 | master->dev.of_node = dev->of_node; |
506 | master->flags = SPI_MASTER_GPIO_SS; | 509 | master->flags = SPI_MASTER_GPIO_SS; |
507 | 510 | ||
511 | if (dws->set_cs) | ||
512 | master->set_cs = dws->set_cs; | ||
513 | |||
508 | /* Basic HW init */ | 514 | /* Basic HW init */ |
509 | spi_hw_init(dev, dws); | 515 | spi_hw_init(dev, dws); |
510 | 516 | ||
@@ -518,7 +524,6 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) | |||
518 | } | 524 | } |
519 | } | 525 | } |
520 | 526 | ||
521 | spi_controller_set_devdata(master, dws); | ||
522 | ret = devm_spi_register_controller(dev, master); | 527 | ret = devm_spi_register_controller(dev, master); |
523 | if (ret) { | 528 | if (ret) { |
524 | dev_err(&master->dev, "problem registering spi master\n"); | 529 | dev_err(&master->dev, "problem registering spi master\n"); |
diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 2cde2473b3e9..0168b08364d5 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h | |||
@@ -112,6 +112,7 @@ struct dw_spi { | |||
112 | u32 reg_io_width; /* DR I/O width in bytes */ | 112 | u32 reg_io_width; /* DR I/O width in bytes */ |
113 | u16 bus_num; | 113 | u16 bus_num; |
114 | u16 num_cs; /* supported slave numbers */ | 114 | u16 num_cs; /* supported slave numbers */ |
115 | void (*set_cs)(struct spi_device *spi, bool enable); | ||
115 | 116 | ||
116 | /* Current message transfer state info */ | 117 | /* Current message transfer state info */ |
117 | size_t len; | 118 | size_t len; |
@@ -244,6 +245,7 @@ struct dw_spi_chip { | |||
244 | void (*cs_control)(u32 command); | 245 | void (*cs_control)(u32 command); |
245 | }; | 246 | }; |
246 | 247 | ||
248 | extern void dw_spi_set_cs(struct spi_device *spi, bool enable); | ||
247 | extern int dw_spi_add_host(struct device *dev, struct dw_spi *dws); | 249 | extern int dw_spi_add_host(struct device *dev, struct dw_spi *dws); |
248 | extern void dw_spi_remove_host(struct dw_spi *dws); | 250 | extern void dw_spi_remove_host(struct dw_spi *dws); |
249 | extern int dw_spi_suspend_host(struct dw_spi *dws); | 251 | extern int dw_spi_suspend_host(struct dw_spi *dws); |
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 0630962ce442..7cb3ab0a35a0 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c | |||
@@ -1,17 +1,9 @@ | |||
1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | * drivers/spi/spi-fsl-dspi.c | 2 | // |
3 | * | 3 | // Copyright 2013 Freescale Semiconductor, Inc. |
4 | * Copyright 2013 Freescale Semiconductor, Inc. | 4 | // |
5 | * | 5 | // Freescale DSPI driver |
6 | * Freescale DSPI driver | 6 | // This file contains a driver for the Freescale DSPI |
7 | * This file contains a driver for the Freescale DSPI | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | */ | ||
15 | 7 | ||
16 | #include <linux/clk.h> | 8 | #include <linux/clk.h> |
17 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
@@ -38,10 +30,6 @@ | |||
38 | 30 | ||
39 | #define DRIVER_NAME "fsl-dspi" | 31 | #define DRIVER_NAME "fsl-dspi" |
40 | 32 | ||
41 | #define TRAN_STATE_RX_VOID 0x01 | ||
42 | #define TRAN_STATE_TX_VOID 0x02 | ||
43 | #define TRAN_STATE_WORD_ODD_NUM 0x04 | ||
44 | |||
45 | #define DSPI_FIFO_SIZE 4 | 33 | #define DSPI_FIFO_SIZE 4 |
46 | #define DSPI_DMA_BUFSIZE (DSPI_FIFO_SIZE * 1024) | 34 | #define DSPI_DMA_BUFSIZE (DSPI_FIFO_SIZE * 1024) |
47 | 35 | ||
@@ -50,6 +38,7 @@ | |||
50 | #define SPI_MCR_PCSIS (0x3F << 16) | 38 | #define SPI_MCR_PCSIS (0x3F << 16) |
51 | #define SPI_MCR_CLR_TXF (1 << 11) | 39 | #define SPI_MCR_CLR_TXF (1 << 11) |
52 | #define SPI_MCR_CLR_RXF (1 << 10) | 40 | #define SPI_MCR_CLR_RXF (1 << 10) |
41 | #define SPI_MCR_XSPI (1 << 3) | ||
53 | 42 | ||
54 | #define SPI_TCR 0x08 | 43 | #define SPI_TCR 0x08 |
55 | #define SPI_TCR_GET_TCNT(x) (((x) & 0xffff0000) >> 16) | 44 | #define SPI_TCR_GET_TCNT(x) (((x) & 0xffff0000) >> 16) |
@@ -86,11 +75,16 @@ | |||
86 | #define SPI_RSER_TCFQE 0x80000000 | 75 | #define SPI_RSER_TCFQE 0x80000000 |
87 | 76 | ||
88 | #define SPI_PUSHR 0x34 | 77 | #define SPI_PUSHR 0x34 |
89 | #define SPI_PUSHR_CONT (1 << 31) | 78 | #define SPI_PUSHR_CMD_CONT (1 << 15) |
90 | #define SPI_PUSHR_CTAS(x) (((x) & 0x00000003) << 28) | 79 | #define SPI_PUSHR_CONT (SPI_PUSHR_CMD_CONT << 16) |
91 | #define SPI_PUSHR_EOQ (1 << 27) | 80 | #define SPI_PUSHR_CMD_CTAS(x) (((x) & 0x0003) << 12) |
92 | #define SPI_PUSHR_CTCNT (1 << 26) | 81 | #define SPI_PUSHR_CTAS(x) (SPI_PUSHR_CMD_CTAS(x) << 16) |
93 | #define SPI_PUSHR_PCS(x) (((1 << x) & 0x0000003f) << 16) | 82 | #define SPI_PUSHR_CMD_EOQ (1 << 11) |
83 | #define SPI_PUSHR_EOQ (SPI_PUSHR_CMD_EOQ << 16) | ||
84 | #define SPI_PUSHR_CMD_CTCNT (1 << 10) | ||
85 | #define SPI_PUSHR_CTCNT (SPI_PUSHR_CMD_CTCNT << 16) | ||
86 | #define SPI_PUSHR_CMD_PCS(x) ((1 << x) & 0x003f) | ||
87 | #define SPI_PUSHR_PCS(x) (SPI_PUSHR_CMD_PCS(x) << 16) | ||
94 | #define SPI_PUSHR_TXDATA(x) ((x) & 0x0000ffff) | 88 | #define SPI_PUSHR_TXDATA(x) ((x) & 0x0000ffff) |
95 | 89 | ||
96 | #define SPI_PUSHR_SLAVE 0x34 | 90 | #define SPI_PUSHR_SLAVE 0x34 |
@@ -107,21 +101,31 @@ | |||
107 | #define SPI_RXFR2 0x84 | 101 | #define SPI_RXFR2 0x84 |
108 | #define SPI_RXFR3 0x88 | 102 | #define SPI_RXFR3 0x88 |
109 | 103 | ||
104 | #define SPI_CTARE(x) (0x11c + (((x) & 0x3) * 4)) | ||
105 | #define SPI_CTARE_FMSZE(x) (((x) & 0x1) << 16) | ||
106 | #define SPI_CTARE_DTCP(x) ((x) & 0x7ff) | ||
107 | |||
108 | #define SPI_SREX 0x13c | ||
109 | |||
110 | #define SPI_FRAME_BITS(bits) SPI_CTAR_FMSZ((bits) - 1) | 110 | #define SPI_FRAME_BITS(bits) SPI_CTAR_FMSZ((bits) - 1) |
111 | #define SPI_FRAME_BITS_MASK SPI_CTAR_FMSZ(0xf) | 111 | #define SPI_FRAME_BITS_MASK SPI_CTAR_FMSZ(0xf) |
112 | #define SPI_FRAME_BITS_16 SPI_CTAR_FMSZ(0xf) | 112 | #define SPI_FRAME_BITS_16 SPI_CTAR_FMSZ(0xf) |
113 | #define SPI_FRAME_BITS_8 SPI_CTAR_FMSZ(0x7) | 113 | #define SPI_FRAME_BITS_8 SPI_CTAR_FMSZ(0x7) |
114 | 114 | ||
115 | #define SPI_FRAME_EBITS(bits) SPI_CTARE_FMSZE(((bits) - 1) >> 4) | ||
116 | #define SPI_FRAME_EBITS_MASK SPI_CTARE_FMSZE(1) | ||
117 | |||
118 | /* Register offsets for regmap_pushr */ | ||
119 | #define PUSHR_CMD 0x0 | ||
120 | #define PUSHR_TX 0x2 | ||
121 | |||
115 | #define SPI_CS_INIT 0x01 | 122 | #define SPI_CS_INIT 0x01 |
116 | #define SPI_CS_ASSERT 0x02 | 123 | #define SPI_CS_ASSERT 0x02 |
117 | #define SPI_CS_DROP 0x04 | 124 | #define SPI_CS_DROP 0x04 |
118 | 125 | ||
119 | #define SPI_TCR_TCNT_MAX 0x10000 | ||
120 | |||
121 | #define DMA_COMPLETION_TIMEOUT msecs_to_jiffies(3000) | 126 | #define DMA_COMPLETION_TIMEOUT msecs_to_jiffies(3000) |
122 | 127 | ||
123 | struct chip_data { | 128 | struct chip_data { |
124 | u32 mcr_val; | ||
125 | u32 ctar_val; | 129 | u32 ctar_val; |
126 | u16 void_write_data; | 130 | u16 void_write_data; |
127 | }; | 131 | }; |
@@ -135,6 +139,7 @@ enum dspi_trans_mode { | |||
135 | struct fsl_dspi_devtype_data { | 139 | struct fsl_dspi_devtype_data { |
136 | enum dspi_trans_mode trans_mode; | 140 | enum dspi_trans_mode trans_mode; |
137 | u8 max_clock_factor; | 141 | u8 max_clock_factor; |
142 | bool xspi_mode; | ||
138 | }; | 143 | }; |
139 | 144 | ||
140 | static const struct fsl_dspi_devtype_data vf610_data = { | 145 | static const struct fsl_dspi_devtype_data vf610_data = { |
@@ -145,6 +150,7 @@ static const struct fsl_dspi_devtype_data vf610_data = { | |||
145 | static const struct fsl_dspi_devtype_data ls1021a_v1_data = { | 150 | static const struct fsl_dspi_devtype_data ls1021a_v1_data = { |
146 | .trans_mode = DSPI_TCFQ_MODE, | 151 | .trans_mode = DSPI_TCFQ_MODE, |
147 | .max_clock_factor = 8, | 152 | .max_clock_factor = 8, |
153 | .xspi_mode = true, | ||
148 | }; | 154 | }; |
149 | 155 | ||
150 | static const struct fsl_dspi_devtype_data ls2085a_data = { | 156 | static const struct fsl_dspi_devtype_data ls2085a_data = { |
@@ -179,6 +185,7 @@ struct fsl_dspi { | |||
179 | struct platform_device *pdev; | 185 | struct platform_device *pdev; |
180 | 186 | ||
181 | struct regmap *regmap; | 187 | struct regmap *regmap; |
188 | struct regmap *regmap_pushr; | ||
182 | int irq; | 189 | int irq; |
183 | struct clk *clk; | 190 | struct clk *clk; |
184 | 191 | ||
@@ -186,32 +193,62 @@ struct fsl_dspi { | |||
186 | struct spi_message *cur_msg; | 193 | struct spi_message *cur_msg; |
187 | struct chip_data *cur_chip; | 194 | struct chip_data *cur_chip; |
188 | size_t len; | 195 | size_t len; |
189 | void *tx; | 196 | const void *tx; |
190 | void *tx_end; | ||
191 | void *rx; | 197 | void *rx; |
192 | void *rx_end; | 198 | void *rx_end; |
193 | char dataflags; | ||
194 | u8 cs; | ||
195 | u16 void_write_data; | 199 | u16 void_write_data; |
196 | u32 cs_change; | 200 | u16 tx_cmd; |
201 | u8 bits_per_word; | ||
202 | u8 bytes_per_word; | ||
197 | const struct fsl_dspi_devtype_data *devtype_data; | 203 | const struct fsl_dspi_devtype_data *devtype_data; |
198 | 204 | ||
199 | wait_queue_head_t waitq; | 205 | wait_queue_head_t waitq; |
200 | u32 waitflags; | 206 | u32 waitflags; |
201 | 207 | ||
202 | u32 spi_tcnt; | ||
203 | struct fsl_dspi_dma *dma; | 208 | struct fsl_dspi_dma *dma; |
204 | }; | 209 | }; |
205 | 210 | ||
206 | static u32 dspi_data_to_pushr(struct fsl_dspi *dspi, int tx_word); | 211 | static u32 dspi_pop_tx(struct fsl_dspi *dspi) |
212 | { | ||
213 | u32 txdata = 0; | ||
214 | |||
215 | if (dspi->tx) { | ||
216 | if (dspi->bytes_per_word == 1) | ||
217 | txdata = *(u8 *)dspi->tx; | ||
218 | else if (dspi->bytes_per_word == 2) | ||
219 | txdata = *(u16 *)dspi->tx; | ||
220 | else /* dspi->bytes_per_word == 4 */ | ||
221 | txdata = *(u32 *)dspi->tx; | ||
222 | dspi->tx += dspi->bytes_per_word; | ||
223 | } | ||
224 | dspi->len -= dspi->bytes_per_word; | ||
225 | return txdata; | ||
226 | } | ||
207 | 227 | ||
208 | static inline int is_double_byte_mode(struct fsl_dspi *dspi) | 228 | static u32 dspi_pop_tx_pushr(struct fsl_dspi *dspi) |
209 | { | 229 | { |
210 | unsigned int val; | 230 | u16 cmd = dspi->tx_cmd, data = dspi_pop_tx(dspi); |
211 | 231 | ||
212 | regmap_read(dspi->regmap, SPI_CTAR(0), &val); | 232 | if (dspi->len > 0) |
233 | cmd |= SPI_PUSHR_CMD_CONT; | ||
234 | return cmd << 16 | data; | ||
235 | } | ||
213 | 236 | ||
214 | return ((val & SPI_FRAME_BITS_MASK) == SPI_FRAME_BITS(8)) ? 0 : 1; | 237 | static void dspi_push_rx(struct fsl_dspi *dspi, u32 rxdata) |
238 | { | ||
239 | if (!dspi->rx) | ||
240 | return; | ||
241 | |||
242 | /* Mask of undefined bits */ | ||
243 | rxdata &= (1 << dspi->bits_per_word) - 1; | ||
244 | |||
245 | if (dspi->bytes_per_word == 1) | ||
246 | *(u8 *)dspi->rx = rxdata; | ||
247 | else if (dspi->bytes_per_word == 2) | ||
248 | *(u16 *)dspi->rx = rxdata; | ||
249 | else /* dspi->bytes_per_word == 4 */ | ||
250 | *(u32 *)dspi->rx = rxdata; | ||
251 | dspi->rx += dspi->bytes_per_word; | ||
215 | } | 252 | } |
216 | 253 | ||
217 | static void dspi_tx_dma_callback(void *arg) | 254 | static void dspi_tx_dma_callback(void *arg) |
@@ -226,19 +263,11 @@ static void dspi_rx_dma_callback(void *arg) | |||
226 | { | 263 | { |
227 | struct fsl_dspi *dspi = arg; | 264 | struct fsl_dspi *dspi = arg; |
228 | struct fsl_dspi_dma *dma = dspi->dma; | 265 | struct fsl_dspi_dma *dma = dspi->dma; |
229 | int rx_word; | ||
230 | int i; | 266 | int i; |
231 | u16 d; | ||
232 | |||
233 | rx_word = is_double_byte_mode(dspi); | ||
234 | 267 | ||
235 | if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) { | 268 | if (dspi->rx) { |
236 | for (i = 0; i < dma->curr_xfer_len; i++) { | 269 | for (i = 0; i < dma->curr_xfer_len; i++) |
237 | d = dspi->dma->rx_dma_buf[i]; | 270 | dspi_push_rx(dspi, dspi->dma->rx_dma_buf[i]); |
238 | rx_word ? (*(u16 *)dspi->rx = d) : | ||
239 | (*(u8 *)dspi->rx = d); | ||
240 | dspi->rx += rx_word + 1; | ||
241 | } | ||
242 | } | 271 | } |
243 | 272 | ||
244 | complete(&dma->cmd_rx_complete); | 273 | complete(&dma->cmd_rx_complete); |
@@ -249,16 +278,10 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi) | |||
249 | struct fsl_dspi_dma *dma = dspi->dma; | 278 | struct fsl_dspi_dma *dma = dspi->dma; |
250 | struct device *dev = &dspi->pdev->dev; | 279 | struct device *dev = &dspi->pdev->dev; |
251 | int time_left; | 280 | int time_left; |
252 | int tx_word; | ||
253 | int i; | 281 | int i; |
254 | 282 | ||
255 | tx_word = is_double_byte_mode(dspi); | 283 | for (i = 0; i < dma->curr_xfer_len; i++) |
256 | 284 | dspi->dma->tx_dma_buf[i] = dspi_pop_tx_pushr(dspi); | |
257 | for (i = 0; i < dma->curr_xfer_len; i++) { | ||
258 | dspi->dma->tx_dma_buf[i] = dspi_data_to_pushr(dspi, tx_word); | ||
259 | if ((dspi->cs_change) && (!dspi->len)) | ||
260 | dspi->dma->tx_dma_buf[i] &= ~SPI_PUSHR_CONT; | ||
261 | } | ||
262 | 285 | ||
263 | dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx, | 286 | dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx, |
264 | dma->tx_dma_phys, | 287 | dma->tx_dma_phys, |
@@ -327,18 +350,17 @@ static int dspi_dma_xfer(struct fsl_dspi *dspi) | |||
327 | { | 350 | { |
328 | struct fsl_dspi_dma *dma = dspi->dma; | 351 | struct fsl_dspi_dma *dma = dspi->dma; |
329 | struct device *dev = &dspi->pdev->dev; | 352 | struct device *dev = &dspi->pdev->dev; |
353 | struct spi_message *message = dspi->cur_msg; | ||
330 | int curr_remaining_bytes; | 354 | int curr_remaining_bytes; |
331 | int bytes_per_buffer; | 355 | int bytes_per_buffer; |
332 | int word = 1; | ||
333 | int ret = 0; | 356 | int ret = 0; |
334 | 357 | ||
335 | if (is_double_byte_mode(dspi)) | ||
336 | word = 2; | ||
337 | curr_remaining_bytes = dspi->len; | 358 | curr_remaining_bytes = dspi->len; |
338 | bytes_per_buffer = DSPI_DMA_BUFSIZE / DSPI_FIFO_SIZE; | 359 | bytes_per_buffer = DSPI_DMA_BUFSIZE / DSPI_FIFO_SIZE; |
339 | while (curr_remaining_bytes) { | 360 | while (curr_remaining_bytes) { |
340 | /* Check if current transfer fits the DMA buffer */ | 361 | /* Check if current transfer fits the DMA buffer */ |
341 | dma->curr_xfer_len = curr_remaining_bytes / word; | 362 | dma->curr_xfer_len = curr_remaining_bytes |
363 | / dspi->bytes_per_word; | ||
342 | if (dma->curr_xfer_len > bytes_per_buffer) | 364 | if (dma->curr_xfer_len > bytes_per_buffer) |
343 | dma->curr_xfer_len = bytes_per_buffer; | 365 | dma->curr_xfer_len = bytes_per_buffer; |
344 | 366 | ||
@@ -348,7 +370,10 @@ static int dspi_dma_xfer(struct fsl_dspi *dspi) | |||
348 | goto exit; | 370 | goto exit; |
349 | 371 | ||
350 | } else { | 372 | } else { |
351 | curr_remaining_bytes -= dma->curr_xfer_len * word; | 373 | const int len = |
374 | dma->curr_xfer_len * dspi->bytes_per_word; | ||
375 | curr_remaining_bytes -= len; | ||
376 | message->actual_length += len; | ||
352 | if (curr_remaining_bytes < 0) | 377 | if (curr_remaining_bytes < 0) |
353 | curr_remaining_bytes = 0; | 378 | curr_remaining_bytes = 0; |
354 | } | 379 | } |
@@ -534,125 +559,91 @@ static void ns_delay_scale(char *psc, char *sc, int delay_ns, | |||
534 | } | 559 | } |
535 | } | 560 | } |
536 | 561 | ||
537 | static u32 dspi_data_to_pushr(struct fsl_dspi *dspi, int tx_word) | 562 | static void fifo_write(struct fsl_dspi *dspi) |
538 | { | 563 | { |
539 | u16 d16; | 564 | regmap_write(dspi->regmap, SPI_PUSHR, dspi_pop_tx_pushr(dspi)); |
540 | |||
541 | if (!(dspi->dataflags & TRAN_STATE_TX_VOID)) | ||
542 | d16 = tx_word ? *(u16 *)dspi->tx : *(u8 *)dspi->tx; | ||
543 | else | ||
544 | d16 = dspi->void_write_data; | ||
545 | |||
546 | dspi->tx += tx_word + 1; | ||
547 | dspi->len -= tx_word + 1; | ||
548 | |||
549 | return SPI_PUSHR_TXDATA(d16) | | ||
550 | SPI_PUSHR_PCS(dspi->cs) | | ||
551 | SPI_PUSHR_CTAS(0) | | ||
552 | SPI_PUSHR_CONT; | ||
553 | } | 565 | } |
554 | 566 | ||
555 | static void dspi_data_from_popr(struct fsl_dspi *dspi, int rx_word) | 567 | static void cmd_fifo_write(struct fsl_dspi *dspi) |
556 | { | 568 | { |
557 | u16 d; | 569 | u16 cmd = dspi->tx_cmd; |
558 | unsigned int val; | ||
559 | |||
560 | regmap_read(dspi->regmap, SPI_POPR, &val); | ||
561 | d = SPI_POPR_RXDATA(val); | ||
562 | 570 | ||
563 | if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) | 571 | if (dspi->len > 0) |
564 | rx_word ? (*(u16 *)dspi->rx = d) : (*(u8 *)dspi->rx = d); | 572 | cmd |= SPI_PUSHR_CMD_CONT; |
565 | 573 | regmap_write(dspi->regmap_pushr, PUSHR_CMD, cmd); | |
566 | dspi->rx += rx_word + 1; | ||
567 | } | 574 | } |
568 | 575 | ||
569 | static int dspi_eoq_write(struct fsl_dspi *dspi) | 576 | static void tx_fifo_write(struct fsl_dspi *dspi, u16 txdata) |
570 | { | 577 | { |
571 | int tx_count = 0; | 578 | regmap_write(dspi->regmap_pushr, PUSHR_TX, txdata); |
572 | int tx_word; | 579 | } |
573 | u32 dspi_pushr = 0; | ||
574 | 580 | ||
575 | tx_word = is_double_byte_mode(dspi); | 581 | static void dspi_tcfq_write(struct fsl_dspi *dspi) |
582 | { | ||
583 | /* Clear transfer count */ | ||
584 | dspi->tx_cmd |= SPI_PUSHR_CMD_CTCNT; | ||
576 | 585 | ||
577 | while (dspi->len && (tx_count < DSPI_FIFO_SIZE)) { | 586 | if (dspi->devtype_data->xspi_mode && dspi->bits_per_word > 16) { |
578 | /* If we are in word mode, only have a single byte to transfer | 587 | /* Write two TX FIFO entries first, and then the corresponding |
579 | * switch to byte mode temporarily. Will switch back at the | 588 | * CMD FIFO entry. |
580 | * end of the transfer. | ||
581 | */ | 589 | */ |
582 | if (tx_word && (dspi->len == 1)) { | 590 | u32 data = dspi_pop_tx(dspi); |
583 | dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM; | ||
584 | regmap_update_bits(dspi->regmap, SPI_CTAR(0), | ||
585 | SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8)); | ||
586 | tx_word = 0; | ||
587 | } | ||
588 | |||
589 | dspi_pushr = dspi_data_to_pushr(dspi, tx_word); | ||
590 | |||
591 | if (dspi->len == 0 || tx_count == DSPI_FIFO_SIZE - 1) { | ||
592 | /* last transfer in the transfer */ | ||
593 | dspi_pushr |= SPI_PUSHR_EOQ; | ||
594 | if ((dspi->cs_change) && (!dspi->len)) | ||
595 | dspi_pushr &= ~SPI_PUSHR_CONT; | ||
596 | } else if (tx_word && (dspi->len == 1)) | ||
597 | dspi_pushr |= SPI_PUSHR_EOQ; | ||
598 | 591 | ||
599 | regmap_write(dspi->regmap, SPI_PUSHR, dspi_pushr); | 592 | if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1)) { |
600 | 593 | /* LSB */ | |
601 | tx_count++; | 594 | tx_fifo_write(dspi, data & 0xFFFF); |
595 | tx_fifo_write(dspi, data >> 16); | ||
596 | } else { | ||
597 | /* MSB */ | ||
598 | tx_fifo_write(dspi, data >> 16); | ||
599 | tx_fifo_write(dspi, data & 0xFFFF); | ||
600 | } | ||
601 | cmd_fifo_write(dspi); | ||
602 | } else { | ||
603 | /* Write one entry to both TX FIFO and CMD FIFO | ||
604 | * simultaneously. | ||
605 | */ | ||
606 | fifo_write(dspi); | ||
602 | } | 607 | } |
603 | |||
604 | return tx_count * (tx_word + 1); | ||
605 | } | 608 | } |
606 | 609 | ||
607 | static int dspi_eoq_read(struct fsl_dspi *dspi) | 610 | static u32 fifo_read(struct fsl_dspi *dspi) |
608 | { | 611 | { |
609 | int rx_count = 0; | 612 | u32 rxdata = 0; |
610 | int rx_word = is_double_byte_mode(dspi); | ||
611 | |||
612 | while ((dspi->rx < dspi->rx_end) | ||
613 | && (rx_count < DSPI_FIFO_SIZE)) { | ||
614 | if (rx_word && (dspi->rx_end - dspi->rx) == 1) | ||
615 | rx_word = 0; | ||
616 | 613 | ||
617 | dspi_data_from_popr(dspi, rx_word); | 614 | regmap_read(dspi->regmap, SPI_POPR, &rxdata); |
618 | rx_count++; | 615 | return rxdata; |
619 | } | ||
620 | |||
621 | return rx_count; | ||
622 | } | 616 | } |
623 | 617 | ||
624 | static int dspi_tcfq_write(struct fsl_dspi *dspi) | 618 | static void dspi_tcfq_read(struct fsl_dspi *dspi) |
625 | { | 619 | { |
626 | int tx_word; | 620 | dspi_push_rx(dspi, fifo_read(dspi)); |
627 | u32 dspi_pushr = 0; | 621 | } |
628 | |||
629 | tx_word = is_double_byte_mode(dspi); | ||
630 | 622 | ||
631 | if (tx_word && (dspi->len == 1)) { | 623 | static void dspi_eoq_write(struct fsl_dspi *dspi) |
632 | dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM; | 624 | { |
633 | regmap_update_bits(dspi->regmap, SPI_CTAR(0), | 625 | int fifo_size = DSPI_FIFO_SIZE; |
634 | SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8)); | 626 | |
635 | tx_word = 0; | 627 | /* Fill TX FIFO with as many transfers as possible */ |
628 | while (dspi->len && fifo_size--) { | ||
629 | /* Request EOQF for last transfer in FIFO */ | ||
630 | if (dspi->len == dspi->bytes_per_word || fifo_size == 0) | ||
631 | dspi->tx_cmd |= SPI_PUSHR_CMD_EOQ; | ||
632 | /* Clear transfer count for first transfer in FIFO */ | ||
633 | if (fifo_size == (DSPI_FIFO_SIZE - 1)) | ||
634 | dspi->tx_cmd |= SPI_PUSHR_CMD_CTCNT; | ||
635 | /* Write combined TX FIFO and CMD FIFO entry */ | ||
636 | fifo_write(dspi); | ||
636 | } | 637 | } |
637 | |||
638 | dspi_pushr = dspi_data_to_pushr(dspi, tx_word); | ||
639 | |||
640 | if ((dspi->cs_change) && (!dspi->len)) | ||
641 | dspi_pushr &= ~SPI_PUSHR_CONT; | ||
642 | |||
643 | regmap_write(dspi->regmap, SPI_PUSHR, dspi_pushr); | ||
644 | |||
645 | return tx_word + 1; | ||
646 | } | 638 | } |
647 | 639 | ||
648 | static void dspi_tcfq_read(struct fsl_dspi *dspi) | 640 | static void dspi_eoq_read(struct fsl_dspi *dspi) |
649 | { | 641 | { |
650 | int rx_word = is_double_byte_mode(dspi); | 642 | int fifo_size = DSPI_FIFO_SIZE; |
651 | |||
652 | if (rx_word && (dspi->rx_end - dspi->rx) == 1) | ||
653 | rx_word = 0; | ||
654 | 643 | ||
655 | dspi_data_from_popr(dspi, rx_word); | 644 | /* Read one FIFO entry at and push to rx buffer */ |
645 | while ((dspi->rx < dspi->rx_end) && fifo_size--) | ||
646 | dspi_push_rx(dspi, fifo_read(dspi)); | ||
656 | } | 647 | } |
657 | 648 | ||
658 | static int dspi_transfer_one_message(struct spi_master *master, | 649 | static int dspi_transfer_one_message(struct spi_master *master, |
@@ -663,10 +654,6 @@ static int dspi_transfer_one_message(struct spi_master *master, | |||
663 | struct spi_transfer *transfer; | 654 | struct spi_transfer *transfer; |
664 | int status = 0; | 655 | int status = 0; |
665 | enum dspi_trans_mode trans_mode; | 656 | enum dspi_trans_mode trans_mode; |
666 | u32 spi_tcr; | ||
667 | |||
668 | regmap_read(dspi->regmap, SPI_TCR, &spi_tcr); | ||
669 | dspi->spi_tcnt = SPI_TCR_GET_TCNT(spi_tcr); | ||
670 | 657 | ||
671 | message->actual_length = 0; | 658 | message->actual_length = 0; |
672 | 659 | ||
@@ -674,32 +661,51 @@ static int dspi_transfer_one_message(struct spi_master *master, | |||
674 | dspi->cur_transfer = transfer; | 661 | dspi->cur_transfer = transfer; |
675 | dspi->cur_msg = message; | 662 | dspi->cur_msg = message; |
676 | dspi->cur_chip = spi_get_ctldata(spi); | 663 | dspi->cur_chip = spi_get_ctldata(spi); |
677 | dspi->cs = spi->chip_select; | 664 | /* Prepare command word for CMD FIFO */ |
678 | dspi->cs_change = 0; | 665 | dspi->tx_cmd = SPI_PUSHR_CMD_CTAS(0) | |
666 | SPI_PUSHR_CMD_PCS(spi->chip_select); | ||
679 | if (list_is_last(&dspi->cur_transfer->transfer_list, | 667 | if (list_is_last(&dspi->cur_transfer->transfer_list, |
680 | &dspi->cur_msg->transfers) || transfer->cs_change) | 668 | &dspi->cur_msg->transfers)) { |
681 | dspi->cs_change = 1; | 669 | /* Leave PCS activated after last transfer when |
670 | * cs_change is set. | ||
671 | */ | ||
672 | if (transfer->cs_change) | ||
673 | dspi->tx_cmd |= SPI_PUSHR_CMD_CONT; | ||
674 | } else { | ||
675 | /* Keep PCS active between transfers in same message | ||
676 | * when cs_change is not set, and de-activate PCS | ||
677 | * between transfers in the same message when | ||
678 | * cs_change is set. | ||
679 | */ | ||
680 | if (!transfer->cs_change) | ||
681 | dspi->tx_cmd |= SPI_PUSHR_CMD_CONT; | ||
682 | } | ||
683 | |||
682 | dspi->void_write_data = dspi->cur_chip->void_write_data; | 684 | dspi->void_write_data = dspi->cur_chip->void_write_data; |
683 | 685 | ||
684 | dspi->dataflags = 0; | 686 | dspi->tx = transfer->tx_buf; |
685 | dspi->tx = (void *)transfer->tx_buf; | ||
686 | dspi->tx_end = dspi->tx + transfer->len; | ||
687 | dspi->rx = transfer->rx_buf; | 687 | dspi->rx = transfer->rx_buf; |
688 | dspi->rx_end = dspi->rx + transfer->len; | 688 | dspi->rx_end = dspi->rx + transfer->len; |
689 | dspi->len = transfer->len; | 689 | dspi->len = transfer->len; |
690 | /* Validated transfer specific frame size (defaults applied) */ | ||
691 | dspi->bits_per_word = transfer->bits_per_word; | ||
692 | if (transfer->bits_per_word <= 8) | ||
693 | dspi->bytes_per_word = 1; | ||
694 | else if (transfer->bits_per_word <= 16) | ||
695 | dspi->bytes_per_word = 2; | ||
696 | else | ||
697 | dspi->bytes_per_word = 4; | ||
690 | 698 | ||
691 | if (!dspi->rx) | ||
692 | dspi->dataflags |= TRAN_STATE_RX_VOID; | ||
693 | |||
694 | if (!dspi->tx) | ||
695 | dspi->dataflags |= TRAN_STATE_TX_VOID; | ||
696 | |||
697 | regmap_write(dspi->regmap, SPI_MCR, dspi->cur_chip->mcr_val); | ||
698 | regmap_update_bits(dspi->regmap, SPI_MCR, | 699 | regmap_update_bits(dspi->regmap, SPI_MCR, |
699 | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF, | 700 | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF, |
700 | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF); | 701 | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF); |
701 | regmap_write(dspi->regmap, SPI_CTAR(0), | 702 | regmap_write(dspi->regmap, SPI_CTAR(0), |
702 | dspi->cur_chip->ctar_val); | 703 | dspi->cur_chip->ctar_val | |
704 | SPI_FRAME_BITS(transfer->bits_per_word)); | ||
705 | if (dspi->devtype_data->xspi_mode) | ||
706 | regmap_write(dspi->regmap, SPI_CTARE(0), | ||
707 | SPI_FRAME_EBITS(transfer->bits_per_word) | ||
708 | | SPI_CTARE_DTCP(1)); | ||
703 | 709 | ||
704 | trans_mode = dspi->devtype_data->trans_mode; | 710 | trans_mode = dspi->devtype_data->trans_mode; |
705 | switch (trans_mode) { | 711 | switch (trans_mode) { |
@@ -750,16 +756,9 @@ static int dspi_setup(struct spi_device *spi) | |||
750 | struct fsl_dspi_platform_data *pdata; | 756 | struct fsl_dspi_platform_data *pdata; |
751 | u32 cs_sck_delay = 0, sck_cs_delay = 0; | 757 | u32 cs_sck_delay = 0, sck_cs_delay = 0; |
752 | unsigned char br = 0, pbr = 0, pcssck = 0, cssck = 0; | 758 | unsigned char br = 0, pbr = 0, pcssck = 0, cssck = 0; |
753 | unsigned char pasc = 0, asc = 0, fmsz = 0; | 759 | unsigned char pasc = 0, asc = 0; |
754 | unsigned long clkrate; | 760 | unsigned long clkrate; |
755 | 761 | ||
756 | if ((spi->bits_per_word >= 4) && (spi->bits_per_word <= 16)) { | ||
757 | fmsz = spi->bits_per_word - 1; | ||
758 | } else { | ||
759 | pr_err("Invalid wordsize\n"); | ||
760 | return -ENODEV; | ||
761 | } | ||
762 | |||
763 | /* Only alloc on first setup */ | 762 | /* Only alloc on first setup */ |
764 | chip = spi_get_ctldata(spi); | 763 | chip = spi_get_ctldata(spi); |
765 | if (chip == NULL) { | 764 | if (chip == NULL) { |
@@ -781,9 +780,6 @@ static int dspi_setup(struct spi_device *spi) | |||
781 | sck_cs_delay = pdata->sck_cs_delay; | 780 | sck_cs_delay = pdata->sck_cs_delay; |
782 | } | 781 | } |
783 | 782 | ||
784 | chip->mcr_val = SPI_MCR_MASTER | SPI_MCR_PCSIS | | ||
785 | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF; | ||
786 | |||
787 | chip->void_write_data = 0; | 783 | chip->void_write_data = 0; |
788 | 784 | ||
789 | clkrate = clk_get_rate(dspi->clk); | 785 | clkrate = clk_get_rate(dspi->clk); |
@@ -795,8 +791,7 @@ static int dspi_setup(struct spi_device *spi) | |||
795 | /* Set After SCK delay scale values */ | 791 | /* Set After SCK delay scale values */ |
796 | ns_delay_scale(&pasc, &asc, sck_cs_delay, clkrate); | 792 | ns_delay_scale(&pasc, &asc, sck_cs_delay, clkrate); |
797 | 793 | ||
798 | chip->ctar_val = SPI_CTAR_FMSZ(fmsz) | 794 | chip->ctar_val = SPI_CTAR_CPOL(spi->mode & SPI_CPOL ? 1 : 0) |
799 | | SPI_CTAR_CPOL(spi->mode & SPI_CPOL ? 1 : 0) | ||
800 | | SPI_CTAR_CPHA(spi->mode & SPI_CPHA ? 1 : 0) | 795 | | SPI_CTAR_CPHA(spi->mode & SPI_CPHA ? 1 : 0) |
801 | | SPI_CTAR_LSBFE(spi->mode & SPI_LSB_FIRST ? 1 : 0) | 796 | | SPI_CTAR_LSBFE(spi->mode & SPI_LSB_FIRST ? 1 : 0) |
802 | | SPI_CTAR_PCSSCK(pcssck) | 797 | | SPI_CTAR_PCSSCK(pcssck) |
@@ -827,36 +822,20 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id) | |||
827 | struct spi_message *msg = dspi->cur_msg; | 822 | struct spi_message *msg = dspi->cur_msg; |
828 | enum dspi_trans_mode trans_mode; | 823 | enum dspi_trans_mode trans_mode; |
829 | u32 spi_sr, spi_tcr; | 824 | u32 spi_sr, spi_tcr; |
830 | u32 spi_tcnt, tcnt_diff; | 825 | u16 spi_tcnt; |
831 | int tx_word; | ||
832 | 826 | ||
833 | regmap_read(dspi->regmap, SPI_SR, &spi_sr); | 827 | regmap_read(dspi->regmap, SPI_SR, &spi_sr); |
834 | regmap_write(dspi->regmap, SPI_SR, spi_sr); | 828 | regmap_write(dspi->regmap, SPI_SR, spi_sr); |
835 | 829 | ||
836 | 830 | ||
837 | if (spi_sr & (SPI_SR_EOQF | SPI_SR_TCFQF)) { | 831 | if (spi_sr & (SPI_SR_EOQF | SPI_SR_TCFQF)) { |
838 | tx_word = is_double_byte_mode(dspi); | 832 | /* Get transfer counter (in number of SPI transfers). It was |
839 | 833 | * reset to 0 when transfer(s) were started. | |
834 | */ | ||
840 | regmap_read(dspi->regmap, SPI_TCR, &spi_tcr); | 835 | regmap_read(dspi->regmap, SPI_TCR, &spi_tcr); |
841 | spi_tcnt = SPI_TCR_GET_TCNT(spi_tcr); | 836 | spi_tcnt = SPI_TCR_GET_TCNT(spi_tcr); |
842 | /* | 837 | /* Update total number of bytes that were transferred */ |
843 | * The width of SPI Transfer Counter in SPI_TCR is 16bits, | 838 | msg->actual_length += spi_tcnt * dspi->bytes_per_word; |
844 | * so the max couner is 65535. When the counter reach 65535, | ||
845 | * it will wrap around, counter reset to zero. | ||
846 | * spi_tcnt my be less than dspi->spi_tcnt, it means the | ||
847 | * counter already wrapped around. | ||
848 | * SPI Transfer Counter is a counter of transmitted frames. | ||
849 | * The size of frame maybe two bytes. | ||
850 | */ | ||
851 | tcnt_diff = ((spi_tcnt + SPI_TCR_TCNT_MAX) - dspi->spi_tcnt) | ||
852 | % SPI_TCR_TCNT_MAX; | ||
853 | tcnt_diff *= (tx_word + 1); | ||
854 | if (dspi->dataflags & TRAN_STATE_WORD_ODD_NUM) | ||
855 | tcnt_diff--; | ||
856 | |||
857 | msg->actual_length += tcnt_diff; | ||
858 | |||
859 | dspi->spi_tcnt = spi_tcnt; | ||
860 | 839 | ||
861 | trans_mode = dspi->devtype_data->trans_mode; | 840 | trans_mode = dspi->devtype_data->trans_mode; |
862 | switch (trans_mode) { | 841 | switch (trans_mode) { |
@@ -873,14 +852,6 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id) | |||
873 | } | 852 | } |
874 | 853 | ||
875 | if (!dspi->len) { | 854 | if (!dspi->len) { |
876 | if (dspi->dataflags & TRAN_STATE_WORD_ODD_NUM) { | ||
877 | regmap_update_bits(dspi->regmap, | ||
878 | SPI_CTAR(0), | ||
879 | SPI_FRAME_BITS_MASK, | ||
880 | SPI_FRAME_BITS(16)); | ||
881 | dspi->dataflags &= ~TRAN_STATE_WORD_ODD_NUM; | ||
882 | } | ||
883 | |||
884 | dspi->waitflags = 1; | 855 | dspi->waitflags = 1; |
885 | wake_up_interruptible(&dspi->waitq); | 856 | wake_up_interruptible(&dspi->waitq); |
886 | } else { | 857 | } else { |
@@ -943,16 +914,62 @@ static int dspi_resume(struct device *dev) | |||
943 | 914 | ||
944 | static SIMPLE_DEV_PM_OPS(dspi_pm, dspi_suspend, dspi_resume); | 915 | static SIMPLE_DEV_PM_OPS(dspi_pm, dspi_suspend, dspi_resume); |
945 | 916 | ||
917 | static const struct regmap_range dspi_volatile_ranges[] = { | ||
918 | regmap_reg_range(SPI_MCR, SPI_TCR), | ||
919 | regmap_reg_range(SPI_SR, SPI_SR), | ||
920 | regmap_reg_range(SPI_PUSHR, SPI_RXFR3), | ||
921 | }; | ||
922 | |||
923 | static const struct regmap_access_table dspi_volatile_table = { | ||
924 | .yes_ranges = dspi_volatile_ranges, | ||
925 | .n_yes_ranges = ARRAY_SIZE(dspi_volatile_ranges), | ||
926 | }; | ||
927 | |||
946 | static const struct regmap_config dspi_regmap_config = { | 928 | static const struct regmap_config dspi_regmap_config = { |
947 | .reg_bits = 32, | 929 | .reg_bits = 32, |
948 | .val_bits = 32, | 930 | .val_bits = 32, |
949 | .reg_stride = 4, | 931 | .reg_stride = 4, |
950 | .max_register = 0x88, | 932 | .max_register = 0x88, |
933 | .volatile_table = &dspi_volatile_table, | ||
934 | }; | ||
935 | |||
936 | static const struct regmap_range dspi_xspi_volatile_ranges[] = { | ||
937 | regmap_reg_range(SPI_MCR, SPI_TCR), | ||
938 | regmap_reg_range(SPI_SR, SPI_SR), | ||
939 | regmap_reg_range(SPI_PUSHR, SPI_RXFR3), | ||
940 | regmap_reg_range(SPI_SREX, SPI_SREX), | ||
941 | }; | ||
942 | |||
943 | static const struct regmap_access_table dspi_xspi_volatile_table = { | ||
944 | .yes_ranges = dspi_xspi_volatile_ranges, | ||
945 | .n_yes_ranges = ARRAY_SIZE(dspi_xspi_volatile_ranges), | ||
946 | }; | ||
947 | |||
948 | static const struct regmap_config dspi_xspi_regmap_config[] = { | ||
949 | { | ||
950 | .reg_bits = 32, | ||
951 | .val_bits = 32, | ||
952 | .reg_stride = 4, | ||
953 | .max_register = 0x13c, | ||
954 | .volatile_table = &dspi_xspi_volatile_table, | ||
955 | }, | ||
956 | { | ||
957 | .name = "pushr", | ||
958 | .reg_bits = 16, | ||
959 | .val_bits = 16, | ||
960 | .reg_stride = 2, | ||
961 | .max_register = 0x2, | ||
962 | }, | ||
951 | }; | 963 | }; |
952 | 964 | ||
953 | static void dspi_init(struct fsl_dspi *dspi) | 965 | static void dspi_init(struct fsl_dspi *dspi) |
954 | { | 966 | { |
967 | regmap_write(dspi->regmap, SPI_MCR, SPI_MCR_MASTER | SPI_MCR_PCSIS | | ||
968 | (dspi->devtype_data->xspi_mode ? SPI_MCR_XSPI : 0)); | ||
955 | regmap_write(dspi->regmap, SPI_SR, SPI_SR_CLEAR); | 969 | regmap_write(dspi->regmap, SPI_SR, SPI_SR_CLEAR); |
970 | if (dspi->devtype_data->xspi_mode) | ||
971 | regmap_write(dspi->regmap, SPI_CTARE(0), | ||
972 | SPI_CTARE_FMSZE(0) | SPI_CTARE_DTCP(1)); | ||
956 | } | 973 | } |
957 | 974 | ||
958 | static int dspi_probe(struct platform_device *pdev) | 975 | static int dspi_probe(struct platform_device *pdev) |
@@ -961,6 +978,7 @@ static int dspi_probe(struct platform_device *pdev) | |||
961 | struct spi_master *master; | 978 | struct spi_master *master; |
962 | struct fsl_dspi *dspi; | 979 | struct fsl_dspi *dspi; |
963 | struct resource *res; | 980 | struct resource *res; |
981 | const struct regmap_config *regmap_config; | ||
964 | void __iomem *base; | 982 | void __iomem *base; |
965 | struct fsl_dspi_platform_data *pdata; | 983 | struct fsl_dspi_platform_data *pdata; |
966 | int ret = 0, cs_num, bus_num; | 984 | int ret = 0, cs_num, bus_num; |
@@ -980,8 +998,6 @@ static int dspi_probe(struct platform_device *pdev) | |||
980 | 998 | ||
981 | master->cleanup = dspi_cleanup; | 999 | master->cleanup = dspi_cleanup; |
982 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST; | 1000 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST; |
983 | master->bits_per_word_mask = SPI_BPW_MASK(4) | SPI_BPW_MASK(8) | | ||
984 | SPI_BPW_MASK(16); | ||
985 | 1001 | ||
986 | pdata = dev_get_platdata(&pdev->dev); | 1002 | pdata = dev_get_platdata(&pdev->dev); |
987 | if (pdata) { | 1003 | if (pdata) { |
@@ -1013,6 +1029,11 @@ static int dspi_probe(struct platform_device *pdev) | |||
1013 | } | 1029 | } |
1014 | } | 1030 | } |
1015 | 1031 | ||
1032 | if (dspi->devtype_data->xspi_mode) | ||
1033 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); | ||
1034 | else | ||
1035 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); | ||
1036 | |||
1016 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1037 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1017 | base = devm_ioremap_resource(&pdev->dev, res); | 1038 | base = devm_ioremap_resource(&pdev->dev, res); |
1018 | if (IS_ERR(base)) { | 1039 | if (IS_ERR(base)) { |
@@ -1020,8 +1041,11 @@ static int dspi_probe(struct platform_device *pdev) | |||
1020 | goto out_master_put; | 1041 | goto out_master_put; |
1021 | } | 1042 | } |
1022 | 1043 | ||
1023 | dspi->regmap = devm_regmap_init_mmio_clk(&pdev->dev, NULL, base, | 1044 | if (dspi->devtype_data->xspi_mode) |
1024 | &dspi_regmap_config); | 1045 | regmap_config = &dspi_xspi_regmap_config[0]; |
1046 | else | ||
1047 | regmap_config = &dspi_regmap_config; | ||
1048 | dspi->regmap = devm_regmap_init_mmio(&pdev->dev, base, regmap_config); | ||
1025 | if (IS_ERR(dspi->regmap)) { | 1049 | if (IS_ERR(dspi->regmap)) { |
1026 | dev_err(&pdev->dev, "failed to init regmap: %ld\n", | 1050 | dev_err(&pdev->dev, "failed to init regmap: %ld\n", |
1027 | PTR_ERR(dspi->regmap)); | 1051 | PTR_ERR(dspi->regmap)); |
@@ -1029,30 +1053,43 @@ static int dspi_probe(struct platform_device *pdev) | |||
1029 | goto out_master_put; | 1053 | goto out_master_put; |
1030 | } | 1054 | } |
1031 | 1055 | ||
1056 | if (dspi->devtype_data->xspi_mode) { | ||
1057 | dspi->regmap_pushr = devm_regmap_init_mmio( | ||
1058 | &pdev->dev, base + SPI_PUSHR, | ||
1059 | &dspi_xspi_regmap_config[1]); | ||
1060 | if (IS_ERR(dspi->regmap_pushr)) { | ||
1061 | dev_err(&pdev->dev, | ||
1062 | "failed to init pushr regmap: %ld\n", | ||
1063 | PTR_ERR(dspi->regmap_pushr)); | ||
1064 | ret = PTR_ERR(dspi->regmap_pushr); | ||
1065 | goto out_master_put; | ||
1066 | } | ||
1067 | } | ||
1068 | |||
1069 | dspi->clk = devm_clk_get(&pdev->dev, "dspi"); | ||
1070 | if (IS_ERR(dspi->clk)) { | ||
1071 | ret = PTR_ERR(dspi->clk); | ||
1072 | dev_err(&pdev->dev, "unable to get clock\n"); | ||
1073 | goto out_master_put; | ||
1074 | } | ||
1075 | ret = clk_prepare_enable(dspi->clk); | ||
1076 | if (ret) | ||
1077 | goto out_master_put; | ||
1078 | |||
1032 | dspi_init(dspi); | 1079 | dspi_init(dspi); |
1033 | dspi->irq = platform_get_irq(pdev, 0); | 1080 | dspi->irq = platform_get_irq(pdev, 0); |
1034 | if (dspi->irq < 0) { | 1081 | if (dspi->irq < 0) { |
1035 | dev_err(&pdev->dev, "can't get platform irq\n"); | 1082 | dev_err(&pdev->dev, "can't get platform irq\n"); |
1036 | ret = dspi->irq; | 1083 | ret = dspi->irq; |
1037 | goto out_master_put; | 1084 | goto out_clk_put; |
1038 | } | 1085 | } |
1039 | 1086 | ||
1040 | ret = devm_request_irq(&pdev->dev, dspi->irq, dspi_interrupt, 0, | 1087 | ret = devm_request_irq(&pdev->dev, dspi->irq, dspi_interrupt, 0, |
1041 | pdev->name, dspi); | 1088 | pdev->name, dspi); |
1042 | if (ret < 0) { | 1089 | if (ret < 0) { |
1043 | dev_err(&pdev->dev, "Unable to attach DSPI interrupt\n"); | 1090 | dev_err(&pdev->dev, "Unable to attach DSPI interrupt\n"); |
1044 | goto out_master_put; | 1091 | goto out_clk_put; |
1045 | } | ||
1046 | |||
1047 | dspi->clk = devm_clk_get(&pdev->dev, "dspi"); | ||
1048 | if (IS_ERR(dspi->clk)) { | ||
1049 | ret = PTR_ERR(dspi->clk); | ||
1050 | dev_err(&pdev->dev, "unable to get clock\n"); | ||
1051 | goto out_master_put; | ||
1052 | } | 1092 | } |
1053 | ret = clk_prepare_enable(dspi->clk); | ||
1054 | if (ret) | ||
1055 | goto out_master_put; | ||
1056 | 1093 | ||
1057 | if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) { | 1094 | if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) { |
1058 | ret = dspi_request_dma(dspi, res->start); | 1095 | ret = dspi_request_dma(dspi, res->start); |
diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index 1d332e23f6ed..1e8ff6256079 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c | |||
@@ -547,8 +547,11 @@ static void fsl_espi_cpu_irq(struct fsl_espi *espi, u32 events) | |||
547 | dev_err(espi->dev, | 547 | dev_err(espi->dev, |
548 | "Transfer done but SPIE_DON isn't set!\n"); | 548 | "Transfer done but SPIE_DON isn't set!\n"); |
549 | 549 | ||
550 | if (SPIE_RXCNT(events) || SPIE_TXCNT(events) != FSL_ESPI_FIFO_SIZE) | 550 | if (SPIE_RXCNT(events) || SPIE_TXCNT(events) != FSL_ESPI_FIFO_SIZE) { |
551 | dev_err(espi->dev, "Transfer done but rx/tx fifo's aren't empty!\n"); | 551 | dev_err(espi->dev, "Transfer done but rx/tx fifo's aren't empty!\n"); |
552 | dev_err(espi->dev, "SPIE_RXCNT = %d, SPIE_TXCNT = %d\n", | ||
553 | SPIE_RXCNT(events), SPIE_TXCNT(events)); | ||
554 | } | ||
552 | 555 | ||
553 | complete(&espi->done); | 556 | complete(&espi->done); |
554 | } | 557 | } |
diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c index 6ae92d4dca19..0626e6e3ea0c 100644 --- a/drivers/spi/spi-gpio.c +++ b/drivers/spi/spi-gpio.c | |||
@@ -121,7 +121,10 @@ static inline int getmiso(const struct spi_device *spi) | |||
121 | { | 121 | { |
122 | struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); | 122 | struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); |
123 | 123 | ||
124 | return !!gpiod_get_value_cansleep(spi_gpio->miso); | 124 | if (spi->mode & SPI_3WIRE) |
125 | return !!gpiod_get_value_cansleep(spi_gpio->mosi); | ||
126 | else | ||
127 | return !!gpiod_get_value_cansleep(spi_gpio->miso); | ||
125 | } | 128 | } |
126 | 129 | ||
127 | /* | 130 | /* |
@@ -149,27 +152,27 @@ static inline int getmiso(const struct spi_device *spi) | |||
149 | */ | 152 | */ |
150 | 153 | ||
151 | static u32 spi_gpio_txrx_word_mode0(struct spi_device *spi, | 154 | static u32 spi_gpio_txrx_word_mode0(struct spi_device *spi, |
152 | unsigned nsecs, u32 word, u8 bits) | 155 | unsigned nsecs, u32 word, u8 bits, unsigned flags) |
153 | { | 156 | { |
154 | return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits); | 157 | return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits); |
155 | } | 158 | } |
156 | 159 | ||
157 | static u32 spi_gpio_txrx_word_mode1(struct spi_device *spi, | 160 | static u32 spi_gpio_txrx_word_mode1(struct spi_device *spi, |
158 | unsigned nsecs, u32 word, u8 bits) | 161 | unsigned nsecs, u32 word, u8 bits, unsigned flags) |
159 | { | 162 | { |
160 | return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits); | 163 | return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits); |
161 | } | 164 | } |
162 | 165 | ||
163 | static u32 spi_gpio_txrx_word_mode2(struct spi_device *spi, | 166 | static u32 spi_gpio_txrx_word_mode2(struct spi_device *spi, |
164 | unsigned nsecs, u32 word, u8 bits) | 167 | unsigned nsecs, u32 word, u8 bits, unsigned flags) |
165 | { | 168 | { |
166 | return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits); | 169 | return bitbang_txrx_be_cpha0(spi, nsecs, 1, flags, word, bits); |
167 | } | 170 | } |
168 | 171 | ||
169 | static u32 spi_gpio_txrx_word_mode3(struct spi_device *spi, | 172 | static u32 spi_gpio_txrx_word_mode3(struct spi_device *spi, |
170 | unsigned nsecs, u32 word, u8 bits) | 173 | unsigned nsecs, u32 word, u8 bits, unsigned flags) |
171 | { | 174 | { |
172 | return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits); | 175 | return bitbang_txrx_be_cpha1(spi, nsecs, 1, flags, word, bits); |
173 | } | 176 | } |
174 | 177 | ||
175 | /* | 178 | /* |
@@ -183,30 +186,30 @@ static u32 spi_gpio_txrx_word_mode3(struct spi_device *spi, | |||
183 | */ | 186 | */ |
184 | 187 | ||
185 | static u32 spi_gpio_spec_txrx_word_mode0(struct spi_device *spi, | 188 | static u32 spi_gpio_spec_txrx_word_mode0(struct spi_device *spi, |
186 | unsigned nsecs, u32 word, u8 bits) | 189 | unsigned nsecs, u32 word, u8 bits, unsigned flags) |
187 | { | 190 | { |
188 | unsigned flags = spi->master->flags; | 191 | flags = spi->master->flags; |
189 | return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits); | 192 | return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits); |
190 | } | 193 | } |
191 | 194 | ||
192 | static u32 spi_gpio_spec_txrx_word_mode1(struct spi_device *spi, | 195 | static u32 spi_gpio_spec_txrx_word_mode1(struct spi_device *spi, |
193 | unsigned nsecs, u32 word, u8 bits) | 196 | unsigned nsecs, u32 word, u8 bits, unsigned flags) |
194 | { | 197 | { |
195 | unsigned flags = spi->master->flags; | 198 | flags = spi->master->flags; |
196 | return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits); | 199 | return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits); |
197 | } | 200 | } |
198 | 201 | ||
199 | static u32 spi_gpio_spec_txrx_word_mode2(struct spi_device *spi, | 202 | static u32 spi_gpio_spec_txrx_word_mode2(struct spi_device *spi, |
200 | unsigned nsecs, u32 word, u8 bits) | 203 | unsigned nsecs, u32 word, u8 bits, unsigned flags) |
201 | { | 204 | { |
202 | unsigned flags = spi->master->flags; | 205 | flags = spi->master->flags; |
203 | return bitbang_txrx_be_cpha0(spi, nsecs, 1, flags, word, bits); | 206 | return bitbang_txrx_be_cpha0(spi, nsecs, 1, flags, word, bits); |
204 | } | 207 | } |
205 | 208 | ||
206 | static u32 spi_gpio_spec_txrx_word_mode3(struct spi_device *spi, | 209 | static u32 spi_gpio_spec_txrx_word_mode3(struct spi_device *spi, |
207 | unsigned nsecs, u32 word, u8 bits) | 210 | unsigned nsecs, u32 word, u8 bits, unsigned flags) |
208 | { | 211 | { |
209 | unsigned flags = spi->master->flags; | 212 | flags = spi->master->flags; |
210 | return bitbang_txrx_be_cpha1(spi, nsecs, 1, flags, word, bits); | 213 | return bitbang_txrx_be_cpha1(spi, nsecs, 1, flags, word, bits); |
211 | } | 214 | } |
212 | 215 | ||
@@ -250,6 +253,16 @@ static int spi_gpio_setup(struct spi_device *spi) | |||
250 | return status; | 253 | return status; |
251 | } | 254 | } |
252 | 255 | ||
256 | static int spi_gpio_set_direction(struct spi_device *spi, bool output) | ||
257 | { | ||
258 | struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); | ||
259 | |||
260 | if (output) | ||
261 | return gpiod_direction_output(spi_gpio->mosi, 1); | ||
262 | else | ||
263 | return gpiod_direction_input(spi_gpio->mosi); | ||
264 | } | ||
265 | |||
253 | static void spi_gpio_cleanup(struct spi_device *spi) | 266 | static void spi_gpio_cleanup(struct spi_device *spi) |
254 | { | 267 | { |
255 | spi_bitbang_cleanup(spi); | 268 | spi_bitbang_cleanup(spi); |
@@ -395,6 +408,7 @@ static int spi_gpio_probe(struct platform_device *pdev) | |||
395 | return status; | 408 | return status; |
396 | 409 | ||
397 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); | 410 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); |
411 | master->mode_bits = SPI_3WIRE | SPI_CPHA | SPI_CPOL; | ||
398 | master->flags = master_flags; | 412 | master->flags = master_flags; |
399 | master->bus_num = pdev->id; | 413 | master->bus_num = pdev->id; |
400 | /* The master needs to think there is a chipselect even if not connected */ | 414 | /* The master needs to think there is a chipselect even if not connected */ |
@@ -407,6 +421,7 @@ static int spi_gpio_probe(struct platform_device *pdev) | |||
407 | 421 | ||
408 | spi_gpio->bitbang.master = master; | 422 | spi_gpio->bitbang.master = master; |
409 | spi_gpio->bitbang.chipselect = spi_gpio_chipselect; | 423 | spi_gpio->bitbang.chipselect = spi_gpio_chipselect; |
424 | spi_gpio->bitbang.set_line_direction = spi_gpio_set_direction; | ||
410 | 425 | ||
411 | if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) { | 426 | if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) { |
412 | spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0; | 427 | spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0; |
diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c index 7a37090dabbe..e6eb979f1b8a 100644 --- a/drivers/spi/spi-img-spfi.c +++ b/drivers/spi/spi-img-spfi.c | |||
@@ -419,6 +419,9 @@ static int img_spfi_prepare(struct spi_master *master, struct spi_message *msg) | |||
419 | u32 val; | 419 | u32 val; |
420 | 420 | ||
421 | val = spfi_readl(spfi, SPFI_PORT_STATE); | 421 | val = spfi_readl(spfi, SPFI_PORT_STATE); |
422 | val &= ~(SPFI_PORT_STATE_DEV_SEL_MASK << | ||
423 | SPFI_PORT_STATE_DEV_SEL_SHIFT); | ||
424 | val |= msg->spi->chip_select << SPFI_PORT_STATE_DEV_SEL_SHIFT; | ||
422 | if (msg->spi->mode & SPI_CPHA) | 425 | if (msg->spi->mode & SPI_CPHA) |
423 | val |= SPFI_PORT_STATE_CK_PHASE(msg->spi->chip_select); | 426 | val |= SPFI_PORT_STATE_CK_PHASE(msg->spi->chip_select); |
424 | else | 427 | else |
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index d3b21faf6b1f..08dd3a31a3e5 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c | |||
@@ -94,8 +94,7 @@ struct spi_imx_data { | |||
94 | void *rx_buf; | 94 | void *rx_buf; |
95 | const void *tx_buf; | 95 | const void *tx_buf; |
96 | unsigned int txfifo; /* number of words pushed in tx FIFO */ | 96 | unsigned int txfifo; /* number of words pushed in tx FIFO */ |
97 | unsigned int dynamic_burst, read_u32; | 97 | unsigned int dynamic_burst; |
98 | unsigned int word_mask; | ||
99 | 98 | ||
100 | /* Slave mode */ | 99 | /* Slave mode */ |
101 | bool slave_mode; | 100 | bool slave_mode; |
@@ -140,6 +139,8 @@ static void spi_imx_buf_rx_##type(struct spi_imx_data *spi_imx) \ | |||
140 | *(type *)spi_imx->rx_buf = val; \ | 139 | *(type *)spi_imx->rx_buf = val; \ |
141 | spi_imx->rx_buf += sizeof(type); \ | 140 | spi_imx->rx_buf += sizeof(type); \ |
142 | } \ | 141 | } \ |
142 | \ | ||
143 | spi_imx->remainder -= sizeof(type); \ | ||
143 | } | 144 | } |
144 | 145 | ||
145 | #define MXC_SPI_BUF_TX(type) \ | 146 | #define MXC_SPI_BUF_TX(type) \ |
@@ -203,7 +204,12 @@ out: | |||
203 | 204 | ||
204 | static int spi_imx_bytes_per_word(const int bits_per_word) | 205 | static int spi_imx_bytes_per_word(const int bits_per_word) |
205 | { | 206 | { |
206 | return DIV_ROUND_UP(bits_per_word, BITS_PER_BYTE); | 207 | if (bits_per_word <= 8) |
208 | return 1; | ||
209 | else if (bits_per_word <= 16) | ||
210 | return 2; | ||
211 | else | ||
212 | return 4; | ||
207 | } | 213 | } |
208 | 214 | ||
209 | static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, | 215 | static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, |
@@ -220,17 +226,11 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, | |||
220 | 226 | ||
221 | bytes_per_word = spi_imx_bytes_per_word(transfer->bits_per_word); | 227 | bytes_per_word = spi_imx_bytes_per_word(transfer->bits_per_word); |
222 | 228 | ||
223 | if (bytes_per_word != 1 && bytes_per_word != 2 && bytes_per_word != 4) | ||
224 | return false; | ||
225 | |||
226 | for (i = spi_imx->devtype_data->fifo_size / 2; i > 0; i--) { | 229 | for (i = spi_imx->devtype_data->fifo_size / 2; i > 0; i--) { |
227 | if (!(transfer->len % (i * bytes_per_word))) | 230 | if (!(transfer->len % (i * bytes_per_word))) |
228 | break; | 231 | break; |
229 | } | 232 | } |
230 | 233 | ||
231 | if (i == 0) | ||
232 | return false; | ||
233 | |||
234 | spi_imx->wml = i; | 234 | spi_imx->wml = i; |
235 | spi_imx->dynamic_burst = 0; | 235 | spi_imx->dynamic_burst = 0; |
236 | 236 | ||
@@ -291,26 +291,39 @@ static void spi_imx_buf_rx_swap_u32(struct spi_imx_data *spi_imx) | |||
291 | else if (bytes_per_word == 2) | 291 | else if (bytes_per_word == 2) |
292 | val = (val << 16) | (val >> 16); | 292 | val = (val << 16) | (val >> 16); |
293 | #endif | 293 | #endif |
294 | val &= spi_imx->word_mask; | ||
295 | *(u32 *)spi_imx->rx_buf = val; | 294 | *(u32 *)spi_imx->rx_buf = val; |
296 | spi_imx->rx_buf += sizeof(u32); | 295 | spi_imx->rx_buf += sizeof(u32); |
297 | } | 296 | } |
297 | |||
298 | spi_imx->remainder -= sizeof(u32); | ||
298 | } | 299 | } |
299 | 300 | ||
300 | static void spi_imx_buf_rx_swap(struct spi_imx_data *spi_imx) | 301 | static void spi_imx_buf_rx_swap(struct spi_imx_data *spi_imx) |
301 | { | 302 | { |
302 | unsigned int bytes_per_word; | 303 | int unaligned; |
304 | u32 val; | ||
303 | 305 | ||
304 | bytes_per_word = spi_imx_bytes_per_word(spi_imx->bits_per_word); | 306 | unaligned = spi_imx->remainder % 4; |
305 | if (spi_imx->read_u32) { | 307 | |
308 | if (!unaligned) { | ||
306 | spi_imx_buf_rx_swap_u32(spi_imx); | 309 | spi_imx_buf_rx_swap_u32(spi_imx); |
307 | return; | 310 | return; |
308 | } | 311 | } |
309 | 312 | ||
310 | if (bytes_per_word == 1) | 313 | if (spi_imx_bytes_per_word(spi_imx->bits_per_word) == 2) { |
311 | spi_imx_buf_rx_u8(spi_imx); | ||
312 | else if (bytes_per_word == 2) | ||
313 | spi_imx_buf_rx_u16(spi_imx); | 314 | spi_imx_buf_rx_u16(spi_imx); |
315 | return; | ||
316 | } | ||
317 | |||
318 | val = readl(spi_imx->base + MXC_CSPIRXDATA); | ||
319 | |||
320 | while (unaligned--) { | ||
321 | if (spi_imx->rx_buf) { | ||
322 | *(u8 *)spi_imx->rx_buf = (val >> (8 * unaligned)) & 0xff; | ||
323 | spi_imx->rx_buf++; | ||
324 | } | ||
325 | spi_imx->remainder--; | ||
326 | } | ||
314 | } | 327 | } |
315 | 328 | ||
316 | static void spi_imx_buf_tx_swap_u32(struct spi_imx_data *spi_imx) | 329 | static void spi_imx_buf_tx_swap_u32(struct spi_imx_data *spi_imx) |
@@ -322,7 +335,6 @@ static void spi_imx_buf_tx_swap_u32(struct spi_imx_data *spi_imx) | |||
322 | 335 | ||
323 | if (spi_imx->tx_buf) { | 336 | if (spi_imx->tx_buf) { |
324 | val = *(u32 *)spi_imx->tx_buf; | 337 | val = *(u32 *)spi_imx->tx_buf; |
325 | val &= spi_imx->word_mask; | ||
326 | spi_imx->tx_buf += sizeof(u32); | 338 | spi_imx->tx_buf += sizeof(u32); |
327 | } | 339 | } |
328 | 340 | ||
@@ -340,40 +352,30 @@ static void spi_imx_buf_tx_swap_u32(struct spi_imx_data *spi_imx) | |||
340 | 352 | ||
341 | static void spi_imx_buf_tx_swap(struct spi_imx_data *spi_imx) | 353 | static void spi_imx_buf_tx_swap(struct spi_imx_data *spi_imx) |
342 | { | 354 | { |
343 | u32 ctrl, val; | 355 | int unaligned; |
344 | unsigned int bytes_per_word; | 356 | u32 val = 0; |
345 | 357 | ||
346 | if (spi_imx->count == spi_imx->remainder) { | 358 | unaligned = spi_imx->count % 4; |
347 | ctrl = readl(spi_imx->base + MX51_ECSPI_CTRL); | ||
348 | ctrl &= ~MX51_ECSPI_CTRL_BL_MASK; | ||
349 | if (spi_imx->count > MX51_ECSPI_CTRL_MAX_BURST) { | ||
350 | spi_imx->remainder = spi_imx->count % | ||
351 | MX51_ECSPI_CTRL_MAX_BURST; | ||
352 | val = MX51_ECSPI_CTRL_MAX_BURST * 8 - 1; | ||
353 | } else if (spi_imx->count >= sizeof(u32)) { | ||
354 | spi_imx->remainder = spi_imx->count % sizeof(u32); | ||
355 | val = (spi_imx->count - spi_imx->remainder) * 8 - 1; | ||
356 | } else { | ||
357 | spi_imx->remainder = 0; | ||
358 | val = spi_imx->bits_per_word - 1; | ||
359 | spi_imx->read_u32 = 0; | ||
360 | } | ||
361 | 359 | ||
362 | ctrl |= (val << MX51_ECSPI_CTRL_BL_OFFSET); | 360 | if (!unaligned) { |
363 | writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL); | 361 | spi_imx_buf_tx_swap_u32(spi_imx); |
362 | return; | ||
364 | } | 363 | } |
365 | 364 | ||
366 | if (spi_imx->count >= sizeof(u32)) { | 365 | if (spi_imx_bytes_per_word(spi_imx->bits_per_word) == 2) { |
367 | spi_imx_buf_tx_swap_u32(spi_imx); | 366 | spi_imx_buf_tx_u16(spi_imx); |
368 | return; | 367 | return; |
369 | } | 368 | } |
370 | 369 | ||
371 | bytes_per_word = spi_imx_bytes_per_word(spi_imx->bits_per_word); | 370 | while (unaligned--) { |
371 | if (spi_imx->tx_buf) { | ||
372 | val |= *(u8 *)spi_imx->tx_buf << (8 * unaligned); | ||
373 | spi_imx->tx_buf++; | ||
374 | } | ||
375 | spi_imx->count--; | ||
376 | } | ||
372 | 377 | ||
373 | if (bytes_per_word == 1) | 378 | writel(val, spi_imx->base + MXC_CSPITXDATA); |
374 | spi_imx_buf_tx_u8(spi_imx); | ||
375 | else if (bytes_per_word == 2) | ||
376 | spi_imx_buf_tx_u16(spi_imx); | ||
377 | } | 379 | } |
378 | 380 | ||
379 | static void mx53_ecspi_rx_slave(struct spi_imx_data *spi_imx) | 381 | static void mx53_ecspi_rx_slave(struct spi_imx_data *spi_imx) |
@@ -392,6 +394,8 @@ static void mx53_ecspi_rx_slave(struct spi_imx_data *spi_imx) | |||
392 | spi_imx->rx_buf += n_bytes; | 394 | spi_imx->rx_buf += n_bytes; |
393 | spi_imx->slave_burst -= n_bytes; | 395 | spi_imx->slave_burst -= n_bytes; |
394 | } | 396 | } |
397 | |||
398 | spi_imx->remainder -= sizeof(u32); | ||
395 | } | 399 | } |
396 | 400 | ||
397 | static void mx53_ecspi_tx_slave(struct spi_imx_data *spi_imx) | 401 | static void mx53_ecspi_tx_slave(struct spi_imx_data *spi_imx) |
@@ -1001,12 +1005,52 @@ static void spi_imx_chipselect(struct spi_device *spi, int is_active) | |||
1001 | gpio_set_value(spi->cs_gpio, dev_is_lowactive ^ active); | 1005 | gpio_set_value(spi->cs_gpio, dev_is_lowactive ^ active); |
1002 | } | 1006 | } |
1003 | 1007 | ||
1008 | static void spi_imx_set_burst_len(struct spi_imx_data *spi_imx, int n_bits) | ||
1009 | { | ||
1010 | u32 ctrl; | ||
1011 | |||
1012 | ctrl = readl(spi_imx->base + MX51_ECSPI_CTRL); | ||
1013 | ctrl &= ~MX51_ECSPI_CTRL_BL_MASK; | ||
1014 | ctrl |= ((n_bits - 1) << MX51_ECSPI_CTRL_BL_OFFSET); | ||
1015 | writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL); | ||
1016 | } | ||
1017 | |||
1004 | static void spi_imx_push(struct spi_imx_data *spi_imx) | 1018 | static void spi_imx_push(struct spi_imx_data *spi_imx) |
1005 | { | 1019 | { |
1020 | unsigned int burst_len, fifo_words; | ||
1021 | |||
1022 | if (spi_imx->dynamic_burst) | ||
1023 | fifo_words = 4; | ||
1024 | else | ||
1025 | fifo_words = spi_imx_bytes_per_word(spi_imx->bits_per_word); | ||
1026 | /* | ||
1027 | * Reload the FIFO when the remaining bytes to be transferred in the | ||
1028 | * current burst is 0. This only applies when bits_per_word is a | ||
1029 | * multiple of 8. | ||
1030 | */ | ||
1031 | if (!spi_imx->remainder) { | ||
1032 | if (spi_imx->dynamic_burst) { | ||
1033 | |||
1034 | /* We need to deal unaligned data first */ | ||
1035 | burst_len = spi_imx->count % MX51_ECSPI_CTRL_MAX_BURST; | ||
1036 | |||
1037 | if (!burst_len) | ||
1038 | burst_len = MX51_ECSPI_CTRL_MAX_BURST; | ||
1039 | |||
1040 | spi_imx_set_burst_len(spi_imx, burst_len * 8); | ||
1041 | |||
1042 | spi_imx->remainder = burst_len; | ||
1043 | } else { | ||
1044 | spi_imx->remainder = fifo_words; | ||
1045 | } | ||
1046 | } | ||
1047 | |||
1006 | while (spi_imx->txfifo < spi_imx->devtype_data->fifo_size) { | 1048 | while (spi_imx->txfifo < spi_imx->devtype_data->fifo_size) { |
1007 | if (!spi_imx->count) | 1049 | if (!spi_imx->count) |
1008 | break; | 1050 | break; |
1009 | if (spi_imx->txfifo && (spi_imx->count == spi_imx->remainder)) | 1051 | if (spi_imx->dynamic_burst && |
1052 | spi_imx->txfifo >= DIV_ROUND_UP(spi_imx->remainder, | ||
1053 | fifo_words)) | ||
1010 | break; | 1054 | break; |
1011 | spi_imx->tx(spi_imx); | 1055 | spi_imx->tx(spi_imx); |
1012 | spi_imx->txfifo++; | 1056 | spi_imx->txfifo++; |
@@ -1102,27 +1146,20 @@ static int spi_imx_setupxfer(struct spi_device *spi, | |||
1102 | spi_imx->bits_per_word = t->bits_per_word; | 1146 | spi_imx->bits_per_word = t->bits_per_word; |
1103 | spi_imx->speed_hz = t->speed_hz; | 1147 | spi_imx->speed_hz = t->speed_hz; |
1104 | 1148 | ||
1105 | /* Initialize the functions for transfer */ | 1149 | /* |
1106 | if (spi_imx->devtype_data->dynamic_burst && !spi_imx->slave_mode) { | 1150 | * Initialize the functions for transfer. To transfer non byte-aligned |
1107 | u32 mask; | 1151 | * words, we have to use multiple word-size bursts, we can't use |
1108 | 1152 | * dynamic_burst in that case. | |
1109 | spi_imx->dynamic_burst = 0; | 1153 | */ |
1110 | spi_imx->remainder = 0; | 1154 | if (spi_imx->devtype_data->dynamic_burst && !spi_imx->slave_mode && |
1111 | spi_imx->read_u32 = 1; | 1155 | (spi_imx->bits_per_word == 8 || |
1156 | spi_imx->bits_per_word == 16 || | ||
1157 | spi_imx->bits_per_word == 32)) { | ||
1112 | 1158 | ||
1113 | mask = (1 << spi_imx->bits_per_word) - 1; | ||
1114 | spi_imx->rx = spi_imx_buf_rx_swap; | 1159 | spi_imx->rx = spi_imx_buf_rx_swap; |
1115 | spi_imx->tx = spi_imx_buf_tx_swap; | 1160 | spi_imx->tx = spi_imx_buf_tx_swap; |
1116 | spi_imx->dynamic_burst = 1; | 1161 | spi_imx->dynamic_burst = 1; |
1117 | spi_imx->remainder = t->len; | 1162 | |
1118 | |||
1119 | if (spi_imx->bits_per_word <= 8) | ||
1120 | spi_imx->word_mask = mask << 24 | mask << 16 | ||
1121 | | mask << 8 | mask; | ||
1122 | else if (spi_imx->bits_per_word <= 16) | ||
1123 | spi_imx->word_mask = mask << 16 | mask; | ||
1124 | else | ||
1125 | spi_imx->word_mask = mask; | ||
1126 | } else { | 1163 | } else { |
1127 | if (spi_imx->bits_per_word <= 8) { | 1164 | if (spi_imx->bits_per_word <= 8) { |
1128 | spi_imx->rx = spi_imx_buf_rx_u8; | 1165 | spi_imx->rx = spi_imx_buf_rx_u8; |
@@ -1134,6 +1171,7 @@ static int spi_imx_setupxfer(struct spi_device *spi, | |||
1134 | spi_imx->rx = spi_imx_buf_rx_u32; | 1171 | spi_imx->rx = spi_imx_buf_rx_u32; |
1135 | spi_imx->tx = spi_imx_buf_tx_u32; | 1172 | spi_imx->tx = spi_imx_buf_tx_u32; |
1136 | } | 1173 | } |
1174 | spi_imx->dynamic_burst = 0; | ||
1137 | } | 1175 | } |
1138 | 1176 | ||
1139 | if (spi_imx_can_dma(spi_imx->bitbang.master, spi, t)) | 1177 | if (spi_imx_can_dma(spi_imx->bitbang.master, spi, t)) |
@@ -1317,6 +1355,7 @@ static int spi_imx_pio_transfer(struct spi_device *spi, | |||
1317 | spi_imx->rx_buf = transfer->rx_buf; | 1355 | spi_imx->rx_buf = transfer->rx_buf; |
1318 | spi_imx->count = transfer->len; | 1356 | spi_imx->count = transfer->len; |
1319 | spi_imx->txfifo = 0; | 1357 | spi_imx->txfifo = 0; |
1358 | spi_imx->remainder = 0; | ||
1320 | 1359 | ||
1321 | reinit_completion(&spi_imx->xfer_done); | 1360 | reinit_completion(&spi_imx->xfer_done); |
1322 | 1361 | ||
@@ -1354,6 +1393,7 @@ static int spi_imx_pio_transfer_slave(struct spi_device *spi, | |||
1354 | spi_imx->rx_buf = transfer->rx_buf; | 1393 | spi_imx->rx_buf = transfer->rx_buf; |
1355 | spi_imx->count = transfer->len; | 1394 | spi_imx->count = transfer->len; |
1356 | spi_imx->txfifo = 0; | 1395 | spi_imx->txfifo = 0; |
1396 | spi_imx->remainder = 0; | ||
1357 | 1397 | ||
1358 | reinit_completion(&spi_imx->xfer_done); | 1398 | reinit_completion(&spi_imx->xfer_done); |
1359 | spi_imx->slave_aborted = false; | 1399 | spi_imx->slave_aborted = false; |
diff --git a/drivers/spi/spi-lm70llp.c b/drivers/spi/spi-lm70llp.c index 61ee0f4269ae..4549efd792da 100644 --- a/drivers/spi/spi-lm70llp.c +++ b/drivers/spi/spi-lm70llp.c | |||
@@ -188,9 +188,10 @@ static void lm70_chipselect(struct spi_device *spi, int value) | |||
188 | /* | 188 | /* |
189 | * Our actual bitbanger routine. | 189 | * Our actual bitbanger routine. |
190 | */ | 190 | */ |
191 | static u32 lm70_txrx(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits) | 191 | static u32 lm70_txrx(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits, |
192 | unsigned flags) | ||
192 | { | 193 | { |
193 | return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits); | 194 | return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits); |
194 | } | 195 | } |
195 | 196 | ||
196 | static void spi_lm70llp_attach(struct parport *p) | 197 | static void spi_lm70llp_attach(struct parport *p) |
diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index 990770dfa5cf..e43842c7a31a 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c | |||
@@ -311,6 +311,24 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) | |||
311 | EXPORT_SYMBOL_GPL(spi_mem_exec_op); | 311 | EXPORT_SYMBOL_GPL(spi_mem_exec_op); |
312 | 312 | ||
313 | /** | 313 | /** |
314 | * spi_mem_get_name() - Return the SPI mem device name to be used by the | ||
315 | * upper layer if necessary | ||
316 | * @mem: the SPI memory | ||
317 | * | ||
318 | * This function allows SPI mem users to retrieve the SPI mem device name. | ||
319 | * It is useful if the upper layer needs to expose a custom name for | ||
320 | * compatibility reasons. | ||
321 | * | ||
322 | * Return: a string containing the name of the memory device to be used | ||
323 | * by the SPI mem user | ||
324 | */ | ||
325 | const char *spi_mem_get_name(struct spi_mem *mem) | ||
326 | { | ||
327 | return mem->name; | ||
328 | } | ||
329 | EXPORT_SYMBOL_GPL(spi_mem_get_name); | ||
330 | |||
331 | /** | ||
314 | * spi_mem_adjust_op_size() - Adjust the data size of a SPI mem operation to | 332 | * spi_mem_adjust_op_size() - Adjust the data size of a SPI mem operation to |
315 | * match controller limitations | 333 | * match controller limitations |
316 | * @mem: the SPI memory | 334 | * @mem: the SPI memory |
@@ -344,6 +362,7 @@ static inline struct spi_mem_driver *to_spi_mem_drv(struct device_driver *drv) | |||
344 | static int spi_mem_probe(struct spi_device *spi) | 362 | static int spi_mem_probe(struct spi_device *spi) |
345 | { | 363 | { |
346 | struct spi_mem_driver *memdrv = to_spi_mem_drv(spi->dev.driver); | 364 | struct spi_mem_driver *memdrv = to_spi_mem_drv(spi->dev.driver); |
365 | struct spi_controller *ctlr = spi->controller; | ||
347 | struct spi_mem *mem; | 366 | struct spi_mem *mem; |
348 | 367 | ||
349 | mem = devm_kzalloc(&spi->dev, sizeof(*mem), GFP_KERNEL); | 368 | mem = devm_kzalloc(&spi->dev, sizeof(*mem), GFP_KERNEL); |
@@ -351,6 +370,15 @@ static int spi_mem_probe(struct spi_device *spi) | |||
351 | return -ENOMEM; | 370 | return -ENOMEM; |
352 | 371 | ||
353 | mem->spi = spi; | 372 | mem->spi = spi; |
373 | |||
374 | if (ctlr->mem_ops && ctlr->mem_ops->get_name) | ||
375 | mem->name = ctlr->mem_ops->get_name(mem); | ||
376 | else | ||
377 | mem->name = dev_name(&spi->dev); | ||
378 | |||
379 | if (IS_ERR_OR_NULL(mem->name)) | ||
380 | return PTR_ERR(mem->name); | ||
381 | |||
354 | spi_set_drvdata(spi, mem); | 382 | spi_set_drvdata(spi, mem); |
355 | 383 | ||
356 | return memdrv->probe(mem); | 384 | return memdrv->probe(mem); |
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 6c628a54e946..508c61c669e7 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
@@ -398,11 +398,9 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi, | |||
398 | { | 398 | { |
399 | struct omap2_mcspi *mcspi; | 399 | struct omap2_mcspi *mcspi; |
400 | struct omap2_mcspi_dma *mcspi_dma; | 400 | struct omap2_mcspi_dma *mcspi_dma; |
401 | unsigned int count; | ||
402 | 401 | ||
403 | mcspi = spi_master_get_devdata(spi->master); | 402 | mcspi = spi_master_get_devdata(spi->master); |
404 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; | 403 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; |
405 | count = xfer->len; | ||
406 | 404 | ||
407 | if (mcspi_dma->dma_tx) { | 405 | if (mcspi_dma->dma_tx) { |
408 | struct dma_async_tx_descriptor *tx; | 406 | struct dma_async_tx_descriptor *tx; |
@@ -582,7 +580,6 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
582 | struct omap2_mcspi_cs *cs = spi->controller_state; | 580 | struct omap2_mcspi_cs *cs = spi->controller_state; |
583 | struct omap2_mcspi_dma *mcspi_dma; | 581 | struct omap2_mcspi_dma *mcspi_dma; |
584 | unsigned int count; | 582 | unsigned int count; |
585 | u32 l; | ||
586 | u8 *rx; | 583 | u8 *rx; |
587 | const u8 *tx; | 584 | const u8 *tx; |
588 | struct dma_slave_config cfg; | 585 | struct dma_slave_config cfg; |
@@ -595,8 +592,6 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
595 | 592 | ||
596 | mcspi = spi_master_get_devdata(spi->master); | 593 | mcspi = spi_master_get_devdata(spi->master); |
597 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; | 594 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; |
598 | l = mcspi_cached_chconf0(spi); | ||
599 | |||
600 | 595 | ||
601 | if (cs->word_len <= 8) { | 596 | if (cs->word_len <= 8) { |
602 | width = DMA_SLAVE_BUSWIDTH_1_BYTE; | 597 | width = DMA_SLAVE_BUSWIDTH_1_BYTE; |
@@ -676,7 +671,6 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
676 | static unsigned | 671 | static unsigned |
677 | omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) | 672 | omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) |
678 | { | 673 | { |
679 | struct omap2_mcspi *mcspi; | ||
680 | struct omap2_mcspi_cs *cs = spi->controller_state; | 674 | struct omap2_mcspi_cs *cs = spi->controller_state; |
681 | unsigned int count, c; | 675 | unsigned int count, c; |
682 | u32 l; | 676 | u32 l; |
@@ -686,7 +680,6 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) | |||
686 | void __iomem *chstat_reg; | 680 | void __iomem *chstat_reg; |
687 | int word_len; | 681 | int word_len; |
688 | 682 | ||
689 | mcspi = spi_master_get_devdata(spi->master); | ||
690 | count = xfer->len; | 683 | count = xfer->len; |
691 | c = count; | 684 | c = count; |
692 | word_len = cs->word_len; | 685 | word_len = cs->word_len; |
@@ -883,13 +876,11 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, | |||
883 | { | 876 | { |
884 | struct omap2_mcspi_cs *cs = spi->controller_state; | 877 | struct omap2_mcspi_cs *cs = spi->controller_state; |
885 | struct omap2_mcspi *mcspi; | 878 | struct omap2_mcspi *mcspi; |
886 | struct spi_master *spi_cntrl; | ||
887 | u32 l = 0, clkd = 0, div, extclk = 0, clkg = 0; | 879 | u32 l = 0, clkd = 0, div, extclk = 0, clkg = 0; |
888 | u8 word_len = spi->bits_per_word; | 880 | u8 word_len = spi->bits_per_word; |
889 | u32 speed_hz = spi->max_speed_hz; | 881 | u32 speed_hz = spi->max_speed_hz; |
890 | 882 | ||
891 | mcspi = spi_master_get_devdata(spi->master); | 883 | mcspi = spi_master_get_devdata(spi->master); |
892 | spi_cntrl = mcspi->master; | ||
893 | 884 | ||
894 | if (t != NULL && t->bits_per_word) | 885 | if (t != NULL && t->bits_per_word) |
895 | word_len = t->bits_per_word; | 886 | word_len = t->bits_per_word; |
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index d01a6adc726e..47ef6b1a2e76 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/of.h> | 20 | #include <linux/of.h> |
21 | #include <linux/of_address.h> | 21 | #include <linux/of_address.h> |
22 | #include <linux/of_device.h> | 22 | #include <linux/of_device.h> |
23 | #include <linux/of_gpio.h> | ||
23 | #include <linux/clk.h> | 24 | #include <linux/clk.h> |
24 | #include <linux/sizes.h> | 25 | #include <linux/sizes.h> |
25 | #include <linux/gpio.h> | 26 | #include <linux/gpio.h> |
@@ -681,9 +682,9 @@ static int orion_spi_probe(struct platform_device *pdev) | |||
681 | goto out_rel_axi_clk; | 682 | goto out_rel_axi_clk; |
682 | } | 683 | } |
683 | 684 | ||
684 | /* Scan all SPI devices of this controller for direct mapped devices */ | ||
685 | for_each_available_child_of_node(pdev->dev.of_node, np) { | 685 | for_each_available_child_of_node(pdev->dev.of_node, np) { |
686 | u32 cs; | 686 | u32 cs; |
687 | int cs_gpio; | ||
687 | 688 | ||
688 | /* Get chip-select number from the "reg" property */ | 689 | /* Get chip-select number from the "reg" property */ |
689 | status = of_property_read_u32(np, "reg", &cs); | 690 | status = of_property_read_u32(np, "reg", &cs); |
@@ -695,6 +696,44 @@ static int orion_spi_probe(struct platform_device *pdev) | |||
695 | } | 696 | } |
696 | 697 | ||
697 | /* | 698 | /* |
699 | * Initialize the CS GPIO: | ||
700 | * - properly request the actual GPIO signal | ||
701 | * - de-assert the logical signal so that all GPIO CS lines | ||
702 | * are inactive when probing for slaves | ||
703 | * - find an unused physical CS which will be driven for any | ||
704 | * slave which uses a CS GPIO | ||
705 | */ | ||
706 | cs_gpio = of_get_named_gpio(pdev->dev.of_node, "cs-gpios", cs); | ||
707 | if (cs_gpio > 0) { | ||
708 | char *gpio_name; | ||
709 | int cs_flags; | ||
710 | |||
711 | if (spi->unused_hw_gpio == -1) { | ||
712 | dev_info(&pdev->dev, | ||
713 | "Selected unused HW CS#%d for any GPIO CSes\n", | ||
714 | cs); | ||
715 | spi->unused_hw_gpio = cs; | ||
716 | } | ||
717 | |||
718 | gpio_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, | ||
719 | "%s-CS%d", dev_name(&pdev->dev), cs); | ||
720 | if (!gpio_name) { | ||
721 | status = -ENOMEM; | ||
722 | goto out_rel_axi_clk; | ||
723 | } | ||
724 | |||
725 | cs_flags = of_property_read_bool(np, "spi-cs-high") ? | ||
726 | GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH; | ||
727 | status = devm_gpio_request_one(&pdev->dev, cs_gpio, | ||
728 | cs_flags, gpio_name); | ||
729 | if (status) { | ||
730 | dev_err(&pdev->dev, | ||
731 | "Can't request GPIO for CS %d\n", cs); | ||
732 | goto out_rel_axi_clk; | ||
733 | } | ||
734 | } | ||
735 | |||
736 | /* | ||
698 | * Check if an address is configured for this SPI device. If | 737 | * Check if an address is configured for this SPI device. If |
699 | * not, the MBus mapping via the 'ranges' property in the 'soc' | 738 | * not, the MBus mapping via the 'ranges' property in the 'soc' |
700 | * node is not configured and this device should not use the | 739 | * node is not configured and this device should not use the |
@@ -740,44 +779,8 @@ static int orion_spi_probe(struct platform_device *pdev) | |||
740 | if (status < 0) | 779 | if (status < 0) |
741 | goto out_rel_pm; | 780 | goto out_rel_pm; |
742 | 781 | ||
743 | if (master->cs_gpios) { | ||
744 | int i; | ||
745 | for (i = 0; i < master->num_chipselect; ++i) { | ||
746 | char *gpio_name; | ||
747 | |||
748 | if (!gpio_is_valid(master->cs_gpios[i])) { | ||
749 | continue; | ||
750 | } | ||
751 | |||
752 | gpio_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, | ||
753 | "%s-CS%d", dev_name(&pdev->dev), i); | ||
754 | if (!gpio_name) { | ||
755 | status = -ENOMEM; | ||
756 | goto out_rel_master; | ||
757 | } | ||
758 | |||
759 | status = devm_gpio_request(&pdev->dev, | ||
760 | master->cs_gpios[i], gpio_name); | ||
761 | if (status) { | ||
762 | dev_err(&pdev->dev, | ||
763 | "Can't request GPIO for CS %d\n", | ||
764 | master->cs_gpios[i]); | ||
765 | goto out_rel_master; | ||
766 | } | ||
767 | if (spi->unused_hw_gpio == -1) { | ||
768 | dev_info(&pdev->dev, | ||
769 | "Selected unused HW CS#%d for any GPIO CSes\n", | ||
770 | i); | ||
771 | spi->unused_hw_gpio = i; | ||
772 | } | ||
773 | } | ||
774 | } | ||
775 | |||
776 | |||
777 | return status; | 782 | return status; |
778 | 783 | ||
779 | out_rel_master: | ||
780 | spi_unregister_master(master); | ||
781 | out_rel_pm: | 784 | out_rel_pm: |
782 | pm_runtime_disable(&pdev->dev); | 785 | pm_runtime_disable(&pdev->dev); |
783 | out_rel_axi_clk: | 786 | out_rel_axi_clk: |
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 0b2d60d30f69..14f4ea59caff 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c | |||
@@ -1391,6 +1391,10 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = { | |||
1391 | { PCI_VDEVICE(INTEL, 0x31c2), LPSS_BXT_SSP }, | 1391 | { PCI_VDEVICE(INTEL, 0x31c2), LPSS_BXT_SSP }, |
1392 | { PCI_VDEVICE(INTEL, 0x31c4), LPSS_BXT_SSP }, | 1392 | { PCI_VDEVICE(INTEL, 0x31c4), LPSS_BXT_SSP }, |
1393 | { PCI_VDEVICE(INTEL, 0x31c6), LPSS_BXT_SSP }, | 1393 | { PCI_VDEVICE(INTEL, 0x31c6), LPSS_BXT_SSP }, |
1394 | /* ICL-LP */ | ||
1395 | { PCI_VDEVICE(INTEL, 0x34aa), LPSS_CNL_SSP }, | ||
1396 | { PCI_VDEVICE(INTEL, 0x34ab), LPSS_CNL_SSP }, | ||
1397 | { PCI_VDEVICE(INTEL, 0x34fb), LPSS_CNL_SSP }, | ||
1394 | /* APL */ | 1398 | /* APL */ |
1395 | { PCI_VDEVICE(INTEL, 0x5ac2), LPSS_BXT_SSP }, | 1399 | { PCI_VDEVICE(INTEL, 0x5ac2), LPSS_BXT_SSP }, |
1396 | { PCI_VDEVICE(INTEL, 0x5ac4), LPSS_BXT_SSP }, | 1400 | { PCI_VDEVICE(INTEL, 0x5ac4), LPSS_BXT_SSP }, |
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 0e74cbf9929d..539d6d1a277a 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c | |||
@@ -49,6 +49,7 @@ struct sh_msiof_spi_priv { | |||
49 | struct platform_device *pdev; | 49 | struct platform_device *pdev; |
50 | struct sh_msiof_spi_info *info; | 50 | struct sh_msiof_spi_info *info; |
51 | struct completion done; | 51 | struct completion done; |
52 | struct completion done_txdma; | ||
52 | unsigned int tx_fifo_size; | 53 | unsigned int tx_fifo_size; |
53 | unsigned int rx_fifo_size; | 54 | unsigned int rx_fifo_size; |
54 | unsigned int min_div_pow; | 55 | unsigned int min_div_pow; |
@@ -649,19 +650,21 @@ static int sh_msiof_slave_abort(struct spi_master *master) | |||
649 | 650 | ||
650 | p->slave_aborted = true; | 651 | p->slave_aborted = true; |
651 | complete(&p->done); | 652 | complete(&p->done); |
653 | complete(&p->done_txdma); | ||
652 | return 0; | 654 | return 0; |
653 | } | 655 | } |
654 | 656 | ||
655 | static int sh_msiof_wait_for_completion(struct sh_msiof_spi_priv *p) | 657 | static int sh_msiof_wait_for_completion(struct sh_msiof_spi_priv *p, |
658 | struct completion *x) | ||
656 | { | 659 | { |
657 | if (spi_controller_is_slave(p->master)) { | 660 | if (spi_controller_is_slave(p->master)) { |
658 | if (wait_for_completion_interruptible(&p->done) || | 661 | if (wait_for_completion_interruptible(x) || |
659 | p->slave_aborted) { | 662 | p->slave_aborted) { |
660 | dev_dbg(&p->pdev->dev, "interrupted\n"); | 663 | dev_dbg(&p->pdev->dev, "interrupted\n"); |
661 | return -EINTR; | 664 | return -EINTR; |
662 | } | 665 | } |
663 | } else { | 666 | } else { |
664 | if (!wait_for_completion_timeout(&p->done, HZ)) { | 667 | if (!wait_for_completion_timeout(x, HZ)) { |
665 | dev_err(&p->pdev->dev, "timeout\n"); | 668 | dev_err(&p->pdev->dev, "timeout\n"); |
666 | return -ETIMEDOUT; | 669 | return -ETIMEDOUT; |
667 | } | 670 | } |
@@ -711,7 +714,7 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p, | |||
711 | } | 714 | } |
712 | 715 | ||
713 | /* wait for tx fifo to be emptied / rx fifo to be filled */ | 716 | /* wait for tx fifo to be emptied / rx fifo to be filled */ |
714 | ret = sh_msiof_wait_for_completion(p); | 717 | ret = sh_msiof_wait_for_completion(p, &p->done); |
715 | if (ret) | 718 | if (ret) |
716 | goto stop_reset; | 719 | goto stop_reset; |
717 | 720 | ||
@@ -740,10 +743,7 @@ stop_ier: | |||
740 | 743 | ||
741 | static void sh_msiof_dma_complete(void *arg) | 744 | static void sh_msiof_dma_complete(void *arg) |
742 | { | 745 | { |
743 | struct sh_msiof_spi_priv *p = arg; | 746 | complete(arg); |
744 | |||
745 | sh_msiof_write(p, IER, 0); | ||
746 | complete(&p->done); | ||
747 | } | 747 | } |
748 | 748 | ||
749 | static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, | 749 | static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, |
@@ -764,7 +764,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, | |||
764 | return -EAGAIN; | 764 | return -EAGAIN; |
765 | 765 | ||
766 | desc_rx->callback = sh_msiof_dma_complete; | 766 | desc_rx->callback = sh_msiof_dma_complete; |
767 | desc_rx->callback_param = p; | 767 | desc_rx->callback_param = &p->done; |
768 | cookie = dmaengine_submit(desc_rx); | 768 | cookie = dmaengine_submit(desc_rx); |
769 | if (dma_submit_error(cookie)) | 769 | if (dma_submit_error(cookie)) |
770 | return cookie; | 770 | return cookie; |
@@ -782,13 +782,8 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, | |||
782 | goto no_dma_tx; | 782 | goto no_dma_tx; |
783 | } | 783 | } |
784 | 784 | ||
785 | if (rx) { | 785 | desc_tx->callback = sh_msiof_dma_complete; |
786 | /* No callback */ | 786 | desc_tx->callback_param = &p->done_txdma; |
787 | desc_tx->callback = NULL; | ||
788 | } else { | ||
789 | desc_tx->callback = sh_msiof_dma_complete; | ||
790 | desc_tx->callback_param = p; | ||
791 | } | ||
792 | cookie = dmaengine_submit(desc_tx); | 787 | cookie = dmaengine_submit(desc_tx); |
793 | if (dma_submit_error(cookie)) { | 788 | if (dma_submit_error(cookie)) { |
794 | ret = cookie; | 789 | ret = cookie; |
@@ -805,6 +800,8 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, | |||
805 | sh_msiof_write(p, IER, ier_bits); | 800 | sh_msiof_write(p, IER, ier_bits); |
806 | 801 | ||
807 | reinit_completion(&p->done); | 802 | reinit_completion(&p->done); |
803 | if (tx) | ||
804 | reinit_completion(&p->done_txdma); | ||
808 | p->slave_aborted = false; | 805 | p->slave_aborted = false; |
809 | 806 | ||
810 | /* Now start DMA */ | 807 | /* Now start DMA */ |
@@ -819,17 +816,24 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, | |||
819 | goto stop_dma; | 816 | goto stop_dma; |
820 | } | 817 | } |
821 | 818 | ||
822 | /* wait for tx/rx DMA completion */ | 819 | if (tx) { |
823 | ret = sh_msiof_wait_for_completion(p); | 820 | /* wait for tx DMA completion */ |
824 | if (ret) | 821 | ret = sh_msiof_wait_for_completion(p, &p->done_txdma); |
825 | goto stop_reset; | 822 | if (ret) |
823 | goto stop_reset; | ||
824 | } | ||
826 | 825 | ||
827 | if (!rx) { | 826 | if (rx) { |
828 | reinit_completion(&p->done); | 827 | /* wait for rx DMA completion */ |
829 | sh_msiof_write(p, IER, IER_TEOFE); | 828 | ret = sh_msiof_wait_for_completion(p, &p->done); |
829 | if (ret) | ||
830 | goto stop_reset; | ||
830 | 831 | ||
832 | sh_msiof_write(p, IER, 0); | ||
833 | } else { | ||
831 | /* wait for tx fifo to be emptied */ | 834 | /* wait for tx fifo to be emptied */ |
832 | ret = sh_msiof_wait_for_completion(p); | 835 | sh_msiof_write(p, IER, IER_TEOFE); |
836 | ret = sh_msiof_wait_for_completion(p, &p->done); | ||
833 | if (ret) | 837 | if (ret) |
834 | goto stop_reset; | 838 | goto stop_reset; |
835 | } | 839 | } |
@@ -1327,6 +1331,7 @@ static int sh_msiof_spi_probe(struct platform_device *pdev) | |||
1327 | p->min_div_pow = chipdata->min_div_pow; | 1331 | p->min_div_pow = chipdata->min_div_pow; |
1328 | 1332 | ||
1329 | init_completion(&p->done); | 1333 | init_completion(&p->done); |
1334 | init_completion(&p->done_txdma); | ||
1330 | 1335 | ||
1331 | p->clk = devm_clk_get(&pdev->dev, NULL); | 1336 | p->clk = devm_clk_get(&pdev->dev, NULL); |
1332 | if (IS_ERR(p->clk)) { | 1337 | if (IS_ERR(p->clk)) { |
diff --git a/drivers/spi/spi-sh-sci.c b/drivers/spi/spi-sh-sci.c index a9beeeed812c..393701cfca3c 100644 --- a/drivers/spi/spi-sh-sci.c +++ b/drivers/spi/spi-sh-sci.c | |||
@@ -80,27 +80,31 @@ static inline u32 getmiso(struct spi_device *dev) | |||
80 | #include "spi-bitbang-txrx.h" | 80 | #include "spi-bitbang-txrx.h" |
81 | 81 | ||
82 | static u32 sh_sci_spi_txrx_mode0(struct spi_device *spi, | 82 | static u32 sh_sci_spi_txrx_mode0(struct spi_device *spi, |
83 | unsigned nsecs, u32 word, u8 bits) | 83 | unsigned nsecs, u32 word, u8 bits, |
84 | unsigned flags) | ||
84 | { | 85 | { |
85 | return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits); | 86 | return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits); |
86 | } | 87 | } |
87 | 88 | ||
88 | static u32 sh_sci_spi_txrx_mode1(struct spi_device *spi, | 89 | static u32 sh_sci_spi_txrx_mode1(struct spi_device *spi, |
89 | unsigned nsecs, u32 word, u8 bits) | 90 | unsigned nsecs, u32 word, u8 bits, |
91 | unsigned flags) | ||
90 | { | 92 | { |
91 | return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits); | 93 | return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits); |
92 | } | 94 | } |
93 | 95 | ||
94 | static u32 sh_sci_spi_txrx_mode2(struct spi_device *spi, | 96 | static u32 sh_sci_spi_txrx_mode2(struct spi_device *spi, |
95 | unsigned nsecs, u32 word, u8 bits) | 97 | unsigned nsecs, u32 word, u8 bits, |
98 | unsigned flags) | ||
96 | { | 99 | { |
97 | return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits); | 100 | return bitbang_txrx_be_cpha0(spi, nsecs, 1, flags, word, bits); |
98 | } | 101 | } |
99 | 102 | ||
100 | static u32 sh_sci_spi_txrx_mode3(struct spi_device *spi, | 103 | static u32 sh_sci_spi_txrx_mode3(struct spi_device *spi, |
101 | unsigned nsecs, u32 word, u8 bits) | 104 | unsigned nsecs, u32 word, u8 bits, |
105 | unsigned flags) | ||
102 | { | 106 | { |
103 | return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits); | 107 | return bitbang_txrx_be_cpha1(spi, nsecs, 1, flags, word, bits); |
104 | } | 108 | } |
105 | 109 | ||
106 | static void sh_sci_spi_chipselect(struct spi_device *dev, int value) | 110 | static void sh_sci_spi_chipselect(struct spi_device *dev, int value) |
diff --git a/drivers/spi/spi-uniphier.c b/drivers/spi/spi-uniphier.c new file mode 100644 index 000000000000..5a6137fe172d --- /dev/null +++ b/drivers/spi/spi-uniphier.c | |||
@@ -0,0 +1,523 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | // spi-uniphier.c - Socionext UniPhier SPI controller driver | ||
3 | // Copyright 2012 Panasonic Corporation | ||
4 | // Copyright 2016-2018 Socionext Inc. | ||
5 | |||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/bitfield.h> | ||
8 | #include <linux/bitops.h> | ||
9 | #include <linux/clk.h> | ||
10 | #include <linux/interrupt.h> | ||
11 | #include <linux/io.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/spi/spi.h> | ||
15 | |||
16 | #include <asm/unaligned.h> | ||
17 | |||
18 | #define SSI_TIMEOUT_MS 2000 | ||
19 | #define SSI_MAX_CLK_DIVIDER 254 | ||
20 | #define SSI_MIN_CLK_DIVIDER 4 | ||
21 | |||
22 | struct uniphier_spi_priv { | ||
23 | void __iomem *base; | ||
24 | struct clk *clk; | ||
25 | struct spi_master *master; | ||
26 | struct completion xfer_done; | ||
27 | |||
28 | int error; | ||
29 | unsigned int tx_bytes; | ||
30 | unsigned int rx_bytes; | ||
31 | const u8 *tx_buf; | ||
32 | u8 *rx_buf; | ||
33 | |||
34 | bool is_save_param; | ||
35 | u8 bits_per_word; | ||
36 | u16 mode; | ||
37 | u32 speed_hz; | ||
38 | }; | ||
39 | |||
40 | #define SSI_CTL 0x00 | ||
41 | #define SSI_CTL_EN BIT(0) | ||
42 | |||
43 | #define SSI_CKS 0x04 | ||
44 | #define SSI_CKS_CKRAT_MASK GENMASK(7, 0) | ||
45 | #define SSI_CKS_CKPHS BIT(14) | ||
46 | #define SSI_CKS_CKINIT BIT(13) | ||
47 | #define SSI_CKS_CKDLY BIT(12) | ||
48 | |||
49 | #define SSI_TXWDS 0x08 | ||
50 | #define SSI_TXWDS_WDLEN_MASK GENMASK(13, 8) | ||
51 | #define SSI_TXWDS_TDTF_MASK GENMASK(7, 6) | ||
52 | #define SSI_TXWDS_DTLEN_MASK GENMASK(5, 0) | ||
53 | |||
54 | #define SSI_RXWDS 0x0c | ||
55 | #define SSI_RXWDS_DTLEN_MASK GENMASK(5, 0) | ||
56 | |||
57 | #define SSI_FPS 0x10 | ||
58 | #define SSI_FPS_FSPOL BIT(15) | ||
59 | #define SSI_FPS_FSTRT BIT(14) | ||
60 | |||
61 | #define SSI_SR 0x14 | ||
62 | #define SSI_SR_RNE BIT(0) | ||
63 | |||
64 | #define SSI_IE 0x18 | ||
65 | #define SSI_IE_RCIE BIT(3) | ||
66 | #define SSI_IE_RORIE BIT(0) | ||
67 | |||
68 | #define SSI_IS 0x1c | ||
69 | #define SSI_IS_RXRS BIT(9) | ||
70 | #define SSI_IS_RCID BIT(3) | ||
71 | #define SSI_IS_RORID BIT(0) | ||
72 | |||
73 | #define SSI_IC 0x1c | ||
74 | #define SSI_IC_TCIC BIT(4) | ||
75 | #define SSI_IC_RCIC BIT(3) | ||
76 | #define SSI_IC_RORIC BIT(0) | ||
77 | |||
78 | #define SSI_FC 0x20 | ||
79 | #define SSI_FC_TXFFL BIT(12) | ||
80 | #define SSI_FC_TXFTH_MASK GENMASK(11, 8) | ||
81 | #define SSI_FC_RXFFL BIT(4) | ||
82 | #define SSI_FC_RXFTH_MASK GENMASK(3, 0) | ||
83 | |||
84 | #define SSI_TXDR 0x24 | ||
85 | #define SSI_RXDR 0x24 | ||
86 | |||
87 | #define SSI_FIFO_DEPTH 8U | ||
88 | |||
89 | static inline unsigned int bytes_per_word(unsigned int bits) | ||
90 | { | ||
91 | return bits <= 8 ? 1 : (bits <= 16 ? 2 : 4); | ||
92 | } | ||
93 | |||
94 | static inline void uniphier_spi_irq_enable(struct spi_device *spi, u32 mask) | ||
95 | { | ||
96 | struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master); | ||
97 | u32 val; | ||
98 | |||
99 | val = readl(priv->base + SSI_IE); | ||
100 | val |= mask; | ||
101 | writel(val, priv->base + SSI_IE); | ||
102 | } | ||
103 | |||
104 | static inline void uniphier_spi_irq_disable(struct spi_device *spi, u32 mask) | ||
105 | { | ||
106 | struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master); | ||
107 | u32 val; | ||
108 | |||
109 | val = readl(priv->base + SSI_IE); | ||
110 | val &= ~mask; | ||
111 | writel(val, priv->base + SSI_IE); | ||
112 | } | ||
113 | |||
114 | static void uniphier_spi_set_mode(struct spi_device *spi) | ||
115 | { | ||
116 | struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master); | ||
117 | u32 val1, val2; | ||
118 | |||
119 | /* | ||
120 | * clock setting | ||
121 | * CKPHS capture timing. 0:rising edge, 1:falling edge | ||
122 | * CKINIT clock initial level. 0:low, 1:high | ||
123 | * CKDLY clock delay. 0:no delay, 1:delay depending on FSTRT | ||
124 | * (FSTRT=0: 1 clock, FSTRT=1: 0.5 clock) | ||
125 | * | ||
126 | * frame setting | ||
127 | * FSPOL frame signal porarity. 0: low, 1: high | ||
128 | * FSTRT start frame timing | ||
129 | * 0: rising edge of clock, 1: falling edge of clock | ||
130 | */ | ||
131 | switch (spi->mode & (SPI_CPOL | SPI_CPHA)) { | ||
132 | case SPI_MODE_0: | ||
133 | /* CKPHS=1, CKINIT=0, CKDLY=1, FSTRT=0 */ | ||
134 | val1 = SSI_CKS_CKPHS | SSI_CKS_CKDLY; | ||
135 | val2 = 0; | ||
136 | break; | ||
137 | case SPI_MODE_1: | ||
138 | /* CKPHS=0, CKINIT=0, CKDLY=0, FSTRT=1 */ | ||
139 | val1 = 0; | ||
140 | val2 = SSI_FPS_FSTRT; | ||
141 | break; | ||
142 | case SPI_MODE_2: | ||
143 | /* CKPHS=0, CKINIT=1, CKDLY=1, FSTRT=1 */ | ||
144 | val1 = SSI_CKS_CKINIT | SSI_CKS_CKDLY; | ||
145 | val2 = SSI_FPS_FSTRT; | ||
146 | break; | ||
147 | case SPI_MODE_3: | ||
148 | /* CKPHS=1, CKINIT=1, CKDLY=0, FSTRT=0 */ | ||
149 | val1 = SSI_CKS_CKPHS | SSI_CKS_CKINIT; | ||
150 | val2 = 0; | ||
151 | break; | ||
152 | } | ||
153 | |||
154 | if (!(spi->mode & SPI_CS_HIGH)) | ||
155 | val2 |= SSI_FPS_FSPOL; | ||
156 | |||
157 | writel(val1, priv->base + SSI_CKS); | ||
158 | writel(val2, priv->base + SSI_FPS); | ||
159 | |||
160 | val1 = 0; | ||
161 | if (spi->mode & SPI_LSB_FIRST) | ||
162 | val1 |= FIELD_PREP(SSI_TXWDS_TDTF_MASK, 1); | ||
163 | writel(val1, priv->base + SSI_TXWDS); | ||
164 | writel(val1, priv->base + SSI_RXWDS); | ||
165 | } | ||
166 | |||
167 | static void uniphier_spi_set_transfer_size(struct spi_device *spi, int size) | ||
168 | { | ||
169 | struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master); | ||
170 | u32 val; | ||
171 | |||
172 | val = readl(priv->base + SSI_TXWDS); | ||
173 | val &= ~(SSI_TXWDS_WDLEN_MASK | SSI_TXWDS_DTLEN_MASK); | ||
174 | val |= FIELD_PREP(SSI_TXWDS_WDLEN_MASK, size); | ||
175 | val |= FIELD_PREP(SSI_TXWDS_DTLEN_MASK, size); | ||
176 | writel(val, priv->base + SSI_TXWDS); | ||
177 | |||
178 | val = readl(priv->base + SSI_RXWDS); | ||
179 | val &= ~SSI_RXWDS_DTLEN_MASK; | ||
180 | val |= FIELD_PREP(SSI_RXWDS_DTLEN_MASK, size); | ||
181 | writel(val, priv->base + SSI_RXWDS); | ||
182 | } | ||
183 | |||
184 | static void uniphier_spi_set_baudrate(struct spi_device *spi, | ||
185 | unsigned int speed) | ||
186 | { | ||
187 | struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master); | ||
188 | u32 val, ckdiv; | ||
189 | |||
190 | /* | ||
191 | * the supported rates are even numbers from 4 to 254. (4,6,8...254) | ||
192 | * round up as we look for equal or less speed | ||
193 | */ | ||
194 | ckdiv = DIV_ROUND_UP(clk_get_rate(priv->clk), speed); | ||
195 | ckdiv = round_up(ckdiv, 2); | ||
196 | |||
197 | val = readl(priv->base + SSI_CKS); | ||
198 | val &= ~SSI_CKS_CKRAT_MASK; | ||
199 | val |= ckdiv & SSI_CKS_CKRAT_MASK; | ||
200 | writel(val, priv->base + SSI_CKS); | ||
201 | } | ||
202 | |||
203 | static void uniphier_spi_setup_transfer(struct spi_device *spi, | ||
204 | struct spi_transfer *t) | ||
205 | { | ||
206 | struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master); | ||
207 | u32 val; | ||
208 | |||
209 | priv->error = 0; | ||
210 | priv->tx_buf = t->tx_buf; | ||
211 | priv->rx_buf = t->rx_buf; | ||
212 | priv->tx_bytes = priv->rx_bytes = t->len; | ||
213 | |||
214 | if (!priv->is_save_param || priv->mode != spi->mode) { | ||
215 | uniphier_spi_set_mode(spi); | ||
216 | priv->mode = spi->mode; | ||
217 | } | ||
218 | |||
219 | if (!priv->is_save_param || priv->bits_per_word != t->bits_per_word) { | ||
220 | uniphier_spi_set_transfer_size(spi, t->bits_per_word); | ||
221 | priv->bits_per_word = t->bits_per_word; | ||
222 | } | ||
223 | |||
224 | if (!priv->is_save_param || priv->speed_hz != t->speed_hz) { | ||
225 | uniphier_spi_set_baudrate(spi, t->speed_hz); | ||
226 | priv->speed_hz = t->speed_hz; | ||
227 | } | ||
228 | |||
229 | if (!priv->is_save_param) | ||
230 | priv->is_save_param = true; | ||
231 | |||
232 | /* reset FIFOs */ | ||
233 | val = SSI_FC_TXFFL | SSI_FC_RXFFL; | ||
234 | writel(val, priv->base + SSI_FC); | ||
235 | } | ||
236 | |||
237 | static void uniphier_spi_send(struct uniphier_spi_priv *priv) | ||
238 | { | ||
239 | int wsize; | ||
240 | u32 val = 0; | ||
241 | |||
242 | wsize = min(bytes_per_word(priv->bits_per_word), priv->tx_bytes); | ||
243 | priv->tx_bytes -= wsize; | ||
244 | |||
245 | if (priv->tx_buf) { | ||
246 | switch (wsize) { | ||
247 | case 1: | ||
248 | val = *priv->tx_buf; | ||
249 | break; | ||
250 | case 2: | ||
251 | val = get_unaligned_le16(priv->tx_buf); | ||
252 | break; | ||
253 | case 4: | ||
254 | val = get_unaligned_le32(priv->tx_buf); | ||
255 | break; | ||
256 | } | ||
257 | |||
258 | priv->tx_buf += wsize; | ||
259 | } | ||
260 | |||
261 | writel(val, priv->base + SSI_TXDR); | ||
262 | } | ||
263 | |||
264 | static void uniphier_spi_recv(struct uniphier_spi_priv *priv) | ||
265 | { | ||
266 | int rsize; | ||
267 | u32 val; | ||
268 | |||
269 | rsize = min(bytes_per_word(priv->bits_per_word), priv->rx_bytes); | ||
270 | priv->rx_bytes -= rsize; | ||
271 | |||
272 | val = readl(priv->base + SSI_RXDR); | ||
273 | |||
274 | if (priv->rx_buf) { | ||
275 | switch (rsize) { | ||
276 | case 1: | ||
277 | *priv->rx_buf = val; | ||
278 | break; | ||
279 | case 2: | ||
280 | put_unaligned_le16(val, priv->rx_buf); | ||
281 | break; | ||
282 | case 4: | ||
283 | put_unaligned_le32(val, priv->rx_buf); | ||
284 | break; | ||
285 | } | ||
286 | |||
287 | priv->rx_buf += rsize; | ||
288 | } | ||
289 | } | ||
290 | |||
291 | static void uniphier_spi_fill_tx_fifo(struct uniphier_spi_priv *priv) | ||
292 | { | ||
293 | unsigned int tx_count; | ||
294 | u32 val; | ||
295 | |||
296 | tx_count = DIV_ROUND_UP(priv->tx_bytes, | ||
297 | bytes_per_word(priv->bits_per_word)); | ||
298 | tx_count = min(tx_count, SSI_FIFO_DEPTH); | ||
299 | |||
300 | /* set fifo threshold */ | ||
301 | val = readl(priv->base + SSI_FC); | ||
302 | val &= ~(SSI_FC_TXFTH_MASK | SSI_FC_RXFTH_MASK); | ||
303 | val |= FIELD_PREP(SSI_FC_TXFTH_MASK, tx_count); | ||
304 | val |= FIELD_PREP(SSI_FC_RXFTH_MASK, tx_count); | ||
305 | writel(val, priv->base + SSI_FC); | ||
306 | |||
307 | while (tx_count--) | ||
308 | uniphier_spi_send(priv); | ||
309 | } | ||
310 | |||
311 | static void uniphier_spi_set_cs(struct spi_device *spi, bool enable) | ||
312 | { | ||
313 | struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master); | ||
314 | u32 val; | ||
315 | |||
316 | val = readl(priv->base + SSI_FPS); | ||
317 | |||
318 | if (enable) | ||
319 | val |= SSI_FPS_FSPOL; | ||
320 | else | ||
321 | val &= ~SSI_FPS_FSPOL; | ||
322 | |||
323 | writel(val, priv->base + SSI_FPS); | ||
324 | } | ||
325 | |||
326 | static int uniphier_spi_transfer_one(struct spi_master *master, | ||
327 | struct spi_device *spi, | ||
328 | struct spi_transfer *t) | ||
329 | { | ||
330 | struct uniphier_spi_priv *priv = spi_master_get_devdata(master); | ||
331 | int status; | ||
332 | |||
333 | uniphier_spi_setup_transfer(spi, t); | ||
334 | |||
335 | reinit_completion(&priv->xfer_done); | ||
336 | |||
337 | uniphier_spi_fill_tx_fifo(priv); | ||
338 | |||
339 | uniphier_spi_irq_enable(spi, SSI_IE_RCIE | SSI_IE_RORIE); | ||
340 | |||
341 | status = wait_for_completion_timeout(&priv->xfer_done, | ||
342 | msecs_to_jiffies(SSI_TIMEOUT_MS)); | ||
343 | |||
344 | uniphier_spi_irq_disable(spi, SSI_IE_RCIE | SSI_IE_RORIE); | ||
345 | |||
346 | if (status < 0) | ||
347 | return status; | ||
348 | |||
349 | return priv->error; | ||
350 | } | ||
351 | |||
352 | static int uniphier_spi_prepare_transfer_hardware(struct spi_master *master) | ||
353 | { | ||
354 | struct uniphier_spi_priv *priv = spi_master_get_devdata(master); | ||
355 | |||
356 | writel(SSI_CTL_EN, priv->base + SSI_CTL); | ||
357 | |||
358 | return 0; | ||
359 | } | ||
360 | |||
361 | static int uniphier_spi_unprepare_transfer_hardware(struct spi_master *master) | ||
362 | { | ||
363 | struct uniphier_spi_priv *priv = spi_master_get_devdata(master); | ||
364 | |||
365 | writel(0, priv->base + SSI_CTL); | ||
366 | |||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | static irqreturn_t uniphier_spi_handler(int irq, void *dev_id) | ||
371 | { | ||
372 | struct uniphier_spi_priv *priv = dev_id; | ||
373 | u32 val, stat; | ||
374 | |||
375 | stat = readl(priv->base + SSI_IS); | ||
376 | val = SSI_IC_TCIC | SSI_IC_RCIC | SSI_IC_RORIC; | ||
377 | writel(val, priv->base + SSI_IC); | ||
378 | |||
379 | /* rx fifo overrun */ | ||
380 | if (stat & SSI_IS_RORID) { | ||
381 | priv->error = -EIO; | ||
382 | goto done; | ||
383 | } | ||
384 | |||
385 | /* rx complete */ | ||
386 | if ((stat & SSI_IS_RCID) && (stat & SSI_IS_RXRS)) { | ||
387 | while ((readl(priv->base + SSI_SR) & SSI_SR_RNE) && | ||
388 | (priv->rx_bytes - priv->tx_bytes) > 0) | ||
389 | uniphier_spi_recv(priv); | ||
390 | |||
391 | if ((readl(priv->base + SSI_SR) & SSI_SR_RNE) || | ||
392 | (priv->rx_bytes != priv->tx_bytes)) { | ||
393 | priv->error = -EIO; | ||
394 | goto done; | ||
395 | } else if (priv->rx_bytes == 0) | ||
396 | goto done; | ||
397 | |||
398 | /* next tx transfer */ | ||
399 | uniphier_spi_fill_tx_fifo(priv); | ||
400 | |||
401 | return IRQ_HANDLED; | ||
402 | } | ||
403 | |||
404 | return IRQ_NONE; | ||
405 | |||
406 | done: | ||
407 | complete(&priv->xfer_done); | ||
408 | return IRQ_HANDLED; | ||
409 | } | ||
410 | |||
411 | static int uniphier_spi_probe(struct platform_device *pdev) | ||
412 | { | ||
413 | struct uniphier_spi_priv *priv; | ||
414 | struct spi_master *master; | ||
415 | struct resource *res; | ||
416 | unsigned long clk_rate; | ||
417 | int irq; | ||
418 | int ret; | ||
419 | |||
420 | master = spi_alloc_master(&pdev->dev, sizeof(*priv)); | ||
421 | if (!master) | ||
422 | return -ENOMEM; | ||
423 | |||
424 | platform_set_drvdata(pdev, master); | ||
425 | |||
426 | priv = spi_master_get_devdata(master); | ||
427 | priv->master = master; | ||
428 | priv->is_save_param = false; | ||
429 | |||
430 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
431 | priv->base = devm_ioremap_resource(&pdev->dev, res); | ||
432 | if (IS_ERR(priv->base)) { | ||
433 | ret = PTR_ERR(priv->base); | ||
434 | goto out_master_put; | ||
435 | } | ||
436 | |||
437 | priv->clk = devm_clk_get(&pdev->dev, NULL); | ||
438 | if (IS_ERR(priv->clk)) { | ||
439 | dev_err(&pdev->dev, "failed to get clock\n"); | ||
440 | ret = PTR_ERR(priv->clk); | ||
441 | goto out_master_put; | ||
442 | } | ||
443 | |||
444 | ret = clk_prepare_enable(priv->clk); | ||
445 | if (ret) | ||
446 | goto out_master_put; | ||
447 | |||
448 | irq = platform_get_irq(pdev, 0); | ||
449 | if (irq < 0) { | ||
450 | dev_err(&pdev->dev, "failed to get IRQ\n"); | ||
451 | ret = irq; | ||
452 | goto out_disable_clk; | ||
453 | } | ||
454 | |||
455 | ret = devm_request_irq(&pdev->dev, irq, uniphier_spi_handler, | ||
456 | 0, "uniphier-spi", priv); | ||
457 | if (ret) { | ||
458 | dev_err(&pdev->dev, "failed to request IRQ\n"); | ||
459 | goto out_disable_clk; | ||
460 | } | ||
461 | |||
462 | init_completion(&priv->xfer_done); | ||
463 | |||
464 | clk_rate = clk_get_rate(priv->clk); | ||
465 | |||
466 | master->max_speed_hz = DIV_ROUND_UP(clk_rate, SSI_MIN_CLK_DIVIDER); | ||
467 | master->min_speed_hz = DIV_ROUND_UP(clk_rate, SSI_MAX_CLK_DIVIDER); | ||
468 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST; | ||
469 | master->dev.of_node = pdev->dev.of_node; | ||
470 | master->bus_num = pdev->id; | ||
471 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); | ||
472 | |||
473 | master->set_cs = uniphier_spi_set_cs; | ||
474 | master->transfer_one = uniphier_spi_transfer_one; | ||
475 | master->prepare_transfer_hardware | ||
476 | = uniphier_spi_prepare_transfer_hardware; | ||
477 | master->unprepare_transfer_hardware | ||
478 | = uniphier_spi_unprepare_transfer_hardware; | ||
479 | master->num_chipselect = 1; | ||
480 | |||
481 | ret = devm_spi_register_master(&pdev->dev, master); | ||
482 | if (ret) | ||
483 | goto out_disable_clk; | ||
484 | |||
485 | return 0; | ||
486 | |||
487 | out_disable_clk: | ||
488 | clk_disable_unprepare(priv->clk); | ||
489 | |||
490 | out_master_put: | ||
491 | spi_master_put(master); | ||
492 | return ret; | ||
493 | } | ||
494 | |||
495 | static int uniphier_spi_remove(struct platform_device *pdev) | ||
496 | { | ||
497 | struct uniphier_spi_priv *priv = platform_get_drvdata(pdev); | ||
498 | |||
499 | clk_disable_unprepare(priv->clk); | ||
500 | |||
501 | return 0; | ||
502 | } | ||
503 | |||
504 | static const struct of_device_id uniphier_spi_match[] = { | ||
505 | { .compatible = "socionext,uniphier-scssi" }, | ||
506 | { /* sentinel */ } | ||
507 | }; | ||
508 | MODULE_DEVICE_TABLE(of, uniphier_spi_match); | ||
509 | |||
510 | static struct platform_driver uniphier_spi_driver = { | ||
511 | .probe = uniphier_spi_probe, | ||
512 | .remove = uniphier_spi_remove, | ||
513 | .driver = { | ||
514 | .name = "uniphier-spi", | ||
515 | .of_match_table = uniphier_spi_match, | ||
516 | }, | ||
517 | }; | ||
518 | module_platform_driver(uniphier_spi_driver); | ||
519 | |||
520 | MODULE_AUTHOR("Kunihiko Hayashi <hayashi.kunihiko@socionext.com>"); | ||
521 | MODULE_AUTHOR("Keiji Hayashibara <hayashibara.keiji@socionext.com>"); | ||
522 | MODULE_DESCRIPTION("Socionext UniPhier SPI controller driver"); | ||
523 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/spi/spi-xtensa-xtfpga.c b/drivers/spi/spi-xtensa-xtfpga.c index be6155cba9de..8ce04f829a80 100644 --- a/drivers/spi/spi-xtensa-xtfpga.c +++ b/drivers/spi/spi-xtensa-xtfpga.c | |||
@@ -54,7 +54,7 @@ static inline void xtfpga_spi_wait_busy(struct xtfpga_spi *xspi) | |||
54 | } | 54 | } |
55 | 55 | ||
56 | static u32 xtfpga_spi_txrx_word(struct spi_device *spi, unsigned nsecs, | 56 | static u32 xtfpga_spi_txrx_word(struct spi_device *spi, unsigned nsecs, |
57 | u32 v, u8 bits) | 57 | u32 v, u8 bits, unsigned flags) |
58 | { | 58 | { |
59 | struct xtfpga_spi *xspi = spi_master_get_devdata(spi->master); | 59 | struct xtfpga_spi *xspi = spi_master_get_devdata(spi->master); |
60 | 60 | ||
diff --git a/include/linux/spi/adi_spi3.h b/include/linux/spi/adi_spi3.h deleted file mode 100644 index c84123aa1d06..000000000000 --- a/include/linux/spi/adi_spi3.h +++ /dev/null | |||
@@ -1,254 +0,0 @@ | |||
1 | /* | ||
2 | * Analog Devices SPI3 controller driver | ||
3 | * | ||
4 | * Copyright (c) 2014 Analog Devices Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #ifndef _ADI_SPI3_H_ | ||
17 | #define _ADI_SPI3_H_ | ||
18 | |||
19 | #include <linux/types.h> | ||
20 | |||
21 | /* SPI_CONTROL */ | ||
22 | #define SPI_CTL_EN 0x00000001 /* Enable */ | ||
23 | #define SPI_CTL_MSTR 0x00000002 /* Master/Slave */ | ||
24 | #define SPI_CTL_PSSE 0x00000004 /* controls modf error in master mode */ | ||
25 | #define SPI_CTL_ODM 0x00000008 /* Open Drain Mode */ | ||
26 | #define SPI_CTL_CPHA 0x00000010 /* Clock Phase */ | ||
27 | #define SPI_CTL_CPOL 0x00000020 /* Clock Polarity */ | ||
28 | #define SPI_CTL_ASSEL 0x00000040 /* Slave Select Pin Control */ | ||
29 | #define SPI_CTL_SELST 0x00000080 /* Slave Select Polarity in-between transfers */ | ||
30 | #define SPI_CTL_EMISO 0x00000100 /* Enable MISO */ | ||
31 | #define SPI_CTL_SIZE 0x00000600 /* Word Transfer Size */ | ||
32 | #define SPI_CTL_SIZE08 0x00000000 /* SIZE: 8 bits */ | ||
33 | #define SPI_CTL_SIZE16 0x00000200 /* SIZE: 16 bits */ | ||
34 | #define SPI_CTL_SIZE32 0x00000400 /* SIZE: 32 bits */ | ||
35 | #define SPI_CTL_LSBF 0x00001000 /* LSB First */ | ||
36 | #define SPI_CTL_FCEN 0x00002000 /* Flow-Control Enable */ | ||
37 | #define SPI_CTL_FCCH 0x00004000 /* Flow-Control Channel Selection */ | ||
38 | #define SPI_CTL_FCPL 0x00008000 /* Flow-Control Polarity */ | ||
39 | #define SPI_CTL_FCWM 0x00030000 /* Flow-Control Water-Mark */ | ||
40 | #define SPI_CTL_FIFO0 0x00000000 /* FCWM: TFIFO empty or RFIFO Full */ | ||
41 | #define SPI_CTL_FIFO1 0x00010000 /* FCWM: TFIFO 75% or more empty or RFIFO 75% or more full */ | ||
42 | #define SPI_CTL_FIFO2 0x00020000 /* FCWM: TFIFO 50% or more empty or RFIFO 50% or more full */ | ||
43 | #define SPI_CTL_FMODE 0x00040000 /* Fast-mode Enable */ | ||
44 | #define SPI_CTL_MIOM 0x00300000 /* Multiple I/O Mode */ | ||
45 | #define SPI_CTL_MIO_DIS 0x00000000 /* MIOM: Disable */ | ||
46 | #define SPI_CTL_MIO_DUAL 0x00100000 /* MIOM: Enable DIOM (Dual I/O Mode) */ | ||
47 | #define SPI_CTL_MIO_QUAD 0x00200000 /* MIOM: Enable QUAD (Quad SPI Mode) */ | ||
48 | #define SPI_CTL_SOSI 0x00400000 /* Start on MOSI */ | ||
49 | /* SPI_RX_CONTROL */ | ||
50 | #define SPI_RXCTL_REN 0x00000001 /* Receive Channel Enable */ | ||
51 | #define SPI_RXCTL_RTI 0x00000004 /* Receive Transfer Initiate */ | ||
52 | #define SPI_RXCTL_RWCEN 0x00000008 /* Receive Word Counter Enable */ | ||
53 | #define SPI_RXCTL_RDR 0x00000070 /* Receive Data Request */ | ||
54 | #define SPI_RXCTL_RDR_DIS 0x00000000 /* RDR: Disabled */ | ||
55 | #define SPI_RXCTL_RDR_NE 0x00000010 /* RDR: RFIFO not empty */ | ||
56 | #define SPI_RXCTL_RDR_25 0x00000020 /* RDR: RFIFO 25% full */ | ||
57 | #define SPI_RXCTL_RDR_50 0x00000030 /* RDR: RFIFO 50% full */ | ||
58 | #define SPI_RXCTL_RDR_75 0x00000040 /* RDR: RFIFO 75% full */ | ||
59 | #define SPI_RXCTL_RDR_FULL 0x00000050 /* RDR: RFIFO full */ | ||
60 | #define SPI_RXCTL_RDO 0x00000100 /* Receive Data Over-Run */ | ||
61 | #define SPI_RXCTL_RRWM 0x00003000 /* FIFO Regular Water-Mark */ | ||
62 | #define SPI_RXCTL_RWM_0 0x00000000 /* RRWM: RFIFO Empty */ | ||
63 | #define SPI_RXCTL_RWM_25 0x00001000 /* RRWM: RFIFO 25% full */ | ||
64 | #define SPI_RXCTL_RWM_50 0x00002000 /* RRWM: RFIFO 50% full */ | ||
65 | #define SPI_RXCTL_RWM_75 0x00003000 /* RRWM: RFIFO 75% full */ | ||
66 | #define SPI_RXCTL_RUWM 0x00070000 /* FIFO Urgent Water-Mark */ | ||
67 | #define SPI_RXCTL_UWM_DIS 0x00000000 /* RUWM: Disabled */ | ||
68 | #define SPI_RXCTL_UWM_25 0x00010000 /* RUWM: RFIFO 25% full */ | ||
69 | #define SPI_RXCTL_UWM_50 0x00020000 /* RUWM: RFIFO 50% full */ | ||
70 | #define SPI_RXCTL_UWM_75 0x00030000 /* RUWM: RFIFO 75% full */ | ||
71 | #define SPI_RXCTL_UWM_FULL 0x00040000 /* RUWM: RFIFO full */ | ||
72 | /* SPI_TX_CONTROL */ | ||
73 | #define SPI_TXCTL_TEN 0x00000001 /* Transmit Channel Enable */ | ||
74 | #define SPI_TXCTL_TTI 0x00000004 /* Transmit Transfer Initiate */ | ||
75 | #define SPI_TXCTL_TWCEN 0x00000008 /* Transmit Word Counter Enable */ | ||
76 | #define SPI_TXCTL_TDR 0x00000070 /* Transmit Data Request */ | ||
77 | #define SPI_TXCTL_TDR_DIS 0x00000000 /* TDR: Disabled */ | ||
78 | #define SPI_TXCTL_TDR_NF 0x00000010 /* TDR: TFIFO not full */ | ||
79 | #define SPI_TXCTL_TDR_25 0x00000020 /* TDR: TFIFO 25% empty */ | ||
80 | #define SPI_TXCTL_TDR_50 0x00000030 /* TDR: TFIFO 50% empty */ | ||
81 | #define SPI_TXCTL_TDR_75 0x00000040 /* TDR: TFIFO 75% empty */ | ||
82 | #define SPI_TXCTL_TDR_EMPTY 0x00000050 /* TDR: TFIFO empty */ | ||
83 | #define SPI_TXCTL_TDU 0x00000100 /* Transmit Data Under-Run */ | ||
84 | #define SPI_TXCTL_TRWM 0x00003000 /* FIFO Regular Water-Mark */ | ||
85 | #define SPI_TXCTL_RWM_FULL 0x00000000 /* TRWM: TFIFO full */ | ||
86 | #define SPI_TXCTL_RWM_25 0x00001000 /* TRWM: TFIFO 25% empty */ | ||
87 | #define SPI_TXCTL_RWM_50 0x00002000 /* TRWM: TFIFO 50% empty */ | ||
88 | #define SPI_TXCTL_RWM_75 0x00003000 /* TRWM: TFIFO 75% empty */ | ||
89 | #define SPI_TXCTL_TUWM 0x00070000 /* FIFO Urgent Water-Mark */ | ||
90 | #define SPI_TXCTL_UWM_DIS 0x00000000 /* TUWM: Disabled */ | ||
91 | #define SPI_TXCTL_UWM_25 0x00010000 /* TUWM: TFIFO 25% empty */ | ||
92 | #define SPI_TXCTL_UWM_50 0x00020000 /* TUWM: TFIFO 50% empty */ | ||
93 | #define SPI_TXCTL_UWM_75 0x00030000 /* TUWM: TFIFO 75% empty */ | ||
94 | #define SPI_TXCTL_UWM_EMPTY 0x00040000 /* TUWM: TFIFO empty */ | ||
95 | /* SPI_CLOCK */ | ||
96 | #define SPI_CLK_BAUD 0x0000FFFF /* Baud Rate */ | ||
97 | /* SPI_DELAY */ | ||
98 | #define SPI_DLY_STOP 0x000000FF /* Transfer delay time in multiples of SCK period */ | ||
99 | #define SPI_DLY_LEADX 0x00000100 /* Extended (1 SCK) LEAD Control */ | ||
100 | #define SPI_DLY_LAGX 0x00000200 /* Extended (1 SCK) LAG control */ | ||
101 | /* SPI_SSEL */ | ||
102 | #define SPI_SLVSEL_SSE1 0x00000002 /* SPISSEL1 Enable */ | ||
103 | #define SPI_SLVSEL_SSE2 0x00000004 /* SPISSEL2 Enable */ | ||
104 | #define SPI_SLVSEL_SSE3 0x00000008 /* SPISSEL3 Enable */ | ||
105 | #define SPI_SLVSEL_SSE4 0x00000010 /* SPISSEL4 Enable */ | ||
106 | #define SPI_SLVSEL_SSE5 0x00000020 /* SPISSEL5 Enable */ | ||
107 | #define SPI_SLVSEL_SSE6 0x00000040 /* SPISSEL6 Enable */ | ||
108 | #define SPI_SLVSEL_SSE7 0x00000080 /* SPISSEL7 Enable */ | ||
109 | #define SPI_SLVSEL_SSEL1 0x00000200 /* SPISSEL1 Value */ | ||
110 | #define SPI_SLVSEL_SSEL2 0x00000400 /* SPISSEL2 Value */ | ||
111 | #define SPI_SLVSEL_SSEL3 0x00000800 /* SPISSEL3 Value */ | ||
112 | #define SPI_SLVSEL_SSEL4 0x00001000 /* SPISSEL4 Value */ | ||
113 | #define SPI_SLVSEL_SSEL5 0x00002000 /* SPISSEL5 Value */ | ||
114 | #define SPI_SLVSEL_SSEL6 0x00004000 /* SPISSEL6 Value */ | ||
115 | #define SPI_SLVSEL_SSEL7 0x00008000 /* SPISSEL7 Value */ | ||
116 | /* SPI_RWC */ | ||
117 | #define SPI_RWC_VALUE 0x0000FFFF /* Received Word-Count */ | ||
118 | /* SPI_RWCR */ | ||
119 | #define SPI_RWCR_VALUE 0x0000FFFF /* Received Word-Count Reload */ | ||
120 | /* SPI_TWC */ | ||
121 | #define SPI_TWC_VALUE 0x0000FFFF /* Transmitted Word-Count */ | ||
122 | /* SPI_TWCR */ | ||
123 | #define SPI_TWCR_VALUE 0x0000FFFF /* Transmitted Word-Count Reload */ | ||
124 | /* SPI_IMASK */ | ||
125 | #define SPI_IMSK_RUWM 0x00000002 /* Receive Urgent Water-Mark Interrupt Mask */ | ||
126 | #define SPI_IMSK_TUWM 0x00000004 /* Transmit Urgent Water-Mark Interrupt Mask */ | ||
127 | #define SPI_IMSK_ROM 0x00000010 /* Receive Over-Run Error Interrupt Mask */ | ||
128 | #define SPI_IMSK_TUM 0x00000020 /* Transmit Under-Run Error Interrupt Mask */ | ||
129 | #define SPI_IMSK_TCM 0x00000040 /* Transmit Collision Error Interrupt Mask */ | ||
130 | #define SPI_IMSK_MFM 0x00000080 /* Mode Fault Error Interrupt Mask */ | ||
131 | #define SPI_IMSK_RSM 0x00000100 /* Receive Start Interrupt Mask */ | ||
132 | #define SPI_IMSK_TSM 0x00000200 /* Transmit Start Interrupt Mask */ | ||
133 | #define SPI_IMSK_RFM 0x00000400 /* Receive Finish Interrupt Mask */ | ||
134 | #define SPI_IMSK_TFM 0x00000800 /* Transmit Finish Interrupt Mask */ | ||
135 | /* SPI_IMASKCL */ | ||
136 | #define SPI_IMSK_CLR_RUW 0x00000002 /* Receive Urgent Water-Mark Interrupt Mask */ | ||
137 | #define SPI_IMSK_CLR_TUWM 0x00000004 /* Transmit Urgent Water-Mark Interrupt Mask */ | ||
138 | #define SPI_IMSK_CLR_ROM 0x00000010 /* Receive Over-Run Error Interrupt Mask */ | ||
139 | #define SPI_IMSK_CLR_TUM 0x00000020 /* Transmit Under-Run Error Interrupt Mask */ | ||
140 | #define SPI_IMSK_CLR_TCM 0x00000040 /* Transmit Collision Error Interrupt Mask */ | ||
141 | #define SPI_IMSK_CLR_MFM 0x00000080 /* Mode Fault Error Interrupt Mask */ | ||
142 | #define SPI_IMSK_CLR_RSM 0x00000100 /* Receive Start Interrupt Mask */ | ||
143 | #define SPI_IMSK_CLR_TSM 0x00000200 /* Transmit Start Interrupt Mask */ | ||
144 | #define SPI_IMSK_CLR_RFM 0x00000400 /* Receive Finish Interrupt Mask */ | ||
145 | #define SPI_IMSK_CLR_TFM 0x00000800 /* Transmit Finish Interrupt Mask */ | ||
146 | /* SPI_IMASKST */ | ||
147 | #define SPI_IMSK_SET_RUWM 0x00000002 /* Receive Urgent Water-Mark Interrupt Mask */ | ||
148 | #define SPI_IMSK_SET_TUWM 0x00000004 /* Transmit Urgent Water-Mark Interrupt Mask */ | ||
149 | #define SPI_IMSK_SET_ROM 0x00000010 /* Receive Over-Run Error Interrupt Mask */ | ||
150 | #define SPI_IMSK_SET_TUM 0x00000020 /* Transmit Under-Run Error Interrupt Mask */ | ||
151 | #define SPI_IMSK_SET_TCM 0x00000040 /* Transmit Collision Error Interrupt Mask */ | ||
152 | #define SPI_IMSK_SET_MFM 0x00000080 /* Mode Fault Error Interrupt Mask */ | ||
153 | #define SPI_IMSK_SET_RSM 0x00000100 /* Receive Start Interrupt Mask */ | ||
154 | #define SPI_IMSK_SET_TSM 0x00000200 /* Transmit Start Interrupt Mask */ | ||
155 | #define SPI_IMSK_SET_RFM 0x00000400 /* Receive Finish Interrupt Mask */ | ||
156 | #define SPI_IMSK_SET_TFM 0x00000800 /* Transmit Finish Interrupt Mask */ | ||
157 | /* SPI_STATUS */ | ||
158 | #define SPI_STAT_SPIF 0x00000001 /* SPI Finished */ | ||
159 | #define SPI_STAT_RUWM 0x00000002 /* Receive Urgent Water-Mark Breached */ | ||
160 | #define SPI_STAT_TUWM 0x00000004 /* Transmit Urgent Water-Mark Breached */ | ||
161 | #define SPI_STAT_ROE 0x00000010 /* Receive Over-Run Error Indication */ | ||
162 | #define SPI_STAT_TUE 0x00000020 /* Transmit Under-Run Error Indication */ | ||
163 | #define SPI_STAT_TCE 0x00000040 /* Transmit Collision Error Indication */ | ||
164 | #define SPI_STAT_MODF 0x00000080 /* Mode Fault Error Indication */ | ||
165 | #define SPI_STAT_RS 0x00000100 /* Receive Start Indication */ | ||
166 | #define SPI_STAT_TS 0x00000200 /* Transmit Start Indication */ | ||
167 | #define SPI_STAT_RF 0x00000400 /* Receive Finish Indication */ | ||
168 | #define SPI_STAT_TF 0x00000800 /* Transmit Finish Indication */ | ||
169 | #define SPI_STAT_RFS 0x00007000 /* SPI_RFIFO status */ | ||
170 | #define SPI_STAT_RFIFO_EMPTY 0x00000000 /* RFS: RFIFO Empty */ | ||
171 | #define SPI_STAT_RFIFO_25 0x00001000 /* RFS: RFIFO 25% Full */ | ||
172 | #define SPI_STAT_RFIFO_50 0x00002000 /* RFS: RFIFO 50% Full */ | ||
173 | #define SPI_STAT_RFIFO_75 0x00003000 /* RFS: RFIFO 75% Full */ | ||
174 | #define SPI_STAT_RFIFO_FULL 0x00004000 /* RFS: RFIFO Full */ | ||
175 | #define SPI_STAT_TFS 0x00070000 /* SPI_TFIFO status */ | ||
176 | #define SPI_STAT_TFIFO_FULL 0x00000000 /* TFS: TFIFO full */ | ||
177 | #define SPI_STAT_TFIFO_25 0x00010000 /* TFS: TFIFO 25% empty */ | ||
178 | #define SPI_STAT_TFIFO_50 0x00020000 /* TFS: TFIFO 50% empty */ | ||
179 | #define SPI_STAT_TFIFO_75 0x00030000 /* TFS: TFIFO 75% empty */ | ||
180 | #define SPI_STAT_TFIFO_EMPTY 0x00040000 /* TFS: TFIFO empty */ | ||
181 | #define SPI_STAT_FCS 0x00100000 /* Flow-Control Stall Indication */ | ||
182 | #define SPI_STAT_RFE 0x00400000 /* SPI_RFIFO Empty */ | ||
183 | #define SPI_STAT_TFF 0x00800000 /* SPI_TFIFO Full */ | ||
184 | /* SPI_ILAT */ | ||
185 | #define SPI_ILAT_RUWMI 0x00000002 /* Receive Urgent Water Mark Interrupt */ | ||
186 | #define SPI_ILAT_TUWMI 0x00000004 /* Transmit Urgent Water Mark Interrupt */ | ||
187 | #define SPI_ILAT_ROI 0x00000010 /* Receive Over-Run Error Indication */ | ||
188 | #define SPI_ILAT_TUI 0x00000020 /* Transmit Under-Run Error Indication */ | ||
189 | #define SPI_ILAT_TCI 0x00000040 /* Transmit Collision Error Indication */ | ||
190 | #define SPI_ILAT_MFI 0x00000080 /* Mode Fault Error Indication */ | ||
191 | #define SPI_ILAT_RSI 0x00000100 /* Receive Start Indication */ | ||
192 | #define SPI_ILAT_TSI 0x00000200 /* Transmit Start Indication */ | ||
193 | #define SPI_ILAT_RFI 0x00000400 /* Receive Finish Indication */ | ||
194 | #define SPI_ILAT_TFI 0x00000800 /* Transmit Finish Indication */ | ||
195 | /* SPI_ILATCL */ | ||
196 | #define SPI_ILAT_CLR_RUWMI 0x00000002 /* Receive Urgent Water Mark Interrupt */ | ||
197 | #define SPI_ILAT_CLR_TUWMI 0x00000004 /* Transmit Urgent Water Mark Interrupt */ | ||
198 | #define SPI_ILAT_CLR_ROI 0x00000010 /* Receive Over-Run Error Indication */ | ||
199 | #define SPI_ILAT_CLR_TUI 0x00000020 /* Transmit Under-Run Error Indication */ | ||
200 | #define SPI_ILAT_CLR_TCI 0x00000040 /* Transmit Collision Error Indication */ | ||
201 | #define SPI_ILAT_CLR_MFI 0x00000080 /* Mode Fault Error Indication */ | ||
202 | #define SPI_ILAT_CLR_RSI 0x00000100 /* Receive Start Indication */ | ||
203 | #define SPI_ILAT_CLR_TSI 0x00000200 /* Transmit Start Indication */ | ||
204 | #define SPI_ILAT_CLR_RFI 0x00000400 /* Receive Finish Indication */ | ||
205 | #define SPI_ILAT_CLR_TFI 0x00000800 /* Transmit Finish Indication */ | ||
206 | |||
207 | /* | ||
208 | * adi spi3 registers layout | ||
209 | */ | ||
210 | struct adi_spi_regs { | ||
211 | u32 revid; | ||
212 | u32 control; | ||
213 | u32 rx_control; | ||
214 | u32 tx_control; | ||
215 | u32 clock; | ||
216 | u32 delay; | ||
217 | u32 ssel; | ||
218 | u32 rwc; | ||
219 | u32 rwcr; | ||
220 | u32 twc; | ||
221 | u32 twcr; | ||
222 | u32 reserved0; | ||
223 | u32 emask; | ||
224 | u32 emaskcl; | ||
225 | u32 emaskst; | ||
226 | u32 reserved1; | ||
227 | u32 status; | ||
228 | u32 elat; | ||
229 | u32 elatcl; | ||
230 | u32 reserved2; | ||
231 | u32 rfifo; | ||
232 | u32 reserved3; | ||
233 | u32 tfifo; | ||
234 | }; | ||
235 | |||
236 | #define MAX_CTRL_CS 8 /* cs in spi controller */ | ||
237 | |||
238 | /* device.platform_data for SSP controller devices */ | ||
239 | struct adi_spi3_master { | ||
240 | u16 num_chipselect; | ||
241 | u16 pin_req[7]; | ||
242 | }; | ||
243 | |||
244 | /* spi_board_info.controller_data for SPI slave devices, | ||
245 | * copied to spi_device.platform_data ... mostly for dma tuning | ||
246 | */ | ||
247 | struct adi_spi3_chip { | ||
248 | u32 control; | ||
249 | u16 cs_chg_udelay; /* Some devices require 16-bit delays */ | ||
250 | u32 tx_dummy_val; /* tx value for rx only transfer */ | ||
251 | bool enable_dma; | ||
252 | }; | ||
253 | |||
254 | #endif /* _ADI_SPI3_H_ */ | ||
diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index 4fa34a227a0f..b2bd4b4127c4 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h | |||
@@ -124,7 +124,8 @@ struct spi_mem_op { | |||
124 | /** | 124 | /** |
125 | * struct spi_mem - describes a SPI memory device | 125 | * struct spi_mem - describes a SPI memory device |
126 | * @spi: the underlying SPI device | 126 | * @spi: the underlying SPI device |
127 | * @drvpriv: spi_mem_drviver private data | 127 | * @drvpriv: spi_mem_driver private data |
128 | * @name: name of the SPI memory device | ||
128 | * | 129 | * |
129 | * Extra information that describe the SPI memory device and may be needed by | 130 | * Extra information that describe the SPI memory device and may be needed by |
130 | * the controller to properly handle this device should be placed here. | 131 | * the controller to properly handle this device should be placed here. |
@@ -135,6 +136,7 @@ struct spi_mem_op { | |||
135 | struct spi_mem { | 136 | struct spi_mem { |
136 | struct spi_device *spi; | 137 | struct spi_device *spi; |
137 | void *drvpriv; | 138 | void *drvpriv; |
139 | const char *name; | ||
138 | }; | 140 | }; |
139 | 141 | ||
140 | /** | 142 | /** |
@@ -167,6 +169,13 @@ static inline void *spi_mem_get_drvdata(struct spi_mem *mem) | |||
167 | * limitations) | 169 | * limitations) |
168 | * @supports_op: check if an operation is supported by the controller | 170 | * @supports_op: check if an operation is supported by the controller |
169 | * @exec_op: execute a SPI memory operation | 171 | * @exec_op: execute a SPI memory operation |
172 | * @get_name: get a custom name for the SPI mem device from the controller. | ||
173 | * This might be needed if the controller driver has been ported | ||
174 | * to use the SPI mem layer and a custom name is used to keep | ||
175 | * mtdparts compatible. | ||
176 | * Note that if the implementation of this function allocates memory | ||
177 | * dynamically, then it should do so with devm_xxx(), as we don't | ||
178 | * have a ->free_name() function. | ||
170 | * | 179 | * |
171 | * This interface should be implemented by SPI controllers providing an | 180 | * This interface should be implemented by SPI controllers providing an |
172 | * high-level interface to execute SPI memory operation, which is usually the | 181 | * high-level interface to execute SPI memory operation, which is usually the |
@@ -178,6 +187,7 @@ struct spi_controller_mem_ops { | |||
178 | const struct spi_mem_op *op); | 187 | const struct spi_mem_op *op); |
179 | int (*exec_op)(struct spi_mem *mem, | 188 | int (*exec_op)(struct spi_mem *mem, |
180 | const struct spi_mem_op *op); | 189 | const struct spi_mem_op *op); |
190 | const char *(*get_name)(struct spi_mem *mem); | ||
181 | }; | 191 | }; |
182 | 192 | ||
183 | /** | 193 | /** |
@@ -236,6 +246,8 @@ bool spi_mem_supports_op(struct spi_mem *mem, | |||
236 | int spi_mem_exec_op(struct spi_mem *mem, | 246 | int spi_mem_exec_op(struct spi_mem *mem, |
237 | const struct spi_mem_op *op); | 247 | const struct spi_mem_op *op); |
238 | 248 | ||
249 | const char *spi_mem_get_name(struct spi_mem *mem); | ||
250 | |||
239 | int spi_mem_driver_register_with_owner(struct spi_mem_driver *drv, | 251 | int spi_mem_driver_register_with_owner(struct spi_mem_driver *drv, |
240 | struct module *owner); | 252 | struct module *owner); |
241 | 253 | ||
diff --git a/include/linux/spi/spi_bitbang.h b/include/linux/spi/spi_bitbang.h index 51d8c060e513..b7e021b274dc 100644 --- a/include/linux/spi/spi_bitbang.h +++ b/include/linux/spi/spi_bitbang.h | |||
@@ -8,7 +8,7 @@ struct spi_bitbang { | |||
8 | struct mutex lock; | 8 | struct mutex lock; |
9 | u8 busy; | 9 | u8 busy; |
10 | u8 use_dma; | 10 | u8 use_dma; |
11 | u8 flags; /* extra spi->mode support */ | 11 | u16 flags; /* extra spi->mode support */ |
12 | 12 | ||
13 | struct spi_master *master; | 13 | struct spi_master *master; |
14 | 14 | ||
@@ -30,7 +30,8 @@ struct spi_bitbang { | |||
30 | /* txrx_word[SPI_MODE_*]() just looks like a shift register */ | 30 | /* txrx_word[SPI_MODE_*]() just looks like a shift register */ |
31 | u32 (*txrx_word[4])(struct spi_device *spi, | 31 | u32 (*txrx_word[4])(struct spi_device *spi, |
32 | unsigned nsecs, | 32 | unsigned nsecs, |
33 | u32 word, u8 bits); | 33 | u32 word, u8 bits, unsigned flags); |
34 | int (*set_line_direction)(struct spi_device *spi, bool output); | ||
34 | }; | 35 | }; |
35 | 36 | ||
36 | /* you can call these default bitbang->master methods from your custom | 37 | /* you can call these default bitbang->master methods from your custom |