diff options
41 files changed, 1282 insertions, 371 deletions
diff --git a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt index 4256a6df9b79..aad527b357a0 100644 --- a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt +++ b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt | |||
| @@ -7,6 +7,9 @@ Required properties: | |||
| 7 | - interrupts : Should contain CSPI/eCSPI interrupt | 7 | - interrupts : Should contain CSPI/eCSPI interrupt |
| 8 | - fsl,spi-num-chipselects : Contains the number of the chipselect | 8 | - fsl,spi-num-chipselects : Contains the number of the chipselect |
| 9 | - cs-gpios : Specifies the gpio pins to be used for chipselects. | 9 | - cs-gpios : Specifies the gpio pins to be used for chipselects. |
| 10 | - dmas: DMA specifiers for tx and rx dma. See the DMA client binding, | ||
| 11 | Documentation/devicetree/bindings/dma/dma.txt | ||
| 12 | - dma-names: DMA request names should include "tx" and "rx" if present. | ||
| 10 | 13 | ||
| 11 | Example: | 14 | Example: |
| 12 | 15 | ||
| @@ -19,4 +22,6 @@ ecspi@70010000 { | |||
| 19 | fsl,spi-num-chipselects = <2>; | 22 | fsl,spi-num-chipselects = <2>; |
| 20 | cs-gpios = <&gpio3 24 0>, /* GPIO3_24 */ | 23 | cs-gpios = <&gpio3 24 0>, /* GPIO3_24 */ |
| 21 | <&gpio3 25 0>; /* GPIO3_25 */ | 24 | <&gpio3 25 0>; /* GPIO3_25 */ |
| 25 | dmas = <&sdma 3 7 1>, <&sdma 4 7 2>; | ||
| 26 | dma-names = "rx", "tx"; | ||
| 22 | }; | 27 | }; |
diff --git a/Documentation/devicetree/bindings/spi/sh-msiof.txt b/Documentation/devicetree/bindings/spi/sh-msiof.txt index f24baf3b6cc1..d11c3721e7cd 100644 --- a/Documentation/devicetree/bindings/spi/sh-msiof.txt +++ b/Documentation/devicetree/bindings/spi/sh-msiof.txt | |||
| @@ -6,8 +6,17 @@ Required properties: | |||
| 6 | "renesas,sh-mobile-msiof" for SH Mobile series. | 6 | "renesas,sh-mobile-msiof" for SH Mobile series. |
| 7 | Examples with soctypes are: | 7 | Examples with soctypes are: |
| 8 | "renesas,msiof-r8a7790" (R-Car H2) | 8 | "renesas,msiof-r8a7790" (R-Car H2) |
| 9 | "renesas,msiof-r8a7791" (R-Car M2) | 9 | "renesas,msiof-r8a7791" (R-Car M2-W) |
| 10 | - reg : Offset and length of the register set for the device | 10 | "renesas,msiof-r8a7792" (R-Car V2H) |
| 11 | "renesas,msiof-r8a7793" (R-Car M2-N) | ||
| 12 | "renesas,msiof-r8a7794" (R-Car E2) | ||
| 13 | - reg : A list of offsets and lengths of the register sets for | ||
| 14 | the device. | ||
| 15 | If only one register set is present, it is to be used | ||
| 16 | by both the CPU and the DMA engine. | ||
| 17 | If two register sets are present, the first is to be | ||
| 18 | used by the CPU, and the second is to be used by the | ||
| 19 | DMA engine. | ||
| 11 | - interrupt-parent : The phandle for the interrupt controller that | 20 | - interrupt-parent : The phandle for the interrupt controller that |
| 12 | services interrupts for this device | 21 | services interrupts for this device |
| 13 | - interrupts : Interrupt specifier | 22 | - interrupts : Interrupt specifier |
| @@ -17,12 +26,16 @@ Required properties: | |||
| 17 | Optional properties: | 26 | Optional properties: |
| 18 | - clocks : Must contain a reference to the functional clock. | 27 | - clocks : Must contain a reference to the functional clock. |
| 19 | - num-cs : Total number of chip-selects (default is 1) | 28 | - num-cs : Total number of chip-selects (default is 1) |
| 29 | - dmas : Must contain a list of two references to DMA | ||
| 30 | specifiers, one for transmission, and one for | ||
| 31 | reception. | ||
| 32 | - dma-names : Must contain a list of two DMA names, "tx" and "rx". | ||
| 20 | 33 | ||
| 21 | Optional properties, deprecated for soctype-specific bindings: | 34 | Optional properties, deprecated for soctype-specific bindings: |
| 22 | - renesas,tx-fifo-size : Overrides the default tx fifo size given in words | 35 | - renesas,tx-fifo-size : Overrides the default tx fifo size given in words |
| 23 | (default is 64) | 36 | (default is 64) |
| 24 | - renesas,rx-fifo-size : Overrides the default rx fifo size given in words | 37 | - renesas,rx-fifo-size : Overrides the default rx fifo size given in words |
| 25 | (default is 64, or 256 on R-Car H2 and M2) | 38 | (default is 64, or 256 on R-Car Gen2) |
| 26 | 39 | ||
| 27 | Pinctrl properties might be needed, too. See | 40 | Pinctrl properties might be needed, too. See |
| 28 | Documentation/devicetree/bindings/pinctrl/renesas,*. | 41 | Documentation/devicetree/bindings/pinctrl/renesas,*. |
| @@ -31,9 +44,11 @@ Example: | |||
| 31 | 44 | ||
| 32 | msiof0: spi@e6e20000 { | 45 | msiof0: spi@e6e20000 { |
| 33 | compatible = "renesas,msiof-r8a7791"; | 46 | compatible = "renesas,msiof-r8a7791"; |
| 34 | reg = <0 0xe6e20000 0 0x0064>; | 47 | reg = <0 0xe6e20000 0 0x0064>, <0 0xe7e20000 0 0x0064>; |
| 35 | interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>; | 48 | interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>; |
| 36 | clocks = <&mstp0_clks R8A7791_CLK_MSIOF0>; | 49 | clocks = <&mstp0_clks R8A7791_CLK_MSIOF0>; |
| 50 | dmas = <&dmac0 0x51>, <&dmac0 0x52>; | ||
| 51 | dma-names = "tx", "rx"; | ||
| 37 | #address-cells = <1>; | 52 | #address-cells = <1>; |
| 38 | #size-cells = <0>; | 53 | #size-cells = <0>; |
| 39 | status = "disabled"; | 54 | status = "disabled"; |
diff --git a/Documentation/devicetree/bindings/spi/spi-davinci.txt b/Documentation/devicetree/bindings/spi/spi-davinci.txt index f80887bca0d6..12ecfe9e3599 100644 --- a/Documentation/devicetree/bindings/spi/spi-davinci.txt +++ b/Documentation/devicetree/bindings/spi/spi-davinci.txt | |||
| @@ -1,5 +1,10 @@ | |||
| 1 | Davinci SPI controller device bindings | 1 | Davinci SPI controller device bindings |
| 2 | 2 | ||
| 3 | Links on DM: | ||
| 4 | Keystone 2 - http://www.ti.com/lit/ug/sprugp2a/sprugp2a.pdf | ||
| 5 | dm644x - http://www.ti.com/lit/ug/sprue32a/sprue32a.pdf | ||
| 6 | OMAP-L138/da830 - http://www.ti.com/lit/ug/spruh77a/spruh77a.pdf | ||
| 7 | |||
| 3 | Required properties: | 8 | Required properties: |
| 4 | - #address-cells: number of cells required to define a chip select | 9 | - #address-cells: number of cells required to define a chip select |
| 5 | address on the SPI bus. Should be set to 1. | 10 | address on the SPI bus. Should be set to 1. |
| @@ -24,6 +29,30 @@ Optional: | |||
| 24 | cs-gpios = <0>, <0>, <0>, <&gpio1 30 0>, <&gpio1 31 0>; | 29 | cs-gpios = <0>, <0>, <0>, <&gpio1 30 0>, <&gpio1 31 0>; |
| 25 | where first three are internal CS and last two are GPIO CS. | 30 | where first three are internal CS and last two are GPIO CS. |
| 26 | 31 | ||
| 32 | Optional properties for slave devices: | ||
| 33 | SPI slave nodes can contain the following properties. | ||
| 34 | Not all SPI Peripherals from Texas Instruments support this. | ||
| 35 | Please check SPI peripheral documentation for a device before using these. | ||
| 36 | |||
| 37 | - ti,spi-wdelay : delay between transmission of words | ||
| 38 | (SPIFMTn.WDELAY, SPIDAT1.WDEL) must be specified in number of SPI module | ||
| 39 | clock periods. | ||
| 40 | |||
| 41 | delay = WDELAY * SPI_module_clock_period + 2 * SPI_module_clock_period | ||
| 42 | |||
| 43 | Below is timing diagram which shows functional meaning of | ||
| 44 | "ti,spi-wdelay" parameter. | ||
| 45 | |||
| 46 | +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ | ||
| 47 | SPI_CLK | | | | | | | | | | | | | | | | | ||
| 48 | +----------+ +-+ +-+ +-+ +-+ +---------------------------+ +-+ +-+ +- | ||
| 49 | |||
| 50 | SPI_SOMI/SIMO+-----------------+ +----------- | ||
| 51 | +----------+ word1 +---------------------------+word2 | ||
| 52 | +-----------------+ +----------- | ||
| 53 | WDELAY | ||
| 54 | <--------------------------> | ||
| 55 | |||
| 27 | Example of a NOR flash slave device (n25q032) connected to DaVinci | 56 | Example of a NOR flash slave device (n25q032) connected to DaVinci |
| 28 | SPI controller device over the SPI bus. | 57 | SPI controller device over the SPI bus. |
| 29 | 58 | ||
| @@ -43,6 +72,7 @@ spi0:spi@20BF0000 { | |||
| 43 | compatible = "st,m25p32"; | 72 | compatible = "st,m25p32"; |
| 44 | spi-max-frequency = <25000000>; | 73 | spi-max-frequency = <25000000>; |
| 45 | reg = <0>; | 74 | reg = <0>; |
| 75 | ti,spi-wdelay = <8>; | ||
| 46 | 76 | ||
| 47 | partition@0 { | 77 | partition@0 { |
| 48 | label = "u-boot-spl"; | 78 | label = "u-boot-spl"; |
diff --git a/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt b/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt index 5376de40f10b..cbbe16ed3874 100644 --- a/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt +++ b/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt | |||
| @@ -10,7 +10,12 @@ Required properties: | |||
| 10 | - pinctrl-names: must contain a "default" entry. | 10 | - pinctrl-names: must contain a "default" entry. |
| 11 | - spi-num-chipselects : the number of the chipselect signals. | 11 | - spi-num-chipselects : the number of the chipselect signals. |
| 12 | - bus-num : the slave chip chipselect signal number. | 12 | - bus-num : the slave chip chipselect signal number. |
| 13 | - big-endian : if DSPI modudle is big endian, the bool will be set in node. | 13 | |
| 14 | Optional property: | ||
| 15 | - big-endian: If present the dspi device's registers are implemented | ||
| 16 | in big endian mode, otherwise in native mode(same with CPU), for more | ||
| 17 | detail please see: Documentation/devicetree/bindings/regmap/regmap.txt. | ||
| 18 | |||
| 14 | Example: | 19 | Example: |
| 15 | 20 | ||
| 16 | dspi0@4002c000 { | 21 | dspi0@4002c000 { |
diff --git a/Documentation/devicetree/bindings/spi/spi-orion.txt b/Documentation/devicetree/bindings/spi/spi-orion.txt index a3ff50fc76fb..50c3a3de61c1 100644 --- a/Documentation/devicetree/bindings/spi/spi-orion.txt +++ b/Documentation/devicetree/bindings/spi/spi-orion.txt | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | Marvell Orion SPI device | 1 | Marvell Orion SPI device |
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible : should be "marvell,orion-spi". | 4 | - compatible : should be "marvell,orion-spi" or "marvell,armada-370-spi". |
| 5 | - reg : offset and length of the register set for the device | 5 | - reg : offset and length of the register set for the device |
| 6 | - cell-index : Which of multiple SPI controllers is this. | 6 | - cell-index : Which of multiple SPI controllers is this. |
| 7 | Optional properties: | 7 | Optional properties: |
diff --git a/Documentation/devicetree/bindings/spi/spi-rspi.txt b/Documentation/devicetree/bindings/spi/spi-rspi.txt index d57d82a74054..8f4169f63936 100644 --- a/Documentation/devicetree/bindings/spi/spi-rspi.txt +++ b/Documentation/devicetree/bindings/spi/spi-rspi.txt | |||
| @@ -11,7 +11,10 @@ Required properties: | |||
| 11 | - "renesas,rspi-sh7757" (SH) | 11 | - "renesas,rspi-sh7757" (SH) |
| 12 | - "renesas,rspi-r7s72100" (RZ/A1H) | 12 | - "renesas,rspi-r7s72100" (RZ/A1H) |
| 13 | - "renesas,qspi-r8a7790" (R-Car H2) | 13 | - "renesas,qspi-r8a7790" (R-Car H2) |
| 14 | - "renesas,qspi-r8a7791" (R-Car M2) | 14 | - "renesas,qspi-r8a7791" (R-Car M2-W) |
| 15 | - "renesas,qspi-r8a7792" (R-Car V2H) | ||
| 16 | - "renesas,qspi-r8a7793" (R-Car M2-N) | ||
| 17 | - "renesas,qspi-r8a7794" (R-Car E2) | ||
| 15 | - reg : Address start and address range size of the device | 18 | - reg : Address start and address range size of the device |
| 16 | - interrupts : A list of interrupt-specifiers, one for each entry in | 19 | - interrupts : A list of interrupt-specifiers, one for each entry in |
| 17 | interrupt-names. | 20 | interrupt-names. |
| @@ -30,6 +33,9 @@ Required properties: | |||
| 30 | 33 | ||
| 31 | Optional properties: | 34 | Optional properties: |
| 32 | - clocks : Must contain a reference to the functional clock. | 35 | - clocks : Must contain a reference to the functional clock. |
| 36 | - dmas : Must contain a list of two references to DMA specifiers, | ||
| 37 | one for transmission, and one for reception. | ||
| 38 | - dma-names : Must contain a list of two DMA names, "tx" and "rx". | ||
| 33 | 39 | ||
| 34 | Pinctrl properties might be needed, too. See | 40 | Pinctrl properties might be needed, too. See |
| 35 | Documentation/devicetree/bindings/pinctrl/renesas,*. | 41 | Documentation/devicetree/bindings/pinctrl/renesas,*. |
| @@ -58,4 +64,6 @@ Examples: | |||
| 58 | num-cs = <1>; | 64 | num-cs = <1>; |
| 59 | #address-cells = <1>; | 65 | #address-cells = <1>; |
| 60 | #size-cells = <0>; | 66 | #size-cells = <0>; |
| 67 | dmas = <&dmac0 0x17>, <&dmac0 0x18>; | ||
| 68 | dma-names = "tx", "rx"; | ||
| 61 | }; | 69 | }; |
diff --git a/Documentation/spi/spi-summary b/Documentation/spi/spi-summary index 7982bcc4d151..d29734bff28c 100644 --- a/Documentation/spi/spi-summary +++ b/Documentation/spi/spi-summary | |||
| @@ -601,13 +601,13 @@ THANKS TO | |||
| 601 | Contributors to Linux-SPI discussions include (in alphabetical order, | 601 | Contributors to Linux-SPI discussions include (in alphabetical order, |
| 602 | by last name): | 602 | by last name): |
| 603 | 603 | ||
| 604 | Mark Brown | ||
| 604 | David Brownell | 605 | David Brownell |
| 605 | Russell King | 606 | Russell King |
| 607 | Grant Likely | ||
| 606 | Dmitry Pervushin | 608 | Dmitry Pervushin |
| 607 | Stephen Street | 609 | Stephen Street |
| 608 | Mark Underwood | 610 | Mark Underwood |
| 609 | Andrew Victor | 611 | Andrew Victor |
| 610 | Vitaly Wool | ||
| 611 | Grant Likely | ||
| 612 | Mark Brown | ||
| 613 | Linus Walleij | 612 | Linus Walleij |
| 613 | Vitaly Wool | ||
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 62e2242ad7e0..84e7c9e6ccef 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
| @@ -69,6 +69,7 @@ config SPI_ATH79 | |||
| 69 | 69 | ||
| 70 | config SPI_ATMEL | 70 | config SPI_ATMEL |
| 71 | tristate "Atmel SPI Controller" | 71 | tristate "Atmel SPI Controller" |
| 72 | depends on HAS_DMA | ||
| 72 | depends on (ARCH_AT91 || AVR32 || COMPILE_TEST) | 73 | depends on (ARCH_AT91 || AVR32 || COMPILE_TEST) |
| 73 | help | 74 | help |
| 74 | This selects a driver for the Atmel SPI Controller, present on | 75 | This selects a driver for the Atmel SPI Controller, present on |
| @@ -112,6 +113,14 @@ config SPI_AU1550 | |||
| 112 | If you say yes to this option, support will be included for the | 113 | If you say yes to this option, support will be included for the |
| 113 | PSC SPI controller found on Au1550, Au1200 and Au1300 series. | 114 | PSC SPI controller found on Au1550, Au1200 and Au1300 series. |
| 114 | 115 | ||
| 116 | config SPI_BCM53XX | ||
| 117 | tristate "Broadcom BCM53xx SPI controller" | ||
| 118 | depends on ARCH_BCM_5301X | ||
| 119 | depends on BCMA_POSSIBLE | ||
| 120 | select BCMA | ||
| 121 | help | ||
| 122 | Enable support for the SPI controller on Broadcom BCM53xx ARM SoCs. | ||
| 123 | |||
| 115 | config SPI_BCM63XX | 124 | config SPI_BCM63XX |
| 116 | tristate "Broadcom BCM63xx SPI controller" | 125 | tristate "Broadcom BCM63xx SPI controller" |
| 117 | depends on BCM63XX | 126 | depends on BCM63XX |
| @@ -185,6 +194,7 @@ config SPI_EFM32 | |||
| 185 | 194 | ||
| 186 | config SPI_EP93XX | 195 | config SPI_EP93XX |
| 187 | tristate "Cirrus Logic EP93xx SPI controller" | 196 | tristate "Cirrus Logic EP93xx SPI controller" |
| 197 | depends on HAS_DMA | ||
| 188 | depends on ARCH_EP93XX || COMPILE_TEST | 198 | depends on ARCH_EP93XX || COMPILE_TEST |
| 189 | help | 199 | help |
| 190 | This enables using the Cirrus EP93xx SPI controller in master | 200 | This enables using the Cirrus EP93xx SPI controller in master |
| @@ -314,6 +324,7 @@ config SPI_OMAP_UWIRE | |||
| 314 | 324 | ||
| 315 | config SPI_OMAP24XX | 325 | config SPI_OMAP24XX |
| 316 | tristate "McSPI driver for OMAP" | 326 | tristate "McSPI driver for OMAP" |
| 327 | depends on HAS_DMA | ||
| 317 | depends on ARM || ARM64 || AVR32 || HEXAGON || MIPS || SUPERH | 328 | depends on ARM || ARM64 || AVR32 || HEXAGON || MIPS || SUPERH |
| 318 | depends on ARCH_OMAP2PLUS || COMPILE_TEST | 329 | depends on ARCH_OMAP2PLUS || COMPILE_TEST |
| 319 | help | 330 | help |
| @@ -380,7 +391,7 @@ config SPI_PXA2XX | |||
| 380 | additional documentation can be found a Documentation/spi/pxa2xx. | 391 | additional documentation can be found a Documentation/spi/pxa2xx. |
| 381 | 392 | ||
| 382 | config SPI_PXA2XX_PCI | 393 | config SPI_PXA2XX_PCI |
| 383 | def_tristate SPI_PXA2XX && PCI | 394 | def_tristate SPI_PXA2XX && PCI && COMMON_CLK |
| 384 | 395 | ||
| 385 | config SPI_ROCKCHIP | 396 | config SPI_ROCKCHIP |
| 386 | tristate "Rockchip SPI controller driver" | 397 | tristate "Rockchip SPI controller driver" |
| @@ -500,7 +511,7 @@ config SPI_MXS | |||
| 500 | config SPI_TEGRA114 | 511 | config SPI_TEGRA114 |
| 501 | tristate "NVIDIA Tegra114 SPI Controller" | 512 | tristate "NVIDIA Tegra114 SPI Controller" |
| 502 | depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST | 513 | depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST |
| 503 | depends on RESET_CONTROLLER | 514 | depends on RESET_CONTROLLER && HAS_DMA |
| 504 | help | 515 | help |
| 505 | SPI driver for NVIDIA Tegra114 SPI Controller interface. This controller | 516 | SPI driver for NVIDIA Tegra114 SPI Controller interface. This controller |
| 506 | is different than the older SoCs SPI controller and also register interface | 517 | is different than the older SoCs SPI controller and also register interface |
| @@ -518,7 +529,7 @@ config SPI_TEGRA20_SFLASH | |||
| 518 | config SPI_TEGRA20_SLINK | 529 | config SPI_TEGRA20_SLINK |
| 519 | tristate "Nvidia Tegra20/Tegra30 SLINK Controller" | 530 | tristate "Nvidia Tegra20/Tegra30 SLINK Controller" |
| 520 | depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST | 531 | depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST |
| 521 | depends on RESET_CONTROLLER | 532 | depends on RESET_CONTROLLER && HAS_DMA |
| 522 | help | 533 | help |
| 523 | SPI driver for Nvidia Tegra20/Tegra30 SLINK Controller interface. | 534 | SPI driver for Nvidia Tegra20/Tegra30 SLINK Controller interface. |
| 524 | 535 | ||
| @@ -591,7 +602,7 @@ config SPI_DW_PCI | |||
| 591 | depends on SPI_DESIGNWARE && PCI | 602 | depends on SPI_DESIGNWARE && PCI |
| 592 | 603 | ||
| 593 | config SPI_DW_MID_DMA | 604 | config SPI_DW_MID_DMA |
| 594 | bool "DMA support for DW SPI controller on Intel Moorestown platform" | 605 | bool "DMA support for DW SPI controller on Intel MID platform" |
| 595 | depends on SPI_DW_PCI && INTEL_MID_DMAC | 606 | depends on SPI_DW_PCI && INTEL_MID_DMAC |
| 596 | 607 | ||
| 597 | config SPI_DW_MMIO | 608 | config SPI_DW_MMIO |
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 762da0741148..78f24ca36fcf 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile | |||
| @@ -15,6 +15,7 @@ obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o | |||
| 15 | obj-$(CONFIG_SPI_ATH79) += spi-ath79.o | 15 | obj-$(CONFIG_SPI_ATH79) += spi-ath79.o |
| 16 | obj-$(CONFIG_SPI_AU1550) += spi-au1550.o | 16 | obj-$(CONFIG_SPI_AU1550) += spi-au1550.o |
| 17 | obj-$(CONFIG_SPI_BCM2835) += spi-bcm2835.o | 17 | obj-$(CONFIG_SPI_BCM2835) += spi-bcm2835.o |
| 18 | obj-$(CONFIG_SPI_BCM53XX) += spi-bcm53xx.o | ||
| 18 | obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o | 19 | obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o |
| 19 | obj-$(CONFIG_SPI_BCM63XX_HSSPI) += spi-bcm63xx-hsspi.o | 20 | obj-$(CONFIG_SPI_BCM63XX_HSSPI) += spi-bcm63xx-hsspi.o |
| 20 | obj-$(CONFIG_SPI_BFIN5XX) += spi-bfin5xx.o | 21 | obj-$(CONFIG_SPI_BFIN5XX) += spi-bfin5xx.o |
diff --git a/drivers/spi/spi-bcm53xx.c b/drivers/spi/spi-bcm53xx.c new file mode 100644 index 000000000000..17b34cbadc03 --- /dev/null +++ b/drivers/spi/spi-bcm53xx.c | |||
| @@ -0,0 +1,299 @@ | |||
| 1 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 2 | |||
| 3 | #include <linux/kernel.h> | ||
| 4 | #include <linux/module.h> | ||
| 5 | #include <linux/slab.h> | ||
| 6 | #include <linux/delay.h> | ||
| 7 | #include <linux/bcma/bcma.h> | ||
| 8 | #include <linux/spi/spi.h> | ||
| 9 | |||
| 10 | #include "spi-bcm53xx.h" | ||
| 11 | |||
| 12 | #define BCM53XXSPI_MAX_SPI_BAUD 13500000 /* 216 MHz? */ | ||
| 13 | |||
| 14 | /* The longest observed required wait was 19 ms */ | ||
| 15 | #define BCM53XXSPI_SPE_TIMEOUT_MS 80 | ||
| 16 | |||
| 17 | struct bcm53xxspi { | ||
| 18 | struct bcma_device *core; | ||
| 19 | struct spi_master *master; | ||
| 20 | |||
| 21 | size_t read_offset; | ||
| 22 | }; | ||
| 23 | |||
| 24 | static inline u32 bcm53xxspi_read(struct bcm53xxspi *b53spi, u16 offset) | ||
| 25 | { | ||
| 26 | return bcma_read32(b53spi->core, offset); | ||
| 27 | } | ||
| 28 | |||
| 29 | static inline void bcm53xxspi_write(struct bcm53xxspi *b53spi, u16 offset, | ||
| 30 | u32 value) | ||
| 31 | { | ||
| 32 | bcma_write32(b53spi->core, offset, value); | ||
| 33 | } | ||
| 34 | |||
| 35 | static inline unsigned int bcm53xxspi_calc_timeout(size_t len) | ||
| 36 | { | ||
| 37 | /* Do some magic calculation based on length and buad. Add 10% and 1. */ | ||
| 38 | return (len * 9000 / BCM53XXSPI_MAX_SPI_BAUD * 110 / 100) + 1; | ||
| 39 | } | ||
| 40 | |||
| 41 | static int bcm53xxspi_wait(struct bcm53xxspi *b53spi, unsigned int timeout_ms) | ||
| 42 | { | ||
| 43 | unsigned long deadline; | ||
| 44 | u32 tmp; | ||
| 45 | |||
| 46 | /* SPE bit has to be 0 before we read MSPI STATUS */ | ||
| 47 | deadline = jiffies + BCM53XXSPI_SPE_TIMEOUT_MS * HZ / 1000; | ||
| 48 | do { | ||
| 49 | tmp = bcm53xxspi_read(b53spi, B53SPI_MSPI_SPCR2); | ||
| 50 | if (!(tmp & B53SPI_MSPI_SPCR2_SPE)) | ||
| 51 | break; | ||
| 52 | udelay(5); | ||
| 53 | } while (!time_after_eq(jiffies, deadline)); | ||
| 54 | |||
| 55 | if (tmp & B53SPI_MSPI_SPCR2_SPE) | ||
| 56 | goto spi_timeout; | ||
| 57 | |||
| 58 | /* Check status */ | ||
| 59 | deadline = jiffies + timeout_ms * HZ / 1000; | ||
| 60 | do { | ||
| 61 | tmp = bcm53xxspi_read(b53spi, B53SPI_MSPI_MSPI_STATUS); | ||
| 62 | if (tmp & B53SPI_MSPI_MSPI_STATUS_SPIF) { | ||
| 63 | bcm53xxspi_write(b53spi, B53SPI_MSPI_MSPI_STATUS, 0); | ||
| 64 | return 0; | ||
| 65 | } | ||
| 66 | |||
| 67 | cpu_relax(); | ||
| 68 | udelay(100); | ||
| 69 | } while (!time_after_eq(jiffies, deadline)); | ||
| 70 | |||
| 71 | spi_timeout: | ||
| 72 | bcm53xxspi_write(b53spi, B53SPI_MSPI_MSPI_STATUS, 0); | ||
| 73 | |||
| 74 | pr_err("Timeout waiting for SPI to be ready!\n"); | ||
| 75 | |||
| 76 | return -EBUSY; | ||
| 77 | } | ||
| 78 | |||
| 79 | static void bcm53xxspi_buf_write(struct bcm53xxspi *b53spi, u8 *w_buf, | ||
| 80 | size_t len, bool cont) | ||
| 81 | { | ||
| 82 | u32 tmp; | ||
| 83 | int i; | ||
| 84 | |||
| 85 | for (i = 0; i < len; i++) { | ||
| 86 | /* Transmit Register File MSB */ | ||
| 87 | bcm53xxspi_write(b53spi, B53SPI_MSPI_TXRAM + 4 * (i * 2), | ||
| 88 | (unsigned int)w_buf[i]); | ||
| 89 | } | ||
| 90 | |||
| 91 | for (i = 0; i < len; i++) { | ||
| 92 | tmp = B53SPI_CDRAM_CONT | B53SPI_CDRAM_PCS_DISABLE_ALL | | ||
| 93 | B53SPI_CDRAM_PCS_DSCK; | ||
| 94 | if (!cont && i == len - 1) | ||
| 95 | tmp &= ~B53SPI_CDRAM_CONT; | ||
| 96 | tmp &= ~0x1; | ||
| 97 | /* Command Register File */ | ||
| 98 | bcm53xxspi_write(b53spi, B53SPI_MSPI_CDRAM + 4 * i, tmp); | ||
| 99 | } | ||
| 100 | |||
| 101 | /* Set queue pointers */ | ||
| 102 | bcm53xxspi_write(b53spi, B53SPI_MSPI_NEWQP, 0); | ||
| 103 | bcm53xxspi_write(b53spi, B53SPI_MSPI_ENDQP, len - 1); | ||
| 104 | |||
| 105 | if (cont) | ||
| 106 | bcm53xxspi_write(b53spi, B53SPI_MSPI_WRITE_LOCK, 1); | ||
| 107 | |||
| 108 | /* Start SPI transfer */ | ||
| 109 | tmp = bcm53xxspi_read(b53spi, B53SPI_MSPI_SPCR2); | ||
| 110 | tmp |= B53SPI_MSPI_SPCR2_SPE; | ||
| 111 | if (cont) | ||
| 112 | tmp |= B53SPI_MSPI_SPCR2_CONT_AFTER_CMD; | ||
| 113 | bcm53xxspi_write(b53spi, B53SPI_MSPI_SPCR2, tmp); | ||
| 114 | |||
| 115 | /* Wait for SPI to finish */ | ||
| 116 | bcm53xxspi_wait(b53spi, bcm53xxspi_calc_timeout(len)); | ||
| 117 | |||
| 118 | if (!cont) | ||
| 119 | bcm53xxspi_write(b53spi, B53SPI_MSPI_WRITE_LOCK, 0); | ||
| 120 | |||
| 121 | b53spi->read_offset = len; | ||
| 122 | } | ||
| 123 | |||
| 124 | static void bcm53xxspi_buf_read(struct bcm53xxspi *b53spi, u8 *r_buf, | ||
| 125 | size_t len, bool cont) | ||
| 126 | { | ||
| 127 | u32 tmp; | ||
| 128 | int i; | ||
| 129 | |||
| 130 | for (i = 0; i < b53spi->read_offset + len; i++) { | ||
| 131 | tmp = B53SPI_CDRAM_CONT | B53SPI_CDRAM_PCS_DISABLE_ALL | | ||
| 132 | B53SPI_CDRAM_PCS_DSCK; | ||
| 133 | if (!cont && i == b53spi->read_offset + len - 1) | ||
| 134 | tmp &= ~B53SPI_CDRAM_CONT; | ||
| 135 | tmp &= ~0x1; | ||
| 136 | /* Command Register File */ | ||
| 137 | bcm53xxspi_write(b53spi, B53SPI_MSPI_CDRAM + 4 * i, tmp); | ||
| 138 | } | ||
| 139 | |||
| 140 | /* Set queue pointers */ | ||
| 141 | bcm53xxspi_write(b53spi, B53SPI_MSPI_NEWQP, 0); | ||
| 142 | bcm53xxspi_write(b53spi, B53SPI_MSPI_ENDQP, | ||
| 143 | b53spi->read_offset + len - 1); | ||
| 144 | |||
| 145 | if (cont) | ||
| 146 | bcm53xxspi_write(b53spi, B53SPI_MSPI_WRITE_LOCK, 1); | ||
| 147 | |||
| 148 | /* Start SPI transfer */ | ||
| 149 | tmp = bcm53xxspi_read(b53spi, B53SPI_MSPI_SPCR2); | ||
| 150 | tmp |= B53SPI_MSPI_SPCR2_SPE; | ||
| 151 | if (cont) | ||
| 152 | tmp |= B53SPI_MSPI_SPCR2_CONT_AFTER_CMD; | ||
| 153 | bcm53xxspi_write(b53spi, B53SPI_MSPI_SPCR2, tmp); | ||
| 154 | |||
| 155 | /* Wait for SPI to finish */ | ||
| 156 | bcm53xxspi_wait(b53spi, bcm53xxspi_calc_timeout(len)); | ||
| 157 | |||
| 158 | if (!cont) | ||
| 159 | bcm53xxspi_write(b53spi, B53SPI_MSPI_WRITE_LOCK, 0); | ||
| 160 | |||
| 161 | for (i = 0; i < len; ++i) { | ||
| 162 | int offset = b53spi->read_offset + i; | ||
| 163 | |||
| 164 | /* Data stored in the transmit register file LSB */ | ||
| 165 | r_buf[i] = (u8)bcm53xxspi_read(b53spi, B53SPI_MSPI_RXRAM + 4 * (1 + offset * 2)); | ||
| 166 | } | ||
| 167 | |||
| 168 | b53spi->read_offset = 0; | ||
| 169 | } | ||
| 170 | |||
| 171 | static int bcm53xxspi_transfer_one(struct spi_master *master, | ||
| 172 | struct spi_device *spi, | ||
| 173 | struct spi_transfer *t) | ||
| 174 | { | ||
| 175 | struct bcm53xxspi *b53spi = spi_master_get_devdata(master); | ||
| 176 | u8 *buf; | ||
| 177 | size_t left; | ||
| 178 | |||
| 179 | if (t->tx_buf) { | ||
| 180 | buf = (u8 *)t->tx_buf; | ||
| 181 | left = t->len; | ||
| 182 | while (left) { | ||
| 183 | size_t to_write = min_t(size_t, 16, left); | ||
| 184 | bool cont = left - to_write > 0; | ||
| 185 | |||
| 186 | bcm53xxspi_buf_write(b53spi, buf, to_write, cont); | ||
| 187 | left -= to_write; | ||
| 188 | buf += to_write; | ||
| 189 | } | ||
| 190 | } | ||
| 191 | |||
| 192 | if (t->rx_buf) { | ||
| 193 | buf = (u8 *)t->rx_buf; | ||
| 194 | left = t->len; | ||
| 195 | while (left) { | ||
| 196 | size_t to_read = min_t(size_t, 16 - b53spi->read_offset, | ||
| 197 | left); | ||
| 198 | bool cont = left - to_read > 0; | ||
| 199 | |||
| 200 | bcm53xxspi_buf_read(b53spi, buf, to_read, cont); | ||
| 201 | left -= to_read; | ||
| 202 | buf += to_read; | ||
| 203 | } | ||
| 204 | } | ||
| 205 | |||
| 206 | return 0; | ||
| 207 | } | ||
| 208 | |||
| 209 | /************************************************** | ||
| 210 | * BCMA | ||
| 211 | **************************************************/ | ||
| 212 | |||
| 213 | static struct spi_board_info bcm53xx_info = { | ||
| 214 | .modalias = "bcm53xxspiflash", | ||
| 215 | }; | ||
| 216 | |||
| 217 | static const struct bcma_device_id bcm53xxspi_bcma_tbl[] = { | ||
| 218 | BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_QSPI, BCMA_ANY_REV, BCMA_ANY_CLASS), | ||
| 219 | BCMA_CORETABLE_END | ||
| 220 | }; | ||
| 221 | MODULE_DEVICE_TABLE(bcma, bcm53xxspi_bcma_tbl); | ||
| 222 | |||
| 223 | static int bcm53xxspi_bcma_probe(struct bcma_device *core) | ||
| 224 | { | ||
| 225 | struct bcm53xxspi *b53spi; | ||
| 226 | struct spi_master *master; | ||
| 227 | int err; | ||
| 228 | |||
| 229 | if (core->bus->drv_cc.core->id.rev != 42) { | ||
| 230 | pr_err("SPI on SoC with unsupported ChipCommon rev\n"); | ||
| 231 | return -ENOTSUPP; | ||
| 232 | } | ||
| 233 | |||
| 234 | master = spi_alloc_master(&core->dev, sizeof(*b53spi)); | ||
| 235 | if (!master) | ||
| 236 | return -ENOMEM; | ||
| 237 | |||
| 238 | b53spi = spi_master_get_devdata(master); | ||
| 239 | b53spi->master = master; | ||
| 240 | b53spi->core = core; | ||
| 241 | |||
| 242 | master->transfer_one = bcm53xxspi_transfer_one; | ||
| 243 | |||
| 244 | bcma_set_drvdata(core, b53spi); | ||
| 245 | |||
| 246 | err = devm_spi_register_master(&core->dev, master); | ||
| 247 | if (err) { | ||
| 248 | spi_master_put(master); | ||
| 249 | bcma_set_drvdata(core, NULL); | ||
| 250 | goto out; | ||
| 251 | } | ||
| 252 | |||
| 253 | /* Broadcom SoCs (at least with the CC rev 42) use SPI for flash only */ | ||
| 254 | spi_new_device(master, &bcm53xx_info); | ||
| 255 | |||
| 256 | out: | ||
| 257 | return err; | ||
| 258 | } | ||
| 259 | |||
| 260 | static void bcm53xxspi_bcma_remove(struct bcma_device *core) | ||
| 261 | { | ||
| 262 | struct bcm53xxspi *b53spi = bcma_get_drvdata(core); | ||
| 263 | |||
| 264 | spi_unregister_master(b53spi->master); | ||
| 265 | } | ||
| 266 | |||
| 267 | static struct bcma_driver bcm53xxspi_bcma_driver = { | ||
| 268 | .name = KBUILD_MODNAME, | ||
| 269 | .id_table = bcm53xxspi_bcma_tbl, | ||
| 270 | .probe = bcm53xxspi_bcma_probe, | ||
| 271 | .remove = bcm53xxspi_bcma_remove, | ||
| 272 | }; | ||
| 273 | |||
| 274 | /************************************************** | ||
| 275 | * Init & exit | ||
| 276 | **************************************************/ | ||
| 277 | |||
| 278 | static int __init bcm53xxspi_module_init(void) | ||
| 279 | { | ||
| 280 | int err = 0; | ||
| 281 | |||
| 282 | err = bcma_driver_register(&bcm53xxspi_bcma_driver); | ||
| 283 | if (err) | ||
| 284 | pr_err("Failed to register bcma driver: %d\n", err); | ||
| 285 | |||
| 286 | return err; | ||
| 287 | } | ||
| 288 | |||
| 289 | static void __exit bcm53xxspi_module_exit(void) | ||
| 290 | { | ||
| 291 | bcma_driver_unregister(&bcm53xxspi_bcma_driver); | ||
| 292 | } | ||
| 293 | |||
| 294 | module_init(bcm53xxspi_module_init); | ||
| 295 | module_exit(bcm53xxspi_module_exit); | ||
| 296 | |||
| 297 | MODULE_DESCRIPTION("Broadcom BCM53xx SPI Controller driver"); | ||
| 298 | MODULE_AUTHOR("Rafał Miłecki <zajec5@gmail.com>"); | ||
| 299 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/spi/spi-bcm53xx.h b/drivers/spi/spi-bcm53xx.h new file mode 100644 index 000000000000..73575dfe6916 --- /dev/null +++ b/drivers/spi/spi-bcm53xx.h | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | #ifndef SPI_BCM53XX_H | ||
| 2 | #define SPI_BCM53XX_H | ||
| 3 | |||
| 4 | #define B53SPI_BSPI_REVISION_ID 0x000 | ||
| 5 | #define B53SPI_BSPI_SCRATCH 0x004 | ||
| 6 | #define B53SPI_BSPI_MAST_N_BOOT_CTRL 0x008 | ||
| 7 | #define B53SPI_BSPI_BUSY_STATUS 0x00c | ||
| 8 | #define B53SPI_BSPI_INTR_STATUS 0x010 | ||
| 9 | #define B53SPI_BSPI_B0_STATUS 0x014 | ||
| 10 | #define B53SPI_BSPI_B0_CTRL 0x018 | ||
| 11 | #define B53SPI_BSPI_B1_STATUS 0x01c | ||
| 12 | #define B53SPI_BSPI_B1_CTRL 0x020 | ||
| 13 | #define B53SPI_BSPI_STRAP_OVERRIDE_CTRL 0x024 | ||
| 14 | #define B53SPI_BSPI_FLEX_MODE_ENABLE 0x028 | ||
| 15 | #define B53SPI_BSPI_BITS_PER_CYCLE 0x02c | ||
| 16 | #define B53SPI_BSPI_BITS_PER_PHASE 0x030 | ||
| 17 | #define B53SPI_BSPI_CMD_AND_MODE_BYTE 0x034 | ||
| 18 | #define B53SPI_BSPI_BSPI_FLASH_UPPER_ADDR_BYTE 0x038 | ||
| 19 | #define B53SPI_BSPI_BSPI_XOR_VALUE 0x03c | ||
| 20 | #define B53SPI_BSPI_BSPI_XOR_ENABLE 0x040 | ||
| 21 | #define B53SPI_BSPI_BSPI_PIO_MODE_ENABLE 0x044 | ||
| 22 | #define B53SPI_BSPI_BSPI_PIO_IODIR 0x048 | ||
| 23 | #define B53SPI_BSPI_BSPI_PIO_DATA 0x04c | ||
| 24 | |||
| 25 | /* RAF */ | ||
| 26 | #define B53SPI_RAF_START_ADDR 0x100 | ||
| 27 | #define B53SPI_RAF_NUM_WORDS 0x104 | ||
| 28 | #define B53SPI_RAF_CTRL 0x108 | ||
| 29 | #define B53SPI_RAF_FULLNESS 0x10c | ||
| 30 | #define B53SPI_RAF_WATERMARK 0x110 | ||
| 31 | #define B53SPI_RAF_STATUS 0x114 | ||
| 32 | #define B53SPI_RAF_READ_DATA 0x118 | ||
| 33 | #define B53SPI_RAF_WORD_CNT 0x11c | ||
| 34 | #define B53SPI_RAF_CURR_ADDR 0x120 | ||
| 35 | |||
| 36 | /* MSPI */ | ||
| 37 | #define B53SPI_MSPI_SPCR0_LSB 0x200 | ||
| 38 | #define B53SPI_MSPI_SPCR0_MSB 0x204 | ||
| 39 | #define B53SPI_MSPI_SPCR1_LSB 0x208 | ||
| 40 | #define B53SPI_MSPI_SPCR1_MSB 0x20c | ||
| 41 | #define B53SPI_MSPI_NEWQP 0x210 | ||
| 42 | #define B53SPI_MSPI_ENDQP 0x214 | ||
| 43 | #define B53SPI_MSPI_SPCR2 0x218 | ||
| 44 | #define B53SPI_MSPI_SPCR2_SPE 0x00000040 | ||
| 45 | #define B53SPI_MSPI_SPCR2_CONT_AFTER_CMD 0x00000080 | ||
| 46 | #define B53SPI_MSPI_MSPI_STATUS 0x220 | ||
| 47 | #define B53SPI_MSPI_MSPI_STATUS_SPIF 0x00000001 | ||
| 48 | #define B53SPI_MSPI_CPTQP 0x224 | ||
| 49 | #define B53SPI_MSPI_TXRAM 0x240 /* 32 registers, up to 0x2b8 */ | ||
| 50 | #define B53SPI_MSPI_RXRAM 0x2c0 /* 32 registers, up to 0x33c */ | ||
| 51 | #define B53SPI_MSPI_CDRAM 0x340 /* 16 registers, up to 0x37c */ | ||
| 52 | #define B53SPI_CDRAM_PCS_PCS0 0x00000001 | ||
| 53 | #define B53SPI_CDRAM_PCS_PCS1 0x00000002 | ||
| 54 | #define B53SPI_CDRAM_PCS_PCS2 0x00000004 | ||
| 55 | #define B53SPI_CDRAM_PCS_PCS3 0x00000008 | ||
| 56 | #define B53SPI_CDRAM_PCS_DISABLE_ALL 0x0000000f | ||
| 57 | #define B53SPI_CDRAM_PCS_DSCK 0x00000010 | ||
| 58 | #define B53SPI_CDRAM_BITSE 0x00000040 | ||
| 59 | #define B53SPI_CDRAM_CONT 0x00000080 | ||
| 60 | #define B53SPI_MSPI_WRITE_LOCK 0x380 | ||
| 61 | #define B53SPI_MSPI_DISABLE_FLUSH_GEN 0x384 | ||
| 62 | |||
| 63 | /* Interrupt */ | ||
| 64 | #define B53SPI_INTR_RAF_LR_FULLNESS_REACHED 0x3a0 | ||
| 65 | #define B53SPI_INTR_RAF_LR_TRUNCATED 0x3a4 | ||
| 66 | #define B53SPI_INTR_RAF_LR_IMPATIENT 0x3a8 | ||
| 67 | #define B53SPI_INTR_RAF_LR_SESSION_DONE 0x3ac | ||
| 68 | #define B53SPI_INTR_RAF_LR_OVERREAD 0x3b0 | ||
| 69 | #define B53SPI_INTR_MSPI_DONE 0x3b4 | ||
| 70 | #define B53SPI_INTR_MSPI_HALT_SET_TRANSACTION_DONE 0x3b8 | ||
| 71 | |||
| 72 | #endif /* SPI_BCM53XX_H */ | ||
diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c index 562ff83debd9..7b811e38c7ad 100644 --- a/drivers/spi/spi-cadence.c +++ b/drivers/spi/spi-cadence.c | |||
| @@ -677,7 +677,6 @@ static struct platform_driver cdns_spi_driver = { | |||
| 677 | .remove = cdns_spi_remove, | 677 | .remove = cdns_spi_remove, |
| 678 | .driver = { | 678 | .driver = { |
| 679 | .name = CDNS_SPI_NAME, | 679 | .name = CDNS_SPI_NAME, |
| 680 | .owner = THIS_MODULE, | ||
| 681 | .of_match_table = cdns_spi_of_match, | 680 | .of_match_table = cdns_spi_of_match, |
| 682 | .pm = &cdns_spi_dev_pm_ops, | 681 | .pm = &cdns_spi_dev_pm_ops, |
| 683 | }, | 682 | }, |
diff --git a/drivers/spi/spi-clps711x.c b/drivers/spi/spi-clps711x.c index ce538dad526b..181cf2262006 100644 --- a/drivers/spi/spi-clps711x.c +++ b/drivers/spi/spi-clps711x.c | |||
| @@ -30,7 +30,6 @@ | |||
| 30 | struct spi_clps711x_data { | 30 | struct spi_clps711x_data { |
| 31 | void __iomem *syncio; | 31 | void __iomem *syncio; |
| 32 | struct regmap *syscon; | 32 | struct regmap *syscon; |
| 33 | struct regmap *syscon1; | ||
| 34 | struct clk *spi_clk; | 33 | struct clk *spi_clk; |
| 35 | 34 | ||
| 36 | u8 *tx_buf; | 35 | u8 *tx_buf; |
| @@ -47,27 +46,6 @@ static int spi_clps711x_setup(struct spi_device *spi) | |||
| 47 | return 0; | 46 | return 0; |
| 48 | } | 47 | } |
| 49 | 48 | ||
| 50 | static void spi_clps711x_setup_xfer(struct spi_device *spi, | ||
| 51 | struct spi_transfer *xfer) | ||
| 52 | { | ||
| 53 | struct spi_master *master = spi->master; | ||
| 54 | struct spi_clps711x_data *hw = spi_master_get_devdata(master); | ||
| 55 | |||
| 56 | /* Setup SPI frequency divider */ | ||
| 57 | if (xfer->speed_hz >= master->max_speed_hz) | ||
| 58 | regmap_update_bits(hw->syscon1, SYSCON_OFFSET, | ||
| 59 | SYSCON1_ADCKSEL_MASK, SYSCON1_ADCKSEL(3)); | ||
| 60 | else if (xfer->speed_hz >= (master->max_speed_hz / 2)) | ||
| 61 | regmap_update_bits(hw->syscon1, SYSCON_OFFSET, | ||
| 62 | SYSCON1_ADCKSEL_MASK, SYSCON1_ADCKSEL(2)); | ||
| 63 | else if (xfer->speed_hz >= (master->max_speed_hz / 8)) | ||
| 64 | regmap_update_bits(hw->syscon1, SYSCON_OFFSET, | ||
| 65 | SYSCON1_ADCKSEL_MASK, SYSCON1_ADCKSEL(1)); | ||
| 66 | else | ||
| 67 | regmap_update_bits(hw->syscon1, SYSCON_OFFSET, | ||
| 68 | SYSCON1_ADCKSEL_MASK, SYSCON1_ADCKSEL(0)); | ||
| 69 | } | ||
| 70 | |||
| 71 | static int spi_clps711x_prepare_message(struct spi_master *master, | 49 | static int spi_clps711x_prepare_message(struct spi_master *master, |
| 72 | struct spi_message *msg) | 50 | struct spi_message *msg) |
| 73 | { | 51 | { |
| @@ -87,7 +65,7 @@ static int spi_clps711x_transfer_one(struct spi_master *master, | |||
| 87 | struct spi_clps711x_data *hw = spi_master_get_devdata(master); | 65 | struct spi_clps711x_data *hw = spi_master_get_devdata(master); |
| 88 | u8 data; | 66 | u8 data; |
| 89 | 67 | ||
| 90 | spi_clps711x_setup_xfer(spi, xfer); | 68 | clk_set_rate(hw->spi_clk, xfer->speed_hz ? : spi->max_speed_hz); |
| 91 | 69 | ||
| 92 | hw->len = xfer->len; | 70 | hw->len = xfer->len; |
| 93 | hw->bpw = xfer->bits_per_word; | 71 | hw->bpw = xfer->bits_per_word; |
| @@ -176,13 +154,11 @@ static int spi_clps711x_probe(struct platform_device *pdev) | |||
| 176 | } | 154 | } |
| 177 | } | 155 | } |
| 178 | 156 | ||
| 179 | hw->spi_clk = devm_clk_get(&pdev->dev, "spi"); | 157 | hw->spi_clk = devm_clk_get(&pdev->dev, NULL); |
| 180 | if (IS_ERR(hw->spi_clk)) { | 158 | if (IS_ERR(hw->spi_clk)) { |
| 181 | dev_err(&pdev->dev, "Can't get clocks\n"); | ||
| 182 | ret = PTR_ERR(hw->spi_clk); | 159 | ret = PTR_ERR(hw->spi_clk); |
| 183 | goto err_out; | 160 | goto err_out; |
| 184 | } | 161 | } |
| 185 | master->max_speed_hz = clk_get_rate(hw->spi_clk); | ||
| 186 | 162 | ||
| 187 | hw->syscon = syscon_regmap_lookup_by_pdevname("syscon.3"); | 163 | hw->syscon = syscon_regmap_lookup_by_pdevname("syscon.3"); |
| 188 | if (IS_ERR(hw->syscon)) { | 164 | if (IS_ERR(hw->syscon)) { |
| @@ -190,12 +166,6 @@ static int spi_clps711x_probe(struct platform_device *pdev) | |||
| 190 | goto err_out; | 166 | goto err_out; |
| 191 | } | 167 | } |
| 192 | 168 | ||
| 193 | hw->syscon1 = syscon_regmap_lookup_by_pdevname("syscon.1"); | ||
| 194 | if (IS_ERR(hw->syscon1)) { | ||
| 195 | ret = PTR_ERR(hw->syscon1); | ||
| 196 | goto err_out; | ||
| 197 | } | ||
| 198 | |||
| 199 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 169 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 200 | hw->syncio = devm_ioremap_resource(&pdev->dev, res); | 170 | hw->syncio = devm_ioremap_resource(&pdev->dev, res); |
| 201 | if (IS_ERR(hw->syncio)) { | 171 | if (IS_ERR(hw->syncio)) { |
diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 134fb6eb7b19..63700ab7bd9f 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c | |||
| @@ -65,6 +65,7 @@ | |||
| 65 | 65 | ||
| 66 | /* SPIDAT1 (upper 16 bit defines) */ | 66 | /* SPIDAT1 (upper 16 bit defines) */ |
| 67 | #define SPIDAT1_CSHOLD_MASK BIT(12) | 67 | #define SPIDAT1_CSHOLD_MASK BIT(12) |
| 68 | #define SPIDAT1_WDEL BIT(10) | ||
| 68 | 69 | ||
| 69 | /* SPIGCR1 */ | 70 | /* SPIGCR1 */ |
| 70 | #define SPIGCR1_CLKMOD_MASK BIT(1) | 71 | #define SPIGCR1_CLKMOD_MASK BIT(1) |
| @@ -167,8 +168,10 @@ static void davinci_spi_rx_buf_u16(u32 data, struct davinci_spi *dspi) | |||
| 167 | static u32 davinci_spi_tx_buf_u8(struct davinci_spi *dspi) | 168 | static u32 davinci_spi_tx_buf_u8(struct davinci_spi *dspi) |
| 168 | { | 169 | { |
| 169 | u32 data = 0; | 170 | u32 data = 0; |
| 171 | |||
| 170 | if (dspi->tx) { | 172 | if (dspi->tx) { |
| 171 | const u8 *tx = dspi->tx; | 173 | const u8 *tx = dspi->tx; |
| 174 | |||
| 172 | data = *tx++; | 175 | data = *tx++; |
| 173 | dspi->tx = tx; | 176 | dspi->tx = tx; |
| 174 | } | 177 | } |
| @@ -178,8 +181,10 @@ static u32 davinci_spi_tx_buf_u8(struct davinci_spi *dspi) | |||
| 178 | static u32 davinci_spi_tx_buf_u16(struct davinci_spi *dspi) | 181 | static u32 davinci_spi_tx_buf_u16(struct davinci_spi *dspi) |
| 179 | { | 182 | { |
| 180 | u32 data = 0; | 183 | u32 data = 0; |
| 184 | |||
| 181 | if (dspi->tx) { | 185 | if (dspi->tx) { |
| 182 | const u16 *tx = dspi->tx; | 186 | const u16 *tx = dspi->tx; |
| 187 | |||
| 183 | data = *tx++; | 188 | data = *tx++; |
| 184 | dspi->tx = tx; | 189 | dspi->tx = tx; |
| 185 | } | 190 | } |
| @@ -209,6 +214,7 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value) | |||
| 209 | { | 214 | { |
| 210 | struct davinci_spi *dspi; | 215 | struct davinci_spi *dspi; |
| 211 | struct davinci_spi_platform_data *pdata; | 216 | struct davinci_spi_platform_data *pdata; |
| 217 | struct davinci_spi_config *spicfg = spi->controller_data; | ||
| 212 | u8 chip_sel = spi->chip_select; | 218 | u8 chip_sel = spi->chip_select; |
| 213 | u16 spidat1 = CS_DEFAULT; | 219 | u16 spidat1 = CS_DEFAULT; |
| 214 | bool gpio_chipsel = false; | 220 | bool gpio_chipsel = false; |
| @@ -223,6 +229,10 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value) | |||
| 223 | gpio = spi->cs_gpio; | 229 | gpio = spi->cs_gpio; |
| 224 | } | 230 | } |
| 225 | 231 | ||
| 232 | /* program delay transfers if tx_delay is non zero */ | ||
| 233 | if (spicfg->wdelay) | ||
| 234 | spidat1 |= SPIDAT1_WDEL; | ||
| 235 | |||
| 226 | /* | 236 | /* |
| 227 | * Board specific chip select logic decides the polarity and cs | 237 | * Board specific chip select logic decides the polarity and cs |
| 228 | * line for the controller | 238 | * line for the controller |
| @@ -237,9 +247,9 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value) | |||
| 237 | spidat1 |= SPIDAT1_CSHOLD_MASK; | 247 | spidat1 |= SPIDAT1_CSHOLD_MASK; |
| 238 | spidat1 &= ~(0x1 << chip_sel); | 248 | spidat1 &= ~(0x1 << chip_sel); |
| 239 | } | 249 | } |
| 240 | |||
| 241 | iowrite16(spidat1, dspi->base + SPIDAT1 + 2); | ||
| 242 | } | 250 | } |
| 251 | |||
| 252 | iowrite16(spidat1, dspi->base + SPIDAT1 + 2); | ||
| 243 | } | 253 | } |
| 244 | 254 | ||
| 245 | /** | 255 | /** |
| @@ -285,7 +295,7 @@ static int davinci_spi_setup_transfer(struct spi_device *spi, | |||
| 285 | int prescale; | 295 | int prescale; |
| 286 | 296 | ||
| 287 | dspi = spi_master_get_devdata(spi->master); | 297 | dspi = spi_master_get_devdata(spi->master); |
| 288 | spicfg = (struct davinci_spi_config *)spi->controller_data; | 298 | spicfg = spi->controller_data; |
| 289 | if (!spicfg) | 299 | if (!spicfg) |
| 290 | spicfg = &davinci_spi_default_cfg; | 300 | spicfg = &davinci_spi_default_cfg; |
| 291 | 301 | ||
| @@ -333,6 +343,14 @@ static int davinci_spi_setup_transfer(struct spi_device *spi, | |||
| 333 | spifmt |= SPIFMT_PHASE_MASK; | 343 | spifmt |= SPIFMT_PHASE_MASK; |
| 334 | 344 | ||
| 335 | /* | 345 | /* |
| 346 | * Assume wdelay is used only on SPI peripherals that has this field | ||
| 347 | * in SPIFMTn register and when it's configured from board file or DT. | ||
| 348 | */ | ||
| 349 | if (spicfg->wdelay) | ||
| 350 | spifmt |= ((spicfg->wdelay << SPIFMT_WDELAY_SHIFT) | ||
| 351 | & SPIFMT_WDELAY_MASK); | ||
| 352 | |||
| 353 | /* | ||
| 336 | * Version 1 hardware supports two basic SPI modes: | 354 | * Version 1 hardware supports two basic SPI modes: |
| 337 | * - Standard SPI mode uses 4 pins, with chipselect | 355 | * - Standard SPI mode uses 4 pins, with chipselect |
| 338 | * - 3 pin SPI is a 4 pin variant without CS (SPI_NO_CS) | 356 | * - 3 pin SPI is a 4 pin variant without CS (SPI_NO_CS) |
| @@ -349,9 +367,6 @@ static int davinci_spi_setup_transfer(struct spi_device *spi, | |||
| 349 | 367 | ||
| 350 | u32 delay = 0; | 368 | u32 delay = 0; |
| 351 | 369 | ||
| 352 | spifmt |= ((spicfg->wdelay << SPIFMT_WDELAY_SHIFT) | ||
| 353 | & SPIFMT_WDELAY_MASK); | ||
| 354 | |||
| 355 | if (spicfg->odd_parity) | 370 | if (spicfg->odd_parity) |
| 356 | spifmt |= SPIFMT_ODD_PARITY_MASK; | 371 | spifmt |= SPIFMT_ODD_PARITY_MASK; |
| 357 | 372 | ||
| @@ -383,6 +398,26 @@ static int davinci_spi_setup_transfer(struct spi_device *spi, | |||
| 383 | return 0; | 398 | return 0; |
| 384 | } | 399 | } |
| 385 | 400 | ||
| 401 | static int davinci_spi_of_setup(struct spi_device *spi) | ||
| 402 | { | ||
| 403 | struct davinci_spi_config *spicfg = spi->controller_data; | ||
| 404 | struct device_node *np = spi->dev.of_node; | ||
| 405 | u32 prop; | ||
| 406 | |||
| 407 | if (spicfg == NULL && np) { | ||
| 408 | spicfg = kzalloc(sizeof(*spicfg), GFP_KERNEL); | ||
| 409 | if (!spicfg) | ||
| 410 | return -ENOMEM; | ||
| 411 | *spicfg = davinci_spi_default_cfg; | ||
| 412 | /* override with dt configured values */ | ||
| 413 | if (!of_property_read_u32(np, "ti,spi-wdelay", &prop)) | ||
| 414 | spicfg->wdelay = (u8)prop; | ||
| 415 | spi->controller_data = spicfg; | ||
| 416 | } | ||
| 417 | |||
| 418 | return 0; | ||
| 419 | } | ||
| 420 | |||
| 386 | /** | 421 | /** |
| 387 | * davinci_spi_setup - This functions will set default transfer method | 422 | * davinci_spi_setup - This functions will set default transfer method |
| 388 | * @spi: spi device on which data transfer to be done | 423 | * @spi: spi device on which data transfer to be done |
| @@ -433,7 +468,16 @@ static int davinci_spi_setup(struct spi_device *spi) | |||
| 433 | else | 468 | else |
| 434 | clear_io_bits(dspi->base + SPIGCR1, SPIGCR1_LOOPBACK_MASK); | 469 | clear_io_bits(dspi->base + SPIGCR1, SPIGCR1_LOOPBACK_MASK); |
| 435 | 470 | ||
| 436 | return retval; | 471 | return davinci_spi_of_setup(spi); |
| 472 | } | ||
| 473 | |||
| 474 | static void davinci_spi_cleanup(struct spi_device *spi) | ||
| 475 | { | ||
| 476 | struct davinci_spi_config *spicfg = spi->controller_data; | ||
| 477 | |||
| 478 | spi->controller_data = NULL; | ||
| 479 | if (spi->dev.of_node) | ||
| 480 | kfree(spicfg); | ||
| 437 | } | 481 | } |
| 438 | 482 | ||
| 439 | static int davinci_spi_check_error(struct davinci_spi *dspi, int int_status) | 483 | static int davinci_spi_check_error(struct davinci_spi *dspi, int int_status) |
| @@ -947,6 +991,7 @@ static int davinci_spi_probe(struct platform_device *pdev) | |||
| 947 | master->num_chipselect = pdata->num_chipselect; | 991 | master->num_chipselect = pdata->num_chipselect; |
| 948 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 16); | 992 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 16); |
| 949 | master->setup = davinci_spi_setup; | 993 | master->setup = davinci_spi_setup; |
| 994 | master->cleanup = davinci_spi_cleanup; | ||
| 950 | 995 | ||
| 951 | dspi->bitbang.chipselect = davinci_spi_chipselect; | 996 | dspi->bitbang.chipselect = davinci_spi_chipselect; |
| 952 | dspi->bitbang.setup_transfer = davinci_spi_setup_transfer; | 997 | dspi->bitbang.setup_transfer = davinci_spi_setup_transfer; |
| @@ -996,8 +1041,8 @@ static int davinci_spi_probe(struct platform_device *pdev) | |||
| 996 | goto free_clk; | 1041 | goto free_clk; |
| 997 | 1042 | ||
| 998 | dev_info(&pdev->dev, "DMA: supported\n"); | 1043 | dev_info(&pdev->dev, "DMA: supported\n"); |
| 999 | dev_info(&pdev->dev, "DMA: RX channel: %pa, TX channel: %pa, " | 1044 | dev_info(&pdev->dev, "DMA: RX channel: %pa, TX channel: %pa, event queue: %d\n", |
| 1000 | "event queue: %d\n", &dma_rx_chan, &dma_tx_chan, | 1045 | &dma_rx_chan, &dma_tx_chan, |
| 1001 | pdata->dma_event_q); | 1046 | pdata->dma_event_q); |
| 1002 | } | 1047 | } |
| 1003 | 1048 | ||
diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index 6d207afec8cb..46c6d58e1fda 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Special handling for DW core on Intel MID platform | 2 | * Special handling for DW core on Intel MID platform |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2009, Intel Corporation. | 4 | * Copyright (c) 2009, 2014 Intel Corporation. |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
| 7 | * under the terms and conditions of the GNU General Public License, | 7 | * under the terms and conditions of the GNU General Public License, |
| @@ -11,10 +11,6 @@ | |||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
| 13 | * more details. | 13 | * more details. |
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License along | ||
| 16 | * with this program; if not, write to the Free Software Foundation, | ||
| 17 | * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 18 | */ | 14 | */ |
| 19 | 15 | ||
| 20 | #include <linux/dma-mapping.h> | 16 | #include <linux/dma-mapping.h> |
| @@ -39,22 +35,25 @@ static bool mid_spi_dma_chan_filter(struct dma_chan *chan, void *param) | |||
| 39 | { | 35 | { |
| 40 | struct dw_spi *dws = param; | 36 | struct dw_spi *dws = param; |
| 41 | 37 | ||
| 42 | return dws->dmac && (&dws->dmac->dev == chan->device->dev); | 38 | return dws->dma_dev == chan->device->dev; |
| 43 | } | 39 | } |
| 44 | 40 | ||
| 45 | static int mid_spi_dma_init(struct dw_spi *dws) | 41 | static int mid_spi_dma_init(struct dw_spi *dws) |
| 46 | { | 42 | { |
| 47 | struct mid_dma *dw_dma = dws->dma_priv; | 43 | struct mid_dma *dw_dma = dws->dma_priv; |
| 44 | struct pci_dev *dma_dev; | ||
| 48 | struct intel_mid_dma_slave *rxs, *txs; | 45 | struct intel_mid_dma_slave *rxs, *txs; |
| 49 | dma_cap_mask_t mask; | 46 | dma_cap_mask_t mask; |
| 50 | 47 | ||
| 51 | /* | 48 | /* |
| 52 | * Get pci device for DMA controller, currently it could only | 49 | * Get pci device for DMA controller, currently it could only |
| 53 | * be the DMA controller of either Moorestown or Medfield | 50 | * be the DMA controller of Medfield |
| 54 | */ | 51 | */ |
| 55 | dws->dmac = pci_get_device(PCI_VENDOR_ID_INTEL, 0x0813, NULL); | 52 | dma_dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x0827, NULL); |
| 56 | if (!dws->dmac) | 53 | if (!dma_dev) |
| 57 | dws->dmac = pci_get_device(PCI_VENDOR_ID_INTEL, 0x0827, NULL); | 54 | return -ENODEV; |
| 55 | |||
| 56 | dws->dma_dev = &dma_dev->dev; | ||
| 58 | 57 | ||
| 59 | dma_cap_zero(mask); | 58 | dma_cap_zero(mask); |
| 60 | dma_cap_set(DMA_SLAVE, mask); | 59 | dma_cap_set(DMA_SLAVE, mask); |
| @@ -83,13 +82,18 @@ static int mid_spi_dma_init(struct dw_spi *dws) | |||
| 83 | free_rxchan: | 82 | free_rxchan: |
| 84 | dma_release_channel(dws->rxchan); | 83 | dma_release_channel(dws->rxchan); |
| 85 | err_exit: | 84 | err_exit: |
| 86 | return -1; | 85 | return -EBUSY; |
| 87 | |||
| 88 | } | 86 | } |
| 89 | 87 | ||
| 90 | static void mid_spi_dma_exit(struct dw_spi *dws) | 88 | static void mid_spi_dma_exit(struct dw_spi *dws) |
| 91 | { | 89 | { |
| 90 | if (!dws->dma_inited) | ||
| 91 | return; | ||
| 92 | |||
| 93 | dmaengine_terminate_all(dws->txchan); | ||
| 92 | dma_release_channel(dws->txchan); | 94 | dma_release_channel(dws->txchan); |
| 95 | |||
| 96 | dmaengine_terminate_all(dws->rxchan); | ||
| 93 | dma_release_channel(dws->rxchan); | 97 | dma_release_channel(dws->rxchan); |
| 94 | } | 98 | } |
| 95 | 99 | ||
| @@ -109,8 +113,7 @@ static void dw_spi_dma_done(void *arg) | |||
| 109 | 113 | ||
| 110 | static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change) | 114 | static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change) |
| 111 | { | 115 | { |
| 112 | struct dma_async_tx_descriptor *txdesc = NULL, *rxdesc = NULL; | 116 | struct dma_async_tx_descriptor *txdesc, *rxdesc; |
| 113 | struct dma_chan *txchan, *rxchan; | ||
| 114 | struct dma_slave_config txconf, rxconf; | 117 | struct dma_slave_config txconf, rxconf; |
| 115 | u16 dma_ctrl = 0; | 118 | u16 dma_ctrl = 0; |
| 116 | 119 | ||
| @@ -120,37 +123,34 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change) | |||
| 120 | dw_writew(dws, DW_SPI_DMARDLR, 0xf); | 123 | dw_writew(dws, DW_SPI_DMARDLR, 0xf); |
| 121 | dw_writew(dws, DW_SPI_DMATDLR, 0x10); | 124 | dw_writew(dws, DW_SPI_DMATDLR, 0x10); |
| 122 | if (dws->tx_dma) | 125 | if (dws->tx_dma) |
| 123 | dma_ctrl |= 0x2; | 126 | dma_ctrl |= SPI_DMA_TDMAE; |
| 124 | if (dws->rx_dma) | 127 | if (dws->rx_dma) |
| 125 | dma_ctrl |= 0x1; | 128 | dma_ctrl |= SPI_DMA_RDMAE; |
| 126 | dw_writew(dws, DW_SPI_DMACR, dma_ctrl); | 129 | dw_writew(dws, DW_SPI_DMACR, dma_ctrl); |
| 127 | spi_enable_chip(dws, 1); | 130 | spi_enable_chip(dws, 1); |
| 128 | } | 131 | } |
| 129 | 132 | ||
| 130 | dws->dma_chan_done = 0; | 133 | dws->dma_chan_done = 0; |
| 131 | txchan = dws->txchan; | ||
| 132 | rxchan = dws->rxchan; | ||
| 133 | 134 | ||
| 134 | /* 2. Prepare the TX dma transfer */ | 135 | /* 2. Prepare the TX dma transfer */ |
| 135 | txconf.direction = DMA_MEM_TO_DEV; | 136 | txconf.direction = DMA_MEM_TO_DEV; |
| 136 | txconf.dst_addr = dws->dma_addr; | 137 | txconf.dst_addr = dws->dma_addr; |
| 137 | txconf.dst_maxburst = LNW_DMA_MSIZE_16; | 138 | txconf.dst_maxburst = LNW_DMA_MSIZE_16; |
| 138 | txconf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | 139 | txconf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
| 139 | txconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | 140 | txconf.dst_addr_width = dws->dma_width; |
| 140 | txconf.device_fc = false; | 141 | txconf.device_fc = false; |
| 141 | 142 | ||
| 142 | txchan->device->device_control(txchan, DMA_SLAVE_CONFIG, | 143 | dmaengine_slave_config(dws->txchan, &txconf); |
| 143 | (unsigned long) &txconf); | ||
| 144 | 144 | ||
| 145 | memset(&dws->tx_sgl, 0, sizeof(dws->tx_sgl)); | 145 | memset(&dws->tx_sgl, 0, sizeof(dws->tx_sgl)); |
| 146 | dws->tx_sgl.dma_address = dws->tx_dma; | 146 | dws->tx_sgl.dma_address = dws->tx_dma; |
| 147 | dws->tx_sgl.length = dws->len; | 147 | dws->tx_sgl.length = dws->len; |
| 148 | 148 | ||
| 149 | txdesc = dmaengine_prep_slave_sg(txchan, | 149 | txdesc = dmaengine_prep_slave_sg(dws->txchan, |
| 150 | &dws->tx_sgl, | 150 | &dws->tx_sgl, |
| 151 | 1, | 151 | 1, |
| 152 | DMA_MEM_TO_DEV, | 152 | DMA_MEM_TO_DEV, |
| 153 | DMA_PREP_INTERRUPT); | 153 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
| 154 | txdesc->callback = dw_spi_dma_done; | 154 | txdesc->callback = dw_spi_dma_done; |
| 155 | txdesc->callback_param = dws; | 155 | txdesc->callback_param = dws; |
| 156 | 156 | ||
| @@ -159,27 +159,30 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change) | |||
| 159 | rxconf.src_addr = dws->dma_addr; | 159 | rxconf.src_addr = dws->dma_addr; |
| 160 | rxconf.src_maxburst = LNW_DMA_MSIZE_16; | 160 | rxconf.src_maxburst = LNW_DMA_MSIZE_16; |
| 161 | rxconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | 161 | rxconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
| 162 | rxconf.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | 162 | rxconf.src_addr_width = dws->dma_width; |
| 163 | rxconf.device_fc = false; | 163 | rxconf.device_fc = false; |
| 164 | 164 | ||
| 165 | rxchan->device->device_control(rxchan, DMA_SLAVE_CONFIG, | 165 | dmaengine_slave_config(dws->rxchan, &rxconf); |
| 166 | (unsigned long) &rxconf); | ||
| 167 | 166 | ||
| 168 | memset(&dws->rx_sgl, 0, sizeof(dws->rx_sgl)); | 167 | memset(&dws->rx_sgl, 0, sizeof(dws->rx_sgl)); |
| 169 | dws->rx_sgl.dma_address = dws->rx_dma; | 168 | dws->rx_sgl.dma_address = dws->rx_dma; |
| 170 | dws->rx_sgl.length = dws->len; | 169 | dws->rx_sgl.length = dws->len; |
| 171 | 170 | ||
| 172 | rxdesc = dmaengine_prep_slave_sg(rxchan, | 171 | rxdesc = dmaengine_prep_slave_sg(dws->rxchan, |
| 173 | &dws->rx_sgl, | 172 | &dws->rx_sgl, |
| 174 | 1, | 173 | 1, |
| 175 | DMA_DEV_TO_MEM, | 174 | DMA_DEV_TO_MEM, |
| 176 | DMA_PREP_INTERRUPT); | 175 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
| 177 | rxdesc->callback = dw_spi_dma_done; | 176 | rxdesc->callback = dw_spi_dma_done; |
| 178 | rxdesc->callback_param = dws; | 177 | rxdesc->callback_param = dws; |
| 179 | 178 | ||
| 180 | /* rx must be started before tx due to spi instinct */ | 179 | /* rx must be started before tx due to spi instinct */ |
| 181 | rxdesc->tx_submit(rxdesc); | 180 | dmaengine_submit(rxdesc); |
| 182 | txdesc->tx_submit(txdesc); | 181 | dma_async_issue_pending(dws->rxchan); |
| 182 | |||
| 183 | dmaengine_submit(txdesc); | ||
| 184 | dma_async_issue_pending(dws->txchan); | ||
| 185 | |||
| 183 | return 0; | 186 | return 0; |
| 184 | } | 187 | } |
| 185 | 188 | ||
| @@ -190,7 +193,7 @@ static struct dw_spi_dma_ops mid_dma_ops = { | |||
| 190 | }; | 193 | }; |
| 191 | #endif | 194 | #endif |
| 192 | 195 | ||
| 193 | /* Some specific info for SPI0 controller on Moorestown */ | 196 | /* Some specific info for SPI0 controller on Intel MID */ |
| 194 | 197 | ||
| 195 | /* HW info for MRST CLk Control Unit, one 32b reg */ | 198 | /* HW info for MRST CLk Control Unit, one 32b reg */ |
| 196 | #define MRST_SPI_CLK_BASE 100000000 /* 100m */ | 199 | #define MRST_SPI_CLK_BASE 100000000 /* 100m */ |
diff --git a/drivers/spi/spi-dw-pci.c b/drivers/spi/spi-dw-pci.c index e14960470d8d..ba68da12cdf0 100644 --- a/drivers/spi/spi-dw-pci.c +++ b/drivers/spi/spi-dw-pci.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * PCI interface driver for DW SPI Core | 2 | * PCI interface driver for DW SPI Core |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2009, Intel Corporation. | 4 | * Copyright (c) 2009, 2014 Intel Corporation. |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
| 7 | * under the terms and conditions of the GNU General Public License, | 7 | * under the terms and conditions of the GNU General Public License, |
| @@ -11,10 +11,6 @@ | |||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
| 13 | * more details. | 13 | * more details. |
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License along | ||
| 16 | * with this program; if not, write to the Free Software Foundation, | ||
| 17 | * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 18 | */ | 14 | */ |
| 19 | 15 | ||
| 20 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
| @@ -32,17 +28,22 @@ struct dw_spi_pci { | |||
| 32 | struct dw_spi dws; | 28 | struct dw_spi dws; |
| 33 | }; | 29 | }; |
| 34 | 30 | ||
| 35 | static int spi_pci_probe(struct pci_dev *pdev, | 31 | struct spi_pci_desc { |
| 36 | const struct pci_device_id *ent) | 32 | int (*setup)(struct dw_spi *); |
| 33 | }; | ||
| 34 | |||
| 35 | static struct spi_pci_desc spi_pci_mid_desc = { | ||
| 36 | .setup = dw_spi_mid_init, | ||
| 37 | }; | ||
| 38 | |||
| 39 | static int spi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | ||
| 37 | { | 40 | { |
| 38 | struct dw_spi_pci *dwpci; | 41 | struct dw_spi_pci *dwpci; |
| 39 | struct dw_spi *dws; | 42 | struct dw_spi *dws; |
| 43 | struct spi_pci_desc *desc = (struct spi_pci_desc *)ent->driver_data; | ||
| 40 | int pci_bar = 0; | 44 | int pci_bar = 0; |
| 41 | int ret; | 45 | int ret; |
| 42 | 46 | ||
| 43 | dev_info(&pdev->dev, "found PCI SPI controller(ID: %04x:%04x)\n", | ||
| 44 | pdev->vendor, pdev->device); | ||
| 45 | |||
| 46 | ret = pcim_enable_device(pdev); | 47 | ret = pcim_enable_device(pdev); |
| 47 | if (ret) | 48 | if (ret) |
| 48 | return ret; | 49 | return ret; |
| @@ -58,7 +59,7 @@ static int spi_pci_probe(struct pci_dev *pdev, | |||
| 58 | /* Get basic io resource and map it */ | 59 | /* Get basic io resource and map it */ |
| 59 | dws->paddr = pci_resource_start(pdev, pci_bar); | 60 | dws->paddr = pci_resource_start(pdev, pci_bar); |
| 60 | 61 | ||
| 61 | ret = pcim_iomap_regions(pdev, 1, dev_name(&pdev->dev)); | 62 | ret = pcim_iomap_regions(pdev, 1 << pci_bar, pci_name(pdev)); |
| 62 | if (ret) | 63 | if (ret) |
| 63 | return ret; | 64 | return ret; |
| 64 | 65 | ||
| @@ -69,11 +70,11 @@ static int spi_pci_probe(struct pci_dev *pdev, | |||
| 69 | dws->irq = pdev->irq; | 70 | dws->irq = pdev->irq; |
| 70 | 71 | ||
| 71 | /* | 72 | /* |
| 72 | * Specific handling for Intel MID paltforms, like dma setup, | 73 | * Specific handling for paltforms, like dma setup, |
| 73 | * clock rate, FIFO depth. | 74 | * clock rate, FIFO depth. |
| 74 | */ | 75 | */ |
| 75 | if (pdev->device == 0x0800) { | 76 | if (desc && desc->setup) { |
| 76 | ret = dw_spi_mid_init(dws); | 77 | ret = desc->setup(dws); |
| 77 | if (ret) | 78 | if (ret) |
| 78 | return ret; | 79 | return ret; |
| 79 | } | 80 | } |
| @@ -85,6 +86,9 @@ static int spi_pci_probe(struct pci_dev *pdev, | |||
| 85 | /* PCI hook and SPI hook use the same drv data */ | 86 | /* PCI hook and SPI hook use the same drv data */ |
| 86 | pci_set_drvdata(pdev, dwpci); | 87 | pci_set_drvdata(pdev, dwpci); |
| 87 | 88 | ||
| 89 | dev_info(&pdev->dev, "found PCI SPI controller(ID: %04x:%04x)\n", | ||
| 90 | pdev->vendor, pdev->device); | ||
| 91 | |||
| 88 | return 0; | 92 | return 0; |
| 89 | } | 93 | } |
| 90 | 94 | ||
| @@ -95,41 +99,29 @@ static void spi_pci_remove(struct pci_dev *pdev) | |||
| 95 | dw_spi_remove_host(&dwpci->dws); | 99 | dw_spi_remove_host(&dwpci->dws); |
| 96 | } | 100 | } |
| 97 | 101 | ||
| 98 | #ifdef CONFIG_PM | 102 | #ifdef CONFIG_PM_SLEEP |
| 99 | static int spi_suspend(struct pci_dev *pdev, pm_message_t state) | 103 | static int spi_suspend(struct device *dev) |
| 100 | { | 104 | { |
| 105 | struct pci_dev *pdev = to_pci_dev(dev); | ||
| 101 | struct dw_spi_pci *dwpci = pci_get_drvdata(pdev); | 106 | struct dw_spi_pci *dwpci = pci_get_drvdata(pdev); |
| 102 | int ret; | ||
| 103 | 107 | ||
| 104 | ret = dw_spi_suspend_host(&dwpci->dws); | 108 | return dw_spi_suspend_host(&dwpci->dws); |
| 105 | if (ret) | ||
| 106 | return ret; | ||
| 107 | pci_save_state(pdev); | ||
| 108 | pci_disable_device(pdev); | ||
| 109 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
| 110 | return ret; | ||
| 111 | } | 109 | } |
| 112 | 110 | ||
| 113 | static int spi_resume(struct pci_dev *pdev) | 111 | static int spi_resume(struct device *dev) |
| 114 | { | 112 | { |
| 113 | struct pci_dev *pdev = to_pci_dev(dev); | ||
| 115 | struct dw_spi_pci *dwpci = pci_get_drvdata(pdev); | 114 | struct dw_spi_pci *dwpci = pci_get_drvdata(pdev); |
| 116 | int ret; | ||
| 117 | 115 | ||
| 118 | pci_set_power_state(pdev, PCI_D0); | ||
| 119 | pci_restore_state(pdev); | ||
| 120 | ret = pci_enable_device(pdev); | ||
| 121 | if (ret) | ||
| 122 | return ret; | ||
| 123 | return dw_spi_resume_host(&dwpci->dws); | 116 | return dw_spi_resume_host(&dwpci->dws); |
| 124 | } | 117 | } |
| 125 | #else | ||
| 126 | #define spi_suspend NULL | ||
| 127 | #define spi_resume NULL | ||
| 128 | #endif | 118 | #endif |
| 129 | 119 | ||
| 120 | static SIMPLE_DEV_PM_OPS(dw_spi_pm_ops, spi_suspend, spi_resume); | ||
| 121 | |||
| 130 | static const struct pci_device_id pci_ids[] = { | 122 | static const struct pci_device_id pci_ids[] = { |
| 131 | /* Intel MID platform SPI controller 0 */ | 123 | /* Intel MID platform SPI controller 0 */ |
| 132 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0800) }, | 124 | { PCI_VDEVICE(INTEL, 0x0800), (kernel_ulong_t)&spi_pci_mid_desc}, |
| 133 | {}, | 125 | {}, |
| 134 | }; | 126 | }; |
| 135 | 127 | ||
| @@ -138,8 +130,9 @@ static struct pci_driver dw_spi_driver = { | |||
| 138 | .id_table = pci_ids, | 130 | .id_table = pci_ids, |
| 139 | .probe = spi_pci_probe, | 131 | .probe = spi_pci_probe, |
| 140 | .remove = spi_pci_remove, | 132 | .remove = spi_pci_remove, |
| 141 | .suspend = spi_suspend, | 133 | .driver = { |
| 142 | .resume = spi_resume, | 134 | .pm = &dw_spi_pm_ops, |
| 135 | }, | ||
| 143 | }; | 136 | }; |
| 144 | 137 | ||
| 145 | module_pci_driver(dw_spi_driver); | 138 | module_pci_driver(dw_spi_driver); |
diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 0dd0623319b0..729215885250 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c | |||
| @@ -11,10 +11,6 @@ | |||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
| 13 | * more details. | 13 | * more details. |
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License along with | ||
| 16 | * this program; if not, write to the Free Software Foundation, Inc., | ||
| 17 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 18 | */ | 14 | */ |
| 19 | 15 | ||
| 20 | #include <linux/dma-mapping.h> | 16 | #include <linux/dma-mapping.h> |
| @@ -59,22 +55,20 @@ struct chip_data { | |||
| 59 | 55 | ||
| 60 | #ifdef CONFIG_DEBUG_FS | 56 | #ifdef CONFIG_DEBUG_FS |
| 61 | #define SPI_REGS_BUFSIZE 1024 | 57 | #define SPI_REGS_BUFSIZE 1024 |
| 62 | static ssize_t spi_show_regs(struct file *file, char __user *user_buf, | 58 | static ssize_t dw_spi_show_regs(struct file *file, char __user *user_buf, |
| 63 | size_t count, loff_t *ppos) | 59 | size_t count, loff_t *ppos) |
| 64 | { | 60 | { |
| 65 | struct dw_spi *dws; | 61 | struct dw_spi *dws = file->private_data; |
| 66 | char *buf; | 62 | char *buf; |
| 67 | u32 len = 0; | 63 | u32 len = 0; |
| 68 | ssize_t ret; | 64 | ssize_t ret; |
| 69 | 65 | ||
| 70 | dws = file->private_data; | ||
| 71 | |||
| 72 | buf = kzalloc(SPI_REGS_BUFSIZE, GFP_KERNEL); | 66 | buf = kzalloc(SPI_REGS_BUFSIZE, GFP_KERNEL); |
| 73 | if (!buf) | 67 | if (!buf) |
| 74 | return 0; | 68 | return 0; |
| 75 | 69 | ||
| 76 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, | 70 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, |
| 77 | "MRST SPI0 registers:\n"); | 71 | "%s registers:\n", dev_name(&dws->master->dev)); |
| 78 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, | 72 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, |
| 79 | "=================================\n"); | 73 | "=================================\n"); |
| 80 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, | 74 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, |
| @@ -110,42 +104,41 @@ static ssize_t spi_show_regs(struct file *file, char __user *user_buf, | |||
| 110 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, | 104 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, |
| 111 | "=================================\n"); | 105 | "=================================\n"); |
| 112 | 106 | ||
| 113 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); | 107 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); |
| 114 | kfree(buf); | 108 | kfree(buf); |
| 115 | return ret; | 109 | return ret; |
| 116 | } | 110 | } |
| 117 | 111 | ||
| 118 | static const struct file_operations mrst_spi_regs_ops = { | 112 | static const struct file_operations dw_spi_regs_ops = { |
| 119 | .owner = THIS_MODULE, | 113 | .owner = THIS_MODULE, |
| 120 | .open = simple_open, | 114 | .open = simple_open, |
| 121 | .read = spi_show_regs, | 115 | .read = dw_spi_show_regs, |
| 122 | .llseek = default_llseek, | 116 | .llseek = default_llseek, |
| 123 | }; | 117 | }; |
| 124 | 118 | ||
| 125 | static int mrst_spi_debugfs_init(struct dw_spi *dws) | 119 | static int dw_spi_debugfs_init(struct dw_spi *dws) |
| 126 | { | 120 | { |
| 127 | dws->debugfs = debugfs_create_dir("mrst_spi", NULL); | 121 | dws->debugfs = debugfs_create_dir("dw_spi", NULL); |
| 128 | if (!dws->debugfs) | 122 | if (!dws->debugfs) |
| 129 | return -ENOMEM; | 123 | return -ENOMEM; |
| 130 | 124 | ||
| 131 | debugfs_create_file("registers", S_IFREG | S_IRUGO, | 125 | debugfs_create_file("registers", S_IFREG | S_IRUGO, |
| 132 | dws->debugfs, (void *)dws, &mrst_spi_regs_ops); | 126 | dws->debugfs, (void *)dws, &dw_spi_regs_ops); |
| 133 | return 0; | 127 | return 0; |
| 134 | } | 128 | } |
| 135 | 129 | ||
| 136 | static void mrst_spi_debugfs_remove(struct dw_spi *dws) | 130 | static void dw_spi_debugfs_remove(struct dw_spi *dws) |
| 137 | { | 131 | { |
| 138 | if (dws->debugfs) | 132 | debugfs_remove_recursive(dws->debugfs); |
| 139 | debugfs_remove_recursive(dws->debugfs); | ||
| 140 | } | 133 | } |
| 141 | 134 | ||
| 142 | #else | 135 | #else |
| 143 | static inline int mrst_spi_debugfs_init(struct dw_spi *dws) | 136 | static inline int dw_spi_debugfs_init(struct dw_spi *dws) |
| 144 | { | 137 | { |
| 145 | return 0; | 138 | return 0; |
| 146 | } | 139 | } |
| 147 | 140 | ||
| 148 | static inline void mrst_spi_debugfs_remove(struct dw_spi *dws) | 141 | static inline void dw_spi_debugfs_remove(struct dw_spi *dws) |
| 149 | { | 142 | { |
| 150 | } | 143 | } |
| 151 | #endif /* CONFIG_DEBUG_FS */ | 144 | #endif /* CONFIG_DEBUG_FS */ |
| @@ -177,7 +170,7 @@ static inline u32 rx_max(struct dw_spi *dws) | |||
| 177 | { | 170 | { |
| 178 | u32 rx_left = (dws->rx_end - dws->rx) / dws->n_bytes; | 171 | u32 rx_left = (dws->rx_end - dws->rx) / dws->n_bytes; |
| 179 | 172 | ||
| 180 | return min(rx_left, (u32)dw_readw(dws, DW_SPI_RXFLR)); | 173 | return min_t(u32, rx_left, dw_readw(dws, DW_SPI_RXFLR)); |
| 181 | } | 174 | } |
| 182 | 175 | ||
| 183 | static void dw_writer(struct dw_spi *dws) | 176 | static void dw_writer(struct dw_spi *dws) |
| @@ -228,8 +221,9 @@ static void *next_transfer(struct dw_spi *dws) | |||
| 228 | struct spi_transfer, | 221 | struct spi_transfer, |
| 229 | transfer_list); | 222 | transfer_list); |
| 230 | return RUNNING_STATE; | 223 | return RUNNING_STATE; |
| 231 | } else | 224 | } |
| 232 | return DONE_STATE; | 225 | |
| 226 | return DONE_STATE; | ||
| 233 | } | 227 | } |
| 234 | 228 | ||
| 235 | /* | 229 | /* |
| @@ -396,7 +390,7 @@ static void pump_transfers(unsigned long data) | |||
| 396 | goto early_exit; | 390 | goto early_exit; |
| 397 | } | 391 | } |
| 398 | 392 | ||
| 399 | /* Delay if requested at end of transfer*/ | 393 | /* Delay if requested at end of transfer */ |
| 400 | if (message->state == RUNNING_STATE) { | 394 | if (message->state == RUNNING_STATE) { |
| 401 | previous = list_entry(transfer->transfer_list.prev, | 395 | previous = list_entry(transfer->transfer_list.prev, |
| 402 | struct spi_transfer, | 396 | struct spi_transfer, |
| @@ -471,10 +465,12 @@ static void pump_transfers(unsigned long data) | |||
| 471 | */ | 465 | */ |
| 472 | if (!dws->dma_mapped && !chip->poll_mode) { | 466 | if (!dws->dma_mapped && !chip->poll_mode) { |
| 473 | int templen = dws->len / dws->n_bytes; | 467 | int templen = dws->len / dws->n_bytes; |
| 468 | |||
| 474 | txint_level = dws->fifo_len / 2; | 469 | txint_level = dws->fifo_len / 2; |
| 475 | txint_level = (templen > txint_level) ? txint_level : templen; | 470 | txint_level = (templen > txint_level) ? txint_level : templen; |
| 476 | 471 | ||
| 477 | imask |= SPI_INT_TXEI | SPI_INT_TXOI | SPI_INT_RXUI | SPI_INT_RXOI; | 472 | imask |= SPI_INT_TXEI | SPI_INT_TXOI | |
| 473 | SPI_INT_RXUI | SPI_INT_RXOI; | ||
| 478 | dws->transfer_handler = interrupt_transfer; | 474 | dws->transfer_handler = interrupt_transfer; |
| 479 | } | 475 | } |
| 480 | 476 | ||
| @@ -515,7 +511,6 @@ static void pump_transfers(unsigned long data) | |||
| 515 | 511 | ||
| 516 | early_exit: | 512 | early_exit: |
| 517 | giveback(dws); | 513 | giveback(dws); |
| 518 | return; | ||
| 519 | } | 514 | } |
| 520 | 515 | ||
| 521 | static int dw_spi_transfer_one_message(struct spi_master *master, | 516 | static int dw_spi_transfer_one_message(struct spi_master *master, |
| @@ -524,7 +519,7 @@ static int dw_spi_transfer_one_message(struct spi_master *master, | |||
| 524 | struct dw_spi *dws = spi_master_get_devdata(master); | 519 | struct dw_spi *dws = spi_master_get_devdata(master); |
| 525 | 520 | ||
| 526 | dws->cur_msg = msg; | 521 | dws->cur_msg = msg; |
| 527 | /* Initial message state*/ | 522 | /* Initial message state */ |
| 528 | dws->cur_msg->state = START_STATE; | 523 | dws->cur_msg->state = START_STATE; |
| 529 | dws->cur_transfer = list_entry(dws->cur_msg->transfers.next, | 524 | dws->cur_transfer = list_entry(dws->cur_msg->transfers.next, |
| 530 | struct spi_transfer, | 525 | struct spi_transfer, |
| @@ -595,6 +590,9 @@ static int dw_spi_setup(struct spi_device *spi) | |||
| 595 | | (spi->mode << SPI_MODE_OFFSET) | 590 | | (spi->mode << SPI_MODE_OFFSET) |
| 596 | | (chip->tmode << SPI_TMOD_OFFSET); | 591 | | (chip->tmode << SPI_TMOD_OFFSET); |
| 597 | 592 | ||
| 593 | if (spi->mode & SPI_LOOP) | ||
| 594 | chip->cr0 |= 1 << SPI_SRL_OFFSET; | ||
| 595 | |||
| 598 | if (gpio_is_valid(spi->cs_gpio)) { | 596 | if (gpio_is_valid(spi->cs_gpio)) { |
| 599 | ret = gpio_direction_output(spi->cs_gpio, | 597 | ret = gpio_direction_output(spi->cs_gpio, |
| 600 | !(spi->mode & SPI_CS_HIGH)); | 598 | !(spi->mode & SPI_CS_HIGH)); |
| @@ -626,6 +624,7 @@ static void spi_hw_init(struct dw_spi *dws) | |||
| 626 | */ | 624 | */ |
| 627 | if (!dws->fifo_len) { | 625 | if (!dws->fifo_len) { |
| 628 | u32 fifo; | 626 | u32 fifo; |
| 627 | |||
| 629 | for (fifo = 2; fifo <= 257; fifo++) { | 628 | for (fifo = 2; fifo <= 257; fifo++) { |
| 630 | dw_writew(dws, DW_SPI_TXFLTR, fifo); | 629 | dw_writew(dws, DW_SPI_TXFLTR, fifo); |
| 631 | if (fifo != dw_readw(dws, DW_SPI_TXFLTR)) | 630 | if (fifo != dw_readw(dws, DW_SPI_TXFLTR)) |
| @@ -653,8 +652,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) | |||
| 653 | dws->prev_chip = NULL; | 652 | dws->prev_chip = NULL; |
| 654 | dws->dma_inited = 0; | 653 | dws->dma_inited = 0; |
| 655 | dws->dma_addr = (dma_addr_t)(dws->paddr + 0x60); | 654 | dws->dma_addr = (dma_addr_t)(dws->paddr + 0x60); |
| 656 | snprintf(dws->name, sizeof(dws->name), "dw_spi%d", | 655 | snprintf(dws->name, sizeof(dws->name), "dw_spi%d", dws->bus_num); |
| 657 | dws->bus_num); | ||
| 658 | 656 | ||
| 659 | ret = devm_request_irq(dev, dws->irq, dw_spi_irq, IRQF_SHARED, | 657 | ret = devm_request_irq(dev, dws->irq, dw_spi_irq, IRQF_SHARED, |
| 660 | dws->name, dws); | 658 | dws->name, dws); |
| @@ -663,7 +661,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) | |||
| 663 | goto err_free_master; | 661 | goto err_free_master; |
| 664 | } | 662 | } |
| 665 | 663 | ||
| 666 | master->mode_bits = SPI_CPOL | SPI_CPHA; | 664 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP; |
| 667 | master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16); | 665 | master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16); |
| 668 | master->bus_num = dws->bus_num; | 666 | master->bus_num = dws->bus_num; |
| 669 | master->num_chipselect = dws->num_cs; | 667 | master->num_chipselect = dws->num_cs; |
| @@ -692,7 +690,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) | |||
| 692 | goto err_dma_exit; | 690 | goto err_dma_exit; |
| 693 | } | 691 | } |
| 694 | 692 | ||
| 695 | mrst_spi_debugfs_init(dws); | 693 | dw_spi_debugfs_init(dws); |
| 696 | return 0; | 694 | return 0; |
| 697 | 695 | ||
| 698 | err_dma_exit: | 696 | err_dma_exit: |
| @@ -709,7 +707,7 @@ void dw_spi_remove_host(struct dw_spi *dws) | |||
| 709 | { | 707 | { |
| 710 | if (!dws) | 708 | if (!dws) |
| 711 | return; | 709 | return; |
| 712 | mrst_spi_debugfs_remove(dws); | 710 | dw_spi_debugfs_remove(dws); |
| 713 | 711 | ||
| 714 | if (dws->dma_ops && dws->dma_ops->dma_exit) | 712 | if (dws->dma_ops && dws->dma_ops->dma_exit) |
| 715 | dws->dma_ops->dma_exit(dws); | 713 | dws->dma_ops->dma_exit(dws); |
diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 6d2acad34f64..83a103a76481 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h | |||
| @@ -74,6 +74,10 @@ | |||
| 74 | #define SPI_INT_RXFI (1 << 4) | 74 | #define SPI_INT_RXFI (1 << 4) |
| 75 | #define SPI_INT_MSTI (1 << 5) | 75 | #define SPI_INT_MSTI (1 << 5) |
| 76 | 76 | ||
| 77 | /* Bit fields in DMACR */ | ||
| 78 | #define SPI_DMA_RDMAE (1 << 0) | ||
| 79 | #define SPI_DMA_TDMAE (1 << 1) | ||
| 80 | |||
| 77 | /* TX RX interrupt level threshold, max can be 256 */ | 81 | /* TX RX interrupt level threshold, max can be 256 */ |
| 78 | #define SPI_INT_THRESHOLD 32 | 82 | #define SPI_INT_THRESHOLD 32 |
| 79 | 83 | ||
| @@ -140,7 +144,6 @@ struct dw_spi { | |||
| 140 | dma_addr_t dma_addr; /* phy address of the Data register */ | 144 | dma_addr_t dma_addr; /* phy address of the Data register */ |
| 141 | struct dw_spi_dma_ops *dma_ops; | 145 | struct dw_spi_dma_ops *dma_ops; |
| 142 | void *dma_priv; /* platform relate info */ | 146 | void *dma_priv; /* platform relate info */ |
| 143 | struct pci_dev *dmac; | ||
| 144 | 147 | ||
| 145 | /* Bus interface info */ | 148 | /* Bus interface info */ |
| 146 | void *priv; | 149 | void *priv; |
| @@ -217,11 +220,11 @@ static inline void spi_umask_intr(struct dw_spi *dws, u32 mask) | |||
| 217 | * Each SPI slave device to work with dw_api controller should | 220 | * Each SPI slave device to work with dw_api controller should |
| 218 | * has such a structure claiming its working mode (PIO/DMA etc), | 221 | * has such a structure claiming its working mode (PIO/DMA etc), |
| 219 | * which can be save in the "controller_data" member of the | 222 | * which can be save in the "controller_data" member of the |
| 220 | * struct spi_device | 223 | * struct spi_device. |
| 221 | */ | 224 | */ |
| 222 | struct dw_spi_chip { | 225 | struct dw_spi_chip { |
| 223 | u8 poll_mode; /* 0 for contoller polling mode */ | 226 | u8 poll_mode; /* 1 for controller polling mode */ |
| 224 | u8 type; /* SPI/SSP/Micrwire */ | 227 | u8 type; /* SPI/SSP/MicroWire */ |
| 225 | u8 enable_dma; | 228 | u8 enable_dma; |
| 226 | void (*cs_control)(u32 command); | 229 | void (*cs_control)(u32 command); |
| 227 | }; | 230 | }; |
diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index 2f675d32df0e..bf9728773247 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c | |||
| @@ -266,6 +266,7 @@ static int ep93xx_spi_setup(struct spi_device *spi) | |||
| 266 | 266 | ||
| 267 | if (chip->ops && chip->ops->setup) { | 267 | if (chip->ops && chip->ops->setup) { |
| 268 | int ret = chip->ops->setup(spi); | 268 | int ret = chip->ops->setup(spi); |
| 269 | |||
| 269 | if (ret) { | 270 | if (ret) { |
| 270 | kfree(chip); | 271 | kfree(chip); |
| 271 | return ret; | 272 | return ret; |
diff --git a/drivers/spi/spi-fsl-cpm.c b/drivers/spi/spi-fsl-cpm.c index 54b06376f03c..c5dd20beee22 100644 --- a/drivers/spi/spi-fsl-cpm.c +++ b/drivers/spi/spi-fsl-cpm.c | |||
| @@ -15,17 +15,17 @@ | |||
| 15 | * Free Software Foundation; either version 2 of the License, or (at your | 15 | * Free Software Foundation; either version 2 of the License, or (at your |
| 16 | * option) any later version. | 16 | * option) any later version. |
| 17 | */ | 17 | */ |
| 18 | #include <linux/types.h> | ||
| 19 | #include <linux/kernel.h> | ||
| 20 | #include <linux/spi/spi.h> | ||
| 21 | #include <linux/fsl_devices.h> | ||
| 22 | #include <linux/dma-mapping.h> | ||
| 23 | #include <linux/of_address.h> | ||
| 24 | #include <asm/cpm.h> | 18 | #include <asm/cpm.h> |
| 25 | #include <asm/qe.h> | 19 | #include <asm/qe.h> |
| 20 | #include <linux/dma-mapping.h> | ||
| 21 | #include <linux/fsl_devices.h> | ||
| 22 | #include <linux/kernel.h> | ||
| 23 | #include <linux/of_address.h> | ||
| 24 | #include <linux/spi/spi.h> | ||
| 25 | #include <linux/types.h> | ||
| 26 | 26 | ||
| 27 | #include "spi-fsl-lib.h" | ||
| 28 | #include "spi-fsl-cpm.h" | 27 | #include "spi-fsl-cpm.h" |
| 28 | #include "spi-fsl-lib.h" | ||
| 29 | #include "spi-fsl-spi.h" | 29 | #include "spi-fsl-spi.h" |
| 30 | 30 | ||
| 31 | /* CPM1 and CPM2 are mutually exclusive. */ | 31 | /* CPM1 and CPM2 are mutually exclusive. */ |
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 5021ddf03f60..448216025ce8 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c | |||
| @@ -13,22 +13,22 @@ | |||
| 13 | * | 13 | * |
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | #include <linux/clk.h> | ||
| 17 | #include <linux/delay.h> | ||
| 18 | #include <linux/err.h> | ||
| 19 | #include <linux/errno.h> | ||
| 20 | #include <linux/interrupt.h> | ||
| 21 | #include <linux/io.h> | ||
| 16 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
| 17 | #include <linux/module.h> | 23 | #include <linux/module.h> |
| 18 | #include <linux/interrupt.h> | 24 | #include <linux/of.h> |
| 19 | #include <linux/errno.h> | 25 | #include <linux/of_device.h> |
| 20 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
| 27 | #include <linux/pm_runtime.h> | ||
| 21 | #include <linux/regmap.h> | 28 | #include <linux/regmap.h> |
| 22 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
| 23 | #include <linux/delay.h> | ||
| 24 | #include <linux/io.h> | ||
| 25 | #include <linux/clk.h> | ||
| 26 | #include <linux/err.h> | ||
| 27 | #include <linux/spi/spi.h> | 30 | #include <linux/spi/spi.h> |
| 28 | #include <linux/spi/spi_bitbang.h> | 31 | #include <linux/spi/spi_bitbang.h> |
| 29 | #include <linux/pm_runtime.h> | ||
| 30 | #include <linux/of.h> | ||
| 31 | #include <linux/of_device.h> | ||
| 32 | 32 | ||
| 33 | #define DRIVER_NAME "fsl-dspi" | 33 | #define DRIVER_NAME "fsl-dspi" |
| 34 | 34 | ||
| @@ -493,9 +493,6 @@ static int dspi_probe(struct platform_device *pdev) | |||
| 493 | } | 493 | } |
| 494 | 494 | ||
| 495 | dspi_regmap_config.lock_arg = dspi; | 495 | dspi_regmap_config.lock_arg = dspi; |
| 496 | dspi_regmap_config.val_format_endian = | ||
| 497 | of_property_read_bool(np, "big-endian") | ||
| 498 | ? REGMAP_ENDIAN_BIG : REGMAP_ENDIAN_DEFAULT; | ||
| 499 | dspi->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "dspi", base, | 496 | dspi->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "dspi", base, |
| 500 | &dspi_regmap_config); | 497 | &dspi_regmap_config); |
| 501 | if (IS_ERR(dspi->regmap)) { | 498 | if (IS_ERR(dspi->regmap)) { |
| @@ -535,7 +532,6 @@ static int dspi_probe(struct platform_device *pdev) | |||
| 535 | goto out_clk_put; | 532 | goto out_clk_put; |
| 536 | } | 533 | } |
| 537 | 534 | ||
| 538 | pr_info(KERN_INFO "Freescale DSPI master initialized\n"); | ||
| 539 | return ret; | 535 | return ret; |
| 540 | 536 | ||
| 541 | out_clk_put: | 537 | out_clk_put: |
diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index 429e11190265..a7f94b6a9e70 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c | |||
| @@ -8,19 +8,19 @@ | |||
| 8 | * Free Software Foundation; either version 2 of the License, or (at your | 8 | * Free Software Foundation; either version 2 of the License, or (at your |
| 9 | * option) any later version. | 9 | * option) any later version. |
| 10 | */ | 10 | */ |
| 11 | #include <linux/module.h> | ||
| 12 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
| 13 | #include <linux/irq.h> | 12 | #include <linux/err.h> |
| 14 | #include <linux/spi/spi.h> | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | #include <linux/fsl_devices.h> | 13 | #include <linux/fsl_devices.h> |
| 14 | #include <linux/interrupt.h> | ||
| 15 | #include <linux/irq.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
| 18 | #include <linux/of.h> | 18 | #include <linux/of.h> |
| 19 | #include <linux/of_address.h> | 19 | #include <linux/of_address.h> |
| 20 | #include <linux/of_irq.h> | 20 | #include <linux/of_irq.h> |
| 21 | #include <linux/of_platform.h> | 21 | #include <linux/of_platform.h> |
| 22 | #include <linux/interrupt.h> | 22 | #include <linux/platform_device.h> |
| 23 | #include <linux/err.h> | 23 | #include <linux/spi/spi.h> |
| 24 | #include <sysdev/fsl_soc.h> | 24 | #include <sysdev/fsl_soc.h> |
| 25 | 25 | ||
| 26 | #include "spi-fsl-lib.h" | 26 | #include "spi-fsl-lib.h" |
diff --git a/drivers/spi/spi-fsl-lib.c b/drivers/spi/spi-fsl-lib.c index e0b773fc29cb..5ddb5b098e4e 100644 --- a/drivers/spi/spi-fsl-lib.c +++ b/drivers/spi/spi-fsl-lib.c | |||
| @@ -16,10 +16,10 @@ | |||
| 16 | * Free Software Foundation; either version 2 of the License, or (at your | 16 | * Free Software Foundation; either version 2 of the License, or (at your |
| 17 | * option) any later version. | 17 | * option) any later version. |
| 18 | */ | 18 | */ |
| 19 | #include <linux/kernel.h> | ||
| 20 | #include <linux/interrupt.h> | ||
| 21 | #include <linux/fsl_devices.h> | ||
| 22 | #include <linux/dma-mapping.h> | 19 | #include <linux/dma-mapping.h> |
| 20 | #include <linux/fsl_devices.h> | ||
| 21 | #include <linux/interrupt.h> | ||
| 22 | #include <linux/kernel.h> | ||
| 23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
| 24 | #include <linux/of_platform.h> | 24 | #include <linux/of_platform.h> |
| 25 | #include <linux/spi/spi.h> | 25 | #include <linux/spi/spi.h> |
diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index 590f31bc0aba..ed792880c9d6 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c | |||
| @@ -19,25 +19,25 @@ | |||
| 19 | * Free Software Foundation; either version 2 of the License, or (at your | 19 | * Free Software Foundation; either version 2 of the License, or (at your |
| 20 | * option) any later version. | 20 | * option) any later version. |
| 21 | */ | 21 | */ |
| 22 | #include <linux/module.h> | ||
| 23 | #include <linux/types.h> | ||
| 24 | #include <linux/kernel.h> | ||
| 25 | #include <linux/interrupt.h> | ||
| 26 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
| 27 | #include <linux/irq.h> | ||
| 28 | #include <linux/spi/spi.h> | ||
| 29 | #include <linux/spi/spi_bitbang.h> | ||
| 30 | #include <linux/platform_device.h> | ||
| 31 | #include <linux/fsl_devices.h> | ||
| 32 | #include <linux/dma-mapping.h> | 23 | #include <linux/dma-mapping.h> |
| 24 | #include <linux/fsl_devices.h> | ||
| 25 | #include <linux/gpio.h> | ||
| 26 | #include <linux/interrupt.h> | ||
| 27 | #include <linux/irq.h> | ||
| 28 | #include <linux/kernel.h> | ||
| 33 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
| 30 | #include <linux/module.h> | ||
| 34 | #include <linux/mutex.h> | 31 | #include <linux/mutex.h> |
| 35 | #include <linux/of.h> | 32 | #include <linux/of.h> |
| 36 | #include <linux/of_platform.h> | ||
| 37 | #include <linux/of_address.h> | 33 | #include <linux/of_address.h> |
| 38 | #include <linux/of_irq.h> | 34 | #include <linux/of_irq.h> |
| 39 | #include <linux/gpio.h> | ||
| 40 | #include <linux/of_gpio.h> | 35 | #include <linux/of_gpio.h> |
| 36 | #include <linux/of_platform.h> | ||
| 37 | #include <linux/platform_device.h> | ||
| 38 | #include <linux/spi/spi.h> | ||
| 39 | #include <linux/spi/spi_bitbang.h> | ||
| 40 | #include <linux/types.h> | ||
| 41 | 41 | ||
| 42 | #include "spi-fsl-lib.h" | 42 | #include "spi-fsl-lib.h" |
| 43 | #include "spi-fsl-cpm.h" | 43 | #include "spi-fsl-cpm.h" |
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 5daff2054ae4..3637847b5370 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c | |||
| @@ -21,6 +21,8 @@ | |||
| 21 | #include <linux/clk.h> | 21 | #include <linux/clk.h> |
| 22 | #include <linux/completion.h> | 22 | #include <linux/completion.h> |
| 23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
| 24 | #include <linux/dmaengine.h> | ||
| 25 | #include <linux/dma-mapping.h> | ||
| 24 | #include <linux/err.h> | 26 | #include <linux/err.h> |
| 25 | #include <linux/gpio.h> | 27 | #include <linux/gpio.h> |
| 26 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
| @@ -37,6 +39,7 @@ | |||
| 37 | #include <linux/of_device.h> | 39 | #include <linux/of_device.h> |
| 38 | #include <linux/of_gpio.h> | 40 | #include <linux/of_gpio.h> |
| 39 | 41 | ||
| 42 | #include <linux/platform_data/dma-imx.h> | ||
| 40 | #include <linux/platform_data/spi-imx.h> | 43 | #include <linux/platform_data/spi-imx.h> |
| 41 | 44 | ||
| 42 | #define DRIVER_NAME "spi_imx" | 45 | #define DRIVER_NAME "spi_imx" |
| @@ -51,6 +54,9 @@ | |||
| 51 | #define MXC_INT_RR (1 << 0) /* Receive data ready interrupt */ | 54 | #define MXC_INT_RR (1 << 0) /* Receive data ready interrupt */ |
| 52 | #define MXC_INT_TE (1 << 1) /* Transmit FIFO empty interrupt */ | 55 | #define MXC_INT_TE (1 << 1) /* Transmit FIFO empty interrupt */ |
| 53 | 56 | ||
| 57 | /* The maximum bytes that a sdma BD can transfer.*/ | ||
| 58 | #define MAX_SDMA_BD_BYTES (1 << 15) | ||
| 59 | #define IMX_DMA_TIMEOUT (msecs_to_jiffies(3000)) | ||
| 54 | struct spi_imx_config { | 60 | struct spi_imx_config { |
| 55 | unsigned int speed_hz; | 61 | unsigned int speed_hz; |
| 56 | unsigned int bpw; | 62 | unsigned int bpw; |
| @@ -95,6 +101,16 @@ struct spi_imx_data { | |||
| 95 | const void *tx_buf; | 101 | const void *tx_buf; |
| 96 | unsigned int txfifo; /* number of words pushed in tx FIFO */ | 102 | unsigned int txfifo; /* number of words pushed in tx FIFO */ |
| 97 | 103 | ||
| 104 | /* DMA */ | ||
| 105 | unsigned int dma_is_inited; | ||
| 106 | unsigned int dma_finished; | ||
| 107 | bool usedma; | ||
| 108 | u32 rx_wml; | ||
| 109 | u32 tx_wml; | ||
| 110 | u32 rxt_wml; | ||
| 111 | struct completion dma_rx_completion; | ||
| 112 | struct completion dma_tx_completion; | ||
| 113 | |||
| 98 | const struct spi_imx_devtype_data *devtype_data; | 114 | const struct spi_imx_devtype_data *devtype_data; |
| 99 | int chipselect[0]; | 115 | int chipselect[0]; |
| 100 | }; | 116 | }; |
| @@ -181,9 +197,21 @@ static unsigned int spi_imx_clkdiv_2(unsigned int fin, | |||
| 181 | return 7; | 197 | return 7; |
| 182 | } | 198 | } |
| 183 | 199 | ||
| 200 | static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, | ||
| 201 | struct spi_transfer *transfer) | ||
| 202 | { | ||
| 203 | struct spi_imx_data *spi_imx = spi_master_get_devdata(master); | ||
| 204 | |||
| 205 | if (spi_imx->dma_is_inited && (transfer->len > spi_imx->rx_wml) | ||
| 206 | && (transfer->len > spi_imx->tx_wml)) | ||
| 207 | return true; | ||
| 208 | return false; | ||
| 209 | } | ||
| 210 | |||
| 184 | #define MX51_ECSPI_CTRL 0x08 | 211 | #define MX51_ECSPI_CTRL 0x08 |
| 185 | #define MX51_ECSPI_CTRL_ENABLE (1 << 0) | 212 | #define MX51_ECSPI_CTRL_ENABLE (1 << 0) |
| 186 | #define MX51_ECSPI_CTRL_XCH (1 << 2) | 213 | #define MX51_ECSPI_CTRL_XCH (1 << 2) |
| 214 | #define MX51_ECSPI_CTRL_SMC (1 << 3) | ||
| 187 | #define MX51_ECSPI_CTRL_MODE_MASK (0xf << 4) | 215 | #define MX51_ECSPI_CTRL_MODE_MASK (0xf << 4) |
| 188 | #define MX51_ECSPI_CTRL_POSTDIV_OFFSET 8 | 216 | #define MX51_ECSPI_CTRL_POSTDIV_OFFSET 8 |
| 189 | #define MX51_ECSPI_CTRL_PREDIV_OFFSET 12 | 217 | #define MX51_ECSPI_CTRL_PREDIV_OFFSET 12 |
| @@ -201,6 +229,18 @@ static unsigned int spi_imx_clkdiv_2(unsigned int fin, | |||
| 201 | #define MX51_ECSPI_INT_TEEN (1 << 0) | 229 | #define MX51_ECSPI_INT_TEEN (1 << 0) |
| 202 | #define MX51_ECSPI_INT_RREN (1 << 3) | 230 | #define MX51_ECSPI_INT_RREN (1 << 3) |
| 203 | 231 | ||
| 232 | #define MX51_ECSPI_DMA 0x14 | ||
| 233 | #define MX51_ECSPI_DMA_TX_WML_OFFSET 0 | ||
| 234 | #define MX51_ECSPI_DMA_TX_WML_MASK 0x3F | ||
| 235 | #define MX51_ECSPI_DMA_RX_WML_OFFSET 16 | ||
| 236 | #define MX51_ECSPI_DMA_RX_WML_MASK (0x3F << 16) | ||
| 237 | #define MX51_ECSPI_DMA_RXT_WML_OFFSET 24 | ||
| 238 | #define MX51_ECSPI_DMA_RXT_WML_MASK (0x3F << 24) | ||
| 239 | |||
| 240 | #define MX51_ECSPI_DMA_TEDEN_OFFSET 7 | ||
| 241 | #define MX51_ECSPI_DMA_RXDEN_OFFSET 23 | ||
| 242 | #define MX51_ECSPI_DMA_RXTDEN_OFFSET 31 | ||
| 243 | |||
| 204 | #define MX51_ECSPI_STAT 0x18 | 244 | #define MX51_ECSPI_STAT 0x18 |
| 205 | #define MX51_ECSPI_STAT_RR (1 << 3) | 245 | #define MX51_ECSPI_STAT_RR (1 << 3) |
| 206 | 246 | ||
| @@ -257,17 +297,22 @@ static void __maybe_unused mx51_ecspi_intctrl(struct spi_imx_data *spi_imx, int | |||
| 257 | 297 | ||
| 258 | static void __maybe_unused mx51_ecspi_trigger(struct spi_imx_data *spi_imx) | 298 | static void __maybe_unused mx51_ecspi_trigger(struct spi_imx_data *spi_imx) |
| 259 | { | 299 | { |
| 260 | u32 reg; | 300 | u32 reg = readl(spi_imx->base + MX51_ECSPI_CTRL); |
| 261 | 301 | ||
| 262 | reg = readl(spi_imx->base + MX51_ECSPI_CTRL); | 302 | if (!spi_imx->usedma) |
| 263 | reg |= MX51_ECSPI_CTRL_XCH; | 303 | reg |= MX51_ECSPI_CTRL_XCH; |
| 304 | else if (!spi_imx->dma_finished) | ||
| 305 | reg |= MX51_ECSPI_CTRL_SMC; | ||
| 306 | else | ||
| 307 | reg &= ~MX51_ECSPI_CTRL_SMC; | ||
| 264 | writel(reg, spi_imx->base + MX51_ECSPI_CTRL); | 308 | writel(reg, spi_imx->base + MX51_ECSPI_CTRL); |
| 265 | } | 309 | } |
| 266 | 310 | ||
| 267 | static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx, | 311 | static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx, |
| 268 | struct spi_imx_config *config) | 312 | struct spi_imx_config *config) |
| 269 | { | 313 | { |
| 270 | u32 ctrl = MX51_ECSPI_CTRL_ENABLE, cfg = 0; | 314 | u32 ctrl = MX51_ECSPI_CTRL_ENABLE, cfg = 0, dma = 0; |
| 315 | u32 tx_wml_cfg, rx_wml_cfg, rxt_wml_cfg; | ||
| 271 | u32 clk = config->speed_hz, delay; | 316 | u32 clk = config->speed_hz, delay; |
| 272 | 317 | ||
| 273 | /* | 318 | /* |
| @@ -319,6 +364,30 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx, | |||
| 319 | else /* SCLK is _very_ slow */ | 364 | else /* SCLK is _very_ slow */ |
| 320 | usleep_range(delay, delay + 10); | 365 | usleep_range(delay, delay + 10); |
| 321 | 366 | ||
| 367 | /* | ||
| 368 | * Configure the DMA register: setup the watermark | ||
| 369 | * and enable DMA request. | ||
| 370 | */ | ||
| 371 | if (spi_imx->dma_is_inited) { | ||
| 372 | dma = readl(spi_imx->base + MX51_ECSPI_DMA); | ||
| 373 | |||
| 374 | spi_imx->tx_wml = spi_imx_get_fifosize(spi_imx) / 2; | ||
| 375 | spi_imx->rx_wml = spi_imx_get_fifosize(spi_imx) / 2; | ||
| 376 | spi_imx->rxt_wml = spi_imx_get_fifosize(spi_imx) / 2; | ||
| 377 | rx_wml_cfg = spi_imx->rx_wml << MX51_ECSPI_DMA_RX_WML_OFFSET; | ||
| 378 | tx_wml_cfg = spi_imx->tx_wml << MX51_ECSPI_DMA_TX_WML_OFFSET; | ||
| 379 | rxt_wml_cfg = spi_imx->rxt_wml << MX51_ECSPI_DMA_RXT_WML_OFFSET; | ||
| 380 | dma = (dma & ~MX51_ECSPI_DMA_TX_WML_MASK | ||
| 381 | & ~MX51_ECSPI_DMA_RX_WML_MASK | ||
| 382 | & ~MX51_ECSPI_DMA_RXT_WML_MASK) | ||
| 383 | | rx_wml_cfg | tx_wml_cfg | rxt_wml_cfg | ||
| 384 | |(1 << MX51_ECSPI_DMA_TEDEN_OFFSET) | ||
| 385 | |(1 << MX51_ECSPI_DMA_RXDEN_OFFSET) | ||
| 386 | |(1 << MX51_ECSPI_DMA_RXTDEN_OFFSET); | ||
| 387 | |||
| 388 | writel(dma, spi_imx->base + MX51_ECSPI_DMA); | ||
| 389 | } | ||
| 390 | |||
| 322 | return 0; | 391 | return 0; |
| 323 | } | 392 | } |
| 324 | 393 | ||
| @@ -730,7 +799,186 @@ static int spi_imx_setupxfer(struct spi_device *spi, | |||
| 730 | return 0; | 799 | return 0; |
| 731 | } | 800 | } |
| 732 | 801 | ||
| 733 | static int spi_imx_transfer(struct spi_device *spi, | 802 | static void spi_imx_sdma_exit(struct spi_imx_data *spi_imx) |
| 803 | { | ||
| 804 | struct spi_master *master = spi_imx->bitbang.master; | ||
| 805 | |||
| 806 | if (master->dma_rx) { | ||
| 807 | dma_release_channel(master->dma_rx); | ||
| 808 | master->dma_rx = NULL; | ||
| 809 | } | ||
| 810 | |||
| 811 | if (master->dma_tx) { | ||
| 812 | dma_release_channel(master->dma_tx); | ||
| 813 | master->dma_tx = NULL; | ||
| 814 | } | ||
| 815 | |||
| 816 | spi_imx->dma_is_inited = 0; | ||
| 817 | } | ||
| 818 | |||
| 819 | static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, | ||
| 820 | struct spi_master *master, | ||
| 821 | const struct resource *res) | ||
| 822 | { | ||
| 823 | struct dma_slave_config slave_config = {}; | ||
| 824 | int ret; | ||
| 825 | |||
| 826 | /* Prepare for TX DMA: */ | ||
| 827 | master->dma_tx = dma_request_slave_channel(dev, "tx"); | ||
| 828 | if (!master->dma_tx) { | ||
| 829 | dev_err(dev, "cannot get the TX DMA channel!\n"); | ||
| 830 | ret = -EINVAL; | ||
| 831 | goto err; | ||
| 832 | } | ||
| 833 | |||
| 834 | slave_config.direction = DMA_MEM_TO_DEV; | ||
| 835 | slave_config.dst_addr = res->start + MXC_CSPITXDATA; | ||
| 836 | slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
| 837 | slave_config.dst_maxburst = spi_imx_get_fifosize(spi_imx) / 2; | ||
| 838 | ret = dmaengine_slave_config(master->dma_tx, &slave_config); | ||
| 839 | if (ret) { | ||
| 840 | dev_err(dev, "error in TX dma configuration.\n"); | ||
| 841 | goto err; | ||
| 842 | } | ||
| 843 | |||
| 844 | /* Prepare for RX : */ | ||
| 845 | master->dma_rx = dma_request_slave_channel(dev, "rx"); | ||
| 846 | if (!master->dma_rx) { | ||
| 847 | dev_dbg(dev, "cannot get the DMA channel.\n"); | ||
| 848 | ret = -EINVAL; | ||
| 849 | goto err; | ||
| 850 | } | ||
| 851 | |||
| 852 | slave_config.direction = DMA_DEV_TO_MEM; | ||
| 853 | slave_config.src_addr = res->start + MXC_CSPIRXDATA; | ||
| 854 | slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
| 855 | slave_config.src_maxburst = spi_imx_get_fifosize(spi_imx) / 2; | ||
| 856 | ret = dmaengine_slave_config(master->dma_rx, &slave_config); | ||
| 857 | if (ret) { | ||
| 858 | dev_err(dev, "error in RX dma configuration.\n"); | ||
| 859 | goto err; | ||
| 860 | } | ||
| 861 | |||
| 862 | init_completion(&spi_imx->dma_rx_completion); | ||
| 863 | init_completion(&spi_imx->dma_tx_completion); | ||
| 864 | master->can_dma = spi_imx_can_dma; | ||
| 865 | master->max_dma_len = MAX_SDMA_BD_BYTES; | ||
| 866 | spi_imx->bitbang.master->flags = SPI_MASTER_MUST_RX | | ||
| 867 | SPI_MASTER_MUST_TX; | ||
| 868 | spi_imx->dma_is_inited = 1; | ||
| 869 | |||
| 870 | return 0; | ||
| 871 | err: | ||
| 872 | spi_imx_sdma_exit(spi_imx); | ||
| 873 | return ret; | ||
| 874 | } | ||
| 875 | |||
| 876 | static void spi_imx_dma_rx_callback(void *cookie) | ||
| 877 | { | ||
| 878 | struct spi_imx_data *spi_imx = (struct spi_imx_data *)cookie; | ||
| 879 | |||
| 880 | complete(&spi_imx->dma_rx_completion); | ||
| 881 | } | ||
| 882 | |||
| 883 | static void spi_imx_dma_tx_callback(void *cookie) | ||
| 884 | { | ||
| 885 | struct spi_imx_data *spi_imx = (struct spi_imx_data *)cookie; | ||
| 886 | |||
| 887 | complete(&spi_imx->dma_tx_completion); | ||
| 888 | } | ||
| 889 | |||
| 890 | static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx, | ||
| 891 | struct spi_transfer *transfer) | ||
| 892 | { | ||
| 893 | struct dma_async_tx_descriptor *desc_tx = NULL, *desc_rx = NULL; | ||
| 894 | int ret; | ||
| 895 | u32 dma; | ||
| 896 | int left; | ||
| 897 | struct spi_master *master = spi_imx->bitbang.master; | ||
| 898 | struct sg_table *tx = &transfer->tx_sg, *rx = &transfer->rx_sg; | ||
| 899 | |||
| 900 | if (tx) { | ||
| 901 | desc_tx = dmaengine_prep_slave_sg(master->dma_tx, | ||
| 902 | tx->sgl, tx->nents, DMA_TO_DEVICE, | ||
| 903 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
| 904 | if (!desc_tx) | ||
| 905 | goto no_dma; | ||
| 906 | |||
| 907 | desc_tx->callback = spi_imx_dma_tx_callback; | ||
| 908 | desc_tx->callback_param = (void *)spi_imx; | ||
| 909 | dmaengine_submit(desc_tx); | ||
| 910 | } | ||
| 911 | |||
| 912 | if (rx) { | ||
| 913 | desc_rx = dmaengine_prep_slave_sg(master->dma_rx, | ||
| 914 | rx->sgl, rx->nents, DMA_FROM_DEVICE, | ||
| 915 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
| 916 | if (!desc_rx) | ||
| 917 | goto no_dma; | ||
| 918 | |||
| 919 | desc_rx->callback = spi_imx_dma_rx_callback; | ||
| 920 | desc_rx->callback_param = (void *)spi_imx; | ||
| 921 | dmaengine_submit(desc_rx); | ||
| 922 | } | ||
| 923 | |||
| 924 | reinit_completion(&spi_imx->dma_rx_completion); | ||
| 925 | reinit_completion(&spi_imx->dma_tx_completion); | ||
| 926 | |||
| 927 | /* Trigger the cspi module. */ | ||
| 928 | spi_imx->dma_finished = 0; | ||
| 929 | |||
| 930 | dma = readl(spi_imx->base + MX51_ECSPI_DMA); | ||
| 931 | dma = dma & (~MX51_ECSPI_DMA_RXT_WML_MASK); | ||
| 932 | /* Change RX_DMA_LENGTH trigger dma fetch tail data */ | ||
| 933 | left = transfer->len % spi_imx->rxt_wml; | ||
| 934 | if (left) | ||
| 935 | writel(dma | (left << MX51_ECSPI_DMA_RXT_WML_OFFSET), | ||
| 936 | spi_imx->base + MX51_ECSPI_DMA); | ||
| 937 | spi_imx->devtype_data->trigger(spi_imx); | ||
| 938 | |||
| 939 | dma_async_issue_pending(master->dma_tx); | ||
| 940 | dma_async_issue_pending(master->dma_rx); | ||
| 941 | /* Wait SDMA to finish the data transfer.*/ | ||
| 942 | ret = wait_for_completion_timeout(&spi_imx->dma_tx_completion, | ||
| 943 | IMX_DMA_TIMEOUT); | ||
| 944 | if (!ret) { | ||
| 945 | pr_warn("%s %s: I/O Error in DMA TX\n", | ||
| 946 | dev_driver_string(&master->dev), | ||
| 947 | dev_name(&master->dev)); | ||
| 948 | dmaengine_terminate_all(master->dma_tx); | ||
| 949 | } else { | ||
| 950 | ret = wait_for_completion_timeout(&spi_imx->dma_rx_completion, | ||
| 951 | IMX_DMA_TIMEOUT); | ||
| 952 | if (!ret) { | ||
| 953 | pr_warn("%s %s: I/O Error in DMA RX\n", | ||
| 954 | dev_driver_string(&master->dev), | ||
| 955 | dev_name(&master->dev)); | ||
| 956 | spi_imx->devtype_data->reset(spi_imx); | ||
| 957 | dmaengine_terminate_all(master->dma_rx); | ||
| 958 | } | ||
| 959 | writel(dma | | ||
| 960 | spi_imx->rxt_wml << MX51_ECSPI_DMA_RXT_WML_OFFSET, | ||
| 961 | spi_imx->base + MX51_ECSPI_DMA); | ||
| 962 | } | ||
| 963 | |||
| 964 | spi_imx->dma_finished = 1; | ||
| 965 | spi_imx->devtype_data->trigger(spi_imx); | ||
| 966 | |||
| 967 | if (!ret) | ||
| 968 | ret = -ETIMEDOUT; | ||
| 969 | else if (ret > 0) | ||
| 970 | ret = transfer->len; | ||
| 971 | |||
| 972 | return ret; | ||
| 973 | |||
| 974 | no_dma: | ||
| 975 | pr_warn_once("%s %s: DMA not available, falling back to PIO\n", | ||
| 976 | dev_driver_string(&master->dev), | ||
| 977 | dev_name(&master->dev)); | ||
| 978 | return -EAGAIN; | ||
| 979 | } | ||
| 980 | |||
| 981 | static int spi_imx_pio_transfer(struct spi_device *spi, | ||
| 734 | struct spi_transfer *transfer) | 982 | struct spi_transfer *transfer) |
| 735 | { | 983 | { |
| 736 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); | 984 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); |
| @@ -751,6 +999,24 @@ static int spi_imx_transfer(struct spi_device *spi, | |||
| 751 | return transfer->len; | 999 | return transfer->len; |
| 752 | } | 1000 | } |
| 753 | 1001 | ||
| 1002 | static int spi_imx_transfer(struct spi_device *spi, | ||
| 1003 | struct spi_transfer *transfer) | ||
| 1004 | { | ||
| 1005 | int ret; | ||
| 1006 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); | ||
| 1007 | |||
| 1008 | if (spi_imx->bitbang.master->can_dma && | ||
| 1009 | spi_imx_can_dma(spi_imx->bitbang.master, spi, transfer)) { | ||
| 1010 | spi_imx->usedma = true; | ||
| 1011 | ret = spi_imx_dma_transfer(spi_imx, transfer); | ||
| 1012 | if (ret != -EAGAIN) | ||
| 1013 | return ret; | ||
| 1014 | } | ||
| 1015 | spi_imx->usedma = false; | ||
| 1016 | |||
| 1017 | return spi_imx_pio_transfer(spi, transfer); | ||
| 1018 | } | ||
| 1019 | |||
| 754 | static int spi_imx_setup(struct spi_device *spi) | 1020 | static int spi_imx_setup(struct spi_device *spi) |
| 755 | { | 1021 | { |
| 756 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); | 1022 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); |
| @@ -911,6 +1177,13 @@ static int spi_imx_probe(struct platform_device *pdev) | |||
| 911 | goto out_put_per; | 1177 | goto out_put_per; |
| 912 | 1178 | ||
| 913 | spi_imx->spi_clk = clk_get_rate(spi_imx->clk_per); | 1179 | spi_imx->spi_clk = clk_get_rate(spi_imx->clk_per); |
| 1180 | /* | ||
| 1181 | * Only validated on i.mx6 now, can remove the constrain if validated on | ||
| 1182 | * other chips. | ||
| 1183 | */ | ||
| 1184 | if (spi_imx->devtype_data == &imx51_ecspi_devtype_data | ||
| 1185 | && spi_imx_sdma_init(&pdev->dev, spi_imx, master, res)) | ||
| 1186 | dev_err(&pdev->dev, "dma setup error,use pio instead\n"); | ||
| 914 | 1187 | ||
| 915 | spi_imx->devtype_data->reset(spi_imx); | 1188 | spi_imx->devtype_data->reset(spi_imx); |
| 916 | 1189 | ||
| @@ -949,6 +1222,7 @@ static int spi_imx_remove(struct platform_device *pdev) | |||
| 949 | writel(0, spi_imx->base + MXC_CSPICTRL); | 1222 | writel(0, spi_imx->base + MXC_CSPICTRL); |
| 950 | clk_unprepare(spi_imx->clk_ipg); | 1223 | clk_unprepare(spi_imx->clk_ipg); |
| 951 | clk_unprepare(spi_imx->clk_per); | 1224 | clk_unprepare(spi_imx->clk_per); |
| 1225 | spi_imx_sdma_exit(spi_imx); | ||
| 952 | spi_master_put(master); | 1226 | spi_master_put(master); |
| 953 | 1227 | ||
| 954 | return 0; | 1228 | return 0; |
diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c index 2884f0c2f5f0..51460878af04 100644 --- a/drivers/spi/spi-mxs.c +++ b/drivers/spi/spi-mxs.c | |||
| @@ -85,7 +85,7 @@ static int mxs_spi_setup_transfer(struct spi_device *dev, | |||
| 85 | mxs_ssp_set_clk_rate(ssp, hz); | 85 | mxs_ssp_set_clk_rate(ssp, hz); |
| 86 | /* | 86 | /* |
| 87 | * Save requested rate, hz, rather than the actual rate, | 87 | * Save requested rate, hz, rather than the actual rate, |
| 88 | * ssp->clk_rate. Otherwise we would set the rate every trasfer | 88 | * ssp->clk_rate. Otherwise we would set the rate every transfer |
| 89 | * when the actual rate is not quite the same as requested rate. | 89 | * when the actual rate is not quite the same as requested rate. |
| 90 | */ | 90 | */ |
| 91 | spi->sck = hz; | 91 | spi->sck = hz; |
| @@ -154,12 +154,14 @@ static int mxs_ssp_wait(struct mxs_spi *spi, int offset, int mask, bool set) | |||
| 154 | static void mxs_ssp_dma_irq_callback(void *param) | 154 | static void mxs_ssp_dma_irq_callback(void *param) |
| 155 | { | 155 | { |
| 156 | struct mxs_spi *spi = param; | 156 | struct mxs_spi *spi = param; |
| 157 | |||
| 157 | complete(&spi->c); | 158 | complete(&spi->c); |
| 158 | } | 159 | } |
| 159 | 160 | ||
| 160 | static irqreturn_t mxs_ssp_irq_handler(int irq, void *dev_id) | 161 | static irqreturn_t mxs_ssp_irq_handler(int irq, void *dev_id) |
| 161 | { | 162 | { |
| 162 | struct mxs_ssp *ssp = dev_id; | 163 | struct mxs_ssp *ssp = dev_id; |
| 164 | |||
| 163 | dev_err(ssp->dev, "%s[%i] CTRL1=%08x STATUS=%08x\n", | 165 | dev_err(ssp->dev, "%s[%i] CTRL1=%08x STATUS=%08x\n", |
| 164 | __func__, __LINE__, | 166 | __func__, __LINE__, |
| 165 | readl(ssp->base + HW_SSP_CTRL1(ssp)), | 167 | readl(ssp->base + HW_SSP_CTRL1(ssp)), |
| @@ -189,7 +191,7 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, | |||
| 189 | if (!len) | 191 | if (!len) |
| 190 | return -EINVAL; | 192 | return -EINVAL; |
| 191 | 193 | ||
| 192 | dma_xfer = kzalloc(sizeof(*dma_xfer) * sgs, GFP_KERNEL); | 194 | dma_xfer = kcalloc(sgs, sizeof(*dma_xfer), GFP_KERNEL); |
| 193 | if (!dma_xfer) | 195 | if (!dma_xfer) |
| 194 | return -ENOMEM; | 196 | return -ENOMEM; |
| 195 | 197 | ||
diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c index 5e91858f6f01..fb522765ce5a 100644 --- a/drivers/spi/spi-omap-100k.c +++ b/drivers/spi/spi-omap-100k.c | |||
| @@ -70,10 +70,6 @@ | |||
| 70 | #define SPI_STATUS_WE (1UL << 1) | 70 | #define SPI_STATUS_WE (1UL << 1) |
| 71 | #define SPI_STATUS_RD (1UL << 0) | 71 | #define SPI_STATUS_RD (1UL << 0) |
| 72 | 72 | ||
| 73 | #define WRITE 0 | ||
| 74 | #define READ 1 | ||
| 75 | |||
| 76 | |||
| 77 | /* use PIO for small transfers, avoiding DMA setup/teardown overhead and | 73 | /* use PIO for small transfers, avoiding DMA setup/teardown overhead and |
| 78 | * cache operations; better heuristics consider wordsize and bitrate. | 74 | * cache operations; better heuristics consider wordsize and bitrate. |
| 79 | */ | 75 | */ |
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index c4675fa8b645..835cdda6f4f5 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 19 | #include <linux/pm_runtime.h> | 19 | #include <linux/pm_runtime.h> |
| 20 | #include <linux/of.h> | 20 | #include <linux/of.h> |
| 21 | #include <linux/of_device.h> | ||
| 21 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
| 22 | #include <linux/sizes.h> | 23 | #include <linux/sizes.h> |
| 23 | #include <asm/unaligned.h> | 24 | #include <asm/unaligned.h> |
| @@ -40,13 +41,27 @@ | |||
| 40 | #define ORION_SPI_MODE_CPHA (1 << 12) | 41 | #define ORION_SPI_MODE_CPHA (1 << 12) |
| 41 | #define ORION_SPI_IF_8_16_BIT_MODE (1 << 5) | 42 | #define ORION_SPI_IF_8_16_BIT_MODE (1 << 5) |
| 42 | #define ORION_SPI_CLK_PRESCALE_MASK 0x1F | 43 | #define ORION_SPI_CLK_PRESCALE_MASK 0x1F |
| 44 | #define ARMADA_SPI_CLK_PRESCALE_MASK 0xDF | ||
| 43 | #define ORION_SPI_MODE_MASK (ORION_SPI_MODE_CPOL | \ | 45 | #define ORION_SPI_MODE_MASK (ORION_SPI_MODE_CPOL | \ |
| 44 | ORION_SPI_MODE_CPHA) | 46 | ORION_SPI_MODE_CPHA) |
| 45 | 47 | ||
| 48 | enum orion_spi_type { | ||
| 49 | ORION_SPI, | ||
| 50 | ARMADA_SPI, | ||
| 51 | }; | ||
| 52 | |||
| 53 | struct orion_spi_dev { | ||
| 54 | enum orion_spi_type typ; | ||
| 55 | unsigned int min_divisor; | ||
| 56 | unsigned int max_divisor; | ||
| 57 | u32 prescale_mask; | ||
| 58 | }; | ||
| 59 | |||
| 46 | struct orion_spi { | 60 | struct orion_spi { |
| 47 | struct spi_master *master; | 61 | struct spi_master *master; |
| 48 | void __iomem *base; | 62 | void __iomem *base; |
| 49 | struct clk *clk; | 63 | struct clk *clk; |
| 64 | const struct orion_spi_dev *devdata; | ||
| 50 | }; | 65 | }; |
| 51 | 66 | ||
| 52 | static inline void __iomem *spi_reg(struct orion_spi *orion_spi, u32 reg) | 67 | static inline void __iomem *spi_reg(struct orion_spi *orion_spi, u32 reg) |
| @@ -83,30 +98,66 @@ static int orion_spi_baudrate_set(struct spi_device *spi, unsigned int speed) | |||
| 83 | u32 prescale; | 98 | u32 prescale; |
| 84 | u32 reg; | 99 | u32 reg; |
| 85 | struct orion_spi *orion_spi; | 100 | struct orion_spi *orion_spi; |
| 101 | const struct orion_spi_dev *devdata; | ||
| 86 | 102 | ||
| 87 | orion_spi = spi_master_get_devdata(spi->master); | 103 | orion_spi = spi_master_get_devdata(spi->master); |
| 104 | devdata = orion_spi->devdata; | ||
| 88 | 105 | ||
| 89 | tclk_hz = clk_get_rate(orion_spi->clk); | 106 | tclk_hz = clk_get_rate(orion_spi->clk); |
| 90 | 107 | ||
| 91 | /* | 108 | if (devdata->typ == ARMADA_SPI) { |
| 92 | * the supported rates are: 4,6,8...30 | 109 | unsigned int clk, spr, sppr, sppr2, err; |
| 93 | * round up as we look for equal or less speed | 110 | unsigned int best_spr, best_sppr, best_err; |
| 94 | */ | ||
| 95 | rate = DIV_ROUND_UP(tclk_hz, speed); | ||
| 96 | rate = roundup(rate, 2); | ||
| 97 | 111 | ||
| 98 | /* check if requested speed is too small */ | 112 | best_err = speed; |
| 99 | if (rate > 30) | 113 | best_spr = 0; |
| 100 | return -EINVAL; | 114 | best_sppr = 0; |
| 101 | 115 | ||
| 102 | if (rate < 4) | 116 | /* Iterate over the valid range looking for best fit */ |
| 103 | rate = 4; | 117 | for (sppr = 0; sppr < 8; sppr++) { |
| 118 | sppr2 = 0x1 << sppr; | ||
| 119 | |||
| 120 | spr = tclk_hz / sppr2; | ||
| 121 | spr = DIV_ROUND_UP(spr, speed); | ||
| 122 | if ((spr == 0) || (spr > 15)) | ||
| 123 | continue; | ||
| 124 | |||
| 125 | clk = tclk_hz / (spr * sppr2); | ||
| 126 | err = speed - clk; | ||
| 127 | |||
| 128 | if (err < best_err) { | ||
| 129 | best_spr = spr; | ||
| 130 | best_sppr = sppr; | ||
| 131 | best_err = err; | ||
| 132 | } | ||
| 133 | } | ||
| 104 | 134 | ||
| 105 | /* Convert the rate to SPI clock divisor value. */ | 135 | if ((best_sppr == 0) && (best_spr == 0)) |
| 106 | prescale = 0x10 + rate/2; | 136 | return -EINVAL; |
| 137 | |||
| 138 | prescale = ((best_sppr & 0x6) << 5) | | ||
| 139 | ((best_sppr & 0x1) << 4) | best_spr; | ||
| 140 | } else { | ||
| 141 | /* | ||
| 142 | * the supported rates are: 4,6,8...30 | ||
| 143 | * round up as we look for equal or less speed | ||
| 144 | */ | ||
| 145 | rate = DIV_ROUND_UP(tclk_hz, speed); | ||
| 146 | rate = roundup(rate, 2); | ||
| 147 | |||
| 148 | /* check if requested speed is too small */ | ||
| 149 | if (rate > 30) | ||
| 150 | return -EINVAL; | ||
| 151 | |||
| 152 | if (rate < 4) | ||
| 153 | rate = 4; | ||
| 154 | |||
| 155 | /* Convert the rate to SPI clock divisor value. */ | ||
| 156 | prescale = 0x10 + rate/2; | ||
| 157 | } | ||
| 107 | 158 | ||
| 108 | reg = readl(spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG)); | 159 | reg = readl(spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG)); |
| 109 | reg = ((reg & ~ORION_SPI_CLK_PRESCALE_MASK) | prescale); | 160 | reg = ((reg & ~devdata->prescale_mask) | prescale); |
| 110 | writel(reg, spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG)); | 161 | writel(reg, spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG)); |
| 111 | 162 | ||
| 112 | return 0; | 163 | return 0; |
| @@ -179,8 +230,8 @@ static inline int orion_spi_wait_till_ready(struct orion_spi *orion_spi) | |||
| 179 | for (i = 0; i < ORION_SPI_WAIT_RDY_MAX_LOOP; i++) { | 230 | for (i = 0; i < ORION_SPI_WAIT_RDY_MAX_LOOP; i++) { |
| 180 | if (readl(spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG))) | 231 | if (readl(spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG))) |
| 181 | return 1; | 232 | return 1; |
| 182 | else | 233 | |
| 183 | udelay(1); | 234 | udelay(1); |
| 184 | } | 235 | } |
| 185 | 236 | ||
| 186 | return -1; | 237 | return -1; |
| @@ -342,8 +393,31 @@ static int orion_spi_reset(struct orion_spi *orion_spi) | |||
| 342 | return 0; | 393 | return 0; |
| 343 | } | 394 | } |
| 344 | 395 | ||
| 396 | static const struct orion_spi_dev orion_spi_dev_data = { | ||
| 397 | .typ = ORION_SPI, | ||
| 398 | .min_divisor = 4, | ||
| 399 | .max_divisor = 30, | ||
| 400 | .prescale_mask = ORION_SPI_CLK_PRESCALE_MASK, | ||
| 401 | }; | ||
| 402 | |||
| 403 | static const struct orion_spi_dev armada_spi_dev_data = { | ||
| 404 | .typ = ARMADA_SPI, | ||
| 405 | .min_divisor = 1, | ||
| 406 | .max_divisor = 1920, | ||
| 407 | .prescale_mask = ARMADA_SPI_CLK_PRESCALE_MASK, | ||
| 408 | }; | ||
| 409 | |||
| 410 | static const struct of_device_id orion_spi_of_match_table[] = { | ||
| 411 | { .compatible = "marvell,orion-spi", .data = &orion_spi_dev_data, }, | ||
| 412 | { .compatible = "marvell,armada-370-spi", .data = &armada_spi_dev_data, }, | ||
| 413 | {} | ||
| 414 | }; | ||
| 415 | MODULE_DEVICE_TABLE(of, orion_spi_of_match_table); | ||
| 416 | |||
| 345 | static int orion_spi_probe(struct platform_device *pdev) | 417 | static int orion_spi_probe(struct platform_device *pdev) |
| 346 | { | 418 | { |
| 419 | const struct of_device_id *of_id; | ||
| 420 | const struct orion_spi_dev *devdata; | ||
| 347 | struct spi_master *master; | 421 | struct spi_master *master; |
| 348 | struct orion_spi *spi; | 422 | struct orion_spi *spi; |
| 349 | struct resource *r; | 423 | struct resource *r; |
| @@ -360,6 +434,7 @@ static int orion_spi_probe(struct platform_device *pdev) | |||
| 360 | master->bus_num = pdev->id; | 434 | master->bus_num = pdev->id; |
| 361 | if (pdev->dev.of_node) { | 435 | if (pdev->dev.of_node) { |
| 362 | u32 cell_index; | 436 | u32 cell_index; |
| 437 | |||
| 363 | if (!of_property_read_u32(pdev->dev.of_node, "cell-index", | 438 | if (!of_property_read_u32(pdev->dev.of_node, "cell-index", |
| 364 | &cell_index)) | 439 | &cell_index)) |
| 365 | master->bus_num = cell_index; | 440 | master->bus_num = cell_index; |
| @@ -378,6 +453,10 @@ static int orion_spi_probe(struct platform_device *pdev) | |||
| 378 | spi = spi_master_get_devdata(master); | 453 | spi = spi_master_get_devdata(master); |
| 379 | spi->master = master; | 454 | spi->master = master; |
| 380 | 455 | ||
| 456 | of_id = of_match_device(orion_spi_of_match_table, &pdev->dev); | ||
| 457 | devdata = of_id->data; | ||
| 458 | spi->devdata = devdata; | ||
| 459 | |||
| 381 | spi->clk = devm_clk_get(&pdev->dev, NULL); | 460 | spi->clk = devm_clk_get(&pdev->dev, NULL); |
| 382 | if (IS_ERR(spi->clk)) { | 461 | if (IS_ERR(spi->clk)) { |
| 383 | status = PTR_ERR(spi->clk); | 462 | status = PTR_ERR(spi->clk); |
| @@ -389,8 +468,8 @@ static int orion_spi_probe(struct platform_device *pdev) | |||
| 389 | goto out; | 468 | goto out; |
| 390 | 469 | ||
| 391 | tclk_hz = clk_get_rate(spi->clk); | 470 | tclk_hz = clk_get_rate(spi->clk); |
| 392 | master->max_speed_hz = DIV_ROUND_UP(tclk_hz, 4); | 471 | master->max_speed_hz = DIV_ROUND_UP(tclk_hz, devdata->min_divisor); |
| 393 | master->min_speed_hz = DIV_ROUND_UP(tclk_hz, 30); | 472 | master->min_speed_hz = DIV_ROUND_UP(tclk_hz, devdata->max_divisor); |
| 394 | 473 | ||
| 395 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 474 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 396 | spi->base = devm_ioremap_resource(&pdev->dev, r); | 475 | spi->base = devm_ioremap_resource(&pdev->dev, r); |
| @@ -469,12 +548,6 @@ static const struct dev_pm_ops orion_spi_pm_ops = { | |||
| 469 | NULL) | 548 | NULL) |
| 470 | }; | 549 | }; |
| 471 | 550 | ||
| 472 | static const struct of_device_id orion_spi_of_match_table[] = { | ||
| 473 | { .compatible = "marvell,orion-spi", }, | ||
| 474 | {} | ||
| 475 | }; | ||
| 476 | MODULE_DEVICE_TABLE(of, orion_spi_of_match_table); | ||
| 477 | |||
| 478 | static struct platform_driver orion_spi_driver = { | 551 | static struct platform_driver orion_spi_driver = { |
| 479 | .driver = { | 552 | .driver = { |
| 480 | .name = DRIVER_NAME, | 553 | .name = DRIVER_NAME, |
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index f1f0a587e4fc..f35f723816ea 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
| @@ -82,6 +82,7 @@ | |||
| 82 | #define SSP_MIS(r) (r + 0x01C) | 82 | #define SSP_MIS(r) (r + 0x01C) |
| 83 | #define SSP_ICR(r) (r + 0x020) | 83 | #define SSP_ICR(r) (r + 0x020) |
| 84 | #define SSP_DMACR(r) (r + 0x024) | 84 | #define SSP_DMACR(r) (r + 0x024) |
| 85 | #define SSP_CSR(r) (r + 0x030) /* vendor extension */ | ||
| 85 | #define SSP_ITCR(r) (r + 0x080) | 86 | #define SSP_ITCR(r) (r + 0x080) |
| 86 | #define SSP_ITIP(r) (r + 0x084) | 87 | #define SSP_ITIP(r) (r + 0x084) |
| 87 | #define SSP_ITOP(r) (r + 0x088) | 88 | #define SSP_ITOP(r) (r + 0x088) |
| @@ -198,6 +199,12 @@ | |||
| 198 | #define SSP_DMACR_MASK_TXDMAE (0x1UL << 1) | 199 | #define SSP_DMACR_MASK_TXDMAE (0x1UL << 1) |
| 199 | 200 | ||
| 200 | /* | 201 | /* |
| 202 | * SSP Chip Select Control Register - SSP_CSR | ||
| 203 | * (vendor extension) | ||
| 204 | */ | ||
| 205 | #define SSP_CSR_CSVALUE_MASK (0x1FUL << 0) | ||
| 206 | |||
| 207 | /* | ||
| 201 | * SSP Integration Test control Register - SSP_ITCR | 208 | * SSP Integration Test control Register - SSP_ITCR |
| 202 | */ | 209 | */ |
| 203 | #define SSP_ITCR_MASK_ITEN (0x1UL << 0) | 210 | #define SSP_ITCR_MASK_ITEN (0x1UL << 0) |
| @@ -313,6 +320,7 @@ enum ssp_writing { | |||
| 313 | * @extended_cr: 32 bit wide control register 0 with extra | 320 | * @extended_cr: 32 bit wide control register 0 with extra |
| 314 | * features and extra features in CR1 as found in the ST variants | 321 | * features and extra features in CR1 as found in the ST variants |
| 315 | * @pl023: supports a subset of the ST extensions called "PL023" | 322 | * @pl023: supports a subset of the ST extensions called "PL023" |
| 323 | * @internal_cs_ctrl: supports chip select control register | ||
| 316 | */ | 324 | */ |
| 317 | struct vendor_data { | 325 | struct vendor_data { |
| 318 | int fifodepth; | 326 | int fifodepth; |
| @@ -321,6 +329,7 @@ struct vendor_data { | |||
| 321 | bool extended_cr; | 329 | bool extended_cr; |
| 322 | bool pl023; | 330 | bool pl023; |
| 323 | bool loopback; | 331 | bool loopback; |
| 332 | bool internal_cs_ctrl; | ||
| 324 | }; | 333 | }; |
| 325 | 334 | ||
| 326 | /** | 335 | /** |
| @@ -440,9 +449,32 @@ static void null_cs_control(u32 command) | |||
| 440 | pr_debug("pl022: dummy chip select control, CS=0x%x\n", command); | 449 | pr_debug("pl022: dummy chip select control, CS=0x%x\n", command); |
| 441 | } | 450 | } |
| 442 | 451 | ||
| 452 | /** | ||
| 453 | * internal_cs_control - Control chip select signals via SSP_CSR. | ||
| 454 | * @pl022: SSP driver private data structure | ||
| 455 | * @command: select/delect the chip | ||
| 456 | * | ||
| 457 | * Used on controller with internal chip select control via SSP_CSR register | ||
| 458 | * (vendor extension). Each of the 5 LSB in the register controls one chip | ||
| 459 | * select signal. | ||
| 460 | */ | ||
| 461 | static void internal_cs_control(struct pl022 *pl022, u32 command) | ||
| 462 | { | ||
| 463 | u32 tmp; | ||
| 464 | |||
| 465 | tmp = readw(SSP_CSR(pl022->virtbase)); | ||
| 466 | if (command == SSP_CHIP_SELECT) | ||
| 467 | tmp &= ~BIT(pl022->cur_cs); | ||
| 468 | else | ||
| 469 | tmp |= BIT(pl022->cur_cs); | ||
| 470 | writew(tmp, SSP_CSR(pl022->virtbase)); | ||
| 471 | } | ||
| 472 | |||
| 443 | static void pl022_cs_control(struct pl022 *pl022, u32 command) | 473 | static void pl022_cs_control(struct pl022 *pl022, u32 command) |
| 444 | { | 474 | { |
| 445 | if (gpio_is_valid(pl022->cur_cs)) | 475 | if (pl022->vendor->internal_cs_ctrl) |
| 476 | internal_cs_control(pl022, command); | ||
| 477 | else if (gpio_is_valid(pl022->cur_cs)) | ||
| 446 | gpio_set_value(pl022->cur_cs, command); | 478 | gpio_set_value(pl022->cur_cs, command); |
| 447 | else | 479 | else |
| 448 | pl022->cur_chip->cs_control(command); | 480 | pl022->cur_chip->cs_control(command); |
| @@ -2100,6 +2132,10 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
| 2100 | pl022->vendor = id->data; | 2132 | pl022->vendor = id->data; |
| 2101 | pl022->chipselects = devm_kzalloc(dev, num_cs * sizeof(int), | 2133 | pl022->chipselects = devm_kzalloc(dev, num_cs * sizeof(int), |
| 2102 | GFP_KERNEL); | 2134 | GFP_KERNEL); |
| 2135 | if (!pl022->chipselects) { | ||
| 2136 | status = -ENOMEM; | ||
| 2137 | goto err_no_mem; | ||
| 2138 | } | ||
| 2103 | 2139 | ||
| 2104 | /* | 2140 | /* |
| 2105 | * Bus Number Which has been Assigned to this SSP controller | 2141 | * Bus Number Which has been Assigned to this SSP controller |
| @@ -2118,6 +2154,9 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
| 2118 | if (platform_info->num_chipselect && platform_info->chipselects) { | 2154 | if (platform_info->num_chipselect && platform_info->chipselects) { |
| 2119 | for (i = 0; i < num_cs; i++) | 2155 | for (i = 0; i < num_cs; i++) |
| 2120 | pl022->chipselects[i] = platform_info->chipselects[i]; | 2156 | pl022->chipselects[i] = platform_info->chipselects[i]; |
| 2157 | } else if (pl022->vendor->internal_cs_ctrl) { | ||
| 2158 | for (i = 0; i < num_cs; i++) | ||
| 2159 | pl022->chipselects[i] = i; | ||
| 2121 | } else if (IS_ENABLED(CONFIG_OF)) { | 2160 | } else if (IS_ENABLED(CONFIG_OF)) { |
| 2122 | for (i = 0; i < num_cs; i++) { | 2161 | for (i = 0; i < num_cs; i++) { |
| 2123 | int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); | 2162 | int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); |
| @@ -2241,6 +2280,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
| 2241 | amba_release_regions(adev); | 2280 | amba_release_regions(adev); |
| 2242 | err_no_ioregion: | 2281 | err_no_ioregion: |
| 2243 | err_no_gpio: | 2282 | err_no_gpio: |
| 2283 | err_no_mem: | ||
| 2244 | spi_master_put(master); | 2284 | spi_master_put(master); |
| 2245 | return status; | 2285 | return status; |
| 2246 | } | 2286 | } |
| @@ -2347,6 +2387,7 @@ static struct vendor_data vendor_arm = { | |||
| 2347 | .extended_cr = false, | 2387 | .extended_cr = false, |
| 2348 | .pl023 = false, | 2388 | .pl023 = false, |
| 2349 | .loopback = true, | 2389 | .loopback = true, |
| 2390 | .internal_cs_ctrl = false, | ||
| 2350 | }; | 2391 | }; |
| 2351 | 2392 | ||
| 2352 | static struct vendor_data vendor_st = { | 2393 | static struct vendor_data vendor_st = { |
| @@ -2356,6 +2397,7 @@ static struct vendor_data vendor_st = { | |||
| 2356 | .extended_cr = true, | 2397 | .extended_cr = true, |
| 2357 | .pl023 = false, | 2398 | .pl023 = false, |
| 2358 | .loopback = true, | 2399 | .loopback = true, |
| 2400 | .internal_cs_ctrl = false, | ||
| 2359 | }; | 2401 | }; |
| 2360 | 2402 | ||
| 2361 | static struct vendor_data vendor_st_pl023 = { | 2403 | static struct vendor_data vendor_st_pl023 = { |
| @@ -2365,6 +2407,17 @@ static struct vendor_data vendor_st_pl023 = { | |||
| 2365 | .extended_cr = true, | 2407 | .extended_cr = true, |
| 2366 | .pl023 = true, | 2408 | .pl023 = true, |
| 2367 | .loopback = false, | 2409 | .loopback = false, |
| 2410 | .internal_cs_ctrl = false, | ||
| 2411 | }; | ||
| 2412 | |||
| 2413 | static struct vendor_data vendor_lsi = { | ||
| 2414 | .fifodepth = 8, | ||
| 2415 | .max_bpw = 16, | ||
| 2416 | .unidir = false, | ||
| 2417 | .extended_cr = false, | ||
| 2418 | .pl023 = false, | ||
| 2419 | .loopback = true, | ||
| 2420 | .internal_cs_ctrl = true, | ||
| 2368 | }; | 2421 | }; |
| 2369 | 2422 | ||
| 2370 | static struct amba_id pl022_ids[] = { | 2423 | static struct amba_id pl022_ids[] = { |
| @@ -2398,6 +2451,15 @@ static struct amba_id pl022_ids[] = { | |||
| 2398 | .mask = 0xffffffff, | 2451 | .mask = 0xffffffff, |
| 2399 | .data = &vendor_st_pl023, | 2452 | .data = &vendor_st_pl023, |
| 2400 | }, | 2453 | }, |
| 2454 | { | ||
| 2455 | /* | ||
| 2456 | * PL022 variant that has a chip select control register whih | ||
| 2457 | * allows control of 5 output signals nCS[0:4]. | ||
| 2458 | */ | ||
| 2459 | .id = 0x000b6022, | ||
| 2460 | .mask = 0x000fffff, | ||
| 2461 | .data = &vendor_lsi, | ||
| 2462 | }, | ||
| 2401 | { 0, 0 }, | 2463 | { 0, 0 }, |
| 2402 | }; | 2464 | }; |
| 2403 | 2465 | ||
diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c index c1865c92ccb9..536c863bebf1 100644 --- a/drivers/spi/spi-pxa2xx-pci.c +++ b/drivers/spi/spi-pxa2xx-pci.c | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | #include <linux/of_device.h> | 7 | #include <linux/of_device.h> |
| 8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
| 9 | #include <linux/spi/pxa2xx_spi.h> | 9 | #include <linux/spi/pxa2xx_spi.h> |
| 10 | #include <linux/clk.h> | ||
| 11 | #include <linux/clk-provider.h> | ||
| 10 | 12 | ||
| 11 | enum { | 13 | enum { |
| 12 | PORT_CE4100, | 14 | PORT_CE4100, |
| @@ -21,6 +23,7 @@ struct pxa_spi_info { | |||
| 21 | int tx_chan_id; | 23 | int tx_chan_id; |
| 22 | int rx_slave_id; | 24 | int rx_slave_id; |
| 23 | int rx_chan_id; | 25 | int rx_chan_id; |
| 26 | unsigned long max_clk_rate; | ||
| 24 | }; | 27 | }; |
| 25 | 28 | ||
| 26 | static struct pxa_spi_info spi_info_configs[] = { | 29 | static struct pxa_spi_info spi_info_configs[] = { |
| @@ -32,6 +35,7 @@ static struct pxa_spi_info spi_info_configs[] = { | |||
| 32 | .tx_chan_id = -1, | 35 | .tx_chan_id = -1, |
| 33 | .rx_slave_id = -1, | 36 | .rx_slave_id = -1, |
| 34 | .rx_chan_id = -1, | 37 | .rx_chan_id = -1, |
| 38 | .max_clk_rate = 3686400, | ||
| 35 | }, | 39 | }, |
| 36 | [PORT_BYT] = { | 40 | [PORT_BYT] = { |
| 37 | .type = LPSS_SSP, | 41 | .type = LPSS_SSP, |
| @@ -41,6 +45,7 @@ static struct pxa_spi_info spi_info_configs[] = { | |||
| 41 | .tx_chan_id = 0, | 45 | .tx_chan_id = 0, |
| 42 | .rx_slave_id = 1, | 46 | .rx_slave_id = 1, |
| 43 | .rx_chan_id = 1, | 47 | .rx_chan_id = 1, |
| 48 | .max_clk_rate = 50000000, | ||
| 44 | }, | 49 | }, |
| 45 | }; | 50 | }; |
| 46 | 51 | ||
| @@ -53,6 +58,7 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, | |||
| 53 | struct pxa2xx_spi_master spi_pdata; | 58 | struct pxa2xx_spi_master spi_pdata; |
| 54 | struct ssp_device *ssp; | 59 | struct ssp_device *ssp; |
| 55 | struct pxa_spi_info *c; | 60 | struct pxa_spi_info *c; |
| 61 | char buf[40]; | ||
| 56 | 62 | ||
| 57 | ret = pcim_enable_device(dev); | 63 | ret = pcim_enable_device(dev); |
| 58 | if (ret) | 64 | if (ret) |
| @@ -84,6 +90,12 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, | |||
| 84 | ssp->port_id = (c->port_id >= 0) ? c->port_id : dev->devfn; | 90 | ssp->port_id = (c->port_id >= 0) ? c->port_id : dev->devfn; |
| 85 | ssp->type = c->type; | 91 | ssp->type = c->type; |
| 86 | 92 | ||
| 93 | snprintf(buf, sizeof(buf), "pxa2xx-spi.%d", ssp->port_id); | ||
| 94 | ssp->clk = clk_register_fixed_rate(&dev->dev, buf , NULL, | ||
| 95 | CLK_IS_ROOT, c->max_clk_rate); | ||
| 96 | if (IS_ERR(ssp->clk)) | ||
| 97 | return PTR_ERR(ssp->clk); | ||
| 98 | |||
| 87 | memset(&pi, 0, sizeof(pi)); | 99 | memset(&pi, 0, sizeof(pi)); |
| 88 | pi.parent = &dev->dev; | 100 | pi.parent = &dev->dev; |
| 89 | pi.name = "pxa2xx-spi"; | 101 | pi.name = "pxa2xx-spi"; |
| @@ -92,8 +104,10 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, | |||
| 92 | pi.size_data = sizeof(spi_pdata); | 104 | pi.size_data = sizeof(spi_pdata); |
| 93 | 105 | ||
| 94 | pdev = platform_device_register_full(&pi); | 106 | pdev = platform_device_register_full(&pi); |
| 95 | if (IS_ERR(pdev)) | 107 | if (IS_ERR(pdev)) { |
| 108 | clk_unregister(ssp->clk); | ||
| 96 | return PTR_ERR(pdev); | 109 | return PTR_ERR(pdev); |
| 110 | } | ||
| 97 | 111 | ||
| 98 | pci_set_drvdata(dev, pdev); | 112 | pci_set_drvdata(dev, pdev); |
| 99 | 113 | ||
| @@ -103,8 +117,12 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, | |||
| 103 | static void pxa2xx_spi_pci_remove(struct pci_dev *dev) | 117 | static void pxa2xx_spi_pci_remove(struct pci_dev *dev) |
| 104 | { | 118 | { |
| 105 | struct platform_device *pdev = pci_get_drvdata(dev); | 119 | struct platform_device *pdev = pci_get_drvdata(dev); |
| 120 | struct pxa2xx_spi_master *spi_pdata; | ||
| 121 | |||
| 122 | spi_pdata = dev_get_platdata(&pdev->dev); | ||
| 106 | 123 | ||
| 107 | platform_device_unregister(pdev); | 124 | platform_device_unregister(pdev); |
| 125 | clk_unregister(spi_pdata->ssp.clk); | ||
| 108 | } | 126 | } |
| 109 | 127 | ||
| 110 | static const struct pci_device_id pxa2xx_spi_pci_devices[] = { | 128 | static const struct pci_device_id pxa2xx_spi_pci_devices[] = { |
diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c index 3afc266b666d..f96ea8a38d64 100644 --- a/drivers/spi/spi-rockchip.c +++ b/drivers/spi/spi-rockchip.c | |||
| @@ -415,7 +415,7 @@ static void rockchip_spi_dma_txcb(void *data) | |||
| 415 | spin_unlock_irqrestore(&rs->lock, flags); | 415 | spin_unlock_irqrestore(&rs->lock, flags); |
| 416 | } | 416 | } |
| 417 | 417 | ||
| 418 | static int rockchip_spi_dma_transfer(struct rockchip_spi *rs) | 418 | static void rockchip_spi_prepare_dma(struct rockchip_spi *rs) |
| 419 | { | 419 | { |
| 420 | unsigned long flags; | 420 | unsigned long flags; |
| 421 | struct dma_slave_config rxconf, txconf; | 421 | struct dma_slave_config rxconf, txconf; |
| @@ -474,8 +474,6 @@ static int rockchip_spi_dma_transfer(struct rockchip_spi *rs) | |||
| 474 | dmaengine_submit(txdesc); | 474 | dmaengine_submit(txdesc); |
| 475 | dma_async_issue_pending(rs->dma_tx.ch); | 475 | dma_async_issue_pending(rs->dma_tx.ch); |
| 476 | } | 476 | } |
| 477 | |||
| 478 | return 1; | ||
| 479 | } | 477 | } |
| 480 | 478 | ||
| 481 | static void rockchip_spi_config(struct rockchip_spi *rs) | 479 | static void rockchip_spi_config(struct rockchip_spi *rs) |
| @@ -557,16 +555,17 @@ static int rockchip_spi_transfer_one( | |||
| 557 | else if (rs->rx) | 555 | else if (rs->rx) |
| 558 | rs->tmode = CR0_XFM_RO; | 556 | rs->tmode = CR0_XFM_RO; |
| 559 | 557 | ||
| 560 | if (master->can_dma && master->can_dma(master, spi, xfer)) | 558 | /* we need prepare dma before spi was enabled */ |
| 559 | if (master->can_dma && master->can_dma(master, spi, xfer)) { | ||
| 561 | rs->use_dma = 1; | 560 | rs->use_dma = 1; |
| 562 | else | 561 | rockchip_spi_prepare_dma(rs); |
| 562 | } else { | ||
| 563 | rs->use_dma = 0; | 563 | rs->use_dma = 0; |
| 564 | } | ||
| 564 | 565 | ||
| 565 | rockchip_spi_config(rs); | 566 | rockchip_spi_config(rs); |
| 566 | 567 | ||
| 567 | if (rs->use_dma) | 568 | if (!rs->use_dma) |
| 568 | ret = rockchip_spi_dma_transfer(rs); | ||
| 569 | else | ||
| 570 | ret = rockchip_spi_pio_transfer(rs); | 569 | ret = rockchip_spi_pio_transfer(rs); |
| 571 | 570 | ||
| 572 | return ret; | 571 | return ret; |
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index ad87a98f8f68..54bb0faec155 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c | |||
| @@ -87,7 +87,7 @@ | |||
| 87 | /* RSPI on SH only */ | 87 | /* RSPI on SH only */ |
| 88 | #define SPCR_TXMD 0x02 /* TX Only Mode (vs. Full Duplex) */ | 88 | #define SPCR_TXMD 0x02 /* TX Only Mode (vs. Full Duplex) */ |
| 89 | #define SPCR_SPMS 0x01 /* 3-wire Mode (vs. 4-wire) */ | 89 | #define SPCR_SPMS 0x01 /* 3-wire Mode (vs. 4-wire) */ |
| 90 | /* QSPI on R-Car M2 only */ | 90 | /* QSPI on R-Car Gen2 only */ |
| 91 | #define SPCR_WSWAP 0x02 /* Word Swap of read-data for DMAC */ | 91 | #define SPCR_WSWAP 0x02 /* Word Swap of read-data for DMAC */ |
| 92 | #define SPCR_BSWAP 0x01 /* Byte Swap of read-data for DMAC */ | 92 | #define SPCR_BSWAP 0x01 /* Byte Swap of read-data for DMAC */ |
| 93 | 93 | ||
| @@ -909,20 +909,24 @@ static struct dma_chan *rspi_request_dma_chan(struct device *dev, | |||
| 909 | dma_cap_zero(mask); | 909 | dma_cap_zero(mask); |
| 910 | dma_cap_set(DMA_SLAVE, mask); | 910 | dma_cap_set(DMA_SLAVE, mask); |
| 911 | 911 | ||
| 912 | chan = dma_request_channel(mask, shdma_chan_filter, | 912 | chan = dma_request_slave_channel_compat(mask, shdma_chan_filter, |
| 913 | (void *)(unsigned long)id); | 913 | (void *)(unsigned long)id, dev, |
| 914 | dir == DMA_MEM_TO_DEV ? "tx" : "rx"); | ||
| 914 | if (!chan) { | 915 | if (!chan) { |
| 915 | dev_warn(dev, "dma_request_channel failed\n"); | 916 | dev_warn(dev, "dma_request_slave_channel_compat failed\n"); |
| 916 | return NULL; | 917 | return NULL; |
| 917 | } | 918 | } |
| 918 | 919 | ||
| 919 | memset(&cfg, 0, sizeof(cfg)); | 920 | memset(&cfg, 0, sizeof(cfg)); |
| 920 | cfg.slave_id = id; | 921 | cfg.slave_id = id; |
| 921 | cfg.direction = dir; | 922 | cfg.direction = dir; |
| 922 | if (dir == DMA_MEM_TO_DEV) | 923 | if (dir == DMA_MEM_TO_DEV) { |
| 923 | cfg.dst_addr = port_addr; | 924 | cfg.dst_addr = port_addr; |
| 924 | else | 925 | cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; |
| 926 | } else { | ||
| 925 | cfg.src_addr = port_addr; | 927 | cfg.src_addr = port_addr; |
| 928 | cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
| 929 | } | ||
| 926 | 930 | ||
| 927 | ret = dmaengine_slave_config(chan, &cfg); | 931 | ret = dmaengine_slave_config(chan, &cfg); |
| 928 | if (ret) { | 932 | if (ret) { |
| @@ -938,22 +942,30 @@ static int rspi_request_dma(struct device *dev, struct spi_master *master, | |||
| 938 | const struct resource *res) | 942 | const struct resource *res) |
| 939 | { | 943 | { |
| 940 | const struct rspi_plat_data *rspi_pd = dev_get_platdata(dev); | 944 | const struct rspi_plat_data *rspi_pd = dev_get_platdata(dev); |
| 945 | unsigned int dma_tx_id, dma_rx_id; | ||
| 946 | |||
| 947 | if (dev->of_node) { | ||
| 948 | /* In the OF case we will get the slave IDs from the DT */ | ||
| 949 | dma_tx_id = 0; | ||
| 950 | dma_rx_id = 0; | ||
| 951 | } else if (rspi_pd && rspi_pd->dma_tx_id && rspi_pd->dma_rx_id) { | ||
| 952 | dma_tx_id = rspi_pd->dma_tx_id; | ||
| 953 | dma_rx_id = rspi_pd->dma_rx_id; | ||
| 954 | } else { | ||
| 955 | /* The driver assumes no error. */ | ||
| 956 | return 0; | ||
| 957 | } | ||
| 941 | 958 | ||
| 942 | if (!rspi_pd || !rspi_pd->dma_rx_id || !rspi_pd->dma_tx_id) | 959 | master->dma_tx = rspi_request_dma_chan(dev, DMA_MEM_TO_DEV, dma_tx_id, |
| 943 | return 0; /* The driver assumes no error. */ | ||
| 944 | |||
| 945 | master->dma_rx = rspi_request_dma_chan(dev, DMA_DEV_TO_MEM, | ||
| 946 | rspi_pd->dma_rx_id, | ||
| 947 | res->start + RSPI_SPDR); | 960 | res->start + RSPI_SPDR); |
| 948 | if (!master->dma_rx) | 961 | if (!master->dma_tx) |
| 949 | return -ENODEV; | 962 | return -ENODEV; |
| 950 | 963 | ||
| 951 | master->dma_tx = rspi_request_dma_chan(dev, DMA_MEM_TO_DEV, | 964 | master->dma_rx = rspi_request_dma_chan(dev, DMA_DEV_TO_MEM, dma_rx_id, |
| 952 | rspi_pd->dma_tx_id, | ||
| 953 | res->start + RSPI_SPDR); | 965 | res->start + RSPI_SPDR); |
| 954 | if (!master->dma_tx) { | 966 | if (!master->dma_rx) { |
| 955 | dma_release_channel(master->dma_rx); | 967 | dma_release_channel(master->dma_tx); |
| 956 | master->dma_rx = NULL; | 968 | master->dma_tx = NULL; |
| 957 | return -ENODEV; | 969 | return -ENODEV; |
| 958 | } | 970 | } |
| 959 | 971 | ||
| @@ -1046,12 +1058,11 @@ static int rspi_request_irq(struct device *dev, unsigned int irq, | |||
| 1046 | irq_handler_t handler, const char *suffix, | 1058 | irq_handler_t handler, const char *suffix, |
| 1047 | void *dev_id) | 1059 | void *dev_id) |
| 1048 | { | 1060 | { |
| 1049 | const char *base = dev_name(dev); | 1061 | const char *name = devm_kasprintf(dev, GFP_KERNEL, "%s:%s", |
| 1050 | size_t len = strlen(base) + strlen(suffix) + 2; | 1062 | dev_name(dev), suffix); |
| 1051 | char *name = devm_kzalloc(dev, len, GFP_KERNEL); | ||
| 1052 | if (!name) | 1063 | if (!name) |
| 1053 | return -ENOMEM; | 1064 | return -ENOMEM; |
| 1054 | snprintf(name, len, "%s:%s", base, suffix); | 1065 | |
| 1055 | return devm_request_irq(dev, irq, handler, 0, name, dev_id); | 1066 | return devm_request_irq(dev, irq, handler, 0, name, dev_id); |
| 1056 | } | 1067 | } |
| 1057 | 1068 | ||
| @@ -1084,7 +1095,7 @@ static int rspi_probe(struct platform_device *pdev) | |||
| 1084 | master->num_chipselect = rspi_pd->num_chipselect; | 1095 | master->num_chipselect = rspi_pd->num_chipselect; |
| 1085 | else | 1096 | else |
| 1086 | master->num_chipselect = 2; /* default */ | 1097 | master->num_chipselect = 2; /* default */ |
| 1087 | }; | 1098 | } |
| 1088 | 1099 | ||
| 1089 | /* ops parameter check */ | 1100 | /* ops parameter check */ |
| 1090 | if (!ops->set_config_register) { | 1101 | if (!ops->set_config_register) { |
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 543075b80f16..3f365402fcc0 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c | |||
| @@ -642,18 +642,14 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, | |||
| 642 | desc_rx = dmaengine_prep_slave_single(p->master->dma_rx, | 642 | desc_rx = dmaengine_prep_slave_single(p->master->dma_rx, |
| 643 | p->rx_dma_addr, len, DMA_FROM_DEVICE, | 643 | p->rx_dma_addr, len, DMA_FROM_DEVICE, |
| 644 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 644 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
| 645 | if (!desc_rx) { | 645 | if (!desc_rx) |
| 646 | ret = -EAGAIN; | 646 | return -EAGAIN; |
| 647 | goto no_dma_rx; | ||
| 648 | } | ||
| 649 | 647 | ||
| 650 | desc_rx->callback = sh_msiof_dma_complete; | 648 | desc_rx->callback = sh_msiof_dma_complete; |
| 651 | desc_rx->callback_param = p; | 649 | desc_rx->callback_param = p; |
| 652 | cookie = dmaengine_submit(desc_rx); | 650 | cookie = dmaengine_submit(desc_rx); |
| 653 | if (dma_submit_error(cookie)) { | 651 | if (dma_submit_error(cookie)) |
| 654 | ret = cookie; | 652 | return cookie; |
| 655 | goto no_dma_rx; | ||
| 656 | } | ||
| 657 | } | 653 | } |
| 658 | 654 | ||
| 659 | if (tx) { | 655 | if (tx) { |
| @@ -738,7 +734,6 @@ no_dma_tx: | |||
| 738 | if (rx) | 734 | if (rx) |
| 739 | dmaengine_terminate_all(p->master->dma_rx); | 735 | dmaengine_terminate_all(p->master->dma_rx); |
| 740 | sh_msiof_write(p, IER, 0); | 736 | sh_msiof_write(p, IER, 0); |
| 741 | no_dma_rx: | ||
| 742 | return ret; | 737 | return ret; |
| 743 | } | 738 | } |
| 744 | 739 | ||
| @@ -933,6 +928,9 @@ static const struct of_device_id sh_msiof_match[] = { | |||
| 933 | { .compatible = "renesas,sh-mobile-msiof", .data = &sh_data }, | 928 | { .compatible = "renesas,sh-mobile-msiof", .data = &sh_data }, |
| 934 | { .compatible = "renesas,msiof-r8a7790", .data = &r8a779x_data }, | 929 | { .compatible = "renesas,msiof-r8a7790", .data = &r8a779x_data }, |
| 935 | { .compatible = "renesas,msiof-r8a7791", .data = &r8a779x_data }, | 930 | { .compatible = "renesas,msiof-r8a7791", .data = &r8a779x_data }, |
| 931 | { .compatible = "renesas,msiof-r8a7792", .data = &r8a779x_data }, | ||
| 932 | { .compatible = "renesas,msiof-r8a7793", .data = &r8a779x_data }, | ||
| 933 | { .compatible = "renesas,msiof-r8a7794", .data = &r8a779x_data }, | ||
| 936 | {}, | 934 | {}, |
| 937 | }; | 935 | }; |
| 938 | MODULE_DEVICE_TABLE(of, sh_msiof_match); | 936 | MODULE_DEVICE_TABLE(of, sh_msiof_match); |
| @@ -977,20 +975,24 @@ static struct dma_chan *sh_msiof_request_dma_chan(struct device *dev, | |||
| 977 | dma_cap_zero(mask); | 975 | dma_cap_zero(mask); |
| 978 | dma_cap_set(DMA_SLAVE, mask); | 976 | dma_cap_set(DMA_SLAVE, mask); |
| 979 | 977 | ||
| 980 | chan = dma_request_channel(mask, shdma_chan_filter, | 978 | chan = dma_request_slave_channel_compat(mask, shdma_chan_filter, |
| 981 | (void *)(unsigned long)id); | 979 | (void *)(unsigned long)id, dev, |
| 980 | dir == DMA_MEM_TO_DEV ? "tx" : "rx"); | ||
| 982 | if (!chan) { | 981 | if (!chan) { |
| 983 | dev_warn(dev, "dma_request_channel failed\n"); | 982 | dev_warn(dev, "dma_request_slave_channel_compat failed\n"); |
| 984 | return NULL; | 983 | return NULL; |
| 985 | } | 984 | } |
| 986 | 985 | ||
| 987 | memset(&cfg, 0, sizeof(cfg)); | 986 | memset(&cfg, 0, sizeof(cfg)); |
| 988 | cfg.slave_id = id; | 987 | cfg.slave_id = id; |
| 989 | cfg.direction = dir; | 988 | cfg.direction = dir; |
| 990 | if (dir == DMA_MEM_TO_DEV) | 989 | if (dir == DMA_MEM_TO_DEV) { |
| 991 | cfg.dst_addr = port_addr; | 990 | cfg.dst_addr = port_addr; |
| 992 | else | 991 | cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
| 992 | } else { | ||
| 993 | cfg.src_addr = port_addr; | 993 | cfg.src_addr = port_addr; |
| 994 | cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 995 | } | ||
| 994 | 996 | ||
| 995 | ret = dmaengine_slave_config(chan, &cfg); | 997 | ret = dmaengine_slave_config(chan, &cfg); |
| 996 | if (ret) { | 998 | if (ret) { |
| @@ -1007,12 +1009,22 @@ static int sh_msiof_request_dma(struct sh_msiof_spi_priv *p) | |||
| 1007 | struct platform_device *pdev = p->pdev; | 1009 | struct platform_device *pdev = p->pdev; |
| 1008 | struct device *dev = &pdev->dev; | 1010 | struct device *dev = &pdev->dev; |
| 1009 | const struct sh_msiof_spi_info *info = dev_get_platdata(dev); | 1011 | const struct sh_msiof_spi_info *info = dev_get_platdata(dev); |
| 1012 | unsigned int dma_tx_id, dma_rx_id; | ||
| 1010 | const struct resource *res; | 1013 | const struct resource *res; |
| 1011 | struct spi_master *master; | 1014 | struct spi_master *master; |
| 1012 | struct device *tx_dev, *rx_dev; | 1015 | struct device *tx_dev, *rx_dev; |
| 1013 | 1016 | ||
| 1014 | if (!info || !info->dma_tx_id || !info->dma_rx_id) | 1017 | if (dev->of_node) { |
| 1015 | return 0; /* The driver assumes no error */ | 1018 | /* In the OF case we will get the slave IDs from the DT */ |
| 1019 | dma_tx_id = 0; | ||
| 1020 | dma_rx_id = 0; | ||
| 1021 | } else if (info && info->dma_tx_id && info->dma_rx_id) { | ||
| 1022 | dma_tx_id = info->dma_tx_id; | ||
| 1023 | dma_rx_id = info->dma_rx_id; | ||
| 1024 | } else { | ||
| 1025 | /* The driver assumes no error */ | ||
| 1026 | return 0; | ||
| 1027 | } | ||
| 1016 | 1028 | ||
| 1017 | /* The DMA engine uses the second register set, if present */ | 1029 | /* The DMA engine uses the second register set, if present */ |
| 1018 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 1030 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
| @@ -1021,13 +1033,13 @@ static int sh_msiof_request_dma(struct sh_msiof_spi_priv *p) | |||
| 1021 | 1033 | ||
| 1022 | master = p->master; | 1034 | master = p->master; |
| 1023 | master->dma_tx = sh_msiof_request_dma_chan(dev, DMA_MEM_TO_DEV, | 1035 | master->dma_tx = sh_msiof_request_dma_chan(dev, DMA_MEM_TO_DEV, |
| 1024 | info->dma_tx_id, | 1036 | dma_tx_id, |
| 1025 | res->start + TFDR); | 1037 | res->start + TFDR); |
| 1026 | if (!master->dma_tx) | 1038 | if (!master->dma_tx) |
| 1027 | return -ENODEV; | 1039 | return -ENODEV; |
| 1028 | 1040 | ||
| 1029 | master->dma_rx = sh_msiof_request_dma_chan(dev, DMA_DEV_TO_MEM, | 1041 | master->dma_rx = sh_msiof_request_dma_chan(dev, DMA_DEV_TO_MEM, |
| 1030 | info->dma_rx_id, | 1042 | dma_rx_id, |
| 1031 | res->start + RFDR); | 1043 | res->start + RFDR); |
| 1032 | if (!master->dma_rx) | 1044 | if (!master->dma_rx) |
| 1033 | goto free_tx_chan; | 1045 | goto free_tx_chan; |
| @@ -1210,6 +1222,9 @@ static struct platform_device_id spi_driver_ids[] = { | |||
| 1210 | { "spi_sh_msiof", (kernel_ulong_t)&sh_data }, | 1222 | { "spi_sh_msiof", (kernel_ulong_t)&sh_data }, |
| 1211 | { "spi_r8a7790_msiof", (kernel_ulong_t)&r8a779x_data }, | 1223 | { "spi_r8a7790_msiof", (kernel_ulong_t)&r8a779x_data }, |
| 1212 | { "spi_r8a7791_msiof", (kernel_ulong_t)&r8a779x_data }, | 1224 | { "spi_r8a7791_msiof", (kernel_ulong_t)&r8a779x_data }, |
| 1225 | { "spi_r8a7792_msiof", (kernel_ulong_t)&r8a779x_data }, | ||
| 1226 | { "spi_r8a7793_msiof", (kernel_ulong_t)&r8a779x_data }, | ||
| 1227 | { "spi_r8a7794_msiof", (kernel_ulong_t)&r8a779x_data }, | ||
| 1213 | {}, | 1228 | {}, |
| 1214 | }; | 1229 | }; |
| 1215 | MODULE_DEVICE_TABLE(platform, spi_driver_ids); | 1230 | MODULE_DEVICE_TABLE(platform, spi_driver_ids); |
diff --git a/drivers/spi/spi-sirf.c b/drivers/spi/spi-sirf.c index 6f0602fd7401..39e2c0a55a28 100644 --- a/drivers/spi/spi-sirf.c +++ b/drivers/spi/spi-sirf.c | |||
| @@ -62,15 +62,15 @@ | |||
| 62 | #define SIRFSOC_SPI_TRAN_DAT_FORMAT_12 (1 << 26) | 62 | #define SIRFSOC_SPI_TRAN_DAT_FORMAT_12 (1 << 26) |
| 63 | #define SIRFSOC_SPI_TRAN_DAT_FORMAT_16 (2 << 26) | 63 | #define SIRFSOC_SPI_TRAN_DAT_FORMAT_16 (2 << 26) |
| 64 | #define SIRFSOC_SPI_TRAN_DAT_FORMAT_32 (3 << 26) | 64 | #define SIRFSOC_SPI_TRAN_DAT_FORMAT_32 (3 << 26) |
| 65 | #define SIRFSOC_SPI_CMD_BYTE_NUM(x) ((x & 3) << 28) | 65 | #define SIRFSOC_SPI_CMD_BYTE_NUM(x) ((x & 3) << 28) |
| 66 | #define SIRFSOC_SPI_ENA_AUTO_CLR BIT(30) | 66 | #define SIRFSOC_SPI_ENA_AUTO_CLR BIT(30) |
| 67 | #define SIRFSOC_SPI_MUL_DAT_MODE BIT(31) | 67 | #define SIRFSOC_SPI_MUL_DAT_MODE BIT(31) |
| 68 | 68 | ||
| 69 | /* Interrupt Enable */ | 69 | /* Interrupt Enable */ |
| 70 | #define SIRFSOC_SPI_RX_DONE_INT_EN BIT(0) | 70 | #define SIRFSOC_SPI_RX_DONE_INT_EN BIT(0) |
| 71 | #define SIRFSOC_SPI_TX_DONE_INT_EN BIT(1) | 71 | #define SIRFSOC_SPI_TX_DONE_INT_EN BIT(1) |
| 72 | #define SIRFSOC_SPI_RX_OFLOW_INT_EN BIT(2) | 72 | #define SIRFSOC_SPI_RX_OFLOW_INT_EN BIT(2) |
| 73 | #define SIRFSOC_SPI_TX_UFLOW_INT_EN BIT(3) | 73 | #define SIRFSOC_SPI_TX_UFLOW_INT_EN BIT(3) |
| 74 | #define SIRFSOC_SPI_RX_IO_DMA_INT_EN BIT(4) | 74 | #define SIRFSOC_SPI_RX_IO_DMA_INT_EN BIT(4) |
| 75 | #define SIRFSOC_SPI_TX_IO_DMA_INT_EN BIT(5) | 75 | #define SIRFSOC_SPI_TX_IO_DMA_INT_EN BIT(5) |
| 76 | #define SIRFSOC_SPI_RXFIFO_FULL_INT_EN BIT(6) | 76 | #define SIRFSOC_SPI_RXFIFO_FULL_INT_EN BIT(6) |
| @@ -79,7 +79,7 @@ | |||
| 79 | #define SIRFSOC_SPI_TXFIFO_THD_INT_EN BIT(9) | 79 | #define SIRFSOC_SPI_TXFIFO_THD_INT_EN BIT(9) |
| 80 | #define SIRFSOC_SPI_FRM_END_INT_EN BIT(10) | 80 | #define SIRFSOC_SPI_FRM_END_INT_EN BIT(10) |
| 81 | 81 | ||
| 82 | #define SIRFSOC_SPI_INT_MASK_ALL 0x1FFF | 82 | #define SIRFSOC_SPI_INT_MASK_ALL 0x1FFF |
| 83 | 83 | ||
| 84 | /* Interrupt status */ | 84 | /* Interrupt status */ |
| 85 | #define SIRFSOC_SPI_RX_DONE BIT(0) | 85 | #define SIRFSOC_SPI_RX_DONE BIT(0) |
| @@ -170,8 +170,7 @@ struct sirfsoc_spi { | |||
| 170 | * command model | 170 | * command model |
| 171 | */ | 171 | */ |
| 172 | bool tx_by_cmd; | 172 | bool tx_by_cmd; |
| 173 | 173 | bool hw_cs; | |
| 174 | int chipselect[0]; | ||
| 175 | }; | 174 | }; |
| 176 | 175 | ||
| 177 | static void spi_sirfsoc_rx_word_u8(struct sirfsoc_spi *sspi) | 176 | static void spi_sirfsoc_rx_word_u8(struct sirfsoc_spi *sspi) |
| @@ -304,7 +303,7 @@ static void spi_sirfsoc_dma_fini_callback(void *data) | |||
| 304 | complete(dma_complete); | 303 | complete(dma_complete); |
| 305 | } | 304 | } |
| 306 | 305 | ||
| 307 | static int spi_sirfsoc_cmd_transfer(struct spi_device *spi, | 306 | static void spi_sirfsoc_cmd_transfer(struct spi_device *spi, |
| 308 | struct spi_transfer *t) | 307 | struct spi_transfer *t) |
| 309 | { | 308 | { |
| 310 | struct sirfsoc_spi *sspi; | 309 | struct sirfsoc_spi *sspi; |
| @@ -328,10 +327,9 @@ static int spi_sirfsoc_cmd_transfer(struct spi_device *spi, | |||
| 328 | sspi->base + SIRFSOC_SPI_TX_RX_EN); | 327 | sspi->base + SIRFSOC_SPI_TX_RX_EN); |
| 329 | if (wait_for_completion_timeout(&sspi->tx_done, timeout) == 0) { | 328 | if (wait_for_completion_timeout(&sspi->tx_done, timeout) == 0) { |
| 330 | dev_err(&spi->dev, "cmd transfer timeout\n"); | 329 | dev_err(&spi->dev, "cmd transfer timeout\n"); |
| 331 | return 0; | 330 | return; |
| 332 | } | 331 | } |
| 333 | 332 | sspi->left_rx_word -= t->len; | |
| 334 | return t->len; | ||
| 335 | } | 333 | } |
| 336 | 334 | ||
| 337 | static void spi_sirfsoc_dma_transfer(struct spi_device *spi, | 335 | static void spi_sirfsoc_dma_transfer(struct spi_device *spi, |
| @@ -487,7 +485,7 @@ static void spi_sirfsoc_chipselect(struct spi_device *spi, int value) | |||
| 487 | { | 485 | { |
| 488 | struct sirfsoc_spi *sspi = spi_master_get_devdata(spi->master); | 486 | struct sirfsoc_spi *sspi = spi_master_get_devdata(spi->master); |
| 489 | 487 | ||
| 490 | if (sspi->chipselect[spi->chip_select] == 0) { | 488 | if (sspi->hw_cs) { |
| 491 | u32 regval = readl(sspi->base + SIRFSOC_SPI_CTRL); | 489 | u32 regval = readl(sspi->base + SIRFSOC_SPI_CTRL); |
| 492 | switch (value) { | 490 | switch (value) { |
| 493 | case BITBANG_CS_ACTIVE: | 491 | case BITBANG_CS_ACTIVE: |
| @@ -505,14 +503,13 @@ static void spi_sirfsoc_chipselect(struct spi_device *spi, int value) | |||
| 505 | } | 503 | } |
| 506 | writel(regval, sspi->base + SIRFSOC_SPI_CTRL); | 504 | writel(regval, sspi->base + SIRFSOC_SPI_CTRL); |
| 507 | } else { | 505 | } else { |
| 508 | int gpio = sspi->chipselect[spi->chip_select]; | ||
| 509 | switch (value) { | 506 | switch (value) { |
| 510 | case BITBANG_CS_ACTIVE: | 507 | case BITBANG_CS_ACTIVE: |
| 511 | gpio_direction_output(gpio, | 508 | gpio_direction_output(spi->cs_gpio, |
| 512 | spi->mode & SPI_CS_HIGH ? 1 : 0); | 509 | spi->mode & SPI_CS_HIGH ? 1 : 0); |
| 513 | break; | 510 | break; |
| 514 | case BITBANG_CS_INACTIVE: | 511 | case BITBANG_CS_INACTIVE: |
| 515 | gpio_direction_output(gpio, | 512 | gpio_direction_output(spi->cs_gpio, |
| 516 | spi->mode & SPI_CS_HIGH ? 0 : 1); | 513 | spi->mode & SPI_CS_HIGH ? 0 : 1); |
| 517 | break; | 514 | break; |
| 518 | } | 515 | } |
| @@ -606,8 +603,8 @@ spi_sirfsoc_setup_transfer(struct spi_device *spi, struct spi_transfer *t) | |||
| 606 | sspi->tx_by_cmd = false; | 603 | sspi->tx_by_cmd = false; |
| 607 | } | 604 | } |
| 608 | /* | 605 | /* |
| 609 | * set spi controller in RISC chipselect mode, we are controlling CS by | 606 | * it should never set to hardware cs mode because in hardware cs mode, |
| 610 | * software BITBANG_CS_ACTIVE and BITBANG_CS_INACTIVE. | 607 | * cs signal can't controlled by driver. |
| 611 | */ | 608 | */ |
| 612 | regval |= SIRFSOC_SPI_CS_IO_MODE; | 609 | regval |= SIRFSOC_SPI_CS_IO_MODE; |
| 613 | writel(regval, sspi->base + SIRFSOC_SPI_CTRL); | 610 | writel(regval, sspi->base + SIRFSOC_SPI_CTRL); |
| @@ -630,9 +627,17 @@ spi_sirfsoc_setup_transfer(struct spi_device *spi, struct spi_transfer *t) | |||
| 630 | 627 | ||
| 631 | static int spi_sirfsoc_setup(struct spi_device *spi) | 628 | static int spi_sirfsoc_setup(struct spi_device *spi) |
| 632 | { | 629 | { |
| 630 | struct sirfsoc_spi *sspi; | ||
| 631 | |||
| 633 | if (!spi->max_speed_hz) | 632 | if (!spi->max_speed_hz) |
| 634 | return -EINVAL; | 633 | return -EINVAL; |
| 635 | 634 | ||
| 635 | sspi = spi_master_get_devdata(spi->master); | ||
| 636 | |||
| 637 | if (spi->cs_gpio == -ENOENT) | ||
| 638 | sspi->hw_cs = true; | ||
| 639 | else | ||
| 640 | sspi->hw_cs = false; | ||
| 636 | return spi_sirfsoc_setup_transfer(spi, NULL); | 641 | return spi_sirfsoc_setup_transfer(spi, NULL); |
| 637 | } | 642 | } |
| 638 | 643 | ||
| @@ -641,19 +646,10 @@ static int spi_sirfsoc_probe(struct platform_device *pdev) | |||
| 641 | struct sirfsoc_spi *sspi; | 646 | struct sirfsoc_spi *sspi; |
| 642 | struct spi_master *master; | 647 | struct spi_master *master; |
| 643 | struct resource *mem_res; | 648 | struct resource *mem_res; |
| 644 | int num_cs, cs_gpio, irq; | 649 | int irq; |
| 645 | int i; | 650 | int i, ret; |
| 646 | int ret; | ||
| 647 | |||
| 648 | ret = of_property_read_u32(pdev->dev.of_node, | ||
| 649 | "sirf,spi-num-chipselects", &num_cs); | ||
| 650 | if (ret < 0) { | ||
| 651 | dev_err(&pdev->dev, "Unable to get chip select number\n"); | ||
| 652 | goto err_cs; | ||
| 653 | } | ||
| 654 | 651 | ||
| 655 | master = spi_alloc_master(&pdev->dev, | 652 | master = spi_alloc_master(&pdev->dev, sizeof(*sspi)); |
| 656 | sizeof(*sspi) + sizeof(int) * num_cs); | ||
| 657 | if (!master) { | 653 | if (!master) { |
| 658 | dev_err(&pdev->dev, "Unable to allocate SPI master\n"); | 654 | dev_err(&pdev->dev, "Unable to allocate SPI master\n"); |
| 659 | return -ENOMEM; | 655 | return -ENOMEM; |
| @@ -661,32 +657,6 @@ static int spi_sirfsoc_probe(struct platform_device *pdev) | |||
| 661 | platform_set_drvdata(pdev, master); | 657 | platform_set_drvdata(pdev, master); |
| 662 | sspi = spi_master_get_devdata(master); | 658 | sspi = spi_master_get_devdata(master); |
| 663 | 659 | ||
| 664 | master->num_chipselect = num_cs; | ||
| 665 | |||
| 666 | for (i = 0; i < master->num_chipselect; i++) { | ||
| 667 | cs_gpio = of_get_named_gpio(pdev->dev.of_node, "cs-gpios", i); | ||
| 668 | if (cs_gpio < 0) { | ||
| 669 | dev_err(&pdev->dev, "can't get cs gpio from DT\n"); | ||
| 670 | ret = -ENODEV; | ||
| 671 | goto free_master; | ||
| 672 | } | ||
| 673 | |||
| 674 | sspi->chipselect[i] = cs_gpio; | ||
| 675 | if (cs_gpio == 0) | ||
| 676 | continue; /* use cs from spi controller */ | ||
| 677 | |||
| 678 | ret = gpio_request(cs_gpio, DRIVER_NAME); | ||
| 679 | if (ret) { | ||
| 680 | while (i > 0) { | ||
| 681 | i--; | ||
| 682 | if (sspi->chipselect[i] > 0) | ||
| 683 | gpio_free(sspi->chipselect[i]); | ||
| 684 | } | ||
| 685 | dev_err(&pdev->dev, "fail to request cs gpios\n"); | ||
| 686 | goto free_master; | ||
| 687 | } | ||
| 688 | } | ||
| 689 | |||
| 690 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 660 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 691 | sspi->base = devm_ioremap_resource(&pdev->dev, mem_res); | 661 | sspi->base = devm_ioremap_resource(&pdev->dev, mem_res); |
| 692 | if (IS_ERR(sspi->base)) { | 662 | if (IS_ERR(sspi->base)) { |
| @@ -756,7 +726,21 @@ static int spi_sirfsoc_probe(struct platform_device *pdev) | |||
| 756 | ret = spi_bitbang_start(&sspi->bitbang); | 726 | ret = spi_bitbang_start(&sspi->bitbang); |
| 757 | if (ret) | 727 | if (ret) |
| 758 | goto free_dummypage; | 728 | goto free_dummypage; |
| 759 | 729 | for (i = 0; master->cs_gpios && i < master->num_chipselect; i++) { | |
| 730 | if (master->cs_gpios[i] == -ENOENT) | ||
| 731 | continue; | ||
| 732 | if (!gpio_is_valid(master->cs_gpios[i])) { | ||
| 733 | dev_err(&pdev->dev, "no valid gpio\n"); | ||
| 734 | ret = -EINVAL; | ||
| 735 | goto free_dummypage; | ||
| 736 | } | ||
| 737 | ret = devm_gpio_request(&pdev->dev, | ||
| 738 | master->cs_gpios[i], DRIVER_NAME); | ||
| 739 | if (ret) { | ||
| 740 | dev_err(&pdev->dev, "failed to request gpio\n"); | ||
| 741 | goto free_dummypage; | ||
| 742 | } | ||
| 743 | } | ||
| 760 | dev_info(&pdev->dev, "registerred, bus number = %d\n", master->bus_num); | 744 | dev_info(&pdev->dev, "registerred, bus number = %d\n", master->bus_num); |
| 761 | 745 | ||
| 762 | return 0; | 746 | return 0; |
| @@ -771,7 +755,7 @@ free_rx_dma: | |||
| 771 | dma_release_channel(sspi->rx_chan); | 755 | dma_release_channel(sspi->rx_chan); |
| 772 | free_master: | 756 | free_master: |
| 773 | spi_master_put(master); | 757 | spi_master_put(master); |
| 774 | err_cs: | 758 | |
| 775 | return ret; | 759 | return ret; |
| 776 | } | 760 | } |
| 777 | 761 | ||
| @@ -779,16 +763,11 @@ static int spi_sirfsoc_remove(struct platform_device *pdev) | |||
| 779 | { | 763 | { |
| 780 | struct spi_master *master; | 764 | struct spi_master *master; |
| 781 | struct sirfsoc_spi *sspi; | 765 | struct sirfsoc_spi *sspi; |
| 782 | int i; | ||
| 783 | 766 | ||
| 784 | master = platform_get_drvdata(pdev); | 767 | master = platform_get_drvdata(pdev); |
| 785 | sspi = spi_master_get_devdata(master); | 768 | sspi = spi_master_get_devdata(master); |
| 786 | 769 | ||
| 787 | spi_bitbang_stop(&sspi->bitbang); | 770 | spi_bitbang_stop(&sspi->bitbang); |
| 788 | for (i = 0; i < master->num_chipselect; i++) { | ||
| 789 | if (sspi->chipselect[i] > 0) | ||
| 790 | gpio_free(sspi->chipselect[i]); | ||
| 791 | } | ||
| 792 | kfree(sspi->dummypage); | 771 | kfree(sspi->dummypage); |
| 793 | clk_disable_unprepare(sspi->clk); | 772 | clk_disable_unprepare(sspi->clk); |
| 794 | clk_put(sspi->clk); | 773 | clk_put(sspi->clk); |
diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index e4a85ada861d..795bcbc0131b 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c | |||
| @@ -302,6 +302,7 @@ static unsigned tegra_spi_fill_tx_fifo_from_client_txbuf( | |||
| 302 | max_n_32bit = DIV_ROUND_UP(nbytes, 4); | 302 | max_n_32bit = DIV_ROUND_UP(nbytes, 4); |
| 303 | for (count = 0; count < max_n_32bit; count++) { | 303 | for (count = 0; count < max_n_32bit; count++) { |
| 304 | u32 x = 0; | 304 | u32 x = 0; |
| 305 | |||
| 305 | for (i = 0; (i < 4) && nbytes; i++, nbytes--) | 306 | for (i = 0; (i < 4) && nbytes; i++, nbytes--) |
| 306 | x |= (u32)(*tx_buf++) << (i * 8); | 307 | x |= (u32)(*tx_buf++) << (i * 8); |
| 307 | tegra_spi_writel(tspi, x, SPI_TX_FIFO); | 308 | tegra_spi_writel(tspi, x, SPI_TX_FIFO); |
| @@ -312,6 +313,7 @@ static unsigned tegra_spi_fill_tx_fifo_from_client_txbuf( | |||
| 312 | nbytes = written_words * tspi->bytes_per_word; | 313 | nbytes = written_words * tspi->bytes_per_word; |
| 313 | for (count = 0; count < max_n_32bit; count++) { | 314 | for (count = 0; count < max_n_32bit; count++) { |
| 314 | u32 x = 0; | 315 | u32 x = 0; |
| 316 | |||
| 315 | for (i = 0; nbytes && (i < tspi->bytes_per_word); | 317 | for (i = 0; nbytes && (i < tspi->bytes_per_word); |
| 316 | i++, nbytes--) | 318 | i++, nbytes--) |
| 317 | x |= (u32)(*tx_buf++) << (i * 8); | 319 | x |= (u32)(*tx_buf++) << (i * 8); |
| @@ -338,6 +340,7 @@ static unsigned int tegra_spi_read_rx_fifo_to_client_rxbuf( | |||
| 338 | len = tspi->curr_dma_words * tspi->bytes_per_word; | 340 | len = tspi->curr_dma_words * tspi->bytes_per_word; |
| 339 | for (count = 0; count < rx_full_count; count++) { | 341 | for (count = 0; count < rx_full_count; count++) { |
| 340 | u32 x = tegra_spi_readl(tspi, SPI_RX_FIFO); | 342 | u32 x = tegra_spi_readl(tspi, SPI_RX_FIFO); |
| 343 | |||
| 341 | for (i = 0; len && (i < 4); i++, len--) | 344 | for (i = 0; len && (i < 4); i++, len--) |
| 342 | *rx_buf++ = (x >> i*8) & 0xFF; | 345 | *rx_buf++ = (x >> i*8) & 0xFF; |
| 343 | } | 346 | } |
| @@ -345,8 +348,10 @@ static unsigned int tegra_spi_read_rx_fifo_to_client_rxbuf( | |||
| 345 | read_words += tspi->curr_dma_words; | 348 | read_words += tspi->curr_dma_words; |
| 346 | } else { | 349 | } else { |
| 347 | u32 rx_mask = ((u32)1 << t->bits_per_word) - 1; | 350 | u32 rx_mask = ((u32)1 << t->bits_per_word) - 1; |
| 351 | |||
| 348 | for (count = 0; count < rx_full_count; count++) { | 352 | for (count = 0; count < rx_full_count; count++) { |
| 349 | u32 x = tegra_spi_readl(tspi, SPI_RX_FIFO) & rx_mask; | 353 | u32 x = tegra_spi_readl(tspi, SPI_RX_FIFO) & rx_mask; |
| 354 | |||
| 350 | for (i = 0; (i < tspi->bytes_per_word); i++) | 355 | for (i = 0; (i < tspi->bytes_per_word); i++) |
| 351 | *rx_buf++ = (x >> (i*8)) & 0xFF; | 356 | *rx_buf++ = (x >> (i*8)) & 0xFF; |
| 352 | } | 357 | } |
| @@ -365,6 +370,7 @@ static void tegra_spi_copy_client_txbuf_to_spi_txbuf( | |||
| 365 | 370 | ||
| 366 | if (tspi->is_packed) { | 371 | if (tspi->is_packed) { |
| 367 | unsigned len = tspi->curr_dma_words * tspi->bytes_per_word; | 372 | unsigned len = tspi->curr_dma_words * tspi->bytes_per_word; |
| 373 | |||
| 368 | memcpy(tspi->tx_dma_buf, t->tx_buf + tspi->cur_pos, len); | 374 | memcpy(tspi->tx_dma_buf, t->tx_buf + tspi->cur_pos, len); |
| 369 | } else { | 375 | } else { |
| 370 | unsigned int i; | 376 | unsigned int i; |
| @@ -374,6 +380,7 @@ static void tegra_spi_copy_client_txbuf_to_spi_txbuf( | |||
| 374 | 380 | ||
| 375 | for (count = 0; count < tspi->curr_dma_words; count++) { | 381 | for (count = 0; count < tspi->curr_dma_words; count++) { |
| 376 | u32 x = 0; | 382 | u32 x = 0; |
| 383 | |||
| 377 | for (i = 0; consume && (i < tspi->bytes_per_word); | 384 | for (i = 0; consume && (i < tspi->bytes_per_word); |
| 378 | i++, consume--) | 385 | i++, consume--) |
| 379 | x |= (u32)(*tx_buf++) << (i * 8); | 386 | x |= (u32)(*tx_buf++) << (i * 8); |
| @@ -396,6 +403,7 @@ static void tegra_spi_copy_spi_rxbuf_to_client_rxbuf( | |||
| 396 | 403 | ||
| 397 | if (tspi->is_packed) { | 404 | if (tspi->is_packed) { |
| 398 | unsigned len = tspi->curr_dma_words * tspi->bytes_per_word; | 405 | unsigned len = tspi->curr_dma_words * tspi->bytes_per_word; |
| 406 | |||
| 399 | memcpy(t->rx_buf + tspi->cur_rx_pos, tspi->rx_dma_buf, len); | 407 | memcpy(t->rx_buf + tspi->cur_rx_pos, tspi->rx_dma_buf, len); |
| 400 | } else { | 408 | } else { |
| 401 | unsigned int i; | 409 | unsigned int i; |
| @@ -405,6 +413,7 @@ static void tegra_spi_copy_spi_rxbuf_to_client_rxbuf( | |||
| 405 | 413 | ||
| 406 | for (count = 0; count < tspi->curr_dma_words; count++) { | 414 | for (count = 0; count < tspi->curr_dma_words; count++) { |
| 407 | u32 x = tspi->rx_dma_buf[count] & rx_mask; | 415 | u32 x = tspi->rx_dma_buf[count] & rx_mask; |
| 416 | |||
| 408 | for (i = 0; (i < tspi->bytes_per_word); i++) | 417 | for (i = 0; (i < tspi->bytes_per_word); i++) |
| 409 | *rx_buf++ = (x >> (i*8)) & 0xFF; | 418 | *rx_buf++ = (x >> (i*8)) & 0xFF; |
| 410 | } | 419 | } |
diff --git a/drivers/spi/spi-tegra20-sflash.c b/drivers/spi/spi-tegra20-sflash.c index 3548ce25c08f..cd66fe7b78a9 100644 --- a/drivers/spi/spi-tegra20-sflash.c +++ b/drivers/spi/spi-tegra20-sflash.c | |||
| @@ -99,7 +99,7 @@ | |||
| 99 | #define SPI_TX_TRIG_MASK (0x3 << 16) | 99 | #define SPI_TX_TRIG_MASK (0x3 << 16) |
| 100 | #define SPI_TX_TRIG_1W (0x0 << 16) | 100 | #define SPI_TX_TRIG_1W (0x0 << 16) |
| 101 | #define SPI_TX_TRIG_4W (0x1 << 16) | 101 | #define SPI_TX_TRIG_4W (0x1 << 16) |
| 102 | #define SPI_DMA_BLK_COUNT(count) (((count) - 1) & 0xFFFF); | 102 | #define SPI_DMA_BLK_COUNT(count) (((count) - 1) & 0xFFFF) |
| 103 | 103 | ||
| 104 | #define SPI_TX_FIFO 0x10 | 104 | #define SPI_TX_FIFO 0x10 |
| 105 | #define SPI_RX_FIFO 0x20 | 105 | #define SPI_RX_FIFO 0x20 |
| @@ -221,6 +221,7 @@ static int tegra_sflash_read_rx_fifo_to_client_rxbuf( | |||
| 221 | while (!(status & SPI_RXF_EMPTY)) { | 221 | while (!(status & SPI_RXF_EMPTY)) { |
| 222 | int i; | 222 | int i; |
| 223 | u32 x = tegra_sflash_readl(tsd, SPI_RX_FIFO); | 223 | u32 x = tegra_sflash_readl(tsd, SPI_RX_FIFO); |
| 224 | |||
| 224 | for (i = 0; (i < tsd->bytes_per_word); i++) | 225 | for (i = 0; (i < tsd->bytes_per_word); i++) |
| 225 | *rx_buf++ = (x >> (i*8)) & 0xFF; | 226 | *rx_buf++ = (x >> (i*8)) & 0xFF; |
| 226 | read_words++; | 227 | read_words++; |
diff --git a/drivers/spi/spi-txx9.c b/drivers/spi/spi-txx9.c index 5f183baa91a9..2501a8373e89 100644 --- a/drivers/spi/spi-txx9.c +++ b/drivers/spi/spi-txx9.c | |||
| @@ -97,6 +97,7 @@ static void txx9spi_cs_func(struct spi_device *spi, struct txx9spi *c, | |||
| 97 | int on, unsigned int cs_delay) | 97 | int on, unsigned int cs_delay) |
| 98 | { | 98 | { |
| 99 | int val = (spi->mode & SPI_CS_HIGH) ? on : !on; | 99 | int val = (spi->mode & SPI_CS_HIGH) ? on : !on; |
| 100 | |||
| 100 | if (on) { | 101 | if (on) { |
| 101 | /* deselect the chip with cs_change hint in last transfer */ | 102 | /* deselect the chip with cs_change hint in last transfer */ |
| 102 | if (c->last_chipselect >= 0) | 103 | if (c->last_chipselect >= 0) |
| @@ -188,6 +189,7 @@ static void txx9spi_work_one(struct txx9spi *c, struct spi_message *m) | |||
| 188 | if (prev_speed_hz != speed_hz | 189 | if (prev_speed_hz != speed_hz |
| 189 | || prev_bits_per_word != bits_per_word) { | 190 | || prev_bits_per_word != bits_per_word) { |
| 190 | int n = DIV_ROUND_UP(c->baseclk, speed_hz) - 1; | 191 | int n = DIV_ROUND_UP(c->baseclk, speed_hz) - 1; |
| 192 | |||
| 191 | n = clamp(n, SPI_MIN_DIVIDER, SPI_MAX_DIVIDER); | 193 | n = clamp(n, SPI_MIN_DIVIDER, SPI_MAX_DIVIDER); |
| 192 | /* enter config mode */ | 194 | /* enter config mode */ |
| 193 | txx9spi_wr(c, mcr | TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR, | 195 | txx9spi_wr(c, mcr | TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR, |
diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c index 4d8efb16573d..79bd84f43430 100644 --- a/drivers/spi/spi-xilinx.c +++ b/drivers/spi/spi-xilinx.c | |||
| @@ -471,7 +471,6 @@ static struct platform_driver xilinx_spi_driver = { | |||
| 471 | .remove = xilinx_spi_remove, | 471 | .remove = xilinx_spi_remove, |
| 472 | .driver = { | 472 | .driver = { |
| 473 | .name = XILINX_SPI_NAME, | 473 | .name = XILINX_SPI_NAME, |
| 474 | .owner = THIS_MODULE, | ||
| 475 | .of_match_table = xilinx_spi_of_match, | 474 | .of_match_table = xilinx_spi_of_match, |
| 476 | }, | 475 | }, |
| 477 | }; | 476 | }; |
diff --git a/drivers/spi/spi-xtensa-xtfpga.c b/drivers/spi/spi-xtensa-xtfpga.c index 41e158187f9d..0dc5df5233a9 100644 --- a/drivers/spi/spi-xtensa-xtfpga.c +++ b/drivers/spi/spi-xtensa-xtfpga.c | |||
| @@ -46,6 +46,7 @@ static inline unsigned int xtfpga_spi_read32(const struct xtfpga_spi *spi, | |||
| 46 | static inline void xtfpga_spi_wait_busy(struct xtfpga_spi *xspi) | 46 | static inline void xtfpga_spi_wait_busy(struct xtfpga_spi *xspi) |
| 47 | { | 47 | { |
| 48 | unsigned i; | 48 | unsigned i; |
| 49 | |||
| 49 | for (i = 0; xtfpga_spi_read32(xspi, XTFPGA_SPI_BUSY) && | 50 | for (i = 0; xtfpga_spi_read32(xspi, XTFPGA_SPI_BUSY) && |
| 50 | i < BUSY_WAIT_US; ++i) | 51 | i < BUSY_WAIT_US; ++i) |
| 51 | udelay(1); | 52 | udelay(1); |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index ca935df80c88..e19512ffc40e 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
| @@ -552,6 +552,9 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n) | |||
| 552 | struct boardinfo *bi; | 552 | struct boardinfo *bi; |
| 553 | int i; | 553 | int i; |
| 554 | 554 | ||
| 555 | if (!n) | ||
| 556 | return -EINVAL; | ||
| 557 | |||
| 555 | bi = kzalloc(n * sizeof(*bi), GFP_KERNEL); | 558 | bi = kzalloc(n * sizeof(*bi), GFP_KERNEL); |
| 556 | if (!bi) | 559 | if (!bi) |
| 557 | return -ENOMEM; | 560 | return -ENOMEM; |
| @@ -789,27 +792,35 @@ static int spi_transfer_one_message(struct spi_master *master, | |||
| 789 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { | 792 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { |
| 790 | trace_spi_transfer_start(msg, xfer); | 793 | trace_spi_transfer_start(msg, xfer); |
| 791 | 794 | ||
| 792 | reinit_completion(&master->xfer_completion); | 795 | if (xfer->tx_buf || xfer->rx_buf) { |
| 796 | reinit_completion(&master->xfer_completion); | ||
| 793 | 797 | ||
| 794 | ret = master->transfer_one(master, msg->spi, xfer); | 798 | ret = master->transfer_one(master, msg->spi, xfer); |
| 795 | if (ret < 0) { | 799 | if (ret < 0) { |
| 796 | dev_err(&msg->spi->dev, | 800 | dev_err(&msg->spi->dev, |
| 797 | "SPI transfer failed: %d\n", ret); | 801 | "SPI transfer failed: %d\n", ret); |
| 798 | goto out; | 802 | goto out; |
| 799 | } | 803 | } |
| 800 | 804 | ||
| 801 | if (ret > 0) { | 805 | if (ret > 0) { |
| 802 | ret = 0; | 806 | ret = 0; |
| 803 | ms = xfer->len * 8 * 1000 / xfer->speed_hz; | 807 | ms = xfer->len * 8 * 1000 / xfer->speed_hz; |
| 804 | ms += ms + 100; /* some tolerance */ | 808 | ms += ms + 100; /* some tolerance */ |
| 805 | 809 | ||
| 806 | ms = wait_for_completion_timeout(&master->xfer_completion, | 810 | ms = wait_for_completion_timeout(&master->xfer_completion, |
| 807 | msecs_to_jiffies(ms)); | 811 | msecs_to_jiffies(ms)); |
| 808 | } | 812 | } |
| 809 | 813 | ||
| 810 | if (ms == 0) { | 814 | if (ms == 0) { |
| 811 | dev_err(&msg->spi->dev, "SPI transfer timed out\n"); | 815 | dev_err(&msg->spi->dev, |
| 812 | msg->status = -ETIMEDOUT; | 816 | "SPI transfer timed out\n"); |
| 817 | msg->status = -ETIMEDOUT; | ||
| 818 | } | ||
| 819 | } else { | ||
| 820 | if (xfer->len) | ||
| 821 | dev_err(&msg->spi->dev, | ||
| 822 | "Bufferless transfer has length %u\n", | ||
| 823 | xfer->len); | ||
| 813 | } | 824 | } |
| 814 | 825 | ||
| 815 | trace_spi_transfer_stop(msg, xfer); | 826 | trace_spi_transfer_stop(msg, xfer); |
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h index fdd7e1b61f60..c324f5700d1a 100644 --- a/include/linux/amba/bus.h +++ b/include/linux/amba/bus.h | |||
| @@ -44,10 +44,15 @@ struct amba_driver { | |||
| 44 | const struct amba_id *id_table; | 44 | const struct amba_id *id_table; |
| 45 | }; | 45 | }; |
| 46 | 46 | ||
| 47 | /* | ||
| 48 | * Constants for the designer field of the Peripheral ID register. When bit 7 | ||
| 49 | * is set to '1', bits [6:0] should be the JEP106 manufacturer identity code. | ||
| 50 | */ | ||
| 47 | enum amba_vendor { | 51 | enum amba_vendor { |
| 48 | AMBA_VENDOR_ARM = 0x41, | 52 | AMBA_VENDOR_ARM = 0x41, |
| 49 | AMBA_VENDOR_ST = 0x80, | 53 | AMBA_VENDOR_ST = 0x80, |
| 50 | AMBA_VENDOR_QCOM = 0x51, | 54 | AMBA_VENDOR_QCOM = 0x51, |
| 55 | AMBA_VENDOR_LSI = 0xb6, | ||
| 51 | }; | 56 | }; |
| 52 | 57 | ||
| 53 | extern struct bus_type amba_bustype; | 58 | extern struct bus_type amba_bustype; |
