diff options
31 files changed, 2611 insertions, 615 deletions
diff --git a/Documentation/devicetree/bindings/spi/sh-msiof.txt b/Documentation/devicetree/bindings/spi/sh-msiof.txt index aa005c1d10d9..da6614c63796 100644 --- a/Documentation/devicetree/bindings/spi/sh-msiof.txt +++ b/Documentation/devicetree/bindings/spi/sh-msiof.txt | |||
| @@ -10,6 +10,7 @@ Required properties: | |||
| 10 | "renesas,msiof-r8a7792" (R-Car V2H) | 10 | "renesas,msiof-r8a7792" (R-Car V2H) |
| 11 | "renesas,msiof-r8a7793" (R-Car M2-N) | 11 | "renesas,msiof-r8a7793" (R-Car M2-N) |
| 12 | "renesas,msiof-r8a7794" (R-Car E2) | 12 | "renesas,msiof-r8a7794" (R-Car E2) |
| 13 | "renesas,msiof-r8a7796" (R-Car M3-W) | ||
| 13 | "renesas,msiof-sh73a0" (SH-Mobile AG5) | 14 | "renesas,msiof-sh73a0" (SH-Mobile AG5) |
| 14 | - reg : A list of offsets and lengths of the register sets for | 15 | - reg : A list of offsets and lengths of the register sets for |
| 15 | the device. | 16 | the device. |
diff --git a/Documentation/devicetree/bindings/spi/spi-armada-3700.txt b/Documentation/devicetree/bindings/spi/spi-armada-3700.txt new file mode 100644 index 000000000000..1564aa8c02cd --- /dev/null +++ b/Documentation/devicetree/bindings/spi/spi-armada-3700.txt | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | * Marvell Armada 3700 SPI Controller | ||
| 2 | |||
| 3 | Required Properties: | ||
| 4 | |||
| 5 | - compatible: should be "marvell,armada-3700-spi" | ||
| 6 | - reg: physical base address of the controller and length of memory mapped | ||
| 7 | region. | ||
| 8 | - interrupts: The interrupt number. The interrupt specifier format depends on | ||
| 9 | the interrupt controller and of its driver. | ||
| 10 | - clocks: Must contain the clock source, usually from the North Bridge clocks. | ||
| 11 | - num-cs: The number of chip selects that is supported by this SPI Controller | ||
| 12 | - #address-cells: should be 1. | ||
| 13 | - #size-cells: should be 0. | ||
| 14 | |||
| 15 | Example: | ||
| 16 | |||
| 17 | spi0: spi@10600 { | ||
| 18 | compatible = "marvell,armada-3700-spi"; | ||
| 19 | #address-cells = <1>; | ||
| 20 | #size-cells = <0>; | ||
| 21 | reg = <0x10600 0x5d>; | ||
| 22 | clocks = <&nb_perih_clk 7>; | ||
| 23 | interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; | ||
| 24 | num-cs = <4>; | ||
| 25 | }; | ||
diff --git a/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt b/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt new file mode 100644 index 000000000000..225ace1d0c65 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | * Freescale Low Power SPI (LPSPI) for i.MX | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible : | ||
| 5 | - "fsl,imx7ulp-spi" for LPSPI compatible with the one integrated on i.MX7ULP soc | ||
| 6 | - reg : address and length of the lpspi master registers | ||
| 7 | - interrupt-parent : core interrupt controller | ||
| 8 | - interrupts : lpspi interrupt | ||
| 9 | - clocks : lpspi clock specifier | ||
| 10 | |||
| 11 | Examples: | ||
| 12 | |||
| 13 | lpspi2: lpspi@40290000 { | ||
| 14 | compatible = "fsl,imx7ulp-spi"; | ||
| 15 | reg = <0x40290000 0x10000>; | ||
| 16 | interrupt-parent = <&intc>; | ||
| 17 | interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>; | ||
| 18 | clocks = <&clks IMX7ULP_CLK_LPSPI2>; | ||
| 19 | }; | ||
diff --git a/Documentation/devicetree/bindings/spi/spi-sun6i.txt b/Documentation/devicetree/bindings/spi/spi-sun6i.txt index 21de73db6a05..2ec99b86b622 100644 --- a/Documentation/devicetree/bindings/spi/spi-sun6i.txt +++ b/Documentation/devicetree/bindings/spi/spi-sun6i.txt | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | Allwinner A31 SPI controller | 1 | Allwinner A31/H3 SPI controller |
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible: Should be "allwinner,sun6i-a31-spi". | 4 | - compatible: Should be "allwinner,sun6i-a31-spi" or "allwinner,sun8i-h3-spi". |
| 5 | - reg: Should contain register location and length. | 5 | - reg: Should contain register location and length. |
| 6 | - interrupts: Should contain interrupt. | 6 | - interrupts: Should contain interrupt. |
| 7 | - clocks: phandle to the clocks feeding the SPI controller. Two are | 7 | - clocks: phandle to the clocks feeding the SPI controller. Two are |
| @@ -12,6 +12,11 @@ Required properties: | |||
| 12 | - resets: phandle to the reset controller asserting this device in | 12 | - resets: phandle to the reset controller asserting this device in |
| 13 | reset | 13 | reset |
| 14 | 14 | ||
| 15 | Optional properties: | ||
| 16 | - dmas: DMA specifiers for rx and tx dma. See the DMA client binding, | ||
| 17 | Documentation/devicetree/bindings/dma/dma.txt | ||
| 18 | - dma-names: DMA request names should include "rx" and "tx" if present. | ||
| 19 | |||
| 15 | Example: | 20 | Example: |
| 16 | 21 | ||
| 17 | spi1: spi@01c69000 { | 22 | spi1: spi@01c69000 { |
| @@ -22,3 +27,19 @@ spi1: spi@01c69000 { | |||
| 22 | clock-names = "ahb", "mod"; | 27 | clock-names = "ahb", "mod"; |
| 23 | resets = <&ahb1_rst 21>; | 28 | resets = <&ahb1_rst 21>; |
| 24 | }; | 29 | }; |
| 30 | |||
| 31 | spi0: spi@01c68000 { | ||
| 32 | compatible = "allwinner,sun8i-h3-spi"; | ||
| 33 | reg = <0x01c68000 0x1000>; | ||
| 34 | interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; | ||
| 35 | clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>; | ||
| 36 | clock-names = "ahb", "mod"; | ||
| 37 | dmas = <&dma 23>, <&dma 23>; | ||
| 38 | dma-names = "rx", "tx"; | ||
| 39 | pinctrl-names = "default"; | ||
| 40 | pinctrl-0 = <&spi0_pins>; | ||
| 41 | resets = <&ccu RST_BUS_SPI0>; | ||
| 42 | status = "disabled"; | ||
| 43 | #address-cells = <1>; | ||
| 44 | #size-cells = <0>; | ||
| 45 | }; | ||
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index b7995474148c..ec4aa252d6e8 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
| @@ -67,6 +67,13 @@ config SPI_ATH79 | |||
| 67 | This enables support for the SPI controller present on the | 67 | This enables support for the SPI controller present on the |
| 68 | Atheros AR71XX/AR724X/AR913X SoCs. | 68 | Atheros AR71XX/AR724X/AR913X SoCs. |
| 69 | 69 | ||
| 70 | config SPI_ARMADA_3700 | ||
| 71 | tristate "Marvell Armada 3700 SPI Controller" | ||
| 72 | depends on (ARCH_MVEBU && OF) || COMPILE_TEST | ||
| 73 | help | ||
| 74 | This enables support for the SPI controller present on the | ||
| 75 | Marvell Armada 3700 SoCs. | ||
| 76 | |||
| 70 | config SPI_ATMEL | 77 | config SPI_ATMEL |
| 71 | tristate "Atmel SPI Controller" | 78 | tristate "Atmel SPI Controller" |
| 72 | depends on HAS_DMA | 79 | depends on HAS_DMA |
| @@ -264,6 +271,12 @@ config SPI_FALCON | |||
| 264 | has only been tested with m25p80 type chips. The hardware has no | 271 | has only been tested with m25p80 type chips. The hardware has no |
| 265 | support for other types of SPI peripherals. | 272 | support for other types of SPI peripherals. |
| 266 | 273 | ||
| 274 | config SPI_FSL_LPSPI | ||
| 275 | tristate "Freescale i.MX LPSPI controller" | ||
| 276 | depends on ARCH_MXC || COMPILE_TEST | ||
| 277 | help | ||
| 278 | This enables Freescale i.MX LPSPI controllers in master mode. | ||
| 279 | |||
| 267 | config SPI_GPIO | 280 | config SPI_GPIO |
| 268 | tristate "GPIO-based bitbanging SPI Master" | 281 | tristate "GPIO-based bitbanging SPI Master" |
| 269 | depends on GPIOLIB || COMPILE_TEST | 282 | depends on GPIOLIB || COMPILE_TEST |
| @@ -373,7 +386,6 @@ config SPI_FSL_DSPI | |||
| 373 | config SPI_FSL_ESPI | 386 | config SPI_FSL_ESPI |
| 374 | tristate "Freescale eSPI controller" | 387 | tristate "Freescale eSPI controller" |
| 375 | depends on FSL_SOC | 388 | depends on FSL_SOC |
| 376 | select SPI_FSL_LIB | ||
| 377 | help | 389 | help |
| 378 | This enables using the Freescale eSPI controllers in master mode. | 390 | This enables using the Freescale eSPI controllers in master mode. |
| 379 | From MPC8536, 85xx platform uses the controller, and all P10xx, | 391 | From MPC8536, 85xx platform uses the controller, and all P10xx, |
| @@ -451,7 +463,8 @@ config SPI_ORION | |||
| 451 | tristate "Orion SPI master" | 463 | tristate "Orion SPI master" |
| 452 | depends on PLAT_ORION || ARCH_MVEBU || COMPILE_TEST | 464 | depends on PLAT_ORION || ARCH_MVEBU || COMPILE_TEST |
| 453 | help | 465 | help |
| 454 | This enables using the SPI master controller on the Orion chips. | 466 | This enables using the SPI master controller on the Orion |
| 467 | and MVEBU chips. | ||
| 455 | 468 | ||
| 456 | config SPI_PIC32 | 469 | config SPI_PIC32 |
| 457 | tristate "Microchip PIC32 series SPI" | 470 | tristate "Microchip PIC32 series SPI" |
| @@ -553,7 +566,7 @@ config SPI_S3C24XX_FIQ | |||
| 553 | 566 | ||
| 554 | config SPI_S3C64XX | 567 | config SPI_S3C64XX |
| 555 | tristate "Samsung S3C64XX series type SPI" | 568 | tristate "Samsung S3C64XX series type SPI" |
| 556 | depends on (PLAT_SAMSUNG || ARCH_EXYNOS) | 569 | depends on (PLAT_SAMSUNG || ARCH_EXYNOS || COMPILE_TEST) |
| 557 | help | 570 | help |
| 558 | SPI driver for Samsung S3C64XX and newer SoCs. | 571 | SPI driver for Samsung S3C64XX and newer SoCs. |
| 559 | 572 | ||
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index aa939d955521..7a6b64662c82 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile | |||
| @@ -12,6 +12,7 @@ obj-$(CONFIG_SPI_LOOPBACK_TEST) += spi-loopback-test.o | |||
| 12 | 12 | ||
| 13 | # SPI master controller drivers (bus) | 13 | # SPI master controller drivers (bus) |
| 14 | obj-$(CONFIG_SPI_ALTERA) += spi-altera.o | 14 | obj-$(CONFIG_SPI_ALTERA) += spi-altera.o |
| 15 | obj-$(CONFIG_SPI_ARMADA_3700) += spi-armada-3700.o | ||
| 15 | obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o | 16 | obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o |
| 16 | obj-$(CONFIG_SPI_ATH79) += spi-ath79.o | 17 | obj-$(CONFIG_SPI_ATH79) += spi-ath79.o |
| 17 | obj-$(CONFIG_SPI_AU1550) += spi-au1550.o | 18 | obj-$(CONFIG_SPI_AU1550) += spi-au1550.o |
| @@ -43,6 +44,7 @@ obj-$(CONFIG_SPI_FSL_CPM) += spi-fsl-cpm.o | |||
| 43 | obj-$(CONFIG_SPI_FSL_DSPI) += spi-fsl-dspi.o | 44 | obj-$(CONFIG_SPI_FSL_DSPI) += spi-fsl-dspi.o |
| 44 | obj-$(CONFIG_SPI_FSL_LIB) += spi-fsl-lib.o | 45 | obj-$(CONFIG_SPI_FSL_LIB) += spi-fsl-lib.o |
| 45 | obj-$(CONFIG_SPI_FSL_ESPI) += spi-fsl-espi.o | 46 | obj-$(CONFIG_SPI_FSL_ESPI) += spi-fsl-espi.o |
| 47 | obj-$(CONFIG_SPI_FSL_LPSPI) += spi-fsl-lpspi.o | ||
| 46 | obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o | 48 | obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o |
| 47 | obj-$(CONFIG_SPI_GPIO) += spi-gpio.o | 49 | obj-$(CONFIG_SPI_GPIO) += spi-gpio.o |
| 48 | obj-$(CONFIG_SPI_IMG_SPFI) += spi-img-spfi.o | 50 | obj-$(CONFIG_SPI_IMG_SPFI) += spi-img-spfi.o |
diff --git a/drivers/spi/spi-armada-3700.c b/drivers/spi/spi-armada-3700.c new file mode 100644 index 000000000000..e89da0af45d2 --- /dev/null +++ b/drivers/spi/spi-armada-3700.c | |||
| @@ -0,0 +1,923 @@ | |||
| 1 | /* | ||
| 2 | * Marvell Armada-3700 SPI controller driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2016 Marvell Ltd. | ||
| 5 | * | ||
| 6 | * Author: Wilson Ding <dingwei@marvell.com> | ||
| 7 | * Author: Romain Perier <romain.perier@free-electrons.com> | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/clk.h> | ||
| 15 | #include <linux/completion.h> | ||
| 16 | #include <linux/delay.h> | ||
| 17 | #include <linux/err.h> | ||
| 18 | #include <linux/interrupt.h> | ||
| 19 | #include <linux/io.h> | ||
| 20 | #include <linux/kernel.h> | ||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/of.h> | ||
| 23 | #include <linux/of_irq.h> | ||
| 24 | #include <linux/of_device.h> | ||
| 25 | #include <linux/pinctrl/consumer.h> | ||
| 26 | #include <linux/spi/spi.h> | ||
| 27 | |||
| 28 | #define DRIVER_NAME "armada_3700_spi" | ||
| 29 | |||
| 30 | #define A3700_SPI_TIMEOUT 10 | ||
| 31 | |||
| 32 | /* SPI Register Offest */ | ||
| 33 | #define A3700_SPI_IF_CTRL_REG 0x00 | ||
| 34 | #define A3700_SPI_IF_CFG_REG 0x04 | ||
| 35 | #define A3700_SPI_DATA_OUT_REG 0x08 | ||
| 36 | #define A3700_SPI_DATA_IN_REG 0x0C | ||
| 37 | #define A3700_SPI_IF_INST_REG 0x10 | ||
| 38 | #define A3700_SPI_IF_ADDR_REG 0x14 | ||
| 39 | #define A3700_SPI_IF_RMODE_REG 0x18 | ||
| 40 | #define A3700_SPI_IF_HDR_CNT_REG 0x1C | ||
| 41 | #define A3700_SPI_IF_DIN_CNT_REG 0x20 | ||
| 42 | #define A3700_SPI_IF_TIME_REG 0x24 | ||
| 43 | #define A3700_SPI_INT_STAT_REG 0x28 | ||
| 44 | #define A3700_SPI_INT_MASK_REG 0x2C | ||
| 45 | |||
| 46 | /* A3700_SPI_IF_CTRL_REG */ | ||
| 47 | #define A3700_SPI_EN BIT(16) | ||
| 48 | #define A3700_SPI_ADDR_NOT_CONFIG BIT(12) | ||
| 49 | #define A3700_SPI_WFIFO_OVERFLOW BIT(11) | ||
| 50 | #define A3700_SPI_WFIFO_UNDERFLOW BIT(10) | ||
| 51 | #define A3700_SPI_RFIFO_OVERFLOW BIT(9) | ||
| 52 | #define A3700_SPI_RFIFO_UNDERFLOW BIT(8) | ||
| 53 | #define A3700_SPI_WFIFO_FULL BIT(7) | ||
| 54 | #define A3700_SPI_WFIFO_EMPTY BIT(6) | ||
| 55 | #define A3700_SPI_RFIFO_FULL BIT(5) | ||
| 56 | #define A3700_SPI_RFIFO_EMPTY BIT(4) | ||
| 57 | #define A3700_SPI_WFIFO_RDY BIT(3) | ||
| 58 | #define A3700_SPI_RFIFO_RDY BIT(2) | ||
| 59 | #define A3700_SPI_XFER_RDY BIT(1) | ||
| 60 | #define A3700_SPI_XFER_DONE BIT(0) | ||
| 61 | |||
| 62 | /* A3700_SPI_IF_CFG_REG */ | ||
| 63 | #define A3700_SPI_WFIFO_THRS BIT(28) | ||
| 64 | #define A3700_SPI_RFIFO_THRS BIT(24) | ||
| 65 | #define A3700_SPI_AUTO_CS BIT(20) | ||
| 66 | #define A3700_SPI_DMA_RD_EN BIT(18) | ||
| 67 | #define A3700_SPI_FIFO_MODE BIT(17) | ||
| 68 | #define A3700_SPI_SRST BIT(16) | ||
| 69 | #define A3700_SPI_XFER_START BIT(15) | ||
| 70 | #define A3700_SPI_XFER_STOP BIT(14) | ||
| 71 | #define A3700_SPI_INST_PIN BIT(13) | ||
| 72 | #define A3700_SPI_ADDR_PIN BIT(12) | ||
| 73 | #define A3700_SPI_DATA_PIN1 BIT(11) | ||
| 74 | #define A3700_SPI_DATA_PIN0 BIT(10) | ||
| 75 | #define A3700_SPI_FIFO_FLUSH BIT(9) | ||
| 76 | #define A3700_SPI_RW_EN BIT(8) | ||
| 77 | #define A3700_SPI_CLK_POL BIT(7) | ||
| 78 | #define A3700_SPI_CLK_PHA BIT(6) | ||
| 79 | #define A3700_SPI_BYTE_LEN BIT(5) | ||
| 80 | #define A3700_SPI_CLK_PRESCALE BIT(0) | ||
| 81 | #define A3700_SPI_CLK_PRESCALE_MASK (0x1f) | ||
| 82 | |||
| 83 | #define A3700_SPI_WFIFO_THRS_BIT 28 | ||
| 84 | #define A3700_SPI_RFIFO_THRS_BIT 24 | ||
| 85 | #define A3700_SPI_FIFO_THRS_MASK 0x7 | ||
| 86 | |||
| 87 | #define A3700_SPI_DATA_PIN_MASK 0x3 | ||
| 88 | |||
| 89 | /* A3700_SPI_IF_HDR_CNT_REG */ | ||
| 90 | #define A3700_SPI_DUMMY_CNT_BIT 12 | ||
| 91 | #define A3700_SPI_DUMMY_CNT_MASK 0x7 | ||
| 92 | #define A3700_SPI_RMODE_CNT_BIT 8 | ||
| 93 | #define A3700_SPI_RMODE_CNT_MASK 0x3 | ||
| 94 | #define A3700_SPI_ADDR_CNT_BIT 4 | ||
| 95 | #define A3700_SPI_ADDR_CNT_MASK 0x7 | ||
| 96 | #define A3700_SPI_INSTR_CNT_BIT 0 | ||
| 97 | #define A3700_SPI_INSTR_CNT_MASK 0x3 | ||
| 98 | |||
| 99 | /* A3700_SPI_IF_TIME_REG */ | ||
| 100 | #define A3700_SPI_CLK_CAPT_EDGE BIT(7) | ||
| 101 | |||
| 102 | /* Flags and macros for struct a3700_spi */ | ||
| 103 | #define A3700_INSTR_CNT 1 | ||
| 104 | #define A3700_ADDR_CNT 3 | ||
| 105 | #define A3700_DUMMY_CNT 1 | ||
| 106 | |||
| 107 | struct a3700_spi { | ||
| 108 | struct spi_master *master; | ||
| 109 | void __iomem *base; | ||
| 110 | struct clk *clk; | ||
| 111 | unsigned int irq; | ||
| 112 | unsigned int flags; | ||
| 113 | bool xmit_data; | ||
| 114 | const u8 *tx_buf; | ||
| 115 | u8 *rx_buf; | ||
| 116 | size_t buf_len; | ||
| 117 | u8 byte_len; | ||
| 118 | u32 wait_mask; | ||
| 119 | struct completion done; | ||
| 120 | u32 addr_cnt; | ||
| 121 | u32 instr_cnt; | ||
| 122 | size_t hdr_cnt; | ||
| 123 | }; | ||
| 124 | |||
| 125 | static u32 spireg_read(struct a3700_spi *a3700_spi, u32 offset) | ||
| 126 | { | ||
| 127 | return readl(a3700_spi->base + offset); | ||
| 128 | } | ||
| 129 | |||
| 130 | static void spireg_write(struct a3700_spi *a3700_spi, u32 offset, u32 data) | ||
| 131 | { | ||
| 132 | writel(data, a3700_spi->base + offset); | ||
| 133 | } | ||
| 134 | |||
| 135 | static void a3700_spi_auto_cs_unset(struct a3700_spi *a3700_spi) | ||
| 136 | { | ||
| 137 | u32 val; | ||
| 138 | |||
| 139 | val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); | ||
| 140 | val &= ~A3700_SPI_AUTO_CS; | ||
| 141 | spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val); | ||
| 142 | } | ||
| 143 | |||
| 144 | static void a3700_spi_activate_cs(struct a3700_spi *a3700_spi, unsigned int cs) | ||
| 145 | { | ||
| 146 | u32 val; | ||
| 147 | |||
| 148 | val = spireg_read(a3700_spi, A3700_SPI_IF_CTRL_REG); | ||
| 149 | val |= (A3700_SPI_EN << cs); | ||
| 150 | spireg_write(a3700_spi, A3700_SPI_IF_CTRL_REG, val); | ||
| 151 | } | ||
| 152 | |||
| 153 | static void a3700_spi_deactivate_cs(struct a3700_spi *a3700_spi, | ||
| 154 | unsigned int cs) | ||
| 155 | { | ||
| 156 | u32 val; | ||
| 157 | |||
| 158 | val = spireg_read(a3700_spi, A3700_SPI_IF_CTRL_REG); | ||
| 159 | val &= ~(A3700_SPI_EN << cs); | ||
| 160 | spireg_write(a3700_spi, A3700_SPI_IF_CTRL_REG, val); | ||
| 161 | } | ||
| 162 | |||
| 163 | static int a3700_spi_pin_mode_set(struct a3700_spi *a3700_spi, | ||
| 164 | unsigned int pin_mode) | ||
| 165 | { | ||
| 166 | u32 val; | ||
| 167 | |||
| 168 | val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); | ||
| 169 | val &= ~(A3700_SPI_INST_PIN | A3700_SPI_ADDR_PIN); | ||
| 170 | val &= ~(A3700_SPI_DATA_PIN0 | A3700_SPI_DATA_PIN1); | ||
| 171 | |||
| 172 | switch (pin_mode) { | ||
| 173 | case 1: | ||
| 174 | break; | ||
| 175 | case 2: | ||
| 176 | val |= A3700_SPI_DATA_PIN0; | ||
| 177 | break; | ||
| 178 | case 4: | ||
| 179 | val |= A3700_SPI_DATA_PIN1; | ||
| 180 | break; | ||
| 181 | default: | ||
| 182 | dev_err(&a3700_spi->master->dev, "wrong pin mode %u", pin_mode); | ||
| 183 | return -EINVAL; | ||
| 184 | } | ||
| 185 | |||
| 186 | spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val); | ||
| 187 | |||
| 188 | return 0; | ||
| 189 | } | ||
| 190 | |||
| 191 | static void a3700_spi_fifo_mode_set(struct a3700_spi *a3700_spi) | ||
| 192 | { | ||
| 193 | u32 val; | ||
| 194 | |||
| 195 | val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); | ||
| 196 | val |= A3700_SPI_FIFO_MODE; | ||
| 197 | spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val); | ||
| 198 | } | ||
| 199 | |||
| 200 | static void a3700_spi_mode_set(struct a3700_spi *a3700_spi, | ||
| 201 | unsigned int mode_bits) | ||
| 202 | { | ||
| 203 | u32 val; | ||
| 204 | |||
| 205 | val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); | ||
| 206 | |||
| 207 | if (mode_bits & SPI_CPOL) | ||
| 208 | val |= A3700_SPI_CLK_POL; | ||
| 209 | else | ||
| 210 | val &= ~A3700_SPI_CLK_POL; | ||
| 211 | |||
| 212 | if (mode_bits & SPI_CPHA) | ||
| 213 | val |= A3700_SPI_CLK_PHA; | ||
| 214 | else | ||
| 215 | val &= ~A3700_SPI_CLK_PHA; | ||
| 216 | |||
| 217 | spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val); | ||
| 218 | } | ||
| 219 | |||
| 220 | static void a3700_spi_clock_set(struct a3700_spi *a3700_spi, | ||
| 221 | unsigned int speed_hz, u16 mode) | ||
| 222 | { | ||
| 223 | u32 val; | ||
| 224 | u32 prescale; | ||
| 225 | |||
| 226 | prescale = DIV_ROUND_UP(clk_get_rate(a3700_spi->clk), speed_hz); | ||
| 227 | |||
| 228 | val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); | ||
| 229 | val = val & ~A3700_SPI_CLK_PRESCALE_MASK; | ||
| 230 | |||
| 231 | val = val | (prescale & A3700_SPI_CLK_PRESCALE_MASK); | ||
| 232 | spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val); | ||
| 233 | |||
| 234 | if (prescale <= 2) { | ||
| 235 | val = spireg_read(a3700_spi, A3700_SPI_IF_TIME_REG); | ||
| 236 | val |= A3700_SPI_CLK_CAPT_EDGE; | ||
| 237 | spireg_write(a3700_spi, A3700_SPI_IF_TIME_REG, val); | ||
| 238 | } | ||
| 239 | |||
| 240 | val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); | ||
| 241 | val &= ~(A3700_SPI_CLK_POL | A3700_SPI_CLK_PHA); | ||
| 242 | |||
| 243 | if (mode & SPI_CPOL) | ||
| 244 | val |= A3700_SPI_CLK_POL; | ||
| 245 | |||
| 246 | if (mode & SPI_CPHA) | ||
| 247 | val |= A3700_SPI_CLK_PHA; | ||
| 248 | |||
| 249 | spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val); | ||
| 250 | } | ||
| 251 | |||
| 252 | static void a3700_spi_bytelen_set(struct a3700_spi *a3700_spi, unsigned int len) | ||
| 253 | { | ||
| 254 | u32 val; | ||
| 255 | |||
| 256 | val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); | ||
| 257 | if (len == 4) | ||
| 258 | val |= A3700_SPI_BYTE_LEN; | ||
| 259 | else | ||
| 260 | val &= ~A3700_SPI_BYTE_LEN; | ||
| 261 | spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val); | ||
| 262 | |||
| 263 | a3700_spi->byte_len = len; | ||
| 264 | } | ||
| 265 | |||
| 266 | static int a3700_spi_fifo_flush(struct a3700_spi *a3700_spi) | ||
| 267 | { | ||
| 268 | int timeout = A3700_SPI_TIMEOUT; | ||
| 269 | u32 val; | ||
| 270 | |||
| 271 | val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); | ||
| 272 | val |= A3700_SPI_FIFO_FLUSH; | ||
| 273 | spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val); | ||
| 274 | |||
| 275 | while (--timeout) { | ||
| 276 | val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); | ||
| 277 | if (!(val & A3700_SPI_FIFO_FLUSH)) | ||
| 278 | return 0; | ||
| 279 | udelay(1); | ||
| 280 | } | ||
| 281 | |||
| 282 | return -ETIMEDOUT; | ||
| 283 | } | ||
| 284 | |||
| 285 | static int a3700_spi_init(struct a3700_spi *a3700_spi) | ||
| 286 | { | ||
| 287 | struct spi_master *master = a3700_spi->master; | ||
| 288 | u32 val; | ||
| 289 | int i, ret = 0; | ||
| 290 | |||
| 291 | /* Reset SPI unit */ | ||
| 292 | val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); | ||
| 293 | val |= A3700_SPI_SRST; | ||
| 294 | spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val); | ||
| 295 | |||
| 296 | udelay(A3700_SPI_TIMEOUT); | ||
| 297 | |||
| 298 | val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); | ||
| 299 | val &= ~A3700_SPI_SRST; | ||
| 300 | spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val); | ||
| 301 | |||
| 302 | /* Disable AUTO_CS and deactivate all chip-selects */ | ||
| 303 | a3700_spi_auto_cs_unset(a3700_spi); | ||
| 304 | for (i = 0; i < master->num_chipselect; i++) | ||
| 305 | a3700_spi_deactivate_cs(a3700_spi, i); | ||
| 306 | |||
| 307 | /* Enable FIFO mode */ | ||
| 308 | a3700_spi_fifo_mode_set(a3700_spi); | ||
| 309 | |||
| 310 | /* Set SPI mode */ | ||
| 311 | a3700_spi_mode_set(a3700_spi, master->mode_bits); | ||
| 312 | |||
| 313 | /* Reset counters */ | ||
| 314 | spireg_write(a3700_spi, A3700_SPI_IF_HDR_CNT_REG, 0); | ||
| 315 | spireg_write(a3700_spi, A3700_SPI_IF_DIN_CNT_REG, 0); | ||
| 316 | |||
| 317 | /* Mask the interrupts and clear cause bits */ | ||
| 318 | spireg_write(a3700_spi, A3700_SPI_INT_MASK_REG, 0); | ||
| 319 | spireg_write(a3700_spi, A3700_SPI_INT_STAT_REG, ~0U); | ||
| 320 | |||
| 321 | return ret; | ||
| 322 | } | ||
| 323 | |||
| 324 | static irqreturn_t a3700_spi_interrupt(int irq, void *dev_id) | ||
| 325 | { | ||
| 326 | struct spi_master *master = dev_id; | ||
| 327 | struct a3700_spi *a3700_spi; | ||
| 328 | u32 cause; | ||
| 329 | |||
| 330 | a3700_spi = spi_master_get_devdata(master); | ||
| 331 | |||
| 332 | /* Get interrupt causes */ | ||
| 333 | cause = spireg_read(a3700_spi, A3700_SPI_INT_STAT_REG); | ||
| 334 | |||
| 335 | if (!cause || !(a3700_spi->wait_mask & cause)) | ||
| 336 | return IRQ_NONE; | ||
| 337 | |||
| 338 | /* mask and acknowledge the SPI interrupts */ | ||
| 339 | spireg_write(a3700_spi, A3700_SPI_INT_MASK_REG, 0); | ||
| 340 | spireg_write(a3700_spi, A3700_SPI_INT_STAT_REG, cause); | ||
| 341 | |||
| 342 | /* Wake up the transfer */ | ||
| 343 | if (a3700_spi->wait_mask & cause) | ||
| 344 | complete(&a3700_spi->done); | ||
| 345 | |||
| 346 | return IRQ_HANDLED; | ||
| 347 | } | ||
| 348 | |||
| 349 | static bool a3700_spi_wait_completion(struct spi_device *spi) | ||
| 350 | { | ||
| 351 | struct a3700_spi *a3700_spi; | ||
| 352 | unsigned int timeout; | ||
| 353 | unsigned int ctrl_reg; | ||
| 354 | unsigned long timeout_jiffies; | ||
| 355 | |||
| 356 | a3700_spi = spi_master_get_devdata(spi->master); | ||
| 357 | |||
| 358 | /* SPI interrupt is edge-triggered, which means an interrupt will | ||
| 359 | * be generated only when detecting a specific status bit changed | ||
| 360 | * from '0' to '1'. So when we start waiting for a interrupt, we | ||
| 361 | * need to check status bit in control reg first, if it is already 1, | ||
| 362 | * then we do not need to wait for interrupt | ||
| 363 | */ | ||
| 364 | ctrl_reg = spireg_read(a3700_spi, A3700_SPI_IF_CTRL_REG); | ||
| 365 | if (a3700_spi->wait_mask & ctrl_reg) | ||
| 366 | return true; | ||
| 367 | |||
| 368 | reinit_completion(&a3700_spi->done); | ||
| 369 | |||
| 370 | spireg_write(a3700_spi, A3700_SPI_INT_MASK_REG, | ||
| 371 | a3700_spi->wait_mask); | ||
| 372 | |||
| 373 | timeout_jiffies = msecs_to_jiffies(A3700_SPI_TIMEOUT); | ||
| 374 | timeout = wait_for_completion_timeout(&a3700_spi->done, | ||
| 375 | timeout_jiffies); | ||
| 376 | |||
| 377 | a3700_spi->wait_mask = 0; | ||
| 378 | |||
| 379 | if (timeout) | ||
| 380 | return true; | ||
| 381 | |||
| 382 | /* there might be the case that right after we checked the | ||
| 383 | * status bits in this routine and before start to wait for | ||
| 384 | * interrupt by wait_for_completion_timeout, the interrupt | ||
| 385 | * happens, to avoid missing it we need to double check | ||
| 386 | * status bits in control reg, if it is already 1, then | ||
| 387 | * consider that we have the interrupt successfully and | ||
| 388 | * return true. | ||
| 389 | */ | ||
| 390 | ctrl_reg = spireg_read(a3700_spi, A3700_SPI_IF_CTRL_REG); | ||
| 391 | if (a3700_spi->wait_mask & ctrl_reg) | ||
| 392 | return true; | ||
| 393 | |||
| 394 | spireg_write(a3700_spi, A3700_SPI_INT_MASK_REG, 0); | ||
| 395 | |||
| 396 | return true; | ||
| 397 | } | ||
| 398 | |||
| 399 | static bool a3700_spi_transfer_wait(struct spi_device *spi, | ||
| 400 | unsigned int bit_mask) | ||
| 401 | { | ||
| 402 | struct a3700_spi *a3700_spi; | ||
| 403 | |||
| 404 | a3700_spi = spi_master_get_devdata(spi->master); | ||
| 405 | a3700_spi->wait_mask = bit_mask; | ||
| 406 | |||
| 407 | return a3700_spi_wait_completion(spi); | ||
| 408 | } | ||
| 409 | |||
| 410 | static void a3700_spi_fifo_thres_set(struct a3700_spi *a3700_spi, | ||
| 411 | unsigned int bytes) | ||
| 412 | { | ||
| 413 | u32 val; | ||
| 414 | |||
| 415 | val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); | ||
| 416 | val &= ~(A3700_SPI_FIFO_THRS_MASK << A3700_SPI_RFIFO_THRS_BIT); | ||
| 417 | val |= (bytes - 1) << A3700_SPI_RFIFO_THRS_BIT; | ||
| 418 | val &= ~(A3700_SPI_FIFO_THRS_MASK << A3700_SPI_WFIFO_THRS_BIT); | ||
| 419 | val |= (7 - bytes) << A3700_SPI_WFIFO_THRS_BIT; | ||
| 420 | spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val); | ||
| 421 | } | ||
| 422 | |||
| 423 | static void a3700_spi_transfer_setup(struct spi_device *spi, | ||
| 424 | struct spi_transfer *xfer) | ||
| 425 | { | ||
| 426 | struct a3700_spi *a3700_spi; | ||
| 427 | unsigned int byte_len; | ||
| 428 | |||
| 429 | a3700_spi = spi_master_get_devdata(spi->master); | ||
| 430 | |||
| 431 | a3700_spi_clock_set(a3700_spi, xfer->speed_hz, spi->mode); | ||
| 432 | |||
| 433 | byte_len = xfer->bits_per_word >> 3; | ||
| 434 | |||
| 435 | a3700_spi_fifo_thres_set(a3700_spi, byte_len); | ||
| 436 | } | ||
| 437 | |||
| 438 | static void a3700_spi_set_cs(struct spi_device *spi, bool enable) | ||
| 439 | { | ||
| 440 | struct a3700_spi *a3700_spi = spi_master_get_devdata(spi->master); | ||
| 441 | |||
| 442 | if (!enable) | ||
| 443 | a3700_spi_activate_cs(a3700_spi, spi->chip_select); | ||
| 444 | else | ||
| 445 | a3700_spi_deactivate_cs(a3700_spi, spi->chip_select); | ||
| 446 | } | ||
| 447 | |||
| 448 | static void a3700_spi_header_set(struct a3700_spi *a3700_spi) | ||
| 449 | { | ||
| 450 | u32 instr_cnt = 0, addr_cnt = 0, dummy_cnt = 0; | ||
| 451 | u32 val = 0; | ||
| 452 | |||
| 453 | /* Clear the header registers */ | ||
| 454 | spireg_write(a3700_spi, A3700_SPI_IF_INST_REG, 0); | ||
| 455 | spireg_write(a3700_spi, A3700_SPI_IF_ADDR_REG, 0); | ||
| 456 | spireg_write(a3700_spi, A3700_SPI_IF_RMODE_REG, 0); | ||
| 457 | |||
| 458 | /* Set header counters */ | ||
| 459 | if (a3700_spi->tx_buf) { | ||
| 460 | if (a3700_spi->buf_len <= a3700_spi->instr_cnt) { | ||
| 461 | instr_cnt = a3700_spi->buf_len; | ||
| 462 | } else if (a3700_spi->buf_len <= (a3700_spi->instr_cnt + | ||
| 463 | a3700_spi->addr_cnt)) { | ||
| 464 | instr_cnt = a3700_spi->instr_cnt; | ||
| 465 | addr_cnt = a3700_spi->buf_len - instr_cnt; | ||
| 466 | } else if (a3700_spi->buf_len <= a3700_spi->hdr_cnt) { | ||
| 467 | instr_cnt = a3700_spi->instr_cnt; | ||
| 468 | addr_cnt = a3700_spi->addr_cnt; | ||
| 469 | /* Need to handle the normal write case with 1 byte | ||
| 470 | * data | ||
| 471 | */ | ||
| 472 | if (!a3700_spi->tx_buf[instr_cnt + addr_cnt]) | ||
| 473 | dummy_cnt = a3700_spi->buf_len - instr_cnt - | ||
| 474 | addr_cnt; | ||
| 475 | } | ||
| 476 | val |= ((instr_cnt & A3700_SPI_INSTR_CNT_MASK) | ||
| 477 | << A3700_SPI_INSTR_CNT_BIT); | ||
| 478 | val |= ((addr_cnt & A3700_SPI_ADDR_CNT_MASK) | ||
| 479 | << A3700_SPI_ADDR_CNT_BIT); | ||
| 480 | val |= ((dummy_cnt & A3700_SPI_DUMMY_CNT_MASK) | ||
| 481 | << A3700_SPI_DUMMY_CNT_BIT); | ||
| 482 | } | ||
| 483 | spireg_write(a3700_spi, A3700_SPI_IF_HDR_CNT_REG, val); | ||
| 484 | |||
| 485 | /* Update the buffer length to be transferred */ | ||
| 486 | a3700_spi->buf_len -= (instr_cnt + addr_cnt + dummy_cnt); | ||
| 487 | |||
| 488 | /* Set Instruction */ | ||
| 489 | val = 0; | ||
| 490 | while (instr_cnt--) { | ||
| 491 | val = (val << 8) | a3700_spi->tx_buf[0]; | ||
| 492 | a3700_spi->tx_buf++; | ||
| 493 | } | ||
| 494 | spireg_write(a3700_spi, A3700_SPI_IF_INST_REG, val); | ||
| 495 | |||
| 496 | /* Set Address */ | ||
| 497 | val = 0; | ||
| 498 | while (addr_cnt--) { | ||
| 499 | val = (val << 8) | a3700_spi->tx_buf[0]; | ||
| 500 | a3700_spi->tx_buf++; | ||
| 501 | } | ||
| 502 | spireg_write(a3700_spi, A3700_SPI_IF_ADDR_REG, val); | ||
| 503 | } | ||
| 504 | |||
| 505 | static int a3700_is_wfifo_full(struct a3700_spi *a3700_spi) | ||
| 506 | { | ||
| 507 | u32 val; | ||
| 508 | |||
| 509 | val = spireg_read(a3700_spi, A3700_SPI_IF_CTRL_REG); | ||
| 510 | return (val & A3700_SPI_WFIFO_FULL); | ||
| 511 | } | ||
| 512 | |||
| 513 | static int a3700_spi_fifo_write(struct a3700_spi *a3700_spi) | ||
| 514 | { | ||
| 515 | u32 val; | ||
| 516 | int i = 0; | ||
| 517 | |||
| 518 | while (!a3700_is_wfifo_full(a3700_spi) && a3700_spi->buf_len) { | ||
| 519 | val = 0; | ||
| 520 | if (a3700_spi->buf_len >= 4) { | ||
| 521 | val = cpu_to_le32(*(u32 *)a3700_spi->tx_buf); | ||
| 522 | spireg_write(a3700_spi, A3700_SPI_DATA_OUT_REG, val); | ||
| 523 | |||
| 524 | a3700_spi->buf_len -= 4; | ||
| 525 | a3700_spi->tx_buf += 4; | ||
| 526 | } else { | ||
| 527 | /* | ||
| 528 | * If the remained buffer length is less than 4-bytes, | ||
| 529 | * we should pad the write buffer with all ones. So that | ||
| 530 | * it avoids overwrite the unexpected bytes following | ||
| 531 | * the last one. | ||
| 532 | */ | ||
| 533 | val = GENMASK(31, 0); | ||
| 534 | while (a3700_spi->buf_len) { | ||
| 535 | val &= ~(0xff << (8 * i)); | ||
| 536 | val |= *a3700_spi->tx_buf++ << (8 * i); | ||
| 537 | i++; | ||
| 538 | a3700_spi->buf_len--; | ||
| 539 | |||
| 540 | spireg_write(a3700_spi, A3700_SPI_DATA_OUT_REG, | ||
| 541 | val); | ||
| 542 | } | ||
| 543 | break; | ||
| 544 | } | ||
| 545 | } | ||
| 546 | |||
| 547 | return 0; | ||
| 548 | } | ||
| 549 | |||
| 550 | static int a3700_is_rfifo_empty(struct a3700_spi *a3700_spi) | ||
| 551 | { | ||
| 552 | u32 val = spireg_read(a3700_spi, A3700_SPI_IF_CTRL_REG); | ||
| 553 | |||
| 554 | return (val & A3700_SPI_RFIFO_EMPTY); | ||
| 555 | } | ||
| 556 | |||
| 557 | static int a3700_spi_fifo_read(struct a3700_spi *a3700_spi) | ||
| 558 | { | ||
| 559 | u32 val; | ||
| 560 | |||
| 561 | while (!a3700_is_rfifo_empty(a3700_spi) && a3700_spi->buf_len) { | ||
| 562 | val = spireg_read(a3700_spi, A3700_SPI_DATA_IN_REG); | ||
| 563 | if (a3700_spi->buf_len >= 4) { | ||
| 564 | u32 data = le32_to_cpu(val); | ||
| 565 | memcpy(a3700_spi->rx_buf, &data, 4); | ||
| 566 | |||
| 567 | a3700_spi->buf_len -= 4; | ||
| 568 | a3700_spi->rx_buf += 4; | ||
| 569 | } else { | ||
| 570 | /* | ||
| 571 | * When remain bytes is not larger than 4, we should | ||
| 572 | * avoid memory overwriting and just write the left rx | ||
| 573 | * buffer bytes. | ||
| 574 | */ | ||
| 575 | while (a3700_spi->buf_len) { | ||
| 576 | *a3700_spi->rx_buf = val & 0xff; | ||
| 577 | val >>= 8; | ||
| 578 | |||
| 579 | a3700_spi->buf_len--; | ||
| 580 | a3700_spi->rx_buf++; | ||
| 581 | } | ||
| 582 | } | ||
| 583 | } | ||
| 584 | |||
| 585 | return 0; | ||
| 586 | } | ||
| 587 | |||
| 588 | static void a3700_spi_transfer_abort_fifo(struct a3700_spi *a3700_spi) | ||
| 589 | { | ||
| 590 | int timeout = A3700_SPI_TIMEOUT; | ||
| 591 | u32 val; | ||
| 592 | |||
| 593 | val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); | ||
| 594 | val |= A3700_SPI_XFER_STOP; | ||
| 595 | spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val); | ||
| 596 | |||
| 597 | while (--timeout) { | ||
| 598 | val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); | ||
| 599 | if (!(val & A3700_SPI_XFER_START)) | ||
| 600 | break; | ||
| 601 | udelay(1); | ||
| 602 | } | ||
| 603 | |||
| 604 | a3700_spi_fifo_flush(a3700_spi); | ||
| 605 | |||
| 606 | val &= ~A3700_SPI_XFER_STOP; | ||
| 607 | spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val); | ||
| 608 | } | ||
| 609 | |||
| 610 | static int a3700_spi_prepare_message(struct spi_master *master, | ||
| 611 | struct spi_message *message) | ||
| 612 | { | ||
| 613 | struct a3700_spi *a3700_spi = spi_master_get_devdata(master); | ||
| 614 | struct spi_device *spi = message->spi; | ||
| 615 | int ret; | ||
| 616 | |||
| 617 | ret = clk_enable(a3700_spi->clk); | ||
| 618 | if (ret) { | ||
| 619 | dev_err(&spi->dev, "failed to enable clk with error %d\n", ret); | ||
| 620 | return ret; | ||
| 621 | } | ||
| 622 | |||
| 623 | /* Flush the FIFOs */ | ||
| 624 | ret = a3700_spi_fifo_flush(a3700_spi); | ||
| 625 | if (ret) | ||
| 626 | return ret; | ||
| 627 | |||
| 628 | a3700_spi_bytelen_set(a3700_spi, 4); | ||
| 629 | |||
| 630 | return 0; | ||
| 631 | } | ||
| 632 | |||
| 633 | static int a3700_spi_transfer_one(struct spi_master *master, | ||
| 634 | struct spi_device *spi, | ||
| 635 | struct spi_transfer *xfer) | ||
| 636 | { | ||
| 637 | struct a3700_spi *a3700_spi = spi_master_get_devdata(master); | ||
| 638 | int ret = 0, timeout = A3700_SPI_TIMEOUT; | ||
| 639 | unsigned int nbits = 0; | ||
| 640 | u32 val; | ||
| 641 | |||
| 642 | a3700_spi_transfer_setup(spi, xfer); | ||
| 643 | |||
| 644 | a3700_spi->tx_buf = xfer->tx_buf; | ||
| 645 | a3700_spi->rx_buf = xfer->rx_buf; | ||
| 646 | a3700_spi->buf_len = xfer->len; | ||
| 647 | |||
| 648 | /* SPI transfer headers */ | ||
| 649 | a3700_spi_header_set(a3700_spi); | ||
| 650 | |||
| 651 | if (xfer->tx_buf) | ||
| 652 | nbits = xfer->tx_nbits; | ||
| 653 | else if (xfer->rx_buf) | ||
| 654 | nbits = xfer->rx_nbits; | ||
| 655 | |||
| 656 | a3700_spi_pin_mode_set(a3700_spi, nbits); | ||
| 657 | |||
| 658 | if (xfer->rx_buf) { | ||
| 659 | /* Set read data length */ | ||
| 660 | spireg_write(a3700_spi, A3700_SPI_IF_DIN_CNT_REG, | ||
| 661 | a3700_spi->buf_len); | ||
| 662 | /* Start READ transfer */ | ||
| 663 | val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); | ||
| 664 | val &= ~A3700_SPI_RW_EN; | ||
| 665 | val |= A3700_SPI_XFER_START; | ||
| 666 | spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val); | ||
| 667 | } else if (xfer->tx_buf) { | ||
| 668 | /* Start Write transfer */ | ||
| 669 | val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); | ||
| 670 | val |= (A3700_SPI_XFER_START | A3700_SPI_RW_EN); | ||
| 671 | spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val); | ||
| 672 | |||
| 673 | /* | ||
| 674 | * If there are data to be written to the SPI device, xmit_data | ||
| 675 | * flag is set true; otherwise the instruction in SPI_INSTR does | ||
| 676 | * not require data to be written to the SPI device, then | ||
| 677 | * xmit_data flag is set false. | ||
| 678 | */ | ||
| 679 | a3700_spi->xmit_data = (a3700_spi->buf_len != 0); | ||
| 680 | } | ||
| 681 | |||
| 682 | while (a3700_spi->buf_len) { | ||
| 683 | if (a3700_spi->tx_buf) { | ||
| 684 | /* Wait wfifo ready */ | ||
| 685 | if (!a3700_spi_transfer_wait(spi, | ||
| 686 | A3700_SPI_WFIFO_RDY)) { | ||
| 687 | dev_err(&spi->dev, | ||
| 688 | "wait wfifo ready timed out\n"); | ||
| 689 | ret = -ETIMEDOUT; | ||
| 690 | goto error; | ||
| 691 | } | ||
| 692 | /* Fill up the wfifo */ | ||
| 693 | ret = a3700_spi_fifo_write(a3700_spi); | ||
| 694 | if (ret) | ||
| 695 | goto error; | ||
| 696 | } else if (a3700_spi->rx_buf) { | ||
| 697 | /* Wait rfifo ready */ | ||
| 698 | if (!a3700_spi_transfer_wait(spi, | ||
| 699 | A3700_SPI_RFIFO_RDY)) { | ||
| 700 | dev_err(&spi->dev, | ||
| 701 | "wait rfifo ready timed out\n"); | ||
| 702 | ret = -ETIMEDOUT; | ||
| 703 | goto error; | ||
| 704 | } | ||
| 705 | /* Drain out the rfifo */ | ||
| 706 | ret = a3700_spi_fifo_read(a3700_spi); | ||
| 707 | if (ret) | ||
| 708 | goto error; | ||
| 709 | } | ||
| 710 | } | ||
| 711 | |||
| 712 | /* | ||
| 713 | * Stop a write transfer in fifo mode: | ||
| 714 | * - wait all the bytes in wfifo to be shifted out | ||
| 715 | * - set XFER_STOP bit | ||
| 716 | * - wait XFER_START bit clear | ||
| 717 | * - clear XFER_STOP bit | ||
| 718 | * Stop a read transfer in fifo mode: | ||
| 719 | * - the hardware is to reset the XFER_START bit | ||
| 720 | * after the number of bytes indicated in DIN_CNT | ||
| 721 | * register | ||
| 722 | * - just wait XFER_START bit clear | ||
| 723 | */ | ||
| 724 | if (a3700_spi->tx_buf) { | ||
| 725 | if (a3700_spi->xmit_data) { | ||
| 726 | /* | ||
| 727 | * If there are data written to the SPI device, wait | ||
| 728 | * until SPI_WFIFO_EMPTY is 1 to wait for all data to | ||
| 729 | * transfer out of write FIFO. | ||
| 730 | */ | ||
| 731 | if (!a3700_spi_transfer_wait(spi, | ||
| 732 | A3700_SPI_WFIFO_EMPTY)) { | ||
| 733 | dev_err(&spi->dev, "wait wfifo empty timed out\n"); | ||
| 734 | return -ETIMEDOUT; | ||
| 735 | } | ||
| 736 | } else { | ||
| 737 | /* | ||
| 738 | * If the instruction in SPI_INSTR does not require data | ||
| 739 | * to be written to the SPI device, wait until SPI_RDY | ||
| 740 | * is 1 for the SPI interface to be in idle. | ||
| 741 | */ | ||
| 742 | if (!a3700_spi_transfer_wait(spi, A3700_SPI_XFER_RDY)) { | ||
| 743 | dev_err(&spi->dev, "wait xfer ready timed out\n"); | ||
| 744 | return -ETIMEDOUT; | ||
| 745 | } | ||
| 746 | } | ||
| 747 | |||
| 748 | val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); | ||
| 749 | val |= A3700_SPI_XFER_STOP; | ||
| 750 | spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val); | ||
| 751 | } | ||
| 752 | |||
| 753 | while (--timeout) { | ||
| 754 | val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); | ||
| 755 | if (!(val & A3700_SPI_XFER_START)) | ||
| 756 | break; | ||
| 757 | udelay(1); | ||
| 758 | } | ||
| 759 | |||
| 760 | if (timeout == 0) { | ||
| 761 | dev_err(&spi->dev, "wait transfer start clear timed out\n"); | ||
| 762 | ret = -ETIMEDOUT; | ||
| 763 | goto error; | ||
| 764 | } | ||
| 765 | |||
| 766 | val &= ~A3700_SPI_XFER_STOP; | ||
| 767 | spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val); | ||
| 768 | goto out; | ||
| 769 | |||
| 770 | error: | ||
| 771 | a3700_spi_transfer_abort_fifo(a3700_spi); | ||
| 772 | out: | ||
| 773 | spi_finalize_current_transfer(master); | ||
| 774 | |||
| 775 | return ret; | ||
| 776 | } | ||
| 777 | |||
| 778 | static int a3700_spi_unprepare_message(struct spi_master *master, | ||
| 779 | struct spi_message *message) | ||
| 780 | { | ||
| 781 | struct a3700_spi *a3700_spi = spi_master_get_devdata(master); | ||
| 782 | |||
| 783 | clk_disable(a3700_spi->clk); | ||
| 784 | |||
| 785 | return 0; | ||
| 786 | } | ||
| 787 | |||
| 788 | static const struct of_device_id a3700_spi_dt_ids[] = { | ||
| 789 | { .compatible = "marvell,armada-3700-spi", .data = NULL }, | ||
| 790 | {}, | ||
| 791 | }; | ||
| 792 | |||
| 793 | MODULE_DEVICE_TABLE(of, a3700_spi_dt_ids); | ||
| 794 | |||
| 795 | static int a3700_spi_probe(struct platform_device *pdev) | ||
| 796 | { | ||
| 797 | struct device *dev = &pdev->dev; | ||
| 798 | struct device_node *of_node = dev->of_node; | ||
| 799 | struct resource *res; | ||
| 800 | struct spi_master *master; | ||
| 801 | struct a3700_spi *spi; | ||
| 802 | u32 num_cs = 0; | ||
| 803 | int ret = 0; | ||
| 804 | |||
| 805 | master = spi_alloc_master(dev, sizeof(*spi)); | ||
| 806 | if (!master) { | ||
| 807 | dev_err(dev, "master allocation failed\n"); | ||
| 808 | ret = -ENOMEM; | ||
| 809 | goto out; | ||
| 810 | } | ||
| 811 | |||
| 812 | if (of_property_read_u32(of_node, "num-cs", &num_cs)) { | ||
| 813 | dev_err(dev, "could not find num-cs\n"); | ||
| 814 | ret = -ENXIO; | ||
| 815 | goto error; | ||
| 816 | } | ||
| 817 | |||
| 818 | master->bus_num = pdev->id; | ||
| 819 | master->dev.of_node = of_node; | ||
| 820 | master->mode_bits = SPI_MODE_3; | ||
| 821 | master->num_chipselect = num_cs; | ||
| 822 | master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(32); | ||
| 823 | master->prepare_message = a3700_spi_prepare_message; | ||
| 824 | master->transfer_one = a3700_spi_transfer_one; | ||
| 825 | master->unprepare_message = a3700_spi_unprepare_message; | ||
| 826 | master->set_cs = a3700_spi_set_cs; | ||
| 827 | master->flags = SPI_MASTER_HALF_DUPLEX; | ||
| 828 | master->mode_bits |= (SPI_RX_DUAL | SPI_RX_DUAL | | ||
| 829 | SPI_RX_QUAD | SPI_TX_QUAD); | ||
| 830 | |||
| 831 | platform_set_drvdata(pdev, master); | ||
| 832 | |||
| 833 | spi = spi_master_get_devdata(master); | ||
| 834 | memset(spi, 0, sizeof(struct a3700_spi)); | ||
| 835 | |||
| 836 | spi->master = master; | ||
| 837 | spi->instr_cnt = A3700_INSTR_CNT; | ||
| 838 | spi->addr_cnt = A3700_ADDR_CNT; | ||
| 839 | spi->hdr_cnt = A3700_INSTR_CNT + A3700_ADDR_CNT + | ||
| 840 | A3700_DUMMY_CNT; | ||
| 841 | |||
| 842 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 843 | spi->base = devm_ioremap_resource(dev, res); | ||
| 844 | if (IS_ERR(spi->base)) { | ||
| 845 | ret = PTR_ERR(spi->base); | ||
| 846 | goto error; | ||
| 847 | } | ||
| 848 | |||
| 849 | spi->irq = platform_get_irq(pdev, 0); | ||
| 850 | if (spi->irq < 0) { | ||
| 851 | dev_err(dev, "could not get irq: %d\n", spi->irq); | ||
| 852 | ret = -ENXIO; | ||
| 853 | goto error; | ||
| 854 | } | ||
| 855 | |||
| 856 | init_completion(&spi->done); | ||
| 857 | |||
| 858 | spi->clk = devm_clk_get(dev, NULL); | ||
| 859 | if (IS_ERR(spi->clk)) { | ||
| 860 | dev_err(dev, "could not find clk: %ld\n", PTR_ERR(spi->clk)); | ||
| 861 | goto error; | ||
| 862 | } | ||
| 863 | |||
| 864 | ret = clk_prepare(spi->clk); | ||
| 865 | if (ret) { | ||
| 866 | dev_err(dev, "could not prepare clk: %d\n", ret); | ||
| 867 | goto error; | ||
| 868 | } | ||
| 869 | |||
| 870 | ret = a3700_spi_init(spi); | ||
| 871 | if (ret) | ||
| 872 | goto error_clk; | ||
| 873 | |||
| 874 | ret = devm_request_irq(dev, spi->irq, a3700_spi_interrupt, 0, | ||
| 875 | dev_name(dev), master); | ||
| 876 | if (ret) { | ||
| 877 | dev_err(dev, "could not request IRQ: %d\n", ret); | ||
| 878 | goto error_clk; | ||
| 879 | } | ||
| 880 | |||
| 881 | ret = devm_spi_register_master(dev, master); | ||
| 882 | if (ret) { | ||
| 883 | dev_err(dev, "Failed to register master\n"); | ||
| 884 | goto error_clk; | ||
| 885 | } | ||
| 886 | |||
| 887 | return 0; | ||
| 888 | |||
| 889 | error_clk: | ||
| 890 | clk_disable_unprepare(spi->clk); | ||
| 891 | error: | ||
| 892 | spi_master_put(master); | ||
| 893 | out: | ||
| 894 | return ret; | ||
| 895 | } | ||
| 896 | |||
| 897 | static int a3700_spi_remove(struct platform_device *pdev) | ||
| 898 | { | ||
| 899 | struct spi_master *master = platform_get_drvdata(pdev); | ||
| 900 | struct a3700_spi *spi = spi_master_get_devdata(master); | ||
| 901 | |||
| 902 | clk_unprepare(spi->clk); | ||
| 903 | spi_master_put(master); | ||
| 904 | |||
| 905 | return 0; | ||
| 906 | } | ||
| 907 | |||
| 908 | static struct platform_driver a3700_spi_driver = { | ||
| 909 | .driver = { | ||
| 910 | .name = DRIVER_NAME, | ||
| 911 | .owner = THIS_MODULE, | ||
| 912 | .of_match_table = of_match_ptr(a3700_spi_dt_ids), | ||
| 913 | }, | ||
| 914 | .probe = a3700_spi_probe, | ||
| 915 | .remove = a3700_spi_remove, | ||
| 916 | }; | ||
| 917 | |||
| 918 | module_platform_driver(a3700_spi_driver); | ||
| 919 | |||
| 920 | MODULE_DESCRIPTION("Armada-3700 SPI driver"); | ||
| 921 | MODULE_AUTHOR("Wilson Ding <dingwei@marvell.com>"); | ||
| 922 | MODULE_LICENSE("GPL"); | ||
| 923 | MODULE_ALIAS("platform:" DRIVER_NAME); | ||
diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c index 6165bf21d427..f369174fbd88 100644 --- a/drivers/spi/spi-ath79.c +++ b/drivers/spi/spi-ath79.c | |||
| @@ -304,6 +304,7 @@ static const struct of_device_id ath79_spi_of_match[] = { | |||
| 304 | { .compatible = "qca,ar7100-spi", }, | 304 | { .compatible = "qca,ar7100-spi", }, |
| 305 | { }, | 305 | { }, |
| 306 | }; | 306 | }; |
| 307 | MODULE_DEVICE_TABLE(of, ath79_spi_of_match); | ||
| 307 | 308 | ||
| 308 | static struct platform_driver ath79_spi_driver = { | 309 | static struct platform_driver ath79_spi_driver = { |
| 309 | .probe = ath79_spi_probe, | 310 | .probe = ath79_spi_probe, |
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 8feac599e9ab..0e7712bac3b6 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | 24 | ||
| 25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
| 26 | #include <linux/gpio.h> | 26 | #include <linux/gpio.h> |
| 27 | #include <linux/of_gpio.h> | ||
| 27 | #include <linux/pinctrl/consumer.h> | 28 | #include <linux/pinctrl/consumer.h> |
| 28 | #include <linux/pm_runtime.h> | 29 | #include <linux/pm_runtime.h> |
| 29 | 30 | ||
| @@ -264,17 +265,6 @@ | |||
| 264 | 265 | ||
| 265 | #define AUTOSUSPEND_TIMEOUT 2000 | 266 | #define AUTOSUSPEND_TIMEOUT 2000 |
| 266 | 267 | ||
| 267 | struct atmel_spi_dma { | ||
| 268 | struct dma_chan *chan_rx; | ||
| 269 | struct dma_chan *chan_tx; | ||
| 270 | struct scatterlist sgrx; | ||
| 271 | struct scatterlist sgtx; | ||
| 272 | struct dma_async_tx_descriptor *data_desc_rx; | ||
| 273 | struct dma_async_tx_descriptor *data_desc_tx; | ||
| 274 | |||
| 275 | struct at_dma_slave dma_slave; | ||
| 276 | }; | ||
| 277 | |||
| 278 | struct atmel_spi_caps { | 268 | struct atmel_spi_caps { |
| 279 | bool is_spi2; | 269 | bool is_spi2; |
| 280 | bool has_wdrbt; | 270 | bool has_wdrbt; |
| @@ -295,6 +285,7 @@ struct atmel_spi { | |||
| 295 | int irq; | 285 | int irq; |
| 296 | struct clk *clk; | 286 | struct clk *clk; |
| 297 | struct platform_device *pdev; | 287 | struct platform_device *pdev; |
| 288 | unsigned long spi_clk; | ||
| 298 | 289 | ||
| 299 | struct spi_transfer *current_transfer; | 290 | struct spi_transfer *current_transfer; |
| 300 | int current_remaining_bytes; | 291 | int current_remaining_bytes; |
| @@ -302,17 +293,11 @@ struct atmel_spi { | |||
| 302 | 293 | ||
| 303 | struct completion xfer_completion; | 294 | struct completion xfer_completion; |
| 304 | 295 | ||
| 305 | /* scratch buffer */ | ||
| 306 | void *buffer; | ||
| 307 | dma_addr_t buffer_dma; | ||
| 308 | |||
| 309 | struct atmel_spi_caps caps; | 296 | struct atmel_spi_caps caps; |
| 310 | 297 | ||
| 311 | bool use_dma; | 298 | bool use_dma; |
| 312 | bool use_pdc; | 299 | bool use_pdc; |
| 313 | bool use_cs_gpios; | 300 | bool use_cs_gpios; |
| 314 | /* dmaengine data */ | ||
| 315 | struct atmel_spi_dma dma; | ||
| 316 | 301 | ||
| 317 | bool keep_cs; | 302 | bool keep_cs; |
| 318 | bool cs_active; | 303 | bool cs_active; |
| @@ -326,7 +311,7 @@ struct atmel_spi_device { | |||
| 326 | u32 csr; | 311 | u32 csr; |
| 327 | }; | 312 | }; |
| 328 | 313 | ||
| 329 | #define BUFFER_SIZE PAGE_SIZE | 314 | #define SPI_MAX_DMA_XFER 65535 /* true for both PDC and DMA */ |
| 330 | #define INVALID_DMA_ADDRESS 0xffffffff | 315 | #define INVALID_DMA_ADDRESS 0xffffffff |
| 331 | 316 | ||
| 332 | /* | 317 | /* |
| @@ -456,10 +441,20 @@ static inline bool atmel_spi_use_dma(struct atmel_spi *as, | |||
| 456 | return as->use_dma && xfer->len >= DMA_MIN_BYTES; | 441 | return as->use_dma && xfer->len >= DMA_MIN_BYTES; |
| 457 | } | 442 | } |
| 458 | 443 | ||
| 444 | static bool atmel_spi_can_dma(struct spi_master *master, | ||
| 445 | struct spi_device *spi, | ||
| 446 | struct spi_transfer *xfer) | ||
| 447 | { | ||
| 448 | struct atmel_spi *as = spi_master_get_devdata(master); | ||
| 449 | |||
| 450 | return atmel_spi_use_dma(as, xfer); | ||
| 451 | } | ||
| 452 | |||
| 459 | static int atmel_spi_dma_slave_config(struct atmel_spi *as, | 453 | static int atmel_spi_dma_slave_config(struct atmel_spi *as, |
| 460 | struct dma_slave_config *slave_config, | 454 | struct dma_slave_config *slave_config, |
| 461 | u8 bits_per_word) | 455 | u8 bits_per_word) |
| 462 | { | 456 | { |
| 457 | struct spi_master *master = platform_get_drvdata(as->pdev); | ||
| 463 | int err = 0; | 458 | int err = 0; |
| 464 | 459 | ||
| 465 | if (bits_per_word > 8) { | 460 | if (bits_per_word > 8) { |
| @@ -491,7 +486,7 @@ static int atmel_spi_dma_slave_config(struct atmel_spi *as, | |||
| 491 | * path works the same whether FIFOs are available (and enabled) or not. | 486 | * path works the same whether FIFOs are available (and enabled) or not. |
| 492 | */ | 487 | */ |
| 493 | slave_config->direction = DMA_MEM_TO_DEV; | 488 | slave_config->direction = DMA_MEM_TO_DEV; |
| 494 | if (dmaengine_slave_config(as->dma.chan_tx, slave_config)) { | 489 | if (dmaengine_slave_config(master->dma_tx, slave_config)) { |
| 495 | dev_err(&as->pdev->dev, | 490 | dev_err(&as->pdev->dev, |
| 496 | "failed to configure tx dma channel\n"); | 491 | "failed to configure tx dma channel\n"); |
| 497 | err = -EINVAL; | 492 | err = -EINVAL; |
| @@ -506,7 +501,7 @@ static int atmel_spi_dma_slave_config(struct atmel_spi *as, | |||
| 506 | * enabled) or not. | 501 | * enabled) or not. |
| 507 | */ | 502 | */ |
| 508 | slave_config->direction = DMA_DEV_TO_MEM; | 503 | slave_config->direction = DMA_DEV_TO_MEM; |
| 509 | if (dmaengine_slave_config(as->dma.chan_rx, slave_config)) { | 504 | if (dmaengine_slave_config(master->dma_rx, slave_config)) { |
| 510 | dev_err(&as->pdev->dev, | 505 | dev_err(&as->pdev->dev, |
| 511 | "failed to configure rx dma channel\n"); | 506 | "failed to configure rx dma channel\n"); |
| 512 | err = -EINVAL; | 507 | err = -EINVAL; |
| @@ -515,7 +510,8 @@ static int atmel_spi_dma_slave_config(struct atmel_spi *as, | |||
| 515 | return err; | 510 | return err; |
| 516 | } | 511 | } |
| 517 | 512 | ||
| 518 | static int atmel_spi_configure_dma(struct atmel_spi *as) | 513 | static int atmel_spi_configure_dma(struct spi_master *master, |
| 514 | struct atmel_spi *as) | ||
| 519 | { | 515 | { |
| 520 | struct dma_slave_config slave_config; | 516 | struct dma_slave_config slave_config; |
| 521 | struct device *dev = &as->pdev->dev; | 517 | struct device *dev = &as->pdev->dev; |
| @@ -525,26 +521,26 @@ static int atmel_spi_configure_dma(struct atmel_spi *as) | |||
| 525 | dma_cap_zero(mask); | 521 | dma_cap_zero(mask); |
| 526 | dma_cap_set(DMA_SLAVE, mask); | 522 | dma_cap_set(DMA_SLAVE, mask); |
| 527 | 523 | ||
| 528 | as->dma.chan_tx = dma_request_slave_channel_reason(dev, "tx"); | 524 | master->dma_tx = dma_request_slave_channel_reason(dev, "tx"); |
| 529 | if (IS_ERR(as->dma.chan_tx)) { | 525 | if (IS_ERR(master->dma_tx)) { |
| 530 | err = PTR_ERR(as->dma.chan_tx); | 526 | err = PTR_ERR(master->dma_tx); |
| 531 | if (err == -EPROBE_DEFER) { | 527 | if (err == -EPROBE_DEFER) { |
| 532 | dev_warn(dev, "no DMA channel available at the moment\n"); | 528 | dev_warn(dev, "no DMA channel available at the moment\n"); |
| 533 | return err; | 529 | goto error_clear; |
| 534 | } | 530 | } |
| 535 | dev_err(dev, | 531 | dev_err(dev, |
| 536 | "DMA TX channel not available, SPI unable to use DMA\n"); | 532 | "DMA TX channel not available, SPI unable to use DMA\n"); |
| 537 | err = -EBUSY; | 533 | err = -EBUSY; |
| 538 | goto error; | 534 | goto error_clear; |
| 539 | } | 535 | } |
| 540 | 536 | ||
| 541 | /* | 537 | /* |
| 542 | * No reason to check EPROBE_DEFER here since we have already requested | 538 | * No reason to check EPROBE_DEFER here since we have already requested |
| 543 | * tx channel. If it fails here, it's for another reason. | 539 | * tx channel. If it fails here, it's for another reason. |
| 544 | */ | 540 | */ |
| 545 | as->dma.chan_rx = dma_request_slave_channel(dev, "rx"); | 541 | master->dma_rx = dma_request_slave_channel(dev, "rx"); |
| 546 | 542 | ||
| 547 | if (!as->dma.chan_rx) { | 543 | if (!master->dma_rx) { |
| 548 | dev_err(dev, | 544 | dev_err(dev, |
| 549 | "DMA RX channel not available, SPI unable to use DMA\n"); | 545 | "DMA RX channel not available, SPI unable to use DMA\n"); |
| 550 | err = -EBUSY; | 546 | err = -EBUSY; |
| @@ -557,31 +553,38 @@ static int atmel_spi_configure_dma(struct atmel_spi *as) | |||
| 557 | 553 | ||
| 558 | dev_info(&as->pdev->dev, | 554 | dev_info(&as->pdev->dev, |
| 559 | "Using %s (tx) and %s (rx) for DMA transfers\n", | 555 | "Using %s (tx) and %s (rx) for DMA transfers\n", |
| 560 | dma_chan_name(as->dma.chan_tx), | 556 | dma_chan_name(master->dma_tx), |
| 561 | dma_chan_name(as->dma.chan_rx)); | 557 | dma_chan_name(master->dma_rx)); |
| 558 | |||
| 562 | return 0; | 559 | return 0; |
| 563 | error: | 560 | error: |
| 564 | if (as->dma.chan_rx) | 561 | if (master->dma_rx) |
| 565 | dma_release_channel(as->dma.chan_rx); | 562 | dma_release_channel(master->dma_rx); |
| 566 | if (!IS_ERR(as->dma.chan_tx)) | 563 | if (!IS_ERR(master->dma_tx)) |
| 567 | dma_release_channel(as->dma.chan_tx); | 564 | dma_release_channel(master->dma_tx); |
| 565 | error_clear: | ||
| 566 | master->dma_tx = master->dma_rx = NULL; | ||
| 568 | return err; | 567 | return err; |
| 569 | } | 568 | } |
| 570 | 569 | ||
| 571 | static void atmel_spi_stop_dma(struct atmel_spi *as) | 570 | static void atmel_spi_stop_dma(struct spi_master *master) |
| 572 | { | 571 | { |
| 573 | if (as->dma.chan_rx) | 572 | if (master->dma_rx) |
| 574 | dmaengine_terminate_all(as->dma.chan_rx); | 573 | dmaengine_terminate_all(master->dma_rx); |
| 575 | if (as->dma.chan_tx) | 574 | if (master->dma_tx) |
| 576 | dmaengine_terminate_all(as->dma.chan_tx); | 575 | dmaengine_terminate_all(master->dma_tx); |
| 577 | } | 576 | } |
| 578 | 577 | ||
| 579 | static void atmel_spi_release_dma(struct atmel_spi *as) | 578 | static void atmel_spi_release_dma(struct spi_master *master) |
| 580 | { | 579 | { |
| 581 | if (as->dma.chan_rx) | 580 | if (master->dma_rx) { |
| 582 | dma_release_channel(as->dma.chan_rx); | 581 | dma_release_channel(master->dma_rx); |
| 583 | if (as->dma.chan_tx) | 582 | master->dma_rx = NULL; |
| 584 | dma_release_channel(as->dma.chan_tx); | 583 | } |
| 584 | if (master->dma_tx) { | ||
| 585 | dma_release_channel(master->dma_tx); | ||
| 586 | master->dma_tx = NULL; | ||
| 587 | } | ||
| 585 | } | 588 | } |
| 586 | 589 | ||
| 587 | /* This function is called by the DMA driver from tasklet context */ | 590 | /* This function is called by the DMA driver from tasklet context */ |
| @@ -611,14 +614,10 @@ static void atmel_spi_next_xfer_single(struct spi_master *master, | |||
| 611 | cpu_relax(); | 614 | cpu_relax(); |
| 612 | } | 615 | } |
| 613 | 616 | ||
| 614 | if (xfer->tx_buf) { | 617 | if (xfer->bits_per_word > 8) |
| 615 | if (xfer->bits_per_word > 8) | 618 | spi_writel(as, TDR, *(u16 *)(xfer->tx_buf + xfer_pos)); |
| 616 | spi_writel(as, TDR, *(u16 *)(xfer->tx_buf + xfer_pos)); | 619 | else |
| 617 | else | 620 | spi_writel(as, TDR, *(u8 *)(xfer->tx_buf + xfer_pos)); |
| 618 | spi_writel(as, TDR, *(u8 *)(xfer->tx_buf + xfer_pos)); | ||
| 619 | } else { | ||
| 620 | spi_writel(as, TDR, 0); | ||
| 621 | } | ||
| 622 | 621 | ||
| 623 | dev_dbg(master->dev.parent, | 622 | dev_dbg(master->dev.parent, |
| 624 | " start pio xfer %p: len %u tx %p rx %p bitpw %d\n", | 623 | " start pio xfer %p: len %u tx %p rx %p bitpw %d\n", |
| @@ -665,17 +664,12 @@ static void atmel_spi_next_xfer_fifo(struct spi_master *master, | |||
| 665 | 664 | ||
| 666 | /* Fill TX FIFO */ | 665 | /* Fill TX FIFO */ |
| 667 | while (num_data >= 2) { | 666 | while (num_data >= 2) { |
| 668 | if (xfer->tx_buf) { | 667 | if (xfer->bits_per_word > 8) { |
| 669 | if (xfer->bits_per_word > 8) { | 668 | td0 = *words++; |
| 670 | td0 = *words++; | 669 | td1 = *words++; |
| 671 | td1 = *words++; | ||
| 672 | } else { | ||
| 673 | td0 = *bytes++; | ||
| 674 | td1 = *bytes++; | ||
| 675 | } | ||
| 676 | } else { | 670 | } else { |
| 677 | td0 = 0; | 671 | td0 = *bytes++; |
| 678 | td1 = 0; | 672 | td1 = *bytes++; |
| 679 | } | 673 | } |
| 680 | 674 | ||
| 681 | spi_writel(as, TDR, (td1 << 16) | td0); | 675 | spi_writel(as, TDR, (td1 << 16) | td0); |
| @@ -683,14 +677,10 @@ static void atmel_spi_next_xfer_fifo(struct spi_master *master, | |||
| 683 | } | 677 | } |
| 684 | 678 | ||
| 685 | if (num_data) { | 679 | if (num_data) { |
| 686 | if (xfer->tx_buf) { | 680 | if (xfer->bits_per_word > 8) |
| 687 | if (xfer->bits_per_word > 8) | 681 | td0 = *words++; |
| 688 | td0 = *words++; | 682 | else |
| 689 | else | 683 | td0 = *bytes++; |
| 690 | td0 = *bytes++; | ||
| 691 | } else { | ||
| 692 | td0 = 0; | ||
| 693 | } | ||
| 694 | 684 | ||
| 695 | spi_writew(as, TDR, td0); | 685 | spi_writew(as, TDR, td0); |
| 696 | num_data--; | 686 | num_data--; |
| @@ -730,13 +720,12 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master, | |||
| 730 | u32 *plen) | 720 | u32 *plen) |
| 731 | { | 721 | { |
| 732 | struct atmel_spi *as = spi_master_get_devdata(master); | 722 | struct atmel_spi *as = spi_master_get_devdata(master); |
| 733 | struct dma_chan *rxchan = as->dma.chan_rx; | 723 | struct dma_chan *rxchan = master->dma_rx; |
| 734 | struct dma_chan *txchan = as->dma.chan_tx; | 724 | struct dma_chan *txchan = master->dma_tx; |
| 735 | struct dma_async_tx_descriptor *rxdesc; | 725 | struct dma_async_tx_descriptor *rxdesc; |
| 736 | struct dma_async_tx_descriptor *txdesc; | 726 | struct dma_async_tx_descriptor *txdesc; |
| 737 | struct dma_slave_config slave_config; | 727 | struct dma_slave_config slave_config; |
| 738 | dma_cookie_t cookie; | 728 | dma_cookie_t cookie; |
| 739 | u32 len = *plen; | ||
| 740 | 729 | ||
| 741 | dev_vdbg(master->dev.parent, "atmel_spi_next_xfer_dma_submit\n"); | 730 | dev_vdbg(master->dev.parent, "atmel_spi_next_xfer_dma_submit\n"); |
| 742 | 731 | ||
| @@ -747,44 +736,22 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master, | |||
| 747 | /* release lock for DMA operations */ | 736 | /* release lock for DMA operations */ |
| 748 | atmel_spi_unlock(as); | 737 | atmel_spi_unlock(as); |
| 749 | 738 | ||
| 750 | /* prepare the RX dma transfer */ | 739 | *plen = xfer->len; |
| 751 | sg_init_table(&as->dma.sgrx, 1); | ||
| 752 | if (xfer->rx_buf) { | ||
| 753 | as->dma.sgrx.dma_address = xfer->rx_dma + xfer->len - *plen; | ||
| 754 | } else { | ||
| 755 | as->dma.sgrx.dma_address = as->buffer_dma; | ||
| 756 | if (len > BUFFER_SIZE) | ||
| 757 | len = BUFFER_SIZE; | ||
| 758 | } | ||
| 759 | |||
| 760 | /* prepare the TX dma transfer */ | ||
| 761 | sg_init_table(&as->dma.sgtx, 1); | ||
| 762 | if (xfer->tx_buf) { | ||
| 763 | as->dma.sgtx.dma_address = xfer->tx_dma + xfer->len - *plen; | ||
| 764 | } else { | ||
| 765 | as->dma.sgtx.dma_address = as->buffer_dma; | ||
| 766 | if (len > BUFFER_SIZE) | ||
| 767 | len = BUFFER_SIZE; | ||
| 768 | memset(as->buffer, 0, len); | ||
| 769 | } | ||
| 770 | |||
| 771 | sg_dma_len(&as->dma.sgtx) = len; | ||
| 772 | sg_dma_len(&as->dma.sgrx) = len; | ||
| 773 | |||
| 774 | *plen = len; | ||
| 775 | 740 | ||
| 776 | if (atmel_spi_dma_slave_config(as, &slave_config, | 741 | if (atmel_spi_dma_slave_config(as, &slave_config, |
| 777 | xfer->bits_per_word)) | 742 | xfer->bits_per_word)) |
| 778 | goto err_exit; | 743 | goto err_exit; |
| 779 | 744 | ||
| 780 | /* Send both scatterlists */ | 745 | /* Send both scatterlists */ |
| 781 | rxdesc = dmaengine_prep_slave_sg(rxchan, &as->dma.sgrx, 1, | 746 | rxdesc = dmaengine_prep_slave_sg(rxchan, |
| 747 | xfer->rx_sg.sgl, xfer->rx_sg.nents, | ||
| 782 | DMA_FROM_DEVICE, | 748 | DMA_FROM_DEVICE, |
| 783 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 749 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
| 784 | if (!rxdesc) | 750 | if (!rxdesc) |
| 785 | goto err_dma; | 751 | goto err_dma; |
| 786 | 752 | ||
| 787 | txdesc = dmaengine_prep_slave_sg(txchan, &as->dma.sgtx, 1, | 753 | txdesc = dmaengine_prep_slave_sg(txchan, |
| 754 | xfer->tx_sg.sgl, xfer->tx_sg.nents, | ||
| 788 | DMA_TO_DEVICE, | 755 | DMA_TO_DEVICE, |
| 789 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 756 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
| 790 | if (!txdesc) | 757 | if (!txdesc) |
| @@ -818,7 +785,7 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master, | |||
| 818 | 785 | ||
| 819 | err_dma: | 786 | err_dma: |
| 820 | spi_writel(as, IDR, SPI_BIT(OVRES)); | 787 | spi_writel(as, IDR, SPI_BIT(OVRES)); |
| 821 | atmel_spi_stop_dma(as); | 788 | atmel_spi_stop_dma(master); |
| 822 | err_exit: | 789 | err_exit: |
| 823 | atmel_spi_lock(as); | 790 | atmel_spi_lock(as); |
| 824 | return -ENOMEM; | 791 | return -ENOMEM; |
| @@ -830,30 +797,10 @@ static void atmel_spi_next_xfer_data(struct spi_master *master, | |||
| 830 | dma_addr_t *rx_dma, | 797 | dma_addr_t *rx_dma, |
| 831 | u32 *plen) | 798 | u32 *plen) |
| 832 | { | 799 | { |
| 833 | struct atmel_spi *as = spi_master_get_devdata(master); | 800 | *rx_dma = xfer->rx_dma + xfer->len - *plen; |
| 834 | u32 len = *plen; | 801 | *tx_dma = xfer->tx_dma + xfer->len - *plen; |
| 835 | 802 | if (*plen > master->max_dma_len) | |
| 836 | /* use scratch buffer only when rx or tx data is unspecified */ | 803 | *plen = master->max_dma_len; |
| 837 | if (xfer->rx_buf) | ||
| 838 | *rx_dma = xfer->rx_dma + xfer->len - *plen; | ||
| 839 | else { | ||
| 840 | *rx_dma = as->buffer_dma; | ||
| 841 | if (len > BUFFER_SIZE) | ||
| 842 | len = BUFFER_SIZE; | ||
| 843 | } | ||
| 844 | |||
| 845 | if (xfer->tx_buf) | ||
| 846 | *tx_dma = xfer->tx_dma + xfer->len - *plen; | ||
| 847 | else { | ||
| 848 | *tx_dma = as->buffer_dma; | ||
| 849 | if (len > BUFFER_SIZE) | ||
| 850 | len = BUFFER_SIZE; | ||
| 851 | memset(as->buffer, 0, len); | ||
| 852 | dma_sync_single_for_device(&as->pdev->dev, | ||
| 853 | as->buffer_dma, len, DMA_TO_DEVICE); | ||
| 854 | } | ||
| 855 | |||
| 856 | *plen = len; | ||
| 857 | } | 804 | } |
| 858 | 805 | ||
| 859 | static int atmel_spi_set_xfer_speed(struct atmel_spi *as, | 806 | static int atmel_spi_set_xfer_speed(struct atmel_spi *as, |
| @@ -864,7 +811,7 @@ static int atmel_spi_set_xfer_speed(struct atmel_spi *as, | |||
| 864 | unsigned long bus_hz; | 811 | unsigned long bus_hz; |
| 865 | 812 | ||
| 866 | /* v1 chips start out at half the peripheral bus speed. */ | 813 | /* v1 chips start out at half the peripheral bus speed. */ |
| 867 | bus_hz = clk_get_rate(as->clk); | 814 | bus_hz = as->spi_clk; |
| 868 | if (!atmel_spi_is_v2(as)) | 815 | if (!atmel_spi_is_v2(as)) |
| 869 | bus_hz /= 2; | 816 | bus_hz /= 2; |
| 870 | 817 | ||
| @@ -1025,16 +972,12 @@ atmel_spi_pump_single_data(struct atmel_spi *as, struct spi_transfer *xfer) | |||
| 1025 | u16 *rxp16; | 972 | u16 *rxp16; |
| 1026 | unsigned long xfer_pos = xfer->len - as->current_remaining_bytes; | 973 | unsigned long xfer_pos = xfer->len - as->current_remaining_bytes; |
| 1027 | 974 | ||
| 1028 | if (xfer->rx_buf) { | 975 | if (xfer->bits_per_word > 8) { |
| 1029 | if (xfer->bits_per_word > 8) { | 976 | rxp16 = (u16 *)(((u8 *)xfer->rx_buf) + xfer_pos); |
| 1030 | rxp16 = (u16 *)(((u8 *)xfer->rx_buf) + xfer_pos); | 977 | *rxp16 = spi_readl(as, RDR); |
| 1031 | *rxp16 = spi_readl(as, RDR); | ||
| 1032 | } else { | ||
| 1033 | rxp = ((u8 *)xfer->rx_buf) + xfer_pos; | ||
| 1034 | *rxp = spi_readl(as, RDR); | ||
| 1035 | } | ||
| 1036 | } else { | 978 | } else { |
| 1037 | spi_readl(as, RDR); | 979 | rxp = ((u8 *)xfer->rx_buf) + xfer_pos; |
| 980 | *rxp = spi_readl(as, RDR); | ||
| 1038 | } | 981 | } |
| 1039 | if (xfer->bits_per_word > 8) { | 982 | if (xfer->bits_per_word > 8) { |
| 1040 | if (as->current_remaining_bytes > 2) | 983 | if (as->current_remaining_bytes > 2) |
| @@ -1073,12 +1016,10 @@ atmel_spi_pump_fifo_data(struct atmel_spi *as, struct spi_transfer *xfer) | |||
| 1073 | /* Read data */ | 1016 | /* Read data */ |
| 1074 | while (num_data) { | 1017 | while (num_data) { |
| 1075 | rd = spi_readl(as, RDR); | 1018 | rd = spi_readl(as, RDR); |
| 1076 | if (xfer->rx_buf) { | 1019 | if (xfer->bits_per_word > 8) |
| 1077 | if (xfer->bits_per_word > 8) | 1020 | *words++ = rd; |
| 1078 | *words++ = rd; | 1021 | else |
| 1079 | else | 1022 | *bytes++ = rd; |
| 1080 | *bytes++ = rd; | ||
| 1081 | } | ||
| 1082 | num_data--; | 1023 | num_data--; |
| 1083 | } | 1024 | } |
| 1084 | } | 1025 | } |
| @@ -1204,7 +1145,6 @@ static int atmel_spi_setup(struct spi_device *spi) | |||
| 1204 | u32 csr; | 1145 | u32 csr; |
| 1205 | unsigned int bits = spi->bits_per_word; | 1146 | unsigned int bits = spi->bits_per_word; |
| 1206 | unsigned int npcs_pin; | 1147 | unsigned int npcs_pin; |
| 1207 | int ret; | ||
| 1208 | 1148 | ||
| 1209 | as = spi_master_get_devdata(spi->master); | 1149 | as = spi_master_get_devdata(spi->master); |
| 1210 | 1150 | ||
| @@ -1247,16 +1187,9 @@ static int atmel_spi_setup(struct spi_device *spi) | |||
| 1247 | if (!asd) | 1187 | if (!asd) |
| 1248 | return -ENOMEM; | 1188 | return -ENOMEM; |
| 1249 | 1189 | ||
| 1250 | if (as->use_cs_gpios) { | 1190 | if (as->use_cs_gpios) |
| 1251 | ret = gpio_request(npcs_pin, dev_name(&spi->dev)); | ||
| 1252 | if (ret) { | ||
| 1253 | kfree(asd); | ||
| 1254 | return ret; | ||
| 1255 | } | ||
| 1256 | |||
| 1257 | gpio_direction_output(npcs_pin, | 1191 | gpio_direction_output(npcs_pin, |
| 1258 | !(spi->mode & SPI_CS_HIGH)); | 1192 | !(spi->mode & SPI_CS_HIGH)); |
| 1259 | } | ||
| 1260 | 1193 | ||
| 1261 | asd->npcs_pin = npcs_pin; | 1194 | asd->npcs_pin = npcs_pin; |
| 1262 | spi->controller_state = asd; | 1195 | spi->controller_state = asd; |
| @@ -1307,7 +1240,7 @@ static int atmel_spi_one_transfer(struct spi_master *master, | |||
| 1307 | * better fault reporting. | 1240 | * better fault reporting. |
| 1308 | */ | 1241 | */ |
| 1309 | if ((!msg->is_dma_mapped) | 1242 | if ((!msg->is_dma_mapped) |
| 1310 | && (atmel_spi_use_dma(as, xfer) || as->use_pdc)) { | 1243 | && as->use_pdc) { |
| 1311 | if (atmel_spi_dma_map_xfer(as, xfer) < 0) | 1244 | if (atmel_spi_dma_map_xfer(as, xfer) < 0) |
| 1312 | return -ENOMEM; | 1245 | return -ENOMEM; |
| 1313 | } | 1246 | } |
| @@ -1380,11 +1313,11 @@ static int atmel_spi_one_transfer(struct spi_master *master, | |||
| 1380 | spi_readl(as, SR); | 1313 | spi_readl(as, SR); |
| 1381 | 1314 | ||
| 1382 | } else if (atmel_spi_use_dma(as, xfer)) { | 1315 | } else if (atmel_spi_use_dma(as, xfer)) { |
| 1383 | atmel_spi_stop_dma(as); | 1316 | atmel_spi_stop_dma(master); |
| 1384 | } | 1317 | } |
| 1385 | 1318 | ||
| 1386 | if (!msg->is_dma_mapped | 1319 | if (!msg->is_dma_mapped |
| 1387 | && (atmel_spi_use_dma(as, xfer) || as->use_pdc)) | 1320 | && as->use_pdc) |
| 1388 | atmel_spi_dma_unmap_xfer(master, xfer); | 1321 | atmel_spi_dma_unmap_xfer(master, xfer); |
| 1389 | 1322 | ||
| 1390 | return 0; | 1323 | return 0; |
| @@ -1395,7 +1328,7 @@ static int atmel_spi_one_transfer(struct spi_master *master, | |||
| 1395 | } | 1328 | } |
| 1396 | 1329 | ||
| 1397 | if (!msg->is_dma_mapped | 1330 | if (!msg->is_dma_mapped |
| 1398 | && (atmel_spi_use_dma(as, xfer) || as->use_pdc)) | 1331 | && as->use_pdc) |
| 1399 | atmel_spi_dma_unmap_xfer(master, xfer); | 1332 | atmel_spi_dma_unmap_xfer(master, xfer); |
| 1400 | 1333 | ||
| 1401 | if (xfer->delay_usecs) | 1334 | if (xfer->delay_usecs) |
| @@ -1471,13 +1404,11 @@ msg_done: | |||
| 1471 | static void atmel_spi_cleanup(struct spi_device *spi) | 1404 | static void atmel_spi_cleanup(struct spi_device *spi) |
| 1472 | { | 1405 | { |
| 1473 | struct atmel_spi_device *asd = spi->controller_state; | 1406 | struct atmel_spi_device *asd = spi->controller_state; |
| 1474 | unsigned gpio = (unsigned long) spi->controller_data; | ||
| 1475 | 1407 | ||
| 1476 | if (!asd) | 1408 | if (!asd) |
| 1477 | return; | 1409 | return; |
| 1478 | 1410 | ||
| 1479 | spi->controller_state = NULL; | 1411 | spi->controller_state = NULL; |
| 1480 | gpio_free(gpio); | ||
| 1481 | kfree(asd); | 1412 | kfree(asd); |
| 1482 | } | 1413 | } |
| 1483 | 1414 | ||
| @@ -1499,6 +1430,39 @@ static void atmel_get_caps(struct atmel_spi *as) | |||
| 1499 | } | 1430 | } |
| 1500 | 1431 | ||
| 1501 | /*-------------------------------------------------------------------------*/ | 1432 | /*-------------------------------------------------------------------------*/ |
| 1433 | static int atmel_spi_gpio_cs(struct platform_device *pdev) | ||
| 1434 | { | ||
| 1435 | struct spi_master *master = platform_get_drvdata(pdev); | ||
| 1436 | struct atmel_spi *as = spi_master_get_devdata(master); | ||
| 1437 | struct device_node *np = master->dev.of_node; | ||
| 1438 | int i; | ||
| 1439 | int ret = 0; | ||
| 1440 | int nb = 0; | ||
| 1441 | |||
| 1442 | if (!as->use_cs_gpios) | ||
| 1443 | return 0; | ||
| 1444 | |||
| 1445 | if (!np) | ||
| 1446 | return 0; | ||
| 1447 | |||
| 1448 | nb = of_gpio_named_count(np, "cs-gpios"); | ||
| 1449 | for (i = 0; i < nb; i++) { | ||
| 1450 | int cs_gpio = of_get_named_gpio(pdev->dev.of_node, | ||
| 1451 | "cs-gpios", i); | ||
| 1452 | |||
| 1453 | if (cs_gpio == -EPROBE_DEFER) | ||
| 1454 | return cs_gpio; | ||
| 1455 | |||
| 1456 | if (gpio_is_valid(cs_gpio)) { | ||
| 1457 | ret = devm_gpio_request(&pdev->dev, cs_gpio, | ||
| 1458 | dev_name(&pdev->dev)); | ||
| 1459 | if (ret) | ||
| 1460 | return ret; | ||
| 1461 | } | ||
| 1462 | } | ||
| 1463 | |||
| 1464 | return 0; | ||
| 1465 | } | ||
| 1502 | 1466 | ||
| 1503 | static int atmel_spi_probe(struct platform_device *pdev) | 1467 | static int atmel_spi_probe(struct platform_device *pdev) |
| 1504 | { | 1468 | { |
| @@ -1537,29 +1501,23 @@ static int atmel_spi_probe(struct platform_device *pdev) | |||
| 1537 | master->bus_num = pdev->id; | 1501 | master->bus_num = pdev->id; |
| 1538 | master->num_chipselect = master->dev.of_node ? 0 : 4; | 1502 | master->num_chipselect = master->dev.of_node ? 0 : 4; |
| 1539 | master->setup = atmel_spi_setup; | 1503 | master->setup = atmel_spi_setup; |
| 1504 | master->flags = (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX); | ||
| 1540 | master->transfer_one_message = atmel_spi_transfer_one_message; | 1505 | master->transfer_one_message = atmel_spi_transfer_one_message; |
| 1541 | master->cleanup = atmel_spi_cleanup; | 1506 | master->cleanup = atmel_spi_cleanup; |
| 1542 | master->auto_runtime_pm = true; | 1507 | master->auto_runtime_pm = true; |
| 1508 | master->max_dma_len = SPI_MAX_DMA_XFER; | ||
| 1509 | master->can_dma = atmel_spi_can_dma; | ||
| 1543 | platform_set_drvdata(pdev, master); | 1510 | platform_set_drvdata(pdev, master); |
| 1544 | 1511 | ||
| 1545 | as = spi_master_get_devdata(master); | 1512 | as = spi_master_get_devdata(master); |
| 1546 | 1513 | ||
| 1547 | /* | ||
| 1548 | * Scratch buffer is used for throwaway rx and tx data. | ||
| 1549 | * It's coherent to minimize dcache pollution. | ||
| 1550 | */ | ||
| 1551 | as->buffer = dma_alloc_coherent(&pdev->dev, BUFFER_SIZE, | ||
| 1552 | &as->buffer_dma, GFP_KERNEL); | ||
| 1553 | if (!as->buffer) | ||
| 1554 | goto out_free; | ||
| 1555 | |||
| 1556 | spin_lock_init(&as->lock); | 1514 | spin_lock_init(&as->lock); |
| 1557 | 1515 | ||
| 1558 | as->pdev = pdev; | 1516 | as->pdev = pdev; |
| 1559 | as->regs = devm_ioremap_resource(&pdev->dev, regs); | 1517 | as->regs = devm_ioremap_resource(&pdev->dev, regs); |
| 1560 | if (IS_ERR(as->regs)) { | 1518 | if (IS_ERR(as->regs)) { |
| 1561 | ret = PTR_ERR(as->regs); | 1519 | ret = PTR_ERR(as->regs); |
| 1562 | goto out_free_buffer; | 1520 | goto out_unmap_regs; |
| 1563 | } | 1521 | } |
| 1564 | as->phybase = regs->start; | 1522 | as->phybase = regs->start; |
| 1565 | as->irq = irq; | 1523 | as->irq = irq; |
| @@ -1577,14 +1535,19 @@ static int atmel_spi_probe(struct platform_device *pdev) | |||
| 1577 | master->num_chipselect = 4; | 1535 | master->num_chipselect = 4; |
| 1578 | } | 1536 | } |
| 1579 | 1537 | ||
| 1538 | ret = atmel_spi_gpio_cs(pdev); | ||
| 1539 | if (ret) | ||
| 1540 | goto out_unmap_regs; | ||
| 1541 | |||
| 1580 | as->use_dma = false; | 1542 | as->use_dma = false; |
| 1581 | as->use_pdc = false; | 1543 | as->use_pdc = false; |
| 1582 | if (as->caps.has_dma_support) { | 1544 | if (as->caps.has_dma_support) { |
| 1583 | ret = atmel_spi_configure_dma(as); | 1545 | ret = atmel_spi_configure_dma(master, as); |
| 1584 | if (ret == 0) | 1546 | if (ret == 0) { |
| 1585 | as->use_dma = true; | 1547 | as->use_dma = true; |
| 1586 | else if (ret == -EPROBE_DEFER) | 1548 | } else if (ret == -EPROBE_DEFER) { |
| 1587 | return ret; | 1549 | return ret; |
| 1550 | } | ||
| 1588 | } else { | 1551 | } else { |
| 1589 | as->use_pdc = true; | 1552 | as->use_pdc = true; |
| 1590 | } | 1553 | } |
| @@ -1606,6 +1569,9 @@ static int atmel_spi_probe(struct platform_device *pdev) | |||
| 1606 | ret = clk_prepare_enable(clk); | 1569 | ret = clk_prepare_enable(clk); |
| 1607 | if (ret) | 1570 | if (ret) |
| 1608 | goto out_free_irq; | 1571 | goto out_free_irq; |
| 1572 | |||
| 1573 | as->spi_clk = clk_get_rate(clk); | ||
| 1574 | |||
| 1609 | spi_writel(as, CR, SPI_BIT(SWRST)); | 1575 | spi_writel(as, CR, SPI_BIT(SWRST)); |
| 1610 | spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ | 1576 | spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ |
| 1611 | if (as->caps.has_wdrbt) { | 1577 | if (as->caps.has_wdrbt) { |
| @@ -1626,10 +1592,6 @@ static int atmel_spi_probe(struct platform_device *pdev) | |||
| 1626 | spi_writel(as, CR, SPI_BIT(FIFOEN)); | 1592 | spi_writel(as, CR, SPI_BIT(FIFOEN)); |
| 1627 | } | 1593 | } |
| 1628 | 1594 | ||
| 1629 | /* go! */ | ||
| 1630 | dev_info(&pdev->dev, "Atmel SPI Controller at 0x%08lx (irq %d)\n", | ||
| 1631 | (unsigned long)regs->start, irq); | ||
| 1632 | |||
| 1633 | pm_runtime_set_autosuspend_delay(&pdev->dev, AUTOSUSPEND_TIMEOUT); | 1595 | pm_runtime_set_autosuspend_delay(&pdev->dev, AUTOSUSPEND_TIMEOUT); |
| 1634 | pm_runtime_use_autosuspend(&pdev->dev); | 1596 | pm_runtime_use_autosuspend(&pdev->dev); |
| 1635 | pm_runtime_set_active(&pdev->dev); | 1597 | pm_runtime_set_active(&pdev->dev); |
| @@ -1639,6 +1601,10 @@ static int atmel_spi_probe(struct platform_device *pdev) | |||
| 1639 | if (ret) | 1601 | if (ret) |
| 1640 | goto out_free_dma; | 1602 | goto out_free_dma; |
| 1641 | 1603 | ||
| 1604 | /* go! */ | ||
| 1605 | dev_info(&pdev->dev, "Atmel SPI Controller at 0x%08lx (irq %d)\n", | ||
| 1606 | (unsigned long)regs->start, irq); | ||
| 1607 | |||
| 1642 | return 0; | 1608 | return 0; |
| 1643 | 1609 | ||
| 1644 | out_free_dma: | 1610 | out_free_dma: |
| @@ -1646,16 +1612,13 @@ out_free_dma: | |||
| 1646 | pm_runtime_set_suspended(&pdev->dev); | 1612 | pm_runtime_set_suspended(&pdev->dev); |
| 1647 | 1613 | ||
| 1648 | if (as->use_dma) | 1614 | if (as->use_dma) |
| 1649 | atmel_spi_release_dma(as); | 1615 | atmel_spi_release_dma(master); |
| 1650 | 1616 | ||
| 1651 | spi_writel(as, CR, SPI_BIT(SWRST)); | 1617 | spi_writel(as, CR, SPI_BIT(SWRST)); |
| 1652 | spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ | 1618 | spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ |
| 1653 | clk_disable_unprepare(clk); | 1619 | clk_disable_unprepare(clk); |
| 1654 | out_free_irq: | 1620 | out_free_irq: |
| 1655 | out_unmap_regs: | 1621 | out_unmap_regs: |
| 1656 | out_free_buffer: | ||
| 1657 | dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer, | ||
| 1658 | as->buffer_dma); | ||
| 1659 | out_free: | 1622 | out_free: |
| 1660 | spi_master_put(master); | 1623 | spi_master_put(master); |
| 1661 | return ret; | 1624 | return ret; |
| @@ -1671,8 +1634,8 @@ static int atmel_spi_remove(struct platform_device *pdev) | |||
| 1671 | /* reset the hardware and block queue progress */ | 1634 | /* reset the hardware and block queue progress */ |
| 1672 | spin_lock_irq(&as->lock); | 1635 | spin_lock_irq(&as->lock); |
| 1673 | if (as->use_dma) { | 1636 | if (as->use_dma) { |
| 1674 | atmel_spi_stop_dma(as); | 1637 | atmel_spi_stop_dma(master); |
| 1675 | atmel_spi_release_dma(as); | 1638 | atmel_spi_release_dma(master); |
| 1676 | } | 1639 | } |
| 1677 | 1640 | ||
| 1678 | spi_writel(as, CR, SPI_BIT(SWRST)); | 1641 | spi_writel(as, CR, SPI_BIT(SWRST)); |
| @@ -1680,9 +1643,6 @@ static int atmel_spi_remove(struct platform_device *pdev) | |||
| 1680 | spi_readl(as, SR); | 1643 | spi_readl(as, SR); |
| 1681 | spin_unlock_irq(&as->lock); | 1644 | spin_unlock_irq(&as->lock); |
| 1682 | 1645 | ||
| 1683 | dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer, | ||
| 1684 | as->buffer_dma); | ||
| 1685 | |||
| 1686 | clk_disable_unprepare(as->clk); | 1646 | clk_disable_unprepare(as->clk); |
| 1687 | 1647 | ||
| 1688 | pm_runtime_put_noidle(&pdev->dev); | 1648 | pm_runtime_put_noidle(&pdev->dev); |
diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c index 2b1456e5e221..319225d7e761 100644 --- a/drivers/spi/spi-axi-spi-engine.c +++ b/drivers/spi/spi-axi-spi-engine.c | |||
| @@ -574,6 +574,7 @@ static const struct of_device_id spi_engine_match_table[] = { | |||
| 574 | { .compatible = "adi,axi-spi-engine-1.00.a" }, | 574 | { .compatible = "adi,axi-spi-engine-1.00.a" }, |
| 575 | { }, | 575 | { }, |
| 576 | }; | 576 | }; |
| 577 | MODULE_DEVICE_TABLE(of, spi_engine_match_table); | ||
| 577 | 578 | ||
| 578 | static struct platform_driver spi_engine_driver = { | 579 | static struct platform_driver spi_engine_driver = { |
| 579 | .probe = spi_engine_probe, | 580 | .probe = spi_engine_probe, |
diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 27960e46135d..b715a26a9148 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c | |||
| @@ -502,6 +502,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) | |||
| 502 | master->handle_err = dw_spi_handle_err; | 502 | master->handle_err = dw_spi_handle_err; |
| 503 | master->max_speed_hz = dws->max_freq; | 503 | master->max_speed_hz = dws->max_freq; |
| 504 | master->dev.of_node = dev->of_node; | 504 | master->dev.of_node = dev->of_node; |
| 505 | master->flags = SPI_MASTER_GPIO_SS; | ||
| 505 | 506 | ||
| 506 | /* Basic HW init */ | 507 | /* Basic HW init */ |
| 507 | spi_hw_init(dev, dws); | 508 | spi_hw_init(dev, dws); |
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index a67b0ff6a362..14c8e7ce1913 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c | |||
| @@ -15,6 +15,8 @@ | |||
| 15 | 15 | ||
| 16 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
| 17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
| 18 | #include <linux/dmaengine.h> | ||
| 19 | #include <linux/dma-mapping.h> | ||
| 18 | #include <linux/err.h> | 20 | #include <linux/err.h> |
| 19 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
| 20 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
| @@ -40,6 +42,7 @@ | |||
| 40 | #define TRAN_STATE_WORD_ODD_NUM 0x04 | 42 | #define TRAN_STATE_WORD_ODD_NUM 0x04 |
| 41 | 43 | ||
| 42 | #define DSPI_FIFO_SIZE 4 | 44 | #define DSPI_FIFO_SIZE 4 |
| 45 | #define DSPI_DMA_BUFSIZE (DSPI_FIFO_SIZE * 1024) | ||
| 43 | 46 | ||
| 44 | #define SPI_MCR 0x00 | 47 | #define SPI_MCR 0x00 |
| 45 | #define SPI_MCR_MASTER (1 << 31) | 48 | #define SPI_MCR_MASTER (1 << 31) |
| @@ -72,6 +75,11 @@ | |||
| 72 | #define SPI_SR_TCFQF 0x80000000 | 75 | #define SPI_SR_TCFQF 0x80000000 |
| 73 | #define SPI_SR_CLEAR 0xdaad0000 | 76 | #define SPI_SR_CLEAR 0xdaad0000 |
| 74 | 77 | ||
| 78 | #define SPI_RSER_TFFFE BIT(25) | ||
| 79 | #define SPI_RSER_TFFFD BIT(24) | ||
| 80 | #define SPI_RSER_RFDFE BIT(17) | ||
| 81 | #define SPI_RSER_RFDFD BIT(16) | ||
| 82 | |||
| 75 | #define SPI_RSER 0x30 | 83 | #define SPI_RSER 0x30 |
| 76 | #define SPI_RSER_EOQFE 0x10000000 | 84 | #define SPI_RSER_EOQFE 0x10000000 |
| 77 | #define SPI_RSER_TCFQE 0x80000000 | 85 | #define SPI_RSER_TCFQE 0x80000000 |
| @@ -109,6 +117,8 @@ | |||
| 109 | 117 | ||
| 110 | #define SPI_TCR_TCNT_MAX 0x10000 | 118 | #define SPI_TCR_TCNT_MAX 0x10000 |
| 111 | 119 | ||
| 120 | #define DMA_COMPLETION_TIMEOUT msecs_to_jiffies(3000) | ||
| 121 | |||
| 112 | struct chip_data { | 122 | struct chip_data { |
| 113 | u32 mcr_val; | 123 | u32 mcr_val; |
| 114 | u32 ctar_val; | 124 | u32 ctar_val; |
| @@ -118,6 +128,7 @@ struct chip_data { | |||
| 118 | enum dspi_trans_mode { | 128 | enum dspi_trans_mode { |
| 119 | DSPI_EOQ_MODE = 0, | 129 | DSPI_EOQ_MODE = 0, |
| 120 | DSPI_TCFQ_MODE, | 130 | DSPI_TCFQ_MODE, |
| 131 | DSPI_DMA_MODE, | ||
| 121 | }; | 132 | }; |
| 122 | 133 | ||
| 123 | struct fsl_dspi_devtype_data { | 134 | struct fsl_dspi_devtype_data { |
| @@ -126,7 +137,7 @@ struct fsl_dspi_devtype_data { | |||
| 126 | }; | 137 | }; |
| 127 | 138 | ||
| 128 | static const struct fsl_dspi_devtype_data vf610_data = { | 139 | static const struct fsl_dspi_devtype_data vf610_data = { |
| 129 | .trans_mode = DSPI_EOQ_MODE, | 140 | .trans_mode = DSPI_DMA_MODE, |
| 130 | .max_clock_factor = 2, | 141 | .max_clock_factor = 2, |
| 131 | }; | 142 | }; |
| 132 | 143 | ||
| @@ -140,6 +151,23 @@ static const struct fsl_dspi_devtype_data ls2085a_data = { | |||
| 140 | .max_clock_factor = 8, | 151 | .max_clock_factor = 8, |
| 141 | }; | 152 | }; |
| 142 | 153 | ||
| 154 | struct fsl_dspi_dma { | ||
| 155 | /* Length of transfer in words of DSPI_FIFO_SIZE */ | ||
| 156 | u32 curr_xfer_len; | ||
| 157 | |||
| 158 | u32 *tx_dma_buf; | ||
| 159 | struct dma_chan *chan_tx; | ||
| 160 | dma_addr_t tx_dma_phys; | ||
| 161 | struct completion cmd_tx_complete; | ||
| 162 | struct dma_async_tx_descriptor *tx_desc; | ||
| 163 | |||
| 164 | u32 *rx_dma_buf; | ||
| 165 | struct dma_chan *chan_rx; | ||
| 166 | dma_addr_t rx_dma_phys; | ||
| 167 | struct completion cmd_rx_complete; | ||
| 168 | struct dma_async_tx_descriptor *rx_desc; | ||
| 169 | }; | ||
| 170 | |||
| 143 | struct fsl_dspi { | 171 | struct fsl_dspi { |
| 144 | struct spi_master *master; | 172 | struct spi_master *master; |
| 145 | struct platform_device *pdev; | 173 | struct platform_device *pdev; |
| @@ -166,8 +194,11 @@ struct fsl_dspi { | |||
| 166 | u32 waitflags; | 194 | u32 waitflags; |
| 167 | 195 | ||
| 168 | u32 spi_tcnt; | 196 | u32 spi_tcnt; |
| 197 | struct fsl_dspi_dma *dma; | ||
| 169 | }; | 198 | }; |
| 170 | 199 | ||
| 200 | static u32 dspi_data_to_pushr(struct fsl_dspi *dspi, int tx_word); | ||
| 201 | |||
| 171 | static inline int is_double_byte_mode(struct fsl_dspi *dspi) | 202 | static inline int is_double_byte_mode(struct fsl_dspi *dspi) |
| 172 | { | 203 | { |
| 173 | unsigned int val; | 204 | unsigned int val; |
| @@ -177,6 +208,255 @@ static inline int is_double_byte_mode(struct fsl_dspi *dspi) | |||
| 177 | return ((val & SPI_FRAME_BITS_MASK) == SPI_FRAME_BITS(8)) ? 0 : 1; | 208 | return ((val & SPI_FRAME_BITS_MASK) == SPI_FRAME_BITS(8)) ? 0 : 1; |
| 178 | } | 209 | } |
| 179 | 210 | ||
| 211 | static void dspi_tx_dma_callback(void *arg) | ||
| 212 | { | ||
| 213 | struct fsl_dspi *dspi = arg; | ||
| 214 | struct fsl_dspi_dma *dma = dspi->dma; | ||
| 215 | |||
| 216 | complete(&dma->cmd_tx_complete); | ||
| 217 | } | ||
| 218 | |||
| 219 | static void dspi_rx_dma_callback(void *arg) | ||
| 220 | { | ||
| 221 | struct fsl_dspi *dspi = arg; | ||
| 222 | struct fsl_dspi_dma *dma = dspi->dma; | ||
| 223 | int rx_word; | ||
| 224 | int i; | ||
| 225 | u16 d; | ||
| 226 | |||
| 227 | rx_word = is_double_byte_mode(dspi); | ||
| 228 | |||
| 229 | if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) { | ||
| 230 | for (i = 0; i < dma->curr_xfer_len; i++) { | ||
| 231 | d = dspi->dma->rx_dma_buf[i]; | ||
| 232 | rx_word ? (*(u16 *)dspi->rx = d) : | ||
| 233 | (*(u8 *)dspi->rx = d); | ||
| 234 | dspi->rx += rx_word + 1; | ||
| 235 | } | ||
| 236 | } | ||
| 237 | |||
| 238 | complete(&dma->cmd_rx_complete); | ||
| 239 | } | ||
| 240 | |||
| 241 | static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi) | ||
| 242 | { | ||
| 243 | struct fsl_dspi_dma *dma = dspi->dma; | ||
| 244 | struct device *dev = &dspi->pdev->dev; | ||
| 245 | int time_left; | ||
| 246 | int tx_word; | ||
| 247 | int i; | ||
| 248 | |||
| 249 | tx_word = is_double_byte_mode(dspi); | ||
| 250 | |||
| 251 | for (i = 0; i < dma->curr_xfer_len; i++) { | ||
| 252 | dspi->dma->tx_dma_buf[i] = dspi_data_to_pushr(dspi, tx_word); | ||
| 253 | if ((dspi->cs_change) && (!dspi->len)) | ||
| 254 | dspi->dma->tx_dma_buf[i] &= ~SPI_PUSHR_CONT; | ||
| 255 | } | ||
| 256 | |||
| 257 | dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx, | ||
| 258 | dma->tx_dma_phys, | ||
| 259 | dma->curr_xfer_len * | ||
| 260 | DMA_SLAVE_BUSWIDTH_4_BYTES, | ||
| 261 | DMA_MEM_TO_DEV, | ||
| 262 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
| 263 | if (!dma->tx_desc) { | ||
| 264 | dev_err(dev, "Not able to get desc for DMA xfer\n"); | ||
| 265 | return -EIO; | ||
| 266 | } | ||
| 267 | |||
| 268 | dma->tx_desc->callback = dspi_tx_dma_callback; | ||
| 269 | dma->tx_desc->callback_param = dspi; | ||
| 270 | if (dma_submit_error(dmaengine_submit(dma->tx_desc))) { | ||
| 271 | dev_err(dev, "DMA submit failed\n"); | ||
| 272 | return -EINVAL; | ||
| 273 | } | ||
| 274 | |||
| 275 | dma->rx_desc = dmaengine_prep_slave_single(dma->chan_rx, | ||
| 276 | dma->rx_dma_phys, | ||
| 277 | dma->curr_xfer_len * | ||
| 278 | DMA_SLAVE_BUSWIDTH_4_BYTES, | ||
| 279 | DMA_DEV_TO_MEM, | ||
| 280 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
| 281 | if (!dma->rx_desc) { | ||
| 282 | dev_err(dev, "Not able to get desc for DMA xfer\n"); | ||
| 283 | return -EIO; | ||
| 284 | } | ||
| 285 | |||
| 286 | dma->rx_desc->callback = dspi_rx_dma_callback; | ||
| 287 | dma->rx_desc->callback_param = dspi; | ||
| 288 | if (dma_submit_error(dmaengine_submit(dma->rx_desc))) { | ||
| 289 | dev_err(dev, "DMA submit failed\n"); | ||
| 290 | return -EINVAL; | ||
| 291 | } | ||
| 292 | |||
| 293 | reinit_completion(&dspi->dma->cmd_rx_complete); | ||
| 294 | reinit_completion(&dspi->dma->cmd_tx_complete); | ||
| 295 | |||
| 296 | dma_async_issue_pending(dma->chan_rx); | ||
| 297 | dma_async_issue_pending(dma->chan_tx); | ||
| 298 | |||
| 299 | time_left = wait_for_completion_timeout(&dspi->dma->cmd_tx_complete, | ||
| 300 | DMA_COMPLETION_TIMEOUT); | ||
| 301 | if (time_left == 0) { | ||
| 302 | dev_err(dev, "DMA tx timeout\n"); | ||
| 303 | dmaengine_terminate_all(dma->chan_tx); | ||
| 304 | dmaengine_terminate_all(dma->chan_rx); | ||
| 305 | return -ETIMEDOUT; | ||
| 306 | } | ||
| 307 | |||
| 308 | time_left = wait_for_completion_timeout(&dspi->dma->cmd_rx_complete, | ||
| 309 | DMA_COMPLETION_TIMEOUT); | ||
| 310 | if (time_left == 0) { | ||
| 311 | dev_err(dev, "DMA rx timeout\n"); | ||
| 312 | dmaengine_terminate_all(dma->chan_tx); | ||
| 313 | dmaengine_terminate_all(dma->chan_rx); | ||
| 314 | return -ETIMEDOUT; | ||
| 315 | } | ||
| 316 | |||
| 317 | return 0; | ||
| 318 | } | ||
| 319 | |||
| 320 | static int dspi_dma_xfer(struct fsl_dspi *dspi) | ||
| 321 | { | ||
| 322 | struct fsl_dspi_dma *dma = dspi->dma; | ||
| 323 | struct device *dev = &dspi->pdev->dev; | ||
| 324 | int curr_remaining_bytes; | ||
| 325 | int bytes_per_buffer; | ||
| 326 | int word = 1; | ||
| 327 | int ret = 0; | ||
| 328 | |||
| 329 | if (is_double_byte_mode(dspi)) | ||
| 330 | word = 2; | ||
| 331 | curr_remaining_bytes = dspi->len; | ||
| 332 | bytes_per_buffer = DSPI_DMA_BUFSIZE / DSPI_FIFO_SIZE; | ||
| 333 | while (curr_remaining_bytes) { | ||
| 334 | /* Check if current transfer fits the DMA buffer */ | ||
| 335 | dma->curr_xfer_len = curr_remaining_bytes / word; | ||
| 336 | if (dma->curr_xfer_len > bytes_per_buffer) | ||
| 337 | dma->curr_xfer_len = bytes_per_buffer; | ||
| 338 | |||
| 339 | ret = dspi_next_xfer_dma_submit(dspi); | ||
| 340 | if (ret) { | ||
| 341 | dev_err(dev, "DMA transfer failed\n"); | ||
| 342 | goto exit; | ||
| 343 | |||
| 344 | } else { | ||
| 345 | curr_remaining_bytes -= dma->curr_xfer_len * word; | ||
| 346 | if (curr_remaining_bytes < 0) | ||
| 347 | curr_remaining_bytes = 0; | ||
| 348 | } | ||
| 349 | } | ||
| 350 | |||
| 351 | exit: | ||
| 352 | return ret; | ||
| 353 | } | ||
| 354 | |||
| 355 | static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr) | ||
| 356 | { | ||
| 357 | struct fsl_dspi_dma *dma; | ||
| 358 | struct dma_slave_config cfg; | ||
| 359 | struct device *dev = &dspi->pdev->dev; | ||
| 360 | int ret; | ||
| 361 | |||
| 362 | dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL); | ||
| 363 | if (!dma) | ||
| 364 | return -ENOMEM; | ||
| 365 | |||
| 366 | dma->chan_rx = dma_request_slave_channel(dev, "rx"); | ||
| 367 | if (!dma->chan_rx) { | ||
| 368 | dev_err(dev, "rx dma channel not available\n"); | ||
| 369 | ret = -ENODEV; | ||
| 370 | return ret; | ||
| 371 | } | ||
| 372 | |||
| 373 | dma->chan_tx = dma_request_slave_channel(dev, "tx"); | ||
| 374 | if (!dma->chan_tx) { | ||
| 375 | dev_err(dev, "tx dma channel not available\n"); | ||
| 376 | ret = -ENODEV; | ||
| 377 | goto err_tx_channel; | ||
| 378 | } | ||
| 379 | |||
| 380 | dma->tx_dma_buf = dma_alloc_coherent(dev, DSPI_DMA_BUFSIZE, | ||
| 381 | &dma->tx_dma_phys, GFP_KERNEL); | ||
| 382 | if (!dma->tx_dma_buf) { | ||
| 383 | ret = -ENOMEM; | ||
| 384 | goto err_tx_dma_buf; | ||
| 385 | } | ||
| 386 | |||
| 387 | dma->rx_dma_buf = dma_alloc_coherent(dev, DSPI_DMA_BUFSIZE, | ||
| 388 | &dma->rx_dma_phys, GFP_KERNEL); | ||
| 389 | if (!dma->rx_dma_buf) { | ||
| 390 | ret = -ENOMEM; | ||
| 391 | goto err_rx_dma_buf; | ||
| 392 | } | ||
| 393 | |||
| 394 | cfg.src_addr = phy_addr + SPI_POPR; | ||
| 395 | cfg.dst_addr = phy_addr + SPI_PUSHR; | ||
| 396 | cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 397 | cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 398 | cfg.src_maxburst = 1; | ||
| 399 | cfg.dst_maxburst = 1; | ||
| 400 | |||
| 401 | cfg.direction = DMA_DEV_TO_MEM; | ||
| 402 | ret = dmaengine_slave_config(dma->chan_rx, &cfg); | ||
| 403 | if (ret) { | ||
| 404 | dev_err(dev, "can't configure rx dma channel\n"); | ||
| 405 | ret = -EINVAL; | ||
| 406 | goto err_slave_config; | ||
| 407 | } | ||
| 408 | |||
| 409 | cfg.direction = DMA_MEM_TO_DEV; | ||
| 410 | ret = dmaengine_slave_config(dma->chan_tx, &cfg); | ||
| 411 | if (ret) { | ||
| 412 | dev_err(dev, "can't configure tx dma channel\n"); | ||
| 413 | ret = -EINVAL; | ||
| 414 | goto err_slave_config; | ||
| 415 | } | ||
| 416 | |||
| 417 | dspi->dma = dma; | ||
| 418 | init_completion(&dma->cmd_tx_complete); | ||
| 419 | init_completion(&dma->cmd_rx_complete); | ||
| 420 | |||
| 421 | return 0; | ||
| 422 | |||
| 423 | err_slave_config: | ||
| 424 | dma_free_coherent(dev, DSPI_DMA_BUFSIZE, | ||
| 425 | dma->rx_dma_buf, dma->rx_dma_phys); | ||
| 426 | err_rx_dma_buf: | ||
| 427 | dma_free_coherent(dev, DSPI_DMA_BUFSIZE, | ||
| 428 | dma->tx_dma_buf, dma->tx_dma_phys); | ||
| 429 | err_tx_dma_buf: | ||
| 430 | dma_release_channel(dma->chan_tx); | ||
| 431 | err_tx_channel: | ||
| 432 | dma_release_channel(dma->chan_rx); | ||
| 433 | |||
| 434 | devm_kfree(dev, dma); | ||
| 435 | dspi->dma = NULL; | ||
| 436 | |||
| 437 | return ret; | ||
| 438 | } | ||
| 439 | |||
| 440 | static void dspi_release_dma(struct fsl_dspi *dspi) | ||
| 441 | { | ||
| 442 | struct fsl_dspi_dma *dma = dspi->dma; | ||
| 443 | struct device *dev = &dspi->pdev->dev; | ||
| 444 | |||
| 445 | if (dma) { | ||
| 446 | if (dma->chan_tx) { | ||
| 447 | dma_unmap_single(dev, dma->tx_dma_phys, | ||
| 448 | DSPI_DMA_BUFSIZE, DMA_TO_DEVICE); | ||
| 449 | dma_release_channel(dma->chan_tx); | ||
| 450 | } | ||
| 451 | |||
| 452 | if (dma->chan_rx) { | ||
| 453 | dma_unmap_single(dev, dma->rx_dma_phys, | ||
| 454 | DSPI_DMA_BUFSIZE, DMA_FROM_DEVICE); | ||
| 455 | dma_release_channel(dma->chan_rx); | ||
| 456 | } | ||
| 457 | } | ||
| 458 | } | ||
| 459 | |||
| 180 | static void hz_to_spi_baud(char *pbr, char *br, int speed_hz, | 460 | static void hz_to_spi_baud(char *pbr, char *br, int speed_hz, |
| 181 | unsigned long clkrate) | 461 | unsigned long clkrate) |
| 182 | { | 462 | { |
| @@ -425,6 +705,12 @@ static int dspi_transfer_one_message(struct spi_master *master, | |||
| 425 | regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_TCFQE); | 705 | regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_TCFQE); |
| 426 | dspi_tcfq_write(dspi); | 706 | dspi_tcfq_write(dspi); |
| 427 | break; | 707 | break; |
| 708 | case DSPI_DMA_MODE: | ||
| 709 | regmap_write(dspi->regmap, SPI_RSER, | ||
| 710 | SPI_RSER_TFFFE | SPI_RSER_TFFFD | | ||
| 711 | SPI_RSER_RFDFE | SPI_RSER_RFDFD); | ||
| 712 | status = dspi_dma_xfer(dspi); | ||
| 713 | break; | ||
| 428 | default: | 714 | default: |
| 429 | dev_err(&dspi->pdev->dev, "unsupported trans_mode %u\n", | 715 | dev_err(&dspi->pdev->dev, "unsupported trans_mode %u\n", |
| 430 | trans_mode); | 716 | trans_mode); |
| @@ -432,9 +718,13 @@ static int dspi_transfer_one_message(struct spi_master *master, | |||
| 432 | goto out; | 718 | goto out; |
| 433 | } | 719 | } |
| 434 | 720 | ||
| 435 | if (wait_event_interruptible(dspi->waitq, dspi->waitflags)) | 721 | if (trans_mode != DSPI_DMA_MODE) { |
| 436 | dev_err(&dspi->pdev->dev, "wait transfer complete fail!\n"); | 722 | if (wait_event_interruptible(dspi->waitq, |
| 437 | dspi->waitflags = 0; | 723 | dspi->waitflags)) |
| 724 | dev_err(&dspi->pdev->dev, | ||
| 725 | "wait transfer complete fail!\n"); | ||
| 726 | dspi->waitflags = 0; | ||
| 727 | } | ||
| 438 | 728 | ||
| 439 | if (transfer->delay_usecs) | 729 | if (transfer->delay_usecs) |
| 440 | udelay(transfer->delay_usecs); | 730 | udelay(transfer->delay_usecs); |
| @@ -740,6 +1030,13 @@ static int dspi_probe(struct platform_device *pdev) | |||
| 740 | if (ret) | 1030 | if (ret) |
| 741 | goto out_master_put; | 1031 | goto out_master_put; |
| 742 | 1032 | ||
| 1033 | if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) { | ||
| 1034 | if (dspi_request_dma(dspi, res->start)) { | ||
| 1035 | dev_err(&pdev->dev, "can't get dma channels\n"); | ||
| 1036 | goto out_clk_put; | ||
| 1037 | } | ||
| 1038 | } | ||
| 1039 | |||
| 743 | master->max_speed_hz = | 1040 | master->max_speed_hz = |
| 744 | clk_get_rate(dspi->clk) / dspi->devtype_data->max_clock_factor; | 1041 | clk_get_rate(dspi->clk) / dspi->devtype_data->max_clock_factor; |
| 745 | 1042 | ||
| @@ -768,6 +1065,7 @@ static int dspi_remove(struct platform_device *pdev) | |||
| 768 | struct fsl_dspi *dspi = spi_master_get_devdata(master); | 1065 | struct fsl_dspi *dspi = spi_master_get_devdata(master); |
| 769 | 1066 | ||
| 770 | /* Disconnect from the SPI framework */ | 1067 | /* Disconnect from the SPI framework */ |
| 1068 | dspi_release_dma(dspi); | ||
| 771 | clk_disable_unprepare(dspi->clk); | 1069 | clk_disable_unprepare(dspi->clk); |
| 772 | spi_unregister_master(dspi->master); | 1070 | spi_unregister_master(dspi->master); |
| 773 | 1071 | ||
diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index 2c175b9495f7..1d332e23f6ed 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c | |||
| @@ -23,8 +23,6 @@ | |||
| 23 | #include <linux/pm_runtime.h> | 23 | #include <linux/pm_runtime.h> |
| 24 | #include <sysdev/fsl_soc.h> | 24 | #include <sysdev/fsl_soc.h> |
| 25 | 25 | ||
| 26 | #include "spi-fsl-lib.h" | ||
| 27 | |||
| 28 | /* eSPI Controller registers */ | 26 | /* eSPI Controller registers */ |
| 29 | #define ESPI_SPMODE 0x00 /* eSPI mode register */ | 27 | #define ESPI_SPMODE 0x00 /* eSPI mode register */ |
| 30 | #define ESPI_SPIE 0x04 /* eSPI event register */ | 28 | #define ESPI_SPIE 0x04 /* eSPI event register */ |
| @@ -54,8 +52,11 @@ | |||
| 54 | #define CSMODE_AFT(x) ((x) << 8) | 52 | #define CSMODE_AFT(x) ((x) << 8) |
| 55 | #define CSMODE_CG(x) ((x) << 3) | 53 | #define CSMODE_CG(x) ((x) << 3) |
| 56 | 54 | ||
| 55 | #define FSL_ESPI_FIFO_SIZE 32 | ||
| 56 | #define FSL_ESPI_RXTHR 15 | ||
| 57 | |||
| 57 | /* Default mode/csmode for eSPI controller */ | 58 | /* Default mode/csmode for eSPI controller */ |
| 58 | #define SPMODE_INIT_VAL (SPMODE_TXTHR(4) | SPMODE_RXTHR(3)) | 59 | #define SPMODE_INIT_VAL (SPMODE_TXTHR(4) | SPMODE_RXTHR(FSL_ESPI_RXTHR)) |
| 59 | #define CSMODE_INIT_VAL (CSMODE_POL_1 | CSMODE_BEF(0) \ | 60 | #define CSMODE_INIT_VAL (CSMODE_POL_1 | CSMODE_BEF(0) \ |
| 60 | | CSMODE_AFT(0) | CSMODE_CG(1)) | 61 | | CSMODE_AFT(0) | CSMODE_CG(1)) |
| 61 | 62 | ||
| @@ -90,219 +91,342 @@ | |||
| 90 | 91 | ||
| 91 | #define AUTOSUSPEND_TIMEOUT 2000 | 92 | #define AUTOSUSPEND_TIMEOUT 2000 |
| 92 | 93 | ||
| 93 | static inline u32 fsl_espi_read_reg(struct mpc8xxx_spi *mspi, int offset) | 94 | struct fsl_espi { |
| 95 | struct device *dev; | ||
| 96 | void __iomem *reg_base; | ||
| 97 | |||
| 98 | struct list_head *m_transfers; | ||
| 99 | struct spi_transfer *tx_t; | ||
| 100 | unsigned int tx_pos; | ||
| 101 | bool tx_done; | ||
| 102 | struct spi_transfer *rx_t; | ||
| 103 | unsigned int rx_pos; | ||
| 104 | bool rx_done; | ||
| 105 | |||
| 106 | bool swab; | ||
| 107 | unsigned int rxskip; | ||
| 108 | |||
| 109 | spinlock_t lock; | ||
| 110 | |||
| 111 | u32 spibrg; /* SPIBRG input clock */ | ||
| 112 | |||
| 113 | struct completion done; | ||
| 114 | }; | ||
| 115 | |||
| 116 | struct fsl_espi_cs { | ||
| 117 | u32 hw_mode; | ||
| 118 | }; | ||
| 119 | |||
| 120 | static inline u32 fsl_espi_read_reg(struct fsl_espi *espi, int offset) | ||
| 94 | { | 121 | { |
| 95 | return ioread32be(mspi->reg_base + offset); | 122 | return ioread32be(espi->reg_base + offset); |
| 96 | } | 123 | } |
| 97 | 124 | ||
| 98 | static inline u8 fsl_espi_read_reg8(struct mpc8xxx_spi *mspi, int offset) | 125 | static inline u16 fsl_espi_read_reg16(struct fsl_espi *espi, int offset) |
| 99 | { | 126 | { |
| 100 | return ioread8(mspi->reg_base + offset); | 127 | return ioread16be(espi->reg_base + offset); |
| 101 | } | 128 | } |
| 102 | 129 | ||
| 103 | static inline void fsl_espi_write_reg(struct mpc8xxx_spi *mspi, int offset, | 130 | static inline u8 fsl_espi_read_reg8(struct fsl_espi *espi, int offset) |
| 104 | u32 val) | ||
| 105 | { | 131 | { |
| 106 | iowrite32be(val, mspi->reg_base + offset); | 132 | return ioread8(espi->reg_base + offset); |
| 107 | } | 133 | } |
| 108 | 134 | ||
| 109 | static inline void fsl_espi_write_reg8(struct mpc8xxx_spi *mspi, int offset, | 135 | static inline void fsl_espi_write_reg(struct fsl_espi *espi, int offset, |
| 110 | u8 val) | 136 | u32 val) |
| 111 | { | 137 | { |
| 112 | iowrite8(val, mspi->reg_base + offset); | 138 | iowrite32be(val, espi->reg_base + offset); |
| 113 | } | 139 | } |
| 114 | 140 | ||
| 115 | static void fsl_espi_copy_to_buf(struct spi_message *m, | 141 | static inline void fsl_espi_write_reg16(struct fsl_espi *espi, int offset, |
| 116 | struct mpc8xxx_spi *mspi) | 142 | u16 val) |
| 117 | { | 143 | { |
| 118 | struct spi_transfer *t; | 144 | iowrite16be(val, espi->reg_base + offset); |
| 119 | u8 *buf = mspi->local_buf; | ||
| 120 | |||
| 121 | list_for_each_entry(t, &m->transfers, transfer_list) { | ||
| 122 | if (t->tx_buf) | ||
| 123 | memcpy(buf, t->tx_buf, t->len); | ||
| 124 | else | ||
| 125 | memset(buf, 0, t->len); | ||
| 126 | buf += t->len; | ||
| 127 | } | ||
| 128 | } | 145 | } |
| 129 | 146 | ||
| 130 | static void fsl_espi_copy_from_buf(struct spi_message *m, | 147 | static inline void fsl_espi_write_reg8(struct fsl_espi *espi, int offset, |
| 131 | struct mpc8xxx_spi *mspi) | 148 | u8 val) |
| 132 | { | 149 | { |
| 133 | struct spi_transfer *t; | 150 | iowrite8(val, espi->reg_base + offset); |
| 134 | u8 *buf = mspi->local_buf; | ||
| 135 | |||
| 136 | list_for_each_entry(t, &m->transfers, transfer_list) { | ||
| 137 | if (t->rx_buf) | ||
| 138 | memcpy(t->rx_buf, buf, t->len); | ||
| 139 | buf += t->len; | ||
| 140 | } | ||
| 141 | } | 151 | } |
| 142 | 152 | ||
| 143 | static int fsl_espi_check_message(struct spi_message *m) | 153 | static int fsl_espi_check_message(struct spi_message *m) |
| 144 | { | 154 | { |
| 145 | struct mpc8xxx_spi *mspi = spi_master_get_devdata(m->spi->master); | 155 | struct fsl_espi *espi = spi_master_get_devdata(m->spi->master); |
| 146 | struct spi_transfer *t, *first; | 156 | struct spi_transfer *t, *first; |
| 147 | 157 | ||
| 148 | if (m->frame_length > SPCOM_TRANLEN_MAX) { | 158 | if (m->frame_length > SPCOM_TRANLEN_MAX) { |
| 149 | dev_err(mspi->dev, "message too long, size is %u bytes\n", | 159 | dev_err(espi->dev, "message too long, size is %u bytes\n", |
| 150 | m->frame_length); | 160 | m->frame_length); |
| 151 | return -EMSGSIZE; | 161 | return -EMSGSIZE; |
| 152 | } | 162 | } |
| 153 | 163 | ||
| 154 | first = list_first_entry(&m->transfers, struct spi_transfer, | 164 | first = list_first_entry(&m->transfers, struct spi_transfer, |
| 155 | transfer_list); | 165 | transfer_list); |
| 166 | |||
| 156 | list_for_each_entry(t, &m->transfers, transfer_list) { | 167 | list_for_each_entry(t, &m->transfers, transfer_list) { |
| 157 | if (first->bits_per_word != t->bits_per_word || | 168 | if (first->bits_per_word != t->bits_per_word || |
| 158 | first->speed_hz != t->speed_hz) { | 169 | first->speed_hz != t->speed_hz) { |
| 159 | dev_err(mspi->dev, "bits_per_word/speed_hz should be the same for all transfers\n"); | 170 | dev_err(espi->dev, "bits_per_word/speed_hz should be the same for all transfers\n"); |
| 160 | return -EINVAL; | 171 | return -EINVAL; |
| 161 | } | 172 | } |
| 162 | } | 173 | } |
| 163 | 174 | ||
| 175 | /* ESPI supports MSB-first transfers for word size 8 / 16 only */ | ||
| 176 | if (!(m->spi->mode & SPI_LSB_FIRST) && first->bits_per_word != 8 && | ||
| 177 | first->bits_per_word != 16) { | ||
| 178 | dev_err(espi->dev, | ||
| 179 | "MSB-first transfer not supported for wordsize %u\n", | ||
| 180 | first->bits_per_word); | ||
| 181 | return -EINVAL; | ||
| 182 | } | ||
| 183 | |||
| 164 | return 0; | 184 | return 0; |
| 165 | } | 185 | } |
| 166 | 186 | ||
| 167 | static void fsl_espi_change_mode(struct spi_device *spi) | 187 | static unsigned int fsl_espi_check_rxskip_mode(struct spi_message *m) |
| 168 | { | 188 | { |
| 169 | struct mpc8xxx_spi *mspi = spi_master_get_devdata(spi->master); | 189 | struct spi_transfer *t; |
| 170 | struct spi_mpc8xxx_cs *cs = spi->controller_state; | 190 | unsigned int i = 0, rxskip = 0; |
| 171 | u32 tmp; | 191 | |
| 172 | unsigned long flags; | 192 | /* |
| 173 | 193 | * prerequisites for ESPI rxskip mode: | |
| 174 | /* Turn off IRQs locally to minimize time that SPI is disabled. */ | 194 | * - message has two transfers |
| 175 | local_irq_save(flags); | 195 | * - first transfer is a write and second is a read |
| 176 | 196 | * | |
| 177 | /* Turn off SPI unit prior changing mode */ | 197 | * In addition the current low-level transfer mechanism requires |
| 178 | tmp = fsl_espi_read_reg(mspi, ESPI_SPMODE); | 198 | * that the rxskip bytes fit into the TX FIFO. Else the transfer |
| 179 | fsl_espi_write_reg(mspi, ESPI_SPMODE, tmp & ~SPMODE_ENABLE); | 199 | * would hang because after the first FSL_ESPI_FIFO_SIZE bytes |
| 180 | fsl_espi_write_reg(mspi, ESPI_SPMODEx(spi->chip_select), | 200 | * the TX FIFO isn't re-filled. |
| 181 | cs->hw_mode); | 201 | */ |
| 182 | fsl_espi_write_reg(mspi, ESPI_SPMODE, tmp); | 202 | list_for_each_entry(t, &m->transfers, transfer_list) { |
| 183 | 203 | if (i == 0) { | |
| 184 | local_irq_restore(flags); | 204 | if (!t->tx_buf || t->rx_buf || |
| 205 | t->len > FSL_ESPI_FIFO_SIZE) | ||
| 206 | return 0; | ||
| 207 | rxskip = t->len; | ||
| 208 | } else if (i == 1) { | ||
| 209 | if (t->tx_buf || !t->rx_buf) | ||
| 210 | return 0; | ||
| 211 | } | ||
| 212 | i++; | ||
| 213 | } | ||
| 214 | |||
| 215 | return i == 2 ? rxskip : 0; | ||
| 185 | } | 216 | } |
| 186 | 217 | ||
| 187 | static u32 fsl_espi_tx_buf_lsb(struct mpc8xxx_spi *mpc8xxx_spi) | 218 | static void fsl_espi_fill_tx_fifo(struct fsl_espi *espi, u32 events) |
| 188 | { | 219 | { |
| 189 | u32 data; | 220 | u32 tx_fifo_avail; |
| 190 | u16 data_h; | 221 | unsigned int tx_left; |
| 191 | u16 data_l; | 222 | const void *tx_buf; |
| 192 | const u32 *tx = mpc8xxx_spi->tx; | 223 | |
| 224 | /* if events is zero transfer has not started and tx fifo is empty */ | ||
| 225 | tx_fifo_avail = events ? SPIE_TXCNT(events) : FSL_ESPI_FIFO_SIZE; | ||
| 226 | start: | ||
| 227 | tx_left = espi->tx_t->len - espi->tx_pos; | ||
| 228 | tx_buf = espi->tx_t->tx_buf; | ||
| 229 | while (tx_fifo_avail >= min(4U, tx_left) && tx_left) { | ||
| 230 | if (tx_left >= 4) { | ||
| 231 | if (!tx_buf) | ||
| 232 | fsl_espi_write_reg(espi, ESPI_SPITF, 0); | ||
| 233 | else if (espi->swab) | ||
| 234 | fsl_espi_write_reg(espi, ESPI_SPITF, | ||
| 235 | swahb32p(tx_buf + espi->tx_pos)); | ||
| 236 | else | ||
| 237 | fsl_espi_write_reg(espi, ESPI_SPITF, | ||
| 238 | *(u32 *)(tx_buf + espi->tx_pos)); | ||
| 239 | espi->tx_pos += 4; | ||
| 240 | tx_left -= 4; | ||
| 241 | tx_fifo_avail -= 4; | ||
| 242 | } else if (tx_left >= 2 && tx_buf && espi->swab) { | ||
| 243 | fsl_espi_write_reg16(espi, ESPI_SPITF, | ||
| 244 | swab16p(tx_buf + espi->tx_pos)); | ||
| 245 | espi->tx_pos += 2; | ||
| 246 | tx_left -= 2; | ||
| 247 | tx_fifo_avail -= 2; | ||
| 248 | } else { | ||
| 249 | if (!tx_buf) | ||
| 250 | fsl_espi_write_reg8(espi, ESPI_SPITF, 0); | ||
| 251 | else | ||
| 252 | fsl_espi_write_reg8(espi, ESPI_SPITF, | ||
| 253 | *(u8 *)(tx_buf + espi->tx_pos)); | ||
| 254 | espi->tx_pos += 1; | ||
| 255 | tx_left -= 1; | ||
| 256 | tx_fifo_avail -= 1; | ||
| 257 | } | ||
| 258 | } | ||
| 193 | 259 | ||
| 194 | if (!tx) | 260 | if (!tx_left) { |
| 195 | return 0; | 261 | /* Last transfer finished, in rxskip mode only one is needed */ |
| 262 | if (list_is_last(&espi->tx_t->transfer_list, | ||
| 263 | espi->m_transfers) || espi->rxskip) { | ||
| 264 | espi->tx_done = true; | ||
| 265 | return; | ||
| 266 | } | ||
| 267 | espi->tx_t = list_next_entry(espi->tx_t, transfer_list); | ||
| 268 | espi->tx_pos = 0; | ||
| 269 | /* continue with next transfer if tx fifo is not full */ | ||
| 270 | if (tx_fifo_avail) | ||
| 271 | goto start; | ||
| 272 | } | ||
| 273 | } | ||
| 196 | 274 | ||
| 197 | data = *tx++ << mpc8xxx_spi->tx_shift; | 275 | static void fsl_espi_read_rx_fifo(struct fsl_espi *espi, u32 events) |
| 198 | data_l = data & 0xffff; | 276 | { |
| 199 | data_h = (data >> 16) & 0xffff; | 277 | u32 rx_fifo_avail = SPIE_RXCNT(events); |
| 200 | swab16s(&data_l); | 278 | unsigned int rx_left; |
| 201 | swab16s(&data_h); | 279 | void *rx_buf; |
| 202 | data = data_h | data_l; | 280 | |
| 281 | start: | ||
| 282 | rx_left = espi->rx_t->len - espi->rx_pos; | ||
| 283 | rx_buf = espi->rx_t->rx_buf; | ||
| 284 | while (rx_fifo_avail >= min(4U, rx_left) && rx_left) { | ||
| 285 | if (rx_left >= 4) { | ||
| 286 | u32 val = fsl_espi_read_reg(espi, ESPI_SPIRF); | ||
| 287 | |||
| 288 | if (rx_buf && espi->swab) | ||
| 289 | *(u32 *)(rx_buf + espi->rx_pos) = swahb32(val); | ||
| 290 | else if (rx_buf) | ||
| 291 | *(u32 *)(rx_buf + espi->rx_pos) = val; | ||
| 292 | espi->rx_pos += 4; | ||
| 293 | rx_left -= 4; | ||
| 294 | rx_fifo_avail -= 4; | ||
| 295 | } else if (rx_left >= 2 && rx_buf && espi->swab) { | ||
| 296 | u16 val = fsl_espi_read_reg16(espi, ESPI_SPIRF); | ||
| 297 | |||
| 298 | *(u16 *)(rx_buf + espi->rx_pos) = swab16(val); | ||
| 299 | espi->rx_pos += 2; | ||
| 300 | rx_left -= 2; | ||
| 301 | rx_fifo_avail -= 2; | ||
| 302 | } else { | ||
| 303 | u8 val = fsl_espi_read_reg8(espi, ESPI_SPIRF); | ||
| 304 | |||
| 305 | if (rx_buf) | ||
| 306 | *(u8 *)(rx_buf + espi->rx_pos) = val; | ||
| 307 | espi->rx_pos += 1; | ||
| 308 | rx_left -= 1; | ||
| 309 | rx_fifo_avail -= 1; | ||
| 310 | } | ||
| 311 | } | ||
| 203 | 312 | ||
| 204 | mpc8xxx_spi->tx = tx; | 313 | if (!rx_left) { |
| 205 | return data; | 314 | if (list_is_last(&espi->rx_t->transfer_list, |
| 315 | espi->m_transfers)) { | ||
| 316 | espi->rx_done = true; | ||
| 317 | return; | ||
| 318 | } | ||
| 319 | espi->rx_t = list_next_entry(espi->rx_t, transfer_list); | ||
| 320 | espi->rx_pos = 0; | ||
| 321 | /* continue with next transfer if rx fifo is not empty */ | ||
| 322 | if (rx_fifo_avail) | ||
| 323 | goto start; | ||
| 324 | } | ||
| 206 | } | 325 | } |
| 207 | 326 | ||
| 208 | static void fsl_espi_setup_transfer(struct spi_device *spi, | 327 | static void fsl_espi_setup_transfer(struct spi_device *spi, |
| 209 | struct spi_transfer *t) | 328 | struct spi_transfer *t) |
| 210 | { | 329 | { |
| 211 | struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); | 330 | struct fsl_espi *espi = spi_master_get_devdata(spi->master); |
| 212 | int bits_per_word = t ? t->bits_per_word : spi->bits_per_word; | 331 | int bits_per_word = t ? t->bits_per_word : spi->bits_per_word; |
| 213 | u32 hz = t ? t->speed_hz : spi->max_speed_hz; | 332 | u32 pm, hz = t ? t->speed_hz : spi->max_speed_hz; |
| 214 | u8 pm; | 333 | struct fsl_espi_cs *cs = spi_get_ctldata(spi); |
| 215 | struct spi_mpc8xxx_cs *cs = spi->controller_state; | 334 | u32 hw_mode_old = cs->hw_mode; |
| 216 | |||
| 217 | cs->rx_shift = 0; | ||
| 218 | cs->tx_shift = 0; | ||
| 219 | cs->get_rx = mpc8xxx_spi_rx_buf_u32; | ||
| 220 | cs->get_tx = mpc8xxx_spi_tx_buf_u32; | ||
| 221 | if (bits_per_word <= 8) { | ||
| 222 | cs->rx_shift = 8 - bits_per_word; | ||
| 223 | } else { | ||
| 224 | cs->rx_shift = 16 - bits_per_word; | ||
| 225 | if (spi->mode & SPI_LSB_FIRST) | ||
| 226 | cs->get_tx = fsl_espi_tx_buf_lsb; | ||
| 227 | } | ||
| 228 | |||
| 229 | mpc8xxx_spi->rx_shift = cs->rx_shift; | ||
| 230 | mpc8xxx_spi->tx_shift = cs->tx_shift; | ||
| 231 | mpc8xxx_spi->get_rx = cs->get_rx; | ||
| 232 | mpc8xxx_spi->get_tx = cs->get_tx; | ||
| 233 | 335 | ||
| 234 | /* mask out bits we are going to set */ | 336 | /* mask out bits we are going to set */ |
| 235 | cs->hw_mode &= ~(CSMODE_LEN(0xF) | CSMODE_DIV16 | CSMODE_PM(0xF)); | 337 | cs->hw_mode &= ~(CSMODE_LEN(0xF) | CSMODE_DIV16 | CSMODE_PM(0xF)); |
| 236 | 338 | ||
| 237 | cs->hw_mode |= CSMODE_LEN(bits_per_word - 1); | 339 | cs->hw_mode |= CSMODE_LEN(bits_per_word - 1); |
| 238 | 340 | ||
| 239 | if ((mpc8xxx_spi->spibrg / hz) > 64) { | 341 | pm = DIV_ROUND_UP(espi->spibrg, hz * 4) - 1; |
| 342 | |||
| 343 | if (pm > 15) { | ||
| 240 | cs->hw_mode |= CSMODE_DIV16; | 344 | cs->hw_mode |= CSMODE_DIV16; |
| 241 | pm = DIV_ROUND_UP(mpc8xxx_spi->spibrg, hz * 16 * 4); | 345 | pm = DIV_ROUND_UP(espi->spibrg, hz * 16 * 4) - 1; |
| 242 | |||
| 243 | WARN_ONCE(pm > 33, "%s: Requested speed is too low: %d Hz. " | ||
| 244 | "Will use %d Hz instead.\n", dev_name(&spi->dev), | ||
| 245 | hz, mpc8xxx_spi->spibrg / (4 * 16 * (32 + 1))); | ||
| 246 | if (pm > 33) | ||
| 247 | pm = 33; | ||
| 248 | } else { | ||
| 249 | pm = DIV_ROUND_UP(mpc8xxx_spi->spibrg, hz * 4); | ||
| 250 | } | 346 | } |
| 251 | if (pm) | ||
| 252 | pm--; | ||
| 253 | if (pm < 2) | ||
| 254 | pm = 2; | ||
| 255 | 347 | ||
| 256 | cs->hw_mode |= CSMODE_PM(pm); | 348 | cs->hw_mode |= CSMODE_PM(pm); |
| 257 | 349 | ||
| 258 | fsl_espi_change_mode(spi); | 350 | /* don't write the mode register if the mode doesn't change */ |
| 351 | if (cs->hw_mode != hw_mode_old) | ||
| 352 | fsl_espi_write_reg(espi, ESPI_SPMODEx(spi->chip_select), | ||
| 353 | cs->hw_mode); | ||
| 259 | } | 354 | } |
| 260 | 355 | ||
| 261 | static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t) | 356 | static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t) |
| 262 | { | 357 | { |
| 263 | struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); | 358 | struct fsl_espi *espi = spi_master_get_devdata(spi->master); |
| 264 | u32 word; | 359 | unsigned int rx_len = t->len; |
| 360 | u32 mask, spcom; | ||
| 265 | int ret; | 361 | int ret; |
| 266 | 362 | ||
| 267 | mpc8xxx_spi->len = t->len; | 363 | reinit_completion(&espi->done); |
| 268 | mpc8xxx_spi->count = roundup(t->len, 4) / 4; | ||
| 269 | |||
| 270 | mpc8xxx_spi->tx = t->tx_buf; | ||
| 271 | mpc8xxx_spi->rx = t->rx_buf; | ||
| 272 | |||
| 273 | reinit_completion(&mpc8xxx_spi->done); | ||
| 274 | 364 | ||
| 275 | /* Set SPCOM[CS] and SPCOM[TRANLEN] field */ | 365 | /* Set SPCOM[CS] and SPCOM[TRANLEN] field */ |
| 276 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPCOM, | 366 | spcom = SPCOM_CS(spi->chip_select); |
| 277 | (SPCOM_CS(spi->chip_select) | SPCOM_TRANLEN(t->len - 1))); | 367 | spcom |= SPCOM_TRANLEN(t->len - 1); |
| 368 | |||
| 369 | /* configure RXSKIP mode */ | ||
| 370 | if (espi->rxskip) { | ||
| 371 | spcom |= SPCOM_RXSKIP(espi->rxskip); | ||
| 372 | rx_len = t->len - espi->rxskip; | ||
| 373 | if (t->rx_nbits == SPI_NBITS_DUAL) | ||
| 374 | spcom |= SPCOM_DO; | ||
| 375 | } | ||
| 376 | |||
| 377 | fsl_espi_write_reg(espi, ESPI_SPCOM, spcom); | ||
| 278 | 378 | ||
| 279 | /* enable rx ints */ | 379 | /* enable interrupts */ |
| 280 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, SPIM_RNE); | 380 | mask = SPIM_DON; |
| 381 | if (rx_len > FSL_ESPI_FIFO_SIZE) | ||
| 382 | mask |= SPIM_RXT; | ||
| 383 | fsl_espi_write_reg(espi, ESPI_SPIM, mask); | ||
| 281 | 384 | ||
| 282 | /* transmit word */ | 385 | /* Prevent filling the fifo from getting interrupted */ |
| 283 | word = mpc8xxx_spi->get_tx(mpc8xxx_spi); | 386 | spin_lock_irq(&espi->lock); |
| 284 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPITF, word); | 387 | fsl_espi_fill_tx_fifo(espi, 0); |
| 388 | spin_unlock_irq(&espi->lock); | ||
| 285 | 389 | ||
| 286 | /* Won't hang up forever, SPI bus sometimes got lost interrupts... */ | 390 | /* Won't hang up forever, SPI bus sometimes got lost interrupts... */ |
| 287 | ret = wait_for_completion_timeout(&mpc8xxx_spi->done, 2 * HZ); | 391 | ret = wait_for_completion_timeout(&espi->done, 2 * HZ); |
| 288 | if (ret == 0) | 392 | if (ret == 0) |
| 289 | dev_err(mpc8xxx_spi->dev, | 393 | dev_err(espi->dev, "Transfer timed out!\n"); |
| 290 | "Transaction hanging up (left %d bytes)\n", | ||
| 291 | mpc8xxx_spi->count); | ||
| 292 | 394 | ||
| 293 | /* disable rx ints */ | 395 | /* disable rx ints */ |
| 294 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, 0); | 396 | fsl_espi_write_reg(espi, ESPI_SPIM, 0); |
| 295 | 397 | ||
| 296 | return mpc8xxx_spi->count > 0 ? -EMSGSIZE : 0; | 398 | return ret == 0 ? -ETIMEDOUT : 0; |
| 297 | } | 399 | } |
| 298 | 400 | ||
| 299 | static int fsl_espi_trans(struct spi_message *m, struct spi_transfer *trans) | 401 | static int fsl_espi_trans(struct spi_message *m, struct spi_transfer *trans) |
| 300 | { | 402 | { |
| 301 | struct mpc8xxx_spi *mspi = spi_master_get_devdata(m->spi->master); | 403 | struct fsl_espi *espi = spi_master_get_devdata(m->spi->master); |
| 302 | struct spi_device *spi = m->spi; | 404 | struct spi_device *spi = m->spi; |
| 303 | int ret; | 405 | int ret; |
| 304 | 406 | ||
| 305 | fsl_espi_copy_to_buf(m, mspi); | 407 | /* In case of LSB-first and bits_per_word > 8 byte-swap all words */ |
| 408 | espi->swab = spi->mode & SPI_LSB_FIRST && trans->bits_per_word > 8; | ||
| 409 | |||
| 410 | espi->m_transfers = &m->transfers; | ||
| 411 | espi->tx_t = list_first_entry(&m->transfers, struct spi_transfer, | ||
| 412 | transfer_list); | ||
| 413 | espi->tx_pos = 0; | ||
| 414 | espi->tx_done = false; | ||
| 415 | espi->rx_t = list_first_entry(&m->transfers, struct spi_transfer, | ||
| 416 | transfer_list); | ||
| 417 | espi->rx_pos = 0; | ||
| 418 | espi->rx_done = false; | ||
| 419 | |||
| 420 | espi->rxskip = fsl_espi_check_rxskip_mode(m); | ||
| 421 | if (trans->rx_nbits == SPI_NBITS_DUAL && !espi->rxskip) { | ||
| 422 | dev_err(espi->dev, "Dual output mode requires RXSKIP mode!\n"); | ||
| 423 | return -EINVAL; | ||
| 424 | } | ||
| 425 | |||
| 426 | /* In RXSKIP mode skip first transfer for reads */ | ||
| 427 | if (espi->rxskip) | ||
| 428 | espi->rx_t = list_next_entry(espi->rx_t, transfer_list); | ||
| 429 | |||
| 306 | fsl_espi_setup_transfer(spi, trans); | 430 | fsl_espi_setup_transfer(spi, trans); |
| 307 | 431 | ||
| 308 | ret = fsl_espi_bufs(spi, trans); | 432 | ret = fsl_espi_bufs(spi, trans); |
| @@ -310,19 +434,13 @@ static int fsl_espi_trans(struct spi_message *m, struct spi_transfer *trans) | |||
| 310 | if (trans->delay_usecs) | 434 | if (trans->delay_usecs) |
| 311 | udelay(trans->delay_usecs); | 435 | udelay(trans->delay_usecs); |
| 312 | 436 | ||
| 313 | fsl_espi_setup_transfer(spi, NULL); | ||
| 314 | |||
| 315 | if (!ret) | ||
| 316 | fsl_espi_copy_from_buf(m, mspi); | ||
| 317 | |||
| 318 | return ret; | 437 | return ret; |
| 319 | } | 438 | } |
| 320 | 439 | ||
| 321 | static int fsl_espi_do_one_msg(struct spi_master *master, | 440 | static int fsl_espi_do_one_msg(struct spi_master *master, |
| 322 | struct spi_message *m) | 441 | struct spi_message *m) |
| 323 | { | 442 | { |
| 324 | struct mpc8xxx_spi *mspi = spi_master_get_devdata(m->spi->master); | 443 | unsigned int delay_usecs = 0, rx_nbits = 0; |
| 325 | unsigned int delay_usecs = 0; | ||
| 326 | struct spi_transfer *t, trans = {}; | 444 | struct spi_transfer *t, trans = {}; |
| 327 | int ret; | 445 | int ret; |
| 328 | 446 | ||
| @@ -333,6 +451,8 @@ static int fsl_espi_do_one_msg(struct spi_master *master, | |||
| 333 | list_for_each_entry(t, &m->transfers, transfer_list) { | 451 | list_for_each_entry(t, &m->transfers, transfer_list) { |
| 334 | if (t->delay_usecs > delay_usecs) | 452 | if (t->delay_usecs > delay_usecs) |
| 335 | delay_usecs = t->delay_usecs; | 453 | delay_usecs = t->delay_usecs; |
| 454 | if (t->rx_nbits > rx_nbits) | ||
| 455 | rx_nbits = t->rx_nbits; | ||
| 336 | } | 456 | } |
| 337 | 457 | ||
| 338 | t = list_first_entry(&m->transfers, struct spi_transfer, | 458 | t = list_first_entry(&m->transfers, struct spi_transfer, |
| @@ -342,8 +462,7 @@ static int fsl_espi_do_one_msg(struct spi_master *master, | |||
| 342 | trans.speed_hz = t->speed_hz; | 462 | trans.speed_hz = t->speed_hz; |
| 343 | trans.bits_per_word = t->bits_per_word; | 463 | trans.bits_per_word = t->bits_per_word; |
| 344 | trans.delay_usecs = delay_usecs; | 464 | trans.delay_usecs = delay_usecs; |
| 345 | trans.tx_buf = mspi->local_buf; | 465 | trans.rx_nbits = rx_nbits; |
| 346 | trans.rx_buf = mspi->local_buf; | ||
| 347 | 466 | ||
| 348 | if (trans.len) | 467 | if (trans.len) |
| 349 | ret = fsl_espi_trans(m, &trans); | 468 | ret = fsl_espi_trans(m, &trans); |
| @@ -360,12 +479,9 @@ out: | |||
| 360 | 479 | ||
| 361 | static int fsl_espi_setup(struct spi_device *spi) | 480 | static int fsl_espi_setup(struct spi_device *spi) |
| 362 | { | 481 | { |
| 363 | struct mpc8xxx_spi *mpc8xxx_spi; | 482 | struct fsl_espi *espi; |
| 364 | u32 loop_mode; | 483 | u32 loop_mode; |
| 365 | struct spi_mpc8xxx_cs *cs = spi_get_ctldata(spi); | 484 | struct fsl_espi_cs *cs = spi_get_ctldata(spi); |
| 366 | |||
| 367 | if (!spi->max_speed_hz) | ||
| 368 | return -EINVAL; | ||
| 369 | 485 | ||
| 370 | if (!cs) { | 486 | if (!cs) { |
| 371 | cs = kzalloc(sizeof(*cs), GFP_KERNEL); | 487 | cs = kzalloc(sizeof(*cs), GFP_KERNEL); |
| @@ -374,12 +490,11 @@ static int fsl_espi_setup(struct spi_device *spi) | |||
| 374 | spi_set_ctldata(spi, cs); | 490 | spi_set_ctldata(spi, cs); |
| 375 | } | 491 | } |
| 376 | 492 | ||
| 377 | mpc8xxx_spi = spi_master_get_devdata(spi->master); | 493 | espi = spi_master_get_devdata(spi->master); |
| 378 | 494 | ||
| 379 | pm_runtime_get_sync(mpc8xxx_spi->dev); | 495 | pm_runtime_get_sync(espi->dev); |
| 380 | 496 | ||
| 381 | cs->hw_mode = fsl_espi_read_reg(mpc8xxx_spi, | 497 | cs->hw_mode = fsl_espi_read_reg(espi, ESPI_SPMODEx(spi->chip_select)); |
| 382 | ESPI_SPMODEx(spi->chip_select)); | ||
| 383 | /* mask out bits we are going to set */ | 498 | /* mask out bits we are going to set */ |
| 384 | cs->hw_mode &= ~(CSMODE_CP_BEGIN_EDGECLK | CSMODE_CI_INACTIVEHIGH | 499 | cs->hw_mode &= ~(CSMODE_CP_BEGIN_EDGECLK | CSMODE_CI_INACTIVEHIGH |
| 385 | | CSMODE_REV); | 500 | | CSMODE_REV); |
| @@ -392,115 +507,74 @@ static int fsl_espi_setup(struct spi_device *spi) | |||
| 392 | cs->hw_mode |= CSMODE_REV; | 507 | cs->hw_mode |= CSMODE_REV; |
| 393 | 508 | ||
| 394 | /* Handle the loop mode */ | 509 | /* Handle the loop mode */ |
| 395 | loop_mode = fsl_espi_read_reg(mpc8xxx_spi, ESPI_SPMODE); | 510 | loop_mode = fsl_espi_read_reg(espi, ESPI_SPMODE); |
| 396 | loop_mode &= ~SPMODE_LOOP; | 511 | loop_mode &= ~SPMODE_LOOP; |
| 397 | if (spi->mode & SPI_LOOP) | 512 | if (spi->mode & SPI_LOOP) |
| 398 | loop_mode |= SPMODE_LOOP; | 513 | loop_mode |= SPMODE_LOOP; |
| 399 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPMODE, loop_mode); | 514 | fsl_espi_write_reg(espi, ESPI_SPMODE, loop_mode); |
| 400 | 515 | ||
| 401 | fsl_espi_setup_transfer(spi, NULL); | 516 | fsl_espi_setup_transfer(spi, NULL); |
| 402 | 517 | ||
| 403 | pm_runtime_mark_last_busy(mpc8xxx_spi->dev); | 518 | pm_runtime_mark_last_busy(espi->dev); |
| 404 | pm_runtime_put_autosuspend(mpc8xxx_spi->dev); | 519 | pm_runtime_put_autosuspend(espi->dev); |
| 405 | 520 | ||
| 406 | return 0; | 521 | return 0; |
| 407 | } | 522 | } |
| 408 | 523 | ||
| 409 | static void fsl_espi_cleanup(struct spi_device *spi) | 524 | static void fsl_espi_cleanup(struct spi_device *spi) |
| 410 | { | 525 | { |
| 411 | struct spi_mpc8xxx_cs *cs = spi_get_ctldata(spi); | 526 | struct fsl_espi_cs *cs = spi_get_ctldata(spi); |
| 412 | 527 | ||
| 413 | kfree(cs); | 528 | kfree(cs); |
| 414 | spi_set_ctldata(spi, NULL); | 529 | spi_set_ctldata(spi, NULL); |
| 415 | } | 530 | } |
| 416 | 531 | ||
| 417 | static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) | 532 | static void fsl_espi_cpu_irq(struct fsl_espi *espi, u32 events) |
| 418 | { | 533 | { |
| 419 | /* We need handle RX first */ | 534 | if (!espi->rx_done) |
| 420 | if (events & SPIE_RNE) { | 535 | fsl_espi_read_rx_fifo(espi, events); |
| 421 | u32 rx_data, tmp; | ||
| 422 | u8 rx_data_8; | ||
| 423 | int rx_nr_bytes = 4; | ||
| 424 | int ret; | ||
| 425 | |||
| 426 | /* Spin until RX is done */ | ||
| 427 | if (SPIE_RXCNT(events) < min(4, mspi->len)) { | ||
| 428 | ret = spin_event_timeout( | ||
| 429 | !(SPIE_RXCNT(events = | ||
| 430 | fsl_espi_read_reg(mspi, ESPI_SPIE)) < | ||
| 431 | min(4, mspi->len)), | ||
| 432 | 10000, 0); /* 10 msec */ | ||
| 433 | if (!ret) | ||
| 434 | dev_err(mspi->dev, | ||
| 435 | "tired waiting for SPIE_RXCNT\n"); | ||
| 436 | } | ||
| 437 | 536 | ||
| 438 | if (mspi->len >= 4) { | 537 | if (!espi->tx_done) |
| 439 | rx_data = fsl_espi_read_reg(mspi, ESPI_SPIRF); | 538 | fsl_espi_fill_tx_fifo(espi, events); |
| 440 | } else if (mspi->len <= 0) { | ||
| 441 | dev_err(mspi->dev, | ||
| 442 | "unexpected RX(SPIE_RNE) interrupt occurred,\n" | ||
| 443 | "(local rxlen %d bytes, reg rxlen %d bytes)\n", | ||
| 444 | min(4, mspi->len), SPIE_RXCNT(events)); | ||
| 445 | rx_nr_bytes = 0; | ||
| 446 | } else { | ||
| 447 | rx_nr_bytes = mspi->len; | ||
| 448 | tmp = mspi->len; | ||
| 449 | rx_data = 0; | ||
| 450 | while (tmp--) { | ||
| 451 | rx_data_8 = fsl_espi_read_reg8(mspi, | ||
| 452 | ESPI_SPIRF); | ||
| 453 | rx_data |= (rx_data_8 << (tmp * 8)); | ||
| 454 | } | ||
| 455 | |||
| 456 | rx_data <<= (4 - mspi->len) * 8; | ||
| 457 | } | ||
| 458 | 539 | ||
| 459 | mspi->len -= rx_nr_bytes; | 540 | if (!espi->tx_done || !espi->rx_done) |
| 541 | return; | ||
| 460 | 542 | ||
| 461 | if (rx_nr_bytes && mspi->rx) | 543 | /* we're done, but check for errors before returning */ |
| 462 | mspi->get_rx(rx_data, mspi); | 544 | events = fsl_espi_read_reg(espi, ESPI_SPIE); |
| 463 | } | ||
| 464 | 545 | ||
| 465 | if (!(events & SPIE_TNF)) { | 546 | if (!(events & SPIE_DON)) |
| 466 | int ret; | 547 | dev_err(espi->dev, |
| 467 | 548 | "Transfer done but SPIE_DON isn't set!\n"); | |
| 468 | /* spin until TX is done */ | ||
| 469 | ret = spin_event_timeout(((events = fsl_espi_read_reg( | ||
| 470 | mspi, ESPI_SPIE)) & SPIE_TNF), 1000, 0); | ||
| 471 | if (!ret) { | ||
| 472 | dev_err(mspi->dev, "tired waiting for SPIE_TNF\n"); | ||
| 473 | complete(&mspi->done); | ||
| 474 | return; | ||
| 475 | } | ||
| 476 | } | ||
| 477 | 549 | ||
| 478 | mspi->count -= 1; | 550 | if (SPIE_RXCNT(events) || SPIE_TXCNT(events) != FSL_ESPI_FIFO_SIZE) |
| 479 | if (mspi->count) { | 551 | dev_err(espi->dev, "Transfer done but rx/tx fifo's aren't empty!\n"); |
| 480 | u32 word = mspi->get_tx(mspi); | ||
| 481 | 552 | ||
| 482 | fsl_espi_write_reg(mspi, ESPI_SPITF, word); | 553 | complete(&espi->done); |
| 483 | } else { | ||
| 484 | complete(&mspi->done); | ||
| 485 | } | ||
| 486 | } | 554 | } |
| 487 | 555 | ||
| 488 | static irqreturn_t fsl_espi_irq(s32 irq, void *context_data) | 556 | static irqreturn_t fsl_espi_irq(s32 irq, void *context_data) |
| 489 | { | 557 | { |
| 490 | struct mpc8xxx_spi *mspi = context_data; | 558 | struct fsl_espi *espi = context_data; |
| 491 | u32 events; | 559 | u32 events; |
| 492 | 560 | ||
| 561 | spin_lock(&espi->lock); | ||
| 562 | |||
| 493 | /* Get interrupt events(tx/rx) */ | 563 | /* Get interrupt events(tx/rx) */ |
| 494 | events = fsl_espi_read_reg(mspi, ESPI_SPIE); | 564 | events = fsl_espi_read_reg(espi, ESPI_SPIE); |
| 495 | if (!events) | 565 | if (!events) { |
| 566 | spin_unlock(&espi->lock); | ||
| 496 | return IRQ_NONE; | 567 | return IRQ_NONE; |
| 568 | } | ||
| 497 | 569 | ||
| 498 | dev_vdbg(mspi->dev, "%s: events %x\n", __func__, events); | 570 | dev_vdbg(espi->dev, "%s: events %x\n", __func__, events); |
| 499 | 571 | ||
| 500 | fsl_espi_cpu_irq(mspi, events); | 572 | fsl_espi_cpu_irq(espi, events); |
| 501 | 573 | ||
| 502 | /* Clear the events */ | 574 | /* Clear the events */ |
| 503 | fsl_espi_write_reg(mspi, ESPI_SPIE, events); | 575 | fsl_espi_write_reg(espi, ESPI_SPIE, events); |
| 576 | |||
| 577 | spin_unlock(&espi->lock); | ||
| 504 | 578 | ||
| 505 | return IRQ_HANDLED; | 579 | return IRQ_HANDLED; |
| 506 | } | 580 | } |
| @@ -509,12 +583,12 @@ static irqreturn_t fsl_espi_irq(s32 irq, void *context_data) | |||
| 509 | static int fsl_espi_runtime_suspend(struct device *dev) | 583 | static int fsl_espi_runtime_suspend(struct device *dev) |
| 510 | { | 584 | { |
| 511 | struct spi_master *master = dev_get_drvdata(dev); | 585 | struct spi_master *master = dev_get_drvdata(dev); |
| 512 | struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master); | 586 | struct fsl_espi *espi = spi_master_get_devdata(master); |
| 513 | u32 regval; | 587 | u32 regval; |
| 514 | 588 | ||
| 515 | regval = fsl_espi_read_reg(mpc8xxx_spi, ESPI_SPMODE); | 589 | regval = fsl_espi_read_reg(espi, ESPI_SPMODE); |
| 516 | regval &= ~SPMODE_ENABLE; | 590 | regval &= ~SPMODE_ENABLE; |
| 517 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPMODE, regval); | 591 | fsl_espi_write_reg(espi, ESPI_SPMODE, regval); |
| 518 | 592 | ||
| 519 | return 0; | 593 | return 0; |
| 520 | } | 594 | } |
| @@ -522,12 +596,12 @@ static int fsl_espi_runtime_suspend(struct device *dev) | |||
| 522 | static int fsl_espi_runtime_resume(struct device *dev) | 596 | static int fsl_espi_runtime_resume(struct device *dev) |
| 523 | { | 597 | { |
| 524 | struct spi_master *master = dev_get_drvdata(dev); | 598 | struct spi_master *master = dev_get_drvdata(dev); |
| 525 | struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master); | 599 | struct fsl_espi *espi = spi_master_get_devdata(master); |
| 526 | u32 regval; | 600 | u32 regval; |
| 527 | 601 | ||
| 528 | regval = fsl_espi_read_reg(mpc8xxx_spi, ESPI_SPMODE); | 602 | regval = fsl_espi_read_reg(espi, ESPI_SPMODE); |
| 529 | regval |= SPMODE_ENABLE; | 603 | regval |= SPMODE_ENABLE; |
| 530 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPMODE, regval); | 604 | fsl_espi_write_reg(espi, ESPI_SPMODE, regval); |
| 531 | 605 | ||
| 532 | return 0; | 606 | return 0; |
| 533 | } | 607 | } |
| @@ -538,96 +612,105 @@ static size_t fsl_espi_max_message_size(struct spi_device *spi) | |||
| 538 | return SPCOM_TRANLEN_MAX; | 612 | return SPCOM_TRANLEN_MAX; |
| 539 | } | 613 | } |
| 540 | 614 | ||
| 615 | static void fsl_espi_init_regs(struct device *dev, bool initial) | ||
| 616 | { | ||
| 617 | struct spi_master *master = dev_get_drvdata(dev); | ||
| 618 | struct fsl_espi *espi = spi_master_get_devdata(master); | ||
| 619 | struct device_node *nc; | ||
| 620 | u32 csmode, cs, prop; | ||
| 621 | int ret; | ||
| 622 | |||
| 623 | /* SPI controller initializations */ | ||
| 624 | fsl_espi_write_reg(espi, ESPI_SPMODE, 0); | ||
| 625 | fsl_espi_write_reg(espi, ESPI_SPIM, 0); | ||
| 626 | fsl_espi_write_reg(espi, ESPI_SPCOM, 0); | ||
| 627 | fsl_espi_write_reg(espi, ESPI_SPIE, 0xffffffff); | ||
| 628 | |||
| 629 | /* Init eSPI CS mode register */ | ||
| 630 | for_each_available_child_of_node(master->dev.of_node, nc) { | ||
| 631 | /* get chip select */ | ||
| 632 | ret = of_property_read_u32(nc, "reg", &cs); | ||
| 633 | if (ret || cs >= master->num_chipselect) | ||
| 634 | continue; | ||
| 635 | |||
| 636 | csmode = CSMODE_INIT_VAL; | ||
| 637 | |||
| 638 | /* check if CSBEF is set in device tree */ | ||
| 639 | ret = of_property_read_u32(nc, "fsl,csbef", &prop); | ||
| 640 | if (!ret) { | ||
| 641 | csmode &= ~(CSMODE_BEF(0xf)); | ||
| 642 | csmode |= CSMODE_BEF(prop); | ||
| 643 | } | ||
| 644 | |||
| 645 | /* check if CSAFT is set in device tree */ | ||
| 646 | ret = of_property_read_u32(nc, "fsl,csaft", &prop); | ||
| 647 | if (!ret) { | ||
| 648 | csmode &= ~(CSMODE_AFT(0xf)); | ||
| 649 | csmode |= CSMODE_AFT(prop); | ||
| 650 | } | ||
| 651 | |||
| 652 | fsl_espi_write_reg(espi, ESPI_SPMODEx(cs), csmode); | ||
| 653 | |||
| 654 | if (initial) | ||
| 655 | dev_info(dev, "cs=%u, init_csmode=0x%x\n", cs, csmode); | ||
| 656 | } | ||
| 657 | |||
| 658 | /* Enable SPI interface */ | ||
| 659 | fsl_espi_write_reg(espi, ESPI_SPMODE, SPMODE_INIT_VAL | SPMODE_ENABLE); | ||
| 660 | } | ||
| 661 | |||
| 541 | static int fsl_espi_probe(struct device *dev, struct resource *mem, | 662 | static int fsl_espi_probe(struct device *dev, struct resource *mem, |
| 542 | unsigned int irq) | 663 | unsigned int irq, unsigned int num_cs) |
| 543 | { | 664 | { |
| 544 | struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); | ||
| 545 | struct spi_master *master; | 665 | struct spi_master *master; |
| 546 | struct mpc8xxx_spi *mpc8xxx_spi; | 666 | struct fsl_espi *espi; |
| 547 | struct device_node *nc; | 667 | int ret; |
| 548 | const __be32 *prop; | ||
| 549 | u32 regval, csmode; | ||
| 550 | int i, len, ret; | ||
| 551 | 668 | ||
| 552 | master = spi_alloc_master(dev, sizeof(struct mpc8xxx_spi)); | 669 | master = spi_alloc_master(dev, sizeof(struct fsl_espi)); |
| 553 | if (!master) | 670 | if (!master) |
| 554 | return -ENOMEM; | 671 | return -ENOMEM; |
| 555 | 672 | ||
| 556 | dev_set_drvdata(dev, master); | 673 | dev_set_drvdata(dev, master); |
| 557 | 674 | ||
| 558 | mpc8xxx_spi_probe(dev, mem, irq); | 675 | master->mode_bits = SPI_RX_DUAL | SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | |
| 559 | 676 | SPI_LSB_FIRST | SPI_LOOP; | |
| 677 | master->dev.of_node = dev->of_node; | ||
| 560 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); | 678 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); |
| 561 | master->setup = fsl_espi_setup; | 679 | master->setup = fsl_espi_setup; |
| 562 | master->cleanup = fsl_espi_cleanup; | 680 | master->cleanup = fsl_espi_cleanup; |
| 563 | master->transfer_one_message = fsl_espi_do_one_msg; | 681 | master->transfer_one_message = fsl_espi_do_one_msg; |
| 564 | master->auto_runtime_pm = true; | 682 | master->auto_runtime_pm = true; |
| 565 | master->max_message_size = fsl_espi_max_message_size; | 683 | master->max_message_size = fsl_espi_max_message_size; |
| 684 | master->num_chipselect = num_cs; | ||
| 566 | 685 | ||
| 567 | mpc8xxx_spi = spi_master_get_devdata(master); | 686 | espi = spi_master_get_devdata(master); |
| 687 | spin_lock_init(&espi->lock); | ||
| 568 | 688 | ||
| 569 | mpc8xxx_spi->local_buf = | 689 | espi->dev = dev; |
| 570 | devm_kmalloc(dev, SPCOM_TRANLEN_MAX, GFP_KERNEL); | 690 | espi->spibrg = fsl_get_sys_freq(); |
| 571 | if (!mpc8xxx_spi->local_buf) { | 691 | if (espi->spibrg == -1) { |
| 572 | ret = -ENOMEM; | 692 | dev_err(dev, "Can't get sys frequency!\n"); |
| 693 | ret = -EINVAL; | ||
| 573 | goto err_probe; | 694 | goto err_probe; |
| 574 | } | 695 | } |
| 696 | /* determined by clock divider fields DIV16/PM in register SPMODEx */ | ||
| 697 | master->min_speed_hz = DIV_ROUND_UP(espi->spibrg, 4 * 16 * 16); | ||
| 698 | master->max_speed_hz = DIV_ROUND_UP(espi->spibrg, 4); | ||
| 575 | 699 | ||
| 576 | mpc8xxx_spi->reg_base = devm_ioremap_resource(dev, mem); | 700 | init_completion(&espi->done); |
| 577 | if (IS_ERR(mpc8xxx_spi->reg_base)) { | 701 | |
| 578 | ret = PTR_ERR(mpc8xxx_spi->reg_base); | 702 | espi->reg_base = devm_ioremap_resource(dev, mem); |
| 703 | if (IS_ERR(espi->reg_base)) { | ||
| 704 | ret = PTR_ERR(espi->reg_base); | ||
| 579 | goto err_probe; | 705 | goto err_probe; |
| 580 | } | 706 | } |
| 581 | 707 | ||
| 582 | /* Register for SPI Interrupt */ | 708 | /* Register for SPI Interrupt */ |
| 583 | ret = devm_request_irq(dev, mpc8xxx_spi->irq, fsl_espi_irq, | 709 | ret = devm_request_irq(dev, irq, fsl_espi_irq, 0, "fsl_espi", espi); |
| 584 | 0, "fsl_espi", mpc8xxx_spi); | ||
| 585 | if (ret) | 710 | if (ret) |
| 586 | goto err_probe; | 711 | goto err_probe; |
| 587 | 712 | ||
| 588 | if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) { | 713 | fsl_espi_init_regs(dev, true); |
| 589 | mpc8xxx_spi->rx_shift = 16; | ||
| 590 | mpc8xxx_spi->tx_shift = 24; | ||
| 591 | } | ||
| 592 | |||
| 593 | /* SPI controller initializations */ | ||
| 594 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPMODE, 0); | ||
| 595 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, 0); | ||
| 596 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPCOM, 0); | ||
| 597 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIE, 0xffffffff); | ||
| 598 | |||
| 599 | /* Init eSPI CS mode register */ | ||
| 600 | for_each_available_child_of_node(master->dev.of_node, nc) { | ||
| 601 | /* get chip select */ | ||
| 602 | prop = of_get_property(nc, "reg", &len); | ||
| 603 | if (!prop || len < sizeof(*prop)) | ||
| 604 | continue; | ||
| 605 | i = be32_to_cpup(prop); | ||
| 606 | if (i < 0 || i >= pdata->max_chipselect) | ||
| 607 | continue; | ||
| 608 | |||
| 609 | csmode = CSMODE_INIT_VAL; | ||
| 610 | /* check if CSBEF is set in device tree */ | ||
| 611 | prop = of_get_property(nc, "fsl,csbef", &len); | ||
| 612 | if (prop && len >= sizeof(*prop)) { | ||
| 613 | csmode &= ~(CSMODE_BEF(0xf)); | ||
| 614 | csmode |= CSMODE_BEF(be32_to_cpup(prop)); | ||
| 615 | } | ||
| 616 | /* check if CSAFT is set in device tree */ | ||
| 617 | prop = of_get_property(nc, "fsl,csaft", &len); | ||
| 618 | if (prop && len >= sizeof(*prop)) { | ||
| 619 | csmode &= ~(CSMODE_AFT(0xf)); | ||
| 620 | csmode |= CSMODE_AFT(be32_to_cpup(prop)); | ||
| 621 | } | ||
| 622 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPMODEx(i), csmode); | ||
| 623 | |||
| 624 | dev_info(dev, "cs=%d, init_csmode=0x%x\n", i, csmode); | ||
| 625 | } | ||
| 626 | |||
| 627 | /* Enable SPI interface */ | ||
| 628 | regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE; | ||
| 629 | |||
| 630 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPMODE, regval); | ||
| 631 | 714 | ||
| 632 | pm_runtime_set_autosuspend_delay(dev, AUTOSUSPEND_TIMEOUT); | 715 | pm_runtime_set_autosuspend_delay(dev, AUTOSUSPEND_TIMEOUT); |
| 633 | pm_runtime_use_autosuspend(dev); | 716 | pm_runtime_use_autosuspend(dev); |
| @@ -639,8 +722,7 @@ static int fsl_espi_probe(struct device *dev, struct resource *mem, | |||
| 639 | if (ret < 0) | 722 | if (ret < 0) |
| 640 | goto err_pm; | 723 | goto err_pm; |
| 641 | 724 | ||
| 642 | dev_info(dev, "at 0x%p (irq = %d)\n", mpc8xxx_spi->reg_base, | 725 | dev_info(dev, "at 0x%p (irq = %u)\n", espi->reg_base, irq); |
| 643 | mpc8xxx_spi->irq); | ||
| 644 | 726 | ||
| 645 | pm_runtime_mark_last_busy(dev); | 727 | pm_runtime_mark_last_busy(dev); |
| 646 | pm_runtime_put_autosuspend(dev); | 728 | pm_runtime_put_autosuspend(dev); |
| @@ -659,20 +741,16 @@ err_probe: | |||
| 659 | static int of_fsl_espi_get_chipselects(struct device *dev) | 741 | static int of_fsl_espi_get_chipselects(struct device *dev) |
| 660 | { | 742 | { |
| 661 | struct device_node *np = dev->of_node; | 743 | struct device_node *np = dev->of_node; |
| 662 | struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); | 744 | u32 num_cs; |
| 663 | const u32 *prop; | 745 | int ret; |
| 664 | int len; | ||
| 665 | 746 | ||
| 666 | prop = of_get_property(np, "fsl,espi-num-chipselects", &len); | 747 | ret = of_property_read_u32(np, "fsl,espi-num-chipselects", &num_cs); |
| 667 | if (!prop || len < sizeof(*prop)) { | 748 | if (ret) { |
| 668 | dev_err(dev, "No 'fsl,espi-num-chipselects' property\n"); | 749 | dev_err(dev, "No 'fsl,espi-num-chipselects' property\n"); |
| 669 | return -EINVAL; | 750 | return 0; |
| 670 | } | 751 | } |
| 671 | 752 | ||
| 672 | pdata->max_chipselect = *prop; | 753 | return num_cs; |
| 673 | pdata->cs_control = NULL; | ||
| 674 | |||
| 675 | return 0; | ||
| 676 | } | 754 | } |
| 677 | 755 | ||
| 678 | static int of_fsl_espi_probe(struct platform_device *ofdev) | 756 | static int of_fsl_espi_probe(struct platform_device *ofdev) |
| @@ -680,16 +758,17 @@ static int of_fsl_espi_probe(struct platform_device *ofdev) | |||
| 680 | struct device *dev = &ofdev->dev; | 758 | struct device *dev = &ofdev->dev; |
| 681 | struct device_node *np = ofdev->dev.of_node; | 759 | struct device_node *np = ofdev->dev.of_node; |
| 682 | struct resource mem; | 760 | struct resource mem; |
| 683 | unsigned int irq; | 761 | unsigned int irq, num_cs; |
| 684 | int ret; | 762 | int ret; |
| 685 | 763 | ||
| 686 | ret = of_mpc8xxx_spi_probe(ofdev); | 764 | if (of_property_read_bool(np, "mode")) { |
| 687 | if (ret) | 765 | dev_err(dev, "mode property is not supported on ESPI!\n"); |
| 688 | return ret; | 766 | return -EINVAL; |
| 767 | } | ||
| 689 | 768 | ||
| 690 | ret = of_fsl_espi_get_chipselects(dev); | 769 | num_cs = of_fsl_espi_get_chipselects(dev); |
| 691 | if (ret) | 770 | if (!num_cs) |
| 692 | return ret; | 771 | return -EINVAL; |
| 693 | 772 | ||
| 694 | ret = of_address_to_resource(np, 0, &mem); | 773 | ret = of_address_to_resource(np, 0, &mem); |
| 695 | if (ret) | 774 | if (ret) |
| @@ -699,7 +778,7 @@ static int of_fsl_espi_probe(struct platform_device *ofdev) | |||
| 699 | if (!irq) | 778 | if (!irq) |
| 700 | return -EINVAL; | 779 | return -EINVAL; |
| 701 | 780 | ||
| 702 | return fsl_espi_probe(dev, &mem, irq); | 781 | return fsl_espi_probe(dev, &mem, irq, num_cs); |
| 703 | } | 782 | } |
| 704 | 783 | ||
| 705 | static int of_fsl_espi_remove(struct platform_device *dev) | 784 | static int of_fsl_espi_remove(struct platform_device *dev) |
| @@ -721,38 +800,15 @@ static int of_fsl_espi_suspend(struct device *dev) | |||
| 721 | return ret; | 800 | return ret; |
| 722 | } | 801 | } |
| 723 | 802 | ||
| 724 | ret = pm_runtime_force_suspend(dev); | 803 | return pm_runtime_force_suspend(dev); |
| 725 | if (ret < 0) | ||
| 726 | return ret; | ||
| 727 | |||
| 728 | return 0; | ||
| 729 | } | 804 | } |
| 730 | 805 | ||
| 731 | static int of_fsl_espi_resume(struct device *dev) | 806 | static int of_fsl_espi_resume(struct device *dev) |
| 732 | { | 807 | { |
| 733 | struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); | ||
| 734 | struct spi_master *master = dev_get_drvdata(dev); | 808 | struct spi_master *master = dev_get_drvdata(dev); |
| 735 | struct mpc8xxx_spi *mpc8xxx_spi; | 809 | int ret; |
| 736 | u32 regval; | ||
| 737 | int i, ret; | ||
| 738 | |||
| 739 | mpc8xxx_spi = spi_master_get_devdata(master); | ||
| 740 | |||
| 741 | /* SPI controller initializations */ | ||
| 742 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPMODE, 0); | ||
| 743 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, 0); | ||
| 744 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPCOM, 0); | ||
| 745 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIE, 0xffffffff); | ||
| 746 | |||
| 747 | /* Init eSPI CS mode register */ | ||
| 748 | for (i = 0; i < pdata->max_chipselect; i++) | ||
| 749 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPMODEx(i), | ||
| 750 | CSMODE_INIT_VAL); | ||
| 751 | |||
| 752 | /* Enable SPI interface */ | ||
| 753 | regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE; | ||
| 754 | 810 | ||
| 755 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPMODE, regval); | 811 | fsl_espi_init_regs(dev, false); |
| 756 | 812 | ||
| 757 | ret = pm_runtime_force_resume(dev); | 813 | ret = pm_runtime_force_resume(dev); |
| 758 | if (ret < 0) | 814 | if (ret < 0) |
diff --git a/drivers/spi/spi-fsl-lib.h b/drivers/spi/spi-fsl-lib.h index 2925c8089fd9..f303f306b38e 100644 --- a/drivers/spi/spi-fsl-lib.h +++ b/drivers/spi/spi-fsl-lib.h | |||
| @@ -28,10 +28,6 @@ struct mpc8xxx_spi { | |||
| 28 | /* rx & tx bufs from the spi_transfer */ | 28 | /* rx & tx bufs from the spi_transfer */ |
| 29 | const void *tx; | 29 | const void *tx; |
| 30 | void *rx; | 30 | void *rx; |
| 31 | #if IS_ENABLED(CONFIG_SPI_FSL_ESPI) | ||
| 32 | int len; | ||
| 33 | u8 *local_buf; | ||
| 34 | #endif | ||
| 35 | 31 | ||
| 36 | int subblock; | 32 | int subblock; |
| 37 | struct spi_pram __iomem *pram; | 33 | struct spi_pram __iomem *pram; |
diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c new file mode 100644 index 000000000000..52551f6d0c7d --- /dev/null +++ b/drivers/spi/spi-fsl-lpspi.c | |||
| @@ -0,0 +1,525 @@ | |||
| 1 | /* | ||
| 2 | * Freescale i.MX7ULP LPSPI driver | ||
| 3 | * | ||
| 4 | * Copyright 2016 Freescale Semiconductor, Inc. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/clk.h> | ||
| 19 | #include <linux/completion.h> | ||
| 20 | #include <linux/delay.h> | ||
| 21 | #include <linux/err.h> | ||
| 22 | #include <linux/interrupt.h> | ||
| 23 | #include <linux/io.h> | ||
| 24 | #include <linux/irq.h> | ||
| 25 | #include <linux/kernel.h> | ||
| 26 | #include <linux/module.h> | ||
| 27 | #include <linux/of.h> | ||
| 28 | #include <linux/of_device.h> | ||
| 29 | #include <linux/platform_device.h> | ||
| 30 | #include <linux/slab.h> | ||
| 31 | #include <linux/spi/spi.h> | ||
| 32 | #include <linux/spi/spi_bitbang.h> | ||
| 33 | #include <linux/types.h> | ||
| 34 | |||
| 35 | #define DRIVER_NAME "fsl_lpspi" | ||
| 36 | |||
| 37 | /* i.MX7ULP LPSPI registers */ | ||
| 38 | #define IMX7ULP_VERID 0x0 | ||
| 39 | #define IMX7ULP_PARAM 0x4 | ||
| 40 | #define IMX7ULP_CR 0x10 | ||
| 41 | #define IMX7ULP_SR 0x14 | ||
| 42 | #define IMX7ULP_IER 0x18 | ||
| 43 | #define IMX7ULP_DER 0x1c | ||
| 44 | #define IMX7ULP_CFGR0 0x20 | ||
| 45 | #define IMX7ULP_CFGR1 0x24 | ||
| 46 | #define IMX7ULP_DMR0 0x30 | ||
| 47 | #define IMX7ULP_DMR1 0x34 | ||
| 48 | #define IMX7ULP_CCR 0x40 | ||
| 49 | #define IMX7ULP_FCR 0x58 | ||
| 50 | #define IMX7ULP_FSR 0x5c | ||
| 51 | #define IMX7ULP_TCR 0x60 | ||
| 52 | #define IMX7ULP_TDR 0x64 | ||
| 53 | #define IMX7ULP_RSR 0x70 | ||
| 54 | #define IMX7ULP_RDR 0x74 | ||
| 55 | |||
| 56 | /* General control register field define */ | ||
| 57 | #define CR_RRF BIT(9) | ||
| 58 | #define CR_RTF BIT(8) | ||
| 59 | #define CR_RST BIT(1) | ||
| 60 | #define CR_MEN BIT(0) | ||
| 61 | #define SR_TCF BIT(10) | ||
| 62 | #define SR_RDF BIT(1) | ||
| 63 | #define SR_TDF BIT(0) | ||
| 64 | #define IER_TCIE BIT(10) | ||
| 65 | #define IER_RDIE BIT(1) | ||
| 66 | #define IER_TDIE BIT(0) | ||
| 67 | #define CFGR1_PCSCFG BIT(27) | ||
| 68 | #define CFGR1_PCSPOL BIT(8) | ||
| 69 | #define CFGR1_NOSTALL BIT(3) | ||
| 70 | #define CFGR1_MASTER BIT(0) | ||
| 71 | #define RSR_RXEMPTY BIT(1) | ||
| 72 | #define TCR_CPOL BIT(31) | ||
| 73 | #define TCR_CPHA BIT(30) | ||
| 74 | #define TCR_CONT BIT(21) | ||
| 75 | #define TCR_CONTC BIT(20) | ||
| 76 | #define TCR_RXMSK BIT(19) | ||
| 77 | #define TCR_TXMSK BIT(18) | ||
| 78 | |||
| 79 | static int clkdivs[] = {1, 2, 4, 8, 16, 32, 64, 128}; | ||
| 80 | |||
| 81 | struct lpspi_config { | ||
| 82 | u8 bpw; | ||
| 83 | u8 chip_select; | ||
| 84 | u8 prescale; | ||
| 85 | u16 mode; | ||
| 86 | u32 speed_hz; | ||
| 87 | }; | ||
| 88 | |||
| 89 | struct fsl_lpspi_data { | ||
| 90 | struct device *dev; | ||
| 91 | void __iomem *base; | ||
| 92 | struct clk *clk; | ||
| 93 | |||
| 94 | void *rx_buf; | ||
| 95 | const void *tx_buf; | ||
| 96 | void (*tx)(struct fsl_lpspi_data *); | ||
| 97 | void (*rx)(struct fsl_lpspi_data *); | ||
| 98 | |||
| 99 | u32 remain; | ||
| 100 | u8 txfifosize; | ||
| 101 | u8 rxfifosize; | ||
| 102 | |||
| 103 | struct lpspi_config config; | ||
| 104 | struct completion xfer_done; | ||
| 105 | }; | ||
| 106 | |||
| 107 | static const struct of_device_id fsl_lpspi_dt_ids[] = { | ||
| 108 | { .compatible = "fsl,imx7ulp-spi", }, | ||
| 109 | { /* sentinel */ } | ||
| 110 | }; | ||
| 111 | MODULE_DEVICE_TABLE(of, fsl_lpspi_dt_ids); | ||
| 112 | |||
| 113 | #define LPSPI_BUF_RX(type) \ | ||
| 114 | static void fsl_lpspi_buf_rx_##type(struct fsl_lpspi_data *fsl_lpspi) \ | ||
| 115 | { \ | ||
| 116 | unsigned int val = readl(fsl_lpspi->base + IMX7ULP_RDR); \ | ||
| 117 | \ | ||
| 118 | if (fsl_lpspi->rx_buf) { \ | ||
| 119 | *(type *)fsl_lpspi->rx_buf = val; \ | ||
| 120 | fsl_lpspi->rx_buf += sizeof(type); \ | ||
| 121 | } \ | ||
| 122 | } | ||
| 123 | |||
| 124 | #define LPSPI_BUF_TX(type) \ | ||
| 125 | static void fsl_lpspi_buf_tx_##type(struct fsl_lpspi_data *fsl_lpspi) \ | ||
| 126 | { \ | ||
| 127 | type val = 0; \ | ||
| 128 | \ | ||
| 129 | if (fsl_lpspi->tx_buf) { \ | ||
| 130 | val = *(type *)fsl_lpspi->tx_buf; \ | ||
| 131 | fsl_lpspi->tx_buf += sizeof(type); \ | ||
| 132 | } \ | ||
| 133 | \ | ||
| 134 | fsl_lpspi->remain -= sizeof(type); \ | ||
| 135 | writel(val, fsl_lpspi->base + IMX7ULP_TDR); \ | ||
| 136 | } | ||
| 137 | |||
| 138 | LPSPI_BUF_RX(u8) | ||
| 139 | LPSPI_BUF_TX(u8) | ||
| 140 | LPSPI_BUF_RX(u16) | ||
| 141 | LPSPI_BUF_TX(u16) | ||
| 142 | LPSPI_BUF_RX(u32) | ||
| 143 | LPSPI_BUF_TX(u32) | ||
| 144 | |||
| 145 | static void fsl_lpspi_intctrl(struct fsl_lpspi_data *fsl_lpspi, | ||
| 146 | unsigned int enable) | ||
| 147 | { | ||
| 148 | writel(enable, fsl_lpspi->base + IMX7ULP_IER); | ||
| 149 | } | ||
| 150 | |||
| 151 | static int lpspi_prepare_xfer_hardware(struct spi_master *master) | ||
| 152 | { | ||
| 153 | struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master); | ||
| 154 | |||
| 155 | return clk_prepare_enable(fsl_lpspi->clk); | ||
| 156 | } | ||
| 157 | |||
| 158 | static int lpspi_unprepare_xfer_hardware(struct spi_master *master) | ||
| 159 | { | ||
| 160 | struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master); | ||
| 161 | |||
| 162 | clk_disable_unprepare(fsl_lpspi->clk); | ||
| 163 | |||
| 164 | return 0; | ||
| 165 | } | ||
| 166 | |||
| 167 | static int fsl_lpspi_txfifo_empty(struct fsl_lpspi_data *fsl_lpspi) | ||
| 168 | { | ||
| 169 | u32 txcnt; | ||
| 170 | unsigned long orig_jiffies = jiffies; | ||
| 171 | |||
| 172 | do { | ||
| 173 | txcnt = readl(fsl_lpspi->base + IMX7ULP_FSR) & 0xff; | ||
| 174 | |||
| 175 | if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) { | ||
| 176 | dev_dbg(fsl_lpspi->dev, "txfifo empty timeout\n"); | ||
| 177 | return -ETIMEDOUT; | ||
| 178 | } | ||
| 179 | cond_resched(); | ||
| 180 | |||
| 181 | } while (txcnt); | ||
| 182 | |||
| 183 | return 0; | ||
| 184 | } | ||
| 185 | |||
| 186 | static void fsl_lpspi_write_tx_fifo(struct fsl_lpspi_data *fsl_lpspi) | ||
| 187 | { | ||
| 188 | u8 txfifo_cnt; | ||
| 189 | |||
| 190 | txfifo_cnt = readl(fsl_lpspi->base + IMX7ULP_FSR) & 0xff; | ||
| 191 | |||
| 192 | while (txfifo_cnt < fsl_lpspi->txfifosize) { | ||
| 193 | if (!fsl_lpspi->remain) | ||
| 194 | break; | ||
| 195 | fsl_lpspi->tx(fsl_lpspi); | ||
| 196 | txfifo_cnt++; | ||
| 197 | } | ||
| 198 | |||
| 199 | if (!fsl_lpspi->remain && (txfifo_cnt < fsl_lpspi->txfifosize)) | ||
| 200 | writel(0, fsl_lpspi->base + IMX7ULP_TDR); | ||
| 201 | else | ||
| 202 | fsl_lpspi_intctrl(fsl_lpspi, IER_TDIE); | ||
| 203 | } | ||
| 204 | |||
| 205 | static void fsl_lpspi_read_rx_fifo(struct fsl_lpspi_data *fsl_lpspi) | ||
| 206 | { | ||
| 207 | while (!(readl(fsl_lpspi->base + IMX7ULP_RSR) & RSR_RXEMPTY)) | ||
| 208 | fsl_lpspi->rx(fsl_lpspi); | ||
| 209 | } | ||
| 210 | |||
| 211 | static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi, | ||
| 212 | bool is_first_xfer) | ||
| 213 | { | ||
| 214 | u32 temp = 0; | ||
| 215 | |||
| 216 | temp |= fsl_lpspi->config.bpw - 1; | ||
| 217 | temp |= fsl_lpspi->config.prescale << 27; | ||
| 218 | temp |= (fsl_lpspi->config.mode & 0x3) << 30; | ||
| 219 | temp |= (fsl_lpspi->config.chip_select & 0x3) << 24; | ||
| 220 | |||
| 221 | /* | ||
| 222 | * Set TCR_CONT will keep SS asserted after current transfer. | ||
| 223 | * For the first transfer, clear TCR_CONTC to assert SS. | ||
| 224 | * For subsequent transfer, set TCR_CONTC to keep SS asserted. | ||
| 225 | */ | ||
| 226 | temp |= TCR_CONT; | ||
| 227 | if (is_first_xfer) | ||
| 228 | temp &= ~TCR_CONTC; | ||
| 229 | else | ||
| 230 | temp |= TCR_CONTC; | ||
| 231 | |||
| 232 | writel(temp, fsl_lpspi->base + IMX7ULP_TCR); | ||
| 233 | |||
| 234 | dev_dbg(fsl_lpspi->dev, "TCR=0x%x\n", temp); | ||
| 235 | } | ||
| 236 | |||
| 237 | static void fsl_lpspi_set_watermark(struct fsl_lpspi_data *fsl_lpspi) | ||
| 238 | { | ||
| 239 | u32 temp; | ||
| 240 | |||
| 241 | temp = fsl_lpspi->txfifosize >> 1 | (fsl_lpspi->rxfifosize >> 1) << 16; | ||
| 242 | |||
| 243 | writel(temp, fsl_lpspi->base + IMX7ULP_FCR); | ||
| 244 | |||
| 245 | dev_dbg(fsl_lpspi->dev, "FCR=0x%x\n", temp); | ||
| 246 | } | ||
| 247 | |||
| 248 | static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi) | ||
| 249 | { | ||
| 250 | struct lpspi_config config = fsl_lpspi->config; | ||
| 251 | unsigned int perclk_rate, scldiv; | ||
| 252 | u8 prescale; | ||
| 253 | |||
| 254 | perclk_rate = clk_get_rate(fsl_lpspi->clk); | ||
| 255 | for (prescale = 0; prescale < 8; prescale++) { | ||
| 256 | scldiv = perclk_rate / | ||
| 257 | (clkdivs[prescale] * config.speed_hz) - 2; | ||
| 258 | if (scldiv < 256) { | ||
| 259 | fsl_lpspi->config.prescale = prescale; | ||
| 260 | break; | ||
| 261 | } | ||
| 262 | } | ||
| 263 | |||
| 264 | if (prescale == 8 && scldiv >= 256) | ||
| 265 | return -EINVAL; | ||
| 266 | |||
| 267 | writel(scldiv, fsl_lpspi->base + IMX7ULP_CCR); | ||
| 268 | |||
| 269 | dev_dbg(fsl_lpspi->dev, "perclk=%d, speed=%d, prescale =%d, scldiv=%d\n", | ||
| 270 | perclk_rate, config.speed_hz, prescale, scldiv); | ||
| 271 | |||
| 272 | return 0; | ||
| 273 | } | ||
| 274 | |||
| 275 | static int fsl_lpspi_config(struct fsl_lpspi_data *fsl_lpspi) | ||
| 276 | { | ||
| 277 | u32 temp; | ||
| 278 | int ret; | ||
| 279 | |||
| 280 | temp = CR_RST; | ||
| 281 | writel(temp, fsl_lpspi->base + IMX7ULP_CR); | ||
| 282 | writel(0, fsl_lpspi->base + IMX7ULP_CR); | ||
| 283 | |||
| 284 | ret = fsl_lpspi_set_bitrate(fsl_lpspi); | ||
| 285 | if (ret) | ||
| 286 | return ret; | ||
| 287 | |||
| 288 | fsl_lpspi_set_watermark(fsl_lpspi); | ||
| 289 | |||
| 290 | temp = CFGR1_PCSCFG | CFGR1_MASTER | CFGR1_NOSTALL; | ||
| 291 | if (fsl_lpspi->config.mode & SPI_CS_HIGH) | ||
| 292 | temp |= CFGR1_PCSPOL; | ||
| 293 | writel(temp, fsl_lpspi->base + IMX7ULP_CFGR1); | ||
| 294 | |||
| 295 | temp = readl(fsl_lpspi->base + IMX7ULP_CR); | ||
| 296 | temp |= CR_RRF | CR_RTF | CR_MEN; | ||
| 297 | writel(temp, fsl_lpspi->base + IMX7ULP_CR); | ||
| 298 | |||
| 299 | return 0; | ||
| 300 | } | ||
| 301 | |||
| 302 | static void fsl_lpspi_setup_transfer(struct spi_device *spi, | ||
| 303 | struct spi_transfer *t) | ||
| 304 | { | ||
| 305 | struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(spi->master); | ||
| 306 | |||
| 307 | fsl_lpspi->config.mode = spi->mode; | ||
| 308 | fsl_lpspi->config.bpw = t ? t->bits_per_word : spi->bits_per_word; | ||
| 309 | fsl_lpspi->config.speed_hz = t ? t->speed_hz : spi->max_speed_hz; | ||
| 310 | fsl_lpspi->config.chip_select = spi->chip_select; | ||
| 311 | |||
| 312 | if (!fsl_lpspi->config.speed_hz) | ||
| 313 | fsl_lpspi->config.speed_hz = spi->max_speed_hz; | ||
| 314 | if (!fsl_lpspi->config.bpw) | ||
| 315 | fsl_lpspi->config.bpw = spi->bits_per_word; | ||
| 316 | |||
| 317 | /* Initialize the functions for transfer */ | ||
| 318 | if (fsl_lpspi->config.bpw <= 8) { | ||
| 319 | fsl_lpspi->rx = fsl_lpspi_buf_rx_u8; | ||
| 320 | fsl_lpspi->tx = fsl_lpspi_buf_tx_u8; | ||
| 321 | } else if (fsl_lpspi->config.bpw <= 16) { | ||
| 322 | fsl_lpspi->rx = fsl_lpspi_buf_rx_u16; | ||
| 323 | fsl_lpspi->tx = fsl_lpspi_buf_tx_u16; | ||
| 324 | } else { | ||
| 325 | fsl_lpspi->rx = fsl_lpspi_buf_rx_u32; | ||
| 326 | fsl_lpspi->tx = fsl_lpspi_buf_tx_u32; | ||
| 327 | } | ||
| 328 | |||
| 329 | fsl_lpspi_config(fsl_lpspi); | ||
| 330 | } | ||
| 331 | |||
| 332 | static int fsl_lpspi_transfer_one(struct spi_master *master, | ||
| 333 | struct spi_device *spi, | ||
| 334 | struct spi_transfer *t) | ||
| 335 | { | ||
| 336 | struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master); | ||
| 337 | int ret; | ||
| 338 | |||
| 339 | fsl_lpspi->tx_buf = t->tx_buf; | ||
| 340 | fsl_lpspi->rx_buf = t->rx_buf; | ||
| 341 | fsl_lpspi->remain = t->len; | ||
| 342 | |||
| 343 | reinit_completion(&fsl_lpspi->xfer_done); | ||
| 344 | fsl_lpspi_write_tx_fifo(fsl_lpspi); | ||
| 345 | |||
| 346 | ret = wait_for_completion_timeout(&fsl_lpspi->xfer_done, HZ); | ||
| 347 | if (!ret) { | ||
| 348 | dev_dbg(fsl_lpspi->dev, "wait for completion timeout\n"); | ||
| 349 | return -ETIMEDOUT; | ||
| 350 | } | ||
| 351 | |||
| 352 | ret = fsl_lpspi_txfifo_empty(fsl_lpspi); | ||
| 353 | if (ret) | ||
| 354 | return ret; | ||
| 355 | |||
| 356 | fsl_lpspi_read_rx_fifo(fsl_lpspi); | ||
| 357 | |||
| 358 | return 0; | ||
| 359 | } | ||
| 360 | |||
| 361 | static int fsl_lpspi_transfer_one_msg(struct spi_master *master, | ||
| 362 | struct spi_message *msg) | ||
| 363 | { | ||
| 364 | struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master); | ||
| 365 | struct spi_device *spi = msg->spi; | ||
| 366 | struct spi_transfer *xfer; | ||
| 367 | bool is_first_xfer = true; | ||
| 368 | u32 temp; | ||
| 369 | int ret; | ||
| 370 | |||
| 371 | msg->status = 0; | ||
| 372 | msg->actual_length = 0; | ||
| 373 | |||
| 374 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { | ||
| 375 | fsl_lpspi_setup_transfer(spi, xfer); | ||
| 376 | fsl_lpspi_set_cmd(fsl_lpspi, is_first_xfer); | ||
| 377 | |||
| 378 | is_first_xfer = false; | ||
| 379 | |||
| 380 | ret = fsl_lpspi_transfer_one(master, spi, xfer); | ||
| 381 | if (ret < 0) | ||
| 382 | goto complete; | ||
| 383 | |||
| 384 | msg->actual_length += xfer->len; | ||
| 385 | } | ||
| 386 | |||
| 387 | complete: | ||
| 388 | /* de-assert SS, then finalize current message */ | ||
| 389 | temp = readl(fsl_lpspi->base + IMX7ULP_TCR); | ||
| 390 | temp &= ~TCR_CONTC; | ||
| 391 | writel(temp, fsl_lpspi->base + IMX7ULP_TCR); | ||
| 392 | |||
| 393 | msg->status = ret; | ||
| 394 | spi_finalize_current_message(master); | ||
| 395 | |||
| 396 | return ret; | ||
| 397 | } | ||
| 398 | |||
| 399 | static irqreturn_t fsl_lpspi_isr(int irq, void *dev_id) | ||
| 400 | { | ||
| 401 | struct fsl_lpspi_data *fsl_lpspi = dev_id; | ||
| 402 | u32 temp; | ||
| 403 | |||
| 404 | fsl_lpspi_intctrl(fsl_lpspi, 0); | ||
| 405 | temp = readl(fsl_lpspi->base + IMX7ULP_SR); | ||
| 406 | |||
| 407 | fsl_lpspi_read_rx_fifo(fsl_lpspi); | ||
| 408 | |||
| 409 | if (temp & SR_TDF) { | ||
| 410 | fsl_lpspi_write_tx_fifo(fsl_lpspi); | ||
| 411 | |||
| 412 | if (!fsl_lpspi->remain) | ||
| 413 | complete(&fsl_lpspi->xfer_done); | ||
| 414 | |||
| 415 | return IRQ_HANDLED; | ||
| 416 | } | ||
| 417 | |||
| 418 | return IRQ_NONE; | ||
| 419 | } | ||
| 420 | |||
| 421 | static int fsl_lpspi_probe(struct platform_device *pdev) | ||
| 422 | { | ||
| 423 | struct fsl_lpspi_data *fsl_lpspi; | ||
| 424 | struct spi_master *master; | ||
| 425 | struct resource *res; | ||
| 426 | int ret, irq; | ||
| 427 | u32 temp; | ||
| 428 | |||
| 429 | master = spi_alloc_master(&pdev->dev, sizeof(struct fsl_lpspi_data)); | ||
| 430 | if (!master) | ||
| 431 | return -ENOMEM; | ||
| 432 | |||
| 433 | platform_set_drvdata(pdev, master); | ||
| 434 | |||
| 435 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32); | ||
| 436 | master->bus_num = pdev->id; | ||
| 437 | |||
| 438 | fsl_lpspi = spi_master_get_devdata(master); | ||
| 439 | fsl_lpspi->dev = &pdev->dev; | ||
| 440 | |||
| 441 | master->transfer_one_message = fsl_lpspi_transfer_one_msg; | ||
| 442 | master->prepare_transfer_hardware = lpspi_prepare_xfer_hardware; | ||
| 443 | master->unprepare_transfer_hardware = lpspi_unprepare_xfer_hardware; | ||
| 444 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; | ||
| 445 | master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX; | ||
| 446 | master->dev.of_node = pdev->dev.of_node; | ||
| 447 | master->bus_num = pdev->id; | ||
| 448 | |||
| 449 | init_completion(&fsl_lpspi->xfer_done); | ||
| 450 | |||
| 451 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 452 | fsl_lpspi->base = devm_ioremap_resource(&pdev->dev, res); | ||
| 453 | if (IS_ERR(fsl_lpspi->base)) { | ||
| 454 | ret = PTR_ERR(fsl_lpspi->base); | ||
| 455 | goto out_master_put; | ||
| 456 | } | ||
| 457 | |||
| 458 | irq = platform_get_irq(pdev, 0); | ||
| 459 | if (irq < 0) { | ||
| 460 | ret = irq; | ||
| 461 | goto out_master_put; | ||
| 462 | } | ||
| 463 | |||
| 464 | ret = devm_request_irq(&pdev->dev, irq, fsl_lpspi_isr, 0, | ||
| 465 | dev_name(&pdev->dev), fsl_lpspi); | ||
| 466 | if (ret) { | ||
| 467 | dev_err(&pdev->dev, "can't get irq%d: %d\n", irq, ret); | ||
| 468 | goto out_master_put; | ||
| 469 | } | ||
| 470 | |||
| 471 | fsl_lpspi->clk = devm_clk_get(&pdev->dev, "ipg"); | ||
| 472 | if (IS_ERR(fsl_lpspi->clk)) { | ||
| 473 | ret = PTR_ERR(fsl_lpspi->clk); | ||
| 474 | goto out_master_put; | ||
| 475 | } | ||
| 476 | |||
| 477 | ret = clk_prepare_enable(fsl_lpspi->clk); | ||
| 478 | if (ret) { | ||
| 479 | dev_err(&pdev->dev, "can't enable lpspi clock, ret=%d\n", ret); | ||
| 480 | goto out_master_put; | ||
| 481 | } | ||
| 482 | |||
| 483 | temp = readl(fsl_lpspi->base + IMX7ULP_PARAM); | ||
| 484 | fsl_lpspi->txfifosize = 1 << (temp & 0x0f); | ||
| 485 | fsl_lpspi->rxfifosize = 1 << ((temp >> 8) & 0x0f); | ||
| 486 | |||
| 487 | clk_disable_unprepare(fsl_lpspi->clk); | ||
| 488 | |||
| 489 | ret = devm_spi_register_master(&pdev->dev, master); | ||
| 490 | if (ret < 0) { | ||
| 491 | dev_err(&pdev->dev, "spi_register_master error.\n"); | ||
| 492 | goto out_master_put; | ||
| 493 | } | ||
| 494 | |||
| 495 | return 0; | ||
| 496 | |||
| 497 | out_master_put: | ||
| 498 | spi_master_put(master); | ||
| 499 | |||
| 500 | return ret; | ||
| 501 | } | ||
| 502 | |||
| 503 | static int fsl_lpspi_remove(struct platform_device *pdev) | ||
| 504 | { | ||
| 505 | struct spi_master *master = platform_get_drvdata(pdev); | ||
| 506 | struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master); | ||
| 507 | |||
| 508 | clk_disable_unprepare(fsl_lpspi->clk); | ||
| 509 | |||
| 510 | return 0; | ||
| 511 | } | ||
| 512 | |||
| 513 | static struct platform_driver fsl_lpspi_driver = { | ||
| 514 | .driver = { | ||
| 515 | .name = DRIVER_NAME, | ||
| 516 | .of_match_table = fsl_lpspi_dt_ids, | ||
| 517 | }, | ||
| 518 | .probe = fsl_lpspi_probe, | ||
| 519 | .remove = fsl_lpspi_remove, | ||
| 520 | }; | ||
| 521 | module_platform_driver(fsl_lpspi_driver); | ||
| 522 | |||
| 523 | MODULE_DESCRIPTION("LPSPI Master Controller driver"); | ||
| 524 | MODULE_AUTHOR("Gao Pan <pandy.gao@nxp.com>"); | ||
| 525 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index deb782f6556c..32ced64a5bb9 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c | |||
| @@ -173,15 +173,16 @@ static int mxc_clkdivs[] = {0, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, | |||
| 173 | 173 | ||
| 174 | /* MX21, MX27 */ | 174 | /* MX21, MX27 */ |
| 175 | static unsigned int spi_imx_clkdiv_1(unsigned int fin, | 175 | static unsigned int spi_imx_clkdiv_1(unsigned int fin, |
| 176 | unsigned int fspi, unsigned int max) | 176 | unsigned int fspi, unsigned int max, unsigned int *fres) |
| 177 | { | 177 | { |
| 178 | int i; | 178 | int i; |
| 179 | 179 | ||
| 180 | for (i = 2; i < max; i++) | 180 | for (i = 2; i < max; i++) |
| 181 | if (fspi * mxc_clkdivs[i] >= fin) | 181 | if (fspi * mxc_clkdivs[i] >= fin) |
| 182 | return i; | 182 | break; |
| 183 | 183 | ||
| 184 | return max; | 184 | *fres = fin / mxc_clkdivs[i]; |
| 185 | return i; | ||
| 185 | } | 186 | } |
| 186 | 187 | ||
| 187 | /* MX1, MX31, MX35, MX51 CSPI */ | 188 | /* MX1, MX31, MX35, MX51 CSPI */ |
| @@ -442,6 +443,7 @@ static void mx51_ecspi_reset(struct spi_imx_data *spi_imx) | |||
| 442 | #define MX31_CSPICTRL_ENABLE (1 << 0) | 443 | #define MX31_CSPICTRL_ENABLE (1 << 0) |
| 443 | #define MX31_CSPICTRL_MASTER (1 << 1) | 444 | #define MX31_CSPICTRL_MASTER (1 << 1) |
| 444 | #define MX31_CSPICTRL_XCH (1 << 2) | 445 | #define MX31_CSPICTRL_XCH (1 << 2) |
| 446 | #define MX31_CSPICTRL_SMC (1 << 3) | ||
| 445 | #define MX31_CSPICTRL_POL (1 << 4) | 447 | #define MX31_CSPICTRL_POL (1 << 4) |
| 446 | #define MX31_CSPICTRL_PHA (1 << 5) | 448 | #define MX31_CSPICTRL_PHA (1 << 5) |
| 447 | #define MX31_CSPICTRL_SSCTL (1 << 6) | 449 | #define MX31_CSPICTRL_SSCTL (1 << 6) |
| @@ -452,6 +454,10 @@ static void mx51_ecspi_reset(struct spi_imx_data *spi_imx) | |||
| 452 | #define MX35_CSPICTRL_CS_SHIFT 12 | 454 | #define MX35_CSPICTRL_CS_SHIFT 12 |
| 453 | #define MX31_CSPICTRL_DR_SHIFT 16 | 455 | #define MX31_CSPICTRL_DR_SHIFT 16 |
| 454 | 456 | ||
| 457 | #define MX31_CSPI_DMAREG 0x10 | ||
| 458 | #define MX31_DMAREG_RH_DEN (1<<4) | ||
| 459 | #define MX31_DMAREG_TH_DEN (1<<1) | ||
| 460 | |||
| 455 | #define MX31_CSPISTATUS 0x14 | 461 | #define MX31_CSPISTATUS 0x14 |
| 456 | #define MX31_STATUS_RR (1 << 3) | 462 | #define MX31_STATUS_RR (1 << 3) |
| 457 | 463 | ||
| @@ -511,6 +517,9 @@ static int mx31_config(struct spi_device *spi, struct spi_imx_config *config) | |||
| 511 | (is_imx35_cspi(spi_imx) ? MX35_CSPICTRL_CS_SHIFT : | 517 | (is_imx35_cspi(spi_imx) ? MX35_CSPICTRL_CS_SHIFT : |
| 512 | MX31_CSPICTRL_CS_SHIFT); | 518 | MX31_CSPICTRL_CS_SHIFT); |
| 513 | 519 | ||
| 520 | if (spi_imx->usedma) | ||
| 521 | reg |= MX31_CSPICTRL_SMC; | ||
| 522 | |||
| 514 | writel(reg, spi_imx->base + MXC_CSPICTRL); | 523 | writel(reg, spi_imx->base + MXC_CSPICTRL); |
| 515 | 524 | ||
| 516 | reg = readl(spi_imx->base + MX31_CSPI_TESTREG); | 525 | reg = readl(spi_imx->base + MX31_CSPI_TESTREG); |
| @@ -520,6 +529,13 @@ static int mx31_config(struct spi_device *spi, struct spi_imx_config *config) | |||
| 520 | reg &= ~MX31_TEST_LBC; | 529 | reg &= ~MX31_TEST_LBC; |
| 521 | writel(reg, spi_imx->base + MX31_CSPI_TESTREG); | 530 | writel(reg, spi_imx->base + MX31_CSPI_TESTREG); |
| 522 | 531 | ||
| 532 | if (spi_imx->usedma) { | ||
| 533 | /* configure DMA requests when RXFIFO is half full and | ||
| 534 | when TXFIFO is half empty */ | ||
| 535 | writel(MX31_DMAREG_RH_DEN | MX31_DMAREG_TH_DEN, | ||
| 536 | spi_imx->base + MX31_CSPI_DMAREG); | ||
| 537 | } | ||
| 538 | |||
| 523 | return 0; | 539 | return 0; |
| 524 | } | 540 | } |
| 525 | 541 | ||
| @@ -574,9 +590,12 @@ static int mx21_config(struct spi_device *spi, struct spi_imx_config *config) | |||
| 574 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); | 590 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); |
| 575 | unsigned int reg = MX21_CSPICTRL_ENABLE | MX21_CSPICTRL_MASTER; | 591 | unsigned int reg = MX21_CSPICTRL_ENABLE | MX21_CSPICTRL_MASTER; |
| 576 | unsigned int max = is_imx27_cspi(spi_imx) ? 16 : 18; | 592 | unsigned int max = is_imx27_cspi(spi_imx) ? 16 : 18; |
| 593 | unsigned int clk; | ||
| 594 | |||
| 595 | reg |= spi_imx_clkdiv_1(spi_imx->spi_clk, config->speed_hz, max, &clk) | ||
| 596 | << MX21_CSPICTRL_DR_SHIFT; | ||
| 597 | spi_imx->spi_bus_clk = clk; | ||
| 577 | 598 | ||
| 578 | reg |= spi_imx_clkdiv_1(spi_imx->spi_clk, config->speed_hz, max) << | ||
| 579 | MX21_CSPICTRL_DR_SHIFT; | ||
| 580 | reg |= config->bpw - 1; | 599 | reg |= config->bpw - 1; |
| 581 | 600 | ||
| 582 | if (spi->mode & SPI_CPHA) | 601 | if (spi->mode & SPI_CPHA) |
| @@ -1244,10 +1263,10 @@ static int spi_imx_probe(struct platform_device *pdev) | |||
| 1244 | 1263 | ||
| 1245 | spi_imx->spi_clk = clk_get_rate(spi_imx->clk_per); | 1264 | spi_imx->spi_clk = clk_get_rate(spi_imx->clk_per); |
| 1246 | /* | 1265 | /* |
| 1247 | * Only validated on i.mx6 now, can remove the constrain if validated on | 1266 | * Only validated on i.mx35 and i.mx6 now, can remove the constraint |
| 1248 | * other chips. | 1267 | * if validated on other chips. |
| 1249 | */ | 1268 | */ |
| 1250 | if (is_imx51_ecspi(spi_imx)) { | 1269 | if (is_imx35_cspi(spi_imx) || is_imx51_ecspi(spi_imx)) { |
| 1251 | ret = spi_imx_sdma_init(&pdev->dev, spi_imx, master); | 1270 | ret = spi_imx_sdma_init(&pdev->dev, spi_imx, master); |
| 1252 | if (ret == -EPROBE_DEFER) | 1271 | if (ret == -EPROBE_DEFER) |
| 1253 | goto out_clk_put; | 1272 | goto out_clk_put; |
diff --git a/drivers/spi/spi-jcore.c b/drivers/spi/spi-jcore.c index f8117b80fa22..cebfea5faa4b 100644 --- a/drivers/spi/spi-jcore.c +++ b/drivers/spi/spi-jcore.c | |||
| @@ -214,6 +214,7 @@ static const struct of_device_id jcore_spi_of_match[] = { | |||
| 214 | { .compatible = "jcore,spi2" }, | 214 | { .compatible = "jcore,spi2" }, |
| 215 | {}, | 215 | {}, |
| 216 | }; | 216 | }; |
| 217 | MODULE_DEVICE_TABLE(of, jcore_spi_of_match); | ||
| 217 | 218 | ||
| 218 | static struct platform_driver jcore_spi_driver = { | 219 | static struct platform_driver jcore_spi_driver = { |
| 219 | .probe = jcore_spi_probe, | 220 | .probe = jcore_spi_probe, |
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index d5157b2222ce..79800e991ccd 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
| @@ -1386,20 +1386,13 @@ static int omap2_mcspi_probe(struct platform_device *pdev) | |||
| 1386 | regs_offset = pdata->regs_offset; | 1386 | regs_offset = pdata->regs_offset; |
| 1387 | 1387 | ||
| 1388 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1388 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1389 | if (r == NULL) { | ||
| 1390 | status = -ENODEV; | ||
| 1391 | goto free_master; | ||
| 1392 | } | ||
| 1393 | |||
| 1394 | r->start += regs_offset; | ||
| 1395 | r->end += regs_offset; | ||
| 1396 | mcspi->phys = r->start; | ||
| 1397 | |||
| 1398 | mcspi->base = devm_ioremap_resource(&pdev->dev, r); | 1389 | mcspi->base = devm_ioremap_resource(&pdev->dev, r); |
| 1399 | if (IS_ERR(mcspi->base)) { | 1390 | if (IS_ERR(mcspi->base)) { |
| 1400 | status = PTR_ERR(mcspi->base); | 1391 | status = PTR_ERR(mcspi->base); |
| 1401 | goto free_master; | 1392 | goto free_master; |
| 1402 | } | 1393 | } |
| 1394 | mcspi->phys = r->start + regs_offset; | ||
| 1395 | mcspi->base += regs_offset; | ||
| 1403 | 1396 | ||
| 1404 | mcspi->dev = &pdev->dev; | 1397 | mcspi->dev = &pdev->dev; |
| 1405 | 1398 | ||
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index ded37025b445..6b001c4a5640 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c | |||
| @@ -138,37 +138,62 @@ static int orion_spi_baudrate_set(struct spi_device *spi, unsigned int speed) | |||
| 138 | tclk_hz = clk_get_rate(orion_spi->clk); | 138 | tclk_hz = clk_get_rate(orion_spi->clk); |
| 139 | 139 | ||
| 140 | if (devdata->typ == ARMADA_SPI) { | 140 | if (devdata->typ == ARMADA_SPI) { |
| 141 | unsigned int clk, spr, sppr, sppr2, err; | 141 | /* |
| 142 | unsigned int best_spr, best_sppr, best_err; | 142 | * Given the core_clk (tclk_hz) and the target rate (speed) we |
| 143 | 143 | * determine the best values for SPR (in [0 .. 15]) and SPPR (in | |
| 144 | best_err = speed; | 144 | * [0..7]) such that |
| 145 | best_spr = 0; | 145 | * |
| 146 | best_sppr = 0; | 146 | * core_clk / (SPR * 2 ** SPPR) |
| 147 | 147 | * | |
| 148 | /* Iterate over the valid range looking for best fit */ | 148 | * is as big as possible but not bigger than speed. |
| 149 | for (sppr = 0; sppr < 8; sppr++) { | 149 | */ |
| 150 | sppr2 = 0x1 << sppr; | ||
| 151 | |||
| 152 | spr = tclk_hz / sppr2; | ||
| 153 | spr = DIV_ROUND_UP(spr, speed); | ||
| 154 | if ((spr == 0) || (spr > 15)) | ||
| 155 | continue; | ||
| 156 | |||
| 157 | clk = tclk_hz / (spr * sppr2); | ||
| 158 | err = speed - clk; | ||
| 159 | |||
| 160 | if (err < best_err) { | ||
| 161 | best_spr = spr; | ||
| 162 | best_sppr = sppr; | ||
| 163 | best_err = err; | ||
| 164 | } | ||
| 165 | } | ||
| 166 | 150 | ||
| 167 | if ((best_sppr == 0) && (best_spr == 0)) | 151 | /* best integer divider: */ |
| 168 | return -EINVAL; | 152 | unsigned divider = DIV_ROUND_UP(tclk_hz, speed); |
| 153 | unsigned spr, sppr; | ||
| 154 | |||
| 155 | if (divider < 16) { | ||
| 156 | /* This is the easy case, divider is less than 16 */ | ||
| 157 | spr = divider; | ||
| 158 | sppr = 0; | ||
| 159 | |||
| 160 | } else { | ||
| 161 | unsigned two_pow_sppr; | ||
| 162 | /* | ||
| 163 | * Find the highest bit set in divider. This and the | ||
| 164 | * three next bits define SPR (apart from rounding). | ||
| 165 | * SPPR is then the number of zero bits that must be | ||
| 166 | * appended: | ||
| 167 | */ | ||
| 168 | sppr = fls(divider) - 4; | ||
| 169 | |||
| 170 | /* | ||
| 171 | * As SPR only has 4 bits, we have to round divider up | ||
| 172 | * to the next multiple of 2 ** sppr. | ||
| 173 | */ | ||
| 174 | two_pow_sppr = 1 << sppr; | ||
| 175 | divider = (divider + two_pow_sppr - 1) & -two_pow_sppr; | ||
| 176 | |||
| 177 | /* | ||
| 178 | * recalculate sppr as rounding up divider might have | ||
| 179 | * increased it enough to change the position of the | ||
| 180 | * highest set bit. In this case the bit that now | ||
| 181 | * doesn't make it into SPR is 0, so there is no need to | ||
| 182 | * round again. | ||
| 183 | */ | ||
| 184 | sppr = fls(divider) - 4; | ||
| 185 | spr = divider >> sppr; | ||
| 186 | |||
| 187 | /* | ||
| 188 | * Now do range checking. SPR is constructed to have a | ||
| 189 | * width of 4 bits, so this is fine for sure. So we | ||
| 190 | * still need to check for sppr to fit into 3 bits: | ||
| 191 | */ | ||
| 192 | if (sppr > 7) | ||
| 193 | return -EINVAL; | ||
| 194 | } | ||
| 169 | 195 | ||
| 170 | prescale = ((best_sppr & 0x6) << 5) | | 196 | prescale = ((sppr & 0x6) << 5) | ((sppr & 0x1) << 4) | spr; |
| 171 | ((best_sppr & 0x1) << 4) | best_spr; | ||
| 172 | } else { | 197 | } else { |
| 173 | /* | 198 | /* |
| 174 | * the supported rates are: 4,6,8...30 | 199 | * the supported rates are: 4,6,8...30 |
diff --git a/drivers/spi/spi-pxa2xx.h b/drivers/spi/spi-pxa2xx.h index ce31b8199bb3..2823a00a9405 100644 --- a/drivers/spi/spi-pxa2xx.h +++ b/drivers/spi/spi-pxa2xx.h | |||
| @@ -109,7 +109,6 @@ static inline void pxa2xx_spi_write(const struct driver_data *drv_data, | |||
| 109 | #define DONE_STATE ((void *)2) | 109 | #define DONE_STATE ((void *)2) |
| 110 | #define ERROR_STATE ((void *)-1) | 110 | #define ERROR_STATE ((void *)-1) |
| 111 | 111 | ||
| 112 | #define IS_DMA_ALIGNED(x) IS_ALIGNED((unsigned long)(x), DMA_ALIGNMENT) | ||
| 113 | #define DMA_ALIGNMENT 8 | 112 | #define DMA_ALIGNMENT 8 |
| 114 | 113 | ||
| 115 | static inline int pxa25x_ssp_comp(struct driver_data *drv_data) | 114 | static inline int pxa25x_ssp_comp(struct driver_data *drv_data) |
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index a816f07e168e..9daf50031737 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c | |||
| @@ -413,7 +413,7 @@ static unsigned int qspi_set_send_trigger(struct rspi_data *rspi, | |||
| 413 | return n; | 413 | return n; |
| 414 | } | 414 | } |
| 415 | 415 | ||
| 416 | static void qspi_set_receive_trigger(struct rspi_data *rspi, unsigned int len) | 416 | static int qspi_set_receive_trigger(struct rspi_data *rspi, unsigned int len) |
| 417 | { | 417 | { |
| 418 | unsigned int n; | 418 | unsigned int n; |
| 419 | 419 | ||
| @@ -428,6 +428,7 @@ static void qspi_set_receive_trigger(struct rspi_data *rspi, unsigned int len) | |||
| 428 | qspi_update(rspi, SPBFCR_RXTRG_MASK, | 428 | qspi_update(rspi, SPBFCR_RXTRG_MASK, |
| 429 | SPBFCR_RXTRG_1B, QSPI_SPBFCR); | 429 | SPBFCR_RXTRG_1B, QSPI_SPBFCR); |
| 430 | } | 430 | } |
| 431 | return n; | ||
| 431 | } | 432 | } |
| 432 | 433 | ||
| 433 | #define set_config_register(spi, n) spi->ops->set_config_register(spi, n) | 434 | #define set_config_register(spi, n) spi->ops->set_config_register(spi, n) |
| @@ -785,6 +786,9 @@ static int qspi_transfer_out_in(struct rspi_data *rspi, | |||
| 785 | 786 | ||
| 786 | static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer) | 787 | static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer) |
| 787 | { | 788 | { |
| 789 | const u8 *tx = xfer->tx_buf; | ||
| 790 | unsigned int n = xfer->len; | ||
| 791 | unsigned int i, len; | ||
| 788 | int ret; | 792 | int ret; |
| 789 | 793 | ||
| 790 | if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) { | 794 | if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) { |
| @@ -793,9 +797,23 @@ static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer) | |||
| 793 | return ret; | 797 | return ret; |
| 794 | } | 798 | } |
| 795 | 799 | ||
| 796 | ret = rspi_pio_transfer(rspi, xfer->tx_buf, NULL, xfer->len); | 800 | while (n > 0) { |
| 797 | if (ret < 0) | 801 | len = qspi_set_send_trigger(rspi, n); |
| 798 | return ret; | 802 | if (len == QSPI_BUFFER_SIZE) { |
| 803 | ret = rspi_wait_for_tx_empty(rspi); | ||
| 804 | if (ret < 0) { | ||
| 805 | dev_err(&rspi->master->dev, "transmit timeout\n"); | ||
| 806 | return ret; | ||
| 807 | } | ||
| 808 | for (i = 0; i < len; i++) | ||
| 809 | rspi_write_data(rspi, *tx++); | ||
| 810 | } else { | ||
| 811 | ret = rspi_pio_transfer(rspi, tx, NULL, n); | ||
| 812 | if (ret < 0) | ||
| 813 | return ret; | ||
| 814 | } | ||
| 815 | n -= len; | ||
| 816 | } | ||
| 799 | 817 | ||
| 800 | /* Wait for the last transmission */ | 818 | /* Wait for the last transmission */ |
| 801 | rspi_wait_for_tx_empty(rspi); | 819 | rspi_wait_for_tx_empty(rspi); |
| @@ -805,13 +823,37 @@ static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer) | |||
| 805 | 823 | ||
| 806 | static int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer) | 824 | static int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer) |
| 807 | { | 825 | { |
| 826 | u8 *rx = xfer->rx_buf; | ||
| 827 | unsigned int n = xfer->len; | ||
| 828 | unsigned int i, len; | ||
| 829 | int ret; | ||
| 830 | |||
| 808 | if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) { | 831 | if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) { |
| 809 | int ret = rspi_dma_transfer(rspi, NULL, &xfer->rx_sg); | 832 | int ret = rspi_dma_transfer(rspi, NULL, &xfer->rx_sg); |
| 810 | if (ret != -EAGAIN) | 833 | if (ret != -EAGAIN) |
| 811 | return ret; | 834 | return ret; |
| 812 | } | 835 | } |
| 813 | 836 | ||
| 814 | return rspi_pio_transfer(rspi, NULL, xfer->rx_buf, xfer->len); | 837 | while (n > 0) { |
| 838 | len = qspi_set_receive_trigger(rspi, n); | ||
| 839 | if (len == QSPI_BUFFER_SIZE) { | ||
| 840 | ret = rspi_wait_for_rx_full(rspi); | ||
| 841 | if (ret < 0) { | ||
| 842 | dev_err(&rspi->master->dev, "receive timeout\n"); | ||
| 843 | return ret; | ||
| 844 | } | ||
| 845 | for (i = 0; i < len; i++) | ||
| 846 | *rx++ = rspi_read_data(rspi); | ||
| 847 | } else { | ||
| 848 | ret = rspi_pio_transfer(rspi, NULL, rx, n); | ||
| 849 | if (ret < 0) | ||
| 850 | return ret; | ||
| 851 | *rx++ = ret; | ||
| 852 | } | ||
| 853 | n -= len; | ||
| 854 | } | ||
| 855 | |||
| 856 | return 0; | ||
| 815 | } | 857 | } |
| 816 | 858 | ||
| 817 | static int qspi_transfer_one(struct spi_master *master, struct spi_device *spi, | 859 | static int qspi_transfer_one(struct spi_master *master, struct spi_device *spi, |
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 1de3a772eb7d..0012ad02e569 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c | |||
| @@ -980,6 +980,7 @@ static const struct of_device_id sh_msiof_match[] = { | |||
| 980 | { .compatible = "renesas,msiof-r8a7792", .data = &r8a779x_data }, | 980 | { .compatible = "renesas,msiof-r8a7792", .data = &r8a779x_data }, |
| 981 | { .compatible = "renesas,msiof-r8a7793", .data = &r8a779x_data }, | 981 | { .compatible = "renesas,msiof-r8a7793", .data = &r8a779x_data }, |
| 982 | { .compatible = "renesas,msiof-r8a7794", .data = &r8a779x_data }, | 982 | { .compatible = "renesas,msiof-r8a7794", .data = &r8a779x_data }, |
| 983 | { .compatible = "renesas,msiof-r8a7796", .data = &r8a779x_data }, | ||
| 983 | {}, | 984 | {}, |
| 984 | }; | 985 | }; |
| 985 | MODULE_DEVICE_TABLE(of, sh_msiof_match); | 986 | MODULE_DEVICE_TABLE(of, sh_msiof_match); |
diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c index 4969dc10684a..c5cd635c28f3 100644 --- a/drivers/spi/spi-sun4i.c +++ b/drivers/spi/spi-sun4i.c | |||
| @@ -46,6 +46,8 @@ | |||
| 46 | #define SUN4I_CTL_TP BIT(18) | 46 | #define SUN4I_CTL_TP BIT(18) |
| 47 | 47 | ||
| 48 | #define SUN4I_INT_CTL_REG 0x0c | 48 | #define SUN4I_INT_CTL_REG 0x0c |
| 49 | #define SUN4I_INT_CTL_RF_F34 BIT(4) | ||
| 50 | #define SUN4I_INT_CTL_TF_E34 BIT(12) | ||
| 49 | #define SUN4I_INT_CTL_TC BIT(16) | 51 | #define SUN4I_INT_CTL_TC BIT(16) |
| 50 | 52 | ||
| 51 | #define SUN4I_INT_STA_REG 0x10 | 53 | #define SUN4I_INT_STA_REG 0x10 |
| @@ -61,11 +63,14 @@ | |||
| 61 | #define SUN4I_CLK_CTL_CDR1(div) (((div) & SUN4I_CLK_CTL_CDR1_MASK) << 8) | 63 | #define SUN4I_CLK_CTL_CDR1(div) (((div) & SUN4I_CLK_CTL_CDR1_MASK) << 8) |
| 62 | #define SUN4I_CLK_CTL_DRS BIT(12) | 64 | #define SUN4I_CLK_CTL_DRS BIT(12) |
| 63 | 65 | ||
| 66 | #define SUN4I_MAX_XFER_SIZE 0xffffff | ||
| 67 | |||
| 64 | #define SUN4I_BURST_CNT_REG 0x20 | 68 | #define SUN4I_BURST_CNT_REG 0x20 |
| 65 | #define SUN4I_BURST_CNT(cnt) ((cnt) & 0xffffff) | 69 | #define SUN4I_BURST_CNT(cnt) ((cnt) & SUN4I_MAX_XFER_SIZE) |
| 66 | 70 | ||
| 67 | #define SUN4I_XMIT_CNT_REG 0x24 | 71 | #define SUN4I_XMIT_CNT_REG 0x24 |
| 68 | #define SUN4I_XMIT_CNT(cnt) ((cnt) & 0xffffff) | 72 | #define SUN4I_XMIT_CNT(cnt) ((cnt) & SUN4I_MAX_XFER_SIZE) |
| 73 | |||
| 69 | 74 | ||
| 70 | #define SUN4I_FIFO_STA_REG 0x28 | 75 | #define SUN4I_FIFO_STA_REG 0x28 |
| 71 | #define SUN4I_FIFO_STA_RF_CNT_MASK 0x7f | 76 | #define SUN4I_FIFO_STA_RF_CNT_MASK 0x7f |
| @@ -96,6 +101,31 @@ static inline void sun4i_spi_write(struct sun4i_spi *sspi, u32 reg, u32 value) | |||
| 96 | writel(value, sspi->base_addr + reg); | 101 | writel(value, sspi->base_addr + reg); |
| 97 | } | 102 | } |
| 98 | 103 | ||
| 104 | static inline u32 sun4i_spi_get_tx_fifo_count(struct sun4i_spi *sspi) | ||
| 105 | { | ||
| 106 | u32 reg = sun4i_spi_read(sspi, SUN4I_FIFO_STA_REG); | ||
| 107 | |||
| 108 | reg >>= SUN4I_FIFO_STA_TF_CNT_BITS; | ||
| 109 | |||
| 110 | return reg & SUN4I_FIFO_STA_TF_CNT_MASK; | ||
| 111 | } | ||
| 112 | |||
| 113 | static inline void sun4i_spi_enable_interrupt(struct sun4i_spi *sspi, u32 mask) | ||
| 114 | { | ||
| 115 | u32 reg = sun4i_spi_read(sspi, SUN4I_INT_CTL_REG); | ||
| 116 | |||
| 117 | reg |= mask; | ||
| 118 | sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, reg); | ||
| 119 | } | ||
| 120 | |||
| 121 | static inline void sun4i_spi_disable_interrupt(struct sun4i_spi *sspi, u32 mask) | ||
| 122 | { | ||
| 123 | u32 reg = sun4i_spi_read(sspi, SUN4I_INT_CTL_REG); | ||
| 124 | |||
| 125 | reg &= ~mask; | ||
| 126 | sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, reg); | ||
| 127 | } | ||
| 128 | |||
| 99 | static inline void sun4i_spi_drain_fifo(struct sun4i_spi *sspi, int len) | 129 | static inline void sun4i_spi_drain_fifo(struct sun4i_spi *sspi, int len) |
| 100 | { | 130 | { |
| 101 | u32 reg, cnt; | 131 | u32 reg, cnt; |
| @@ -118,10 +148,13 @@ static inline void sun4i_spi_drain_fifo(struct sun4i_spi *sspi, int len) | |||
| 118 | 148 | ||
| 119 | static inline void sun4i_spi_fill_fifo(struct sun4i_spi *sspi, int len) | 149 | static inline void sun4i_spi_fill_fifo(struct sun4i_spi *sspi, int len) |
| 120 | { | 150 | { |
| 151 | u32 cnt; | ||
| 121 | u8 byte; | 152 | u8 byte; |
| 122 | 153 | ||
| 123 | if (len > sspi->len) | 154 | /* See how much data we can fit */ |
| 124 | len = sspi->len; | 155 | cnt = SUN4I_FIFO_DEPTH - sun4i_spi_get_tx_fifo_count(sspi); |
| 156 | |||
| 157 | len = min3(len, (int)cnt, sspi->len); | ||
| 125 | 158 | ||
| 126 | while (len--) { | 159 | while (len--) { |
| 127 | byte = sspi->tx_buf ? *sspi->tx_buf++ : 0; | 160 | byte = sspi->tx_buf ? *sspi->tx_buf++ : 0; |
| @@ -184,10 +217,10 @@ static int sun4i_spi_transfer_one(struct spi_master *master, | |||
| 184 | u32 reg; | 217 | u32 reg; |
| 185 | 218 | ||
| 186 | /* We don't support transfer larger than the FIFO */ | 219 | /* We don't support transfer larger than the FIFO */ |
| 187 | if (tfr->len > SUN4I_FIFO_DEPTH) | 220 | if (tfr->len > SUN4I_MAX_XFER_SIZE) |
| 188 | return -EMSGSIZE; | 221 | return -EMSGSIZE; |
| 189 | 222 | ||
| 190 | if (tfr->tx_buf && tfr->len >= SUN4I_FIFO_DEPTH) | 223 | if (tfr->tx_buf && tfr->len >= SUN4I_MAX_XFER_SIZE) |
| 191 | return -EMSGSIZE; | 224 | return -EMSGSIZE; |
| 192 | 225 | ||
| 193 | reinit_completion(&sspi->done); | 226 | reinit_completion(&sspi->done); |
| @@ -286,7 +319,11 @@ static int sun4i_spi_transfer_one(struct spi_master *master, | |||
| 286 | sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH - 1); | 319 | sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH - 1); |
| 287 | 320 | ||
| 288 | /* Enable the interrupts */ | 321 | /* Enable the interrupts */ |
| 289 | sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, SUN4I_INT_CTL_TC); | 322 | sun4i_spi_enable_interrupt(sspi, SUN4I_INT_CTL_TC | |
| 323 | SUN4I_INT_CTL_RF_F34); | ||
| 324 | /* Only enable Tx FIFO interrupt if we really need it */ | ||
| 325 | if (tx_len > SUN4I_FIFO_DEPTH) | ||
| 326 | sun4i_spi_enable_interrupt(sspi, SUN4I_INT_CTL_TF_E34); | ||
| 290 | 327 | ||
| 291 | /* Start the transfer */ | 328 | /* Start the transfer */ |
| 292 | reg = sun4i_spi_read(sspi, SUN4I_CTL_REG); | 329 | reg = sun4i_spi_read(sspi, SUN4I_CTL_REG); |
| @@ -306,7 +343,6 @@ static int sun4i_spi_transfer_one(struct spi_master *master, | |||
| 306 | goto out; | 343 | goto out; |
| 307 | } | 344 | } |
| 308 | 345 | ||
| 309 | sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH); | ||
| 310 | 346 | ||
| 311 | out: | 347 | out: |
| 312 | sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, 0); | 348 | sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, 0); |
| @@ -322,10 +358,33 @@ static irqreturn_t sun4i_spi_handler(int irq, void *dev_id) | |||
| 322 | /* Transfer complete */ | 358 | /* Transfer complete */ |
| 323 | if (status & SUN4I_INT_CTL_TC) { | 359 | if (status & SUN4I_INT_CTL_TC) { |
| 324 | sun4i_spi_write(sspi, SUN4I_INT_STA_REG, SUN4I_INT_CTL_TC); | 360 | sun4i_spi_write(sspi, SUN4I_INT_STA_REG, SUN4I_INT_CTL_TC); |
| 361 | sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH); | ||
| 325 | complete(&sspi->done); | 362 | complete(&sspi->done); |
| 326 | return IRQ_HANDLED; | 363 | return IRQ_HANDLED; |
| 327 | } | 364 | } |
| 328 | 365 | ||
| 366 | /* Receive FIFO 3/4 full */ | ||
| 367 | if (status & SUN4I_INT_CTL_RF_F34) { | ||
| 368 | sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH); | ||
| 369 | /* Only clear the interrupt _after_ draining the FIFO */ | ||
| 370 | sun4i_spi_write(sspi, SUN4I_INT_STA_REG, SUN4I_INT_CTL_RF_F34); | ||
| 371 | return IRQ_HANDLED; | ||
| 372 | } | ||
| 373 | |||
| 374 | /* Transmit FIFO 3/4 empty */ | ||
| 375 | if (status & SUN4I_INT_CTL_TF_E34) { | ||
| 376 | sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH); | ||
| 377 | |||
| 378 | if (!sspi->len) | ||
| 379 | /* nothing left to transmit */ | ||
| 380 | sun4i_spi_disable_interrupt(sspi, SUN4I_INT_CTL_TF_E34); | ||
| 381 | |||
| 382 | /* Only clear the interrupt _after_ re-seeding the FIFO */ | ||
| 383 | sun4i_spi_write(sspi, SUN4I_INT_STA_REG, SUN4I_INT_CTL_TF_E34); | ||
| 384 | |||
| 385 | return IRQ_HANDLED; | ||
| 386 | } | ||
| 387 | |||
| 329 | return IRQ_NONE; | 388 | return IRQ_NONE; |
| 330 | } | 389 | } |
| 331 | 390 | ||
diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c index 9918a57a6a6e..e3114832c485 100644 --- a/drivers/spi/spi-sun6i.c +++ b/drivers/spi/spi-sun6i.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
| 18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
| 19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
| 20 | #include <linux/of_device.h> | ||
| 20 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
| 21 | #include <linux/pm_runtime.h> | 22 | #include <linux/pm_runtime.h> |
| 22 | #include <linux/reset.h> | 23 | #include <linux/reset.h> |
| @@ -24,6 +25,7 @@ | |||
| 24 | #include <linux/spi/spi.h> | 25 | #include <linux/spi/spi.h> |
| 25 | 26 | ||
| 26 | #define SUN6I_FIFO_DEPTH 128 | 27 | #define SUN6I_FIFO_DEPTH 128 |
| 28 | #define SUN8I_FIFO_DEPTH 64 | ||
| 27 | 29 | ||
| 28 | #define SUN6I_GBL_CTL_REG 0x04 | 30 | #define SUN6I_GBL_CTL_REG 0x04 |
| 29 | #define SUN6I_GBL_CTL_BUS_ENABLE BIT(0) | 31 | #define SUN6I_GBL_CTL_BUS_ENABLE BIT(0) |
| @@ -90,6 +92,7 @@ struct sun6i_spi { | |||
| 90 | const u8 *tx_buf; | 92 | const u8 *tx_buf; |
| 91 | u8 *rx_buf; | 93 | u8 *rx_buf; |
| 92 | int len; | 94 | int len; |
| 95 | unsigned long fifo_depth; | ||
| 93 | }; | 96 | }; |
| 94 | 97 | ||
| 95 | static inline u32 sun6i_spi_read(struct sun6i_spi *sspi, u32 reg) | 98 | static inline u32 sun6i_spi_read(struct sun6i_spi *sspi, u32 reg) |
| @@ -155,7 +158,9 @@ static void sun6i_spi_set_cs(struct spi_device *spi, bool enable) | |||
| 155 | 158 | ||
| 156 | static size_t sun6i_spi_max_transfer_size(struct spi_device *spi) | 159 | static size_t sun6i_spi_max_transfer_size(struct spi_device *spi) |
| 157 | { | 160 | { |
| 158 | return SUN6I_FIFO_DEPTH - 1; | 161 | struct sun6i_spi *sspi = spi_master_get_devdata(spi->master); |
| 162 | |||
| 163 | return sspi->fifo_depth - 1; | ||
| 159 | } | 164 | } |
| 160 | 165 | ||
| 161 | static int sun6i_spi_transfer_one(struct spi_master *master, | 166 | static int sun6i_spi_transfer_one(struct spi_master *master, |
| @@ -170,7 +175,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master, | |||
| 170 | u32 reg; | 175 | u32 reg; |
| 171 | 176 | ||
| 172 | /* We don't support transfer larger than the FIFO */ | 177 | /* We don't support transfer larger than the FIFO */ |
| 173 | if (tfr->len > SUN6I_FIFO_DEPTH) | 178 | if (tfr->len > sspi->fifo_depth) |
| 174 | return -EINVAL; | 179 | return -EINVAL; |
| 175 | 180 | ||
| 176 | reinit_completion(&sspi->done); | 181 | reinit_completion(&sspi->done); |
| @@ -265,7 +270,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master, | |||
| 265 | SUN6I_BURST_CTL_CNT_STC(tx_len)); | 270 | SUN6I_BURST_CTL_CNT_STC(tx_len)); |
| 266 | 271 | ||
| 267 | /* Fill the TX FIFO */ | 272 | /* Fill the TX FIFO */ |
| 268 | sun6i_spi_fill_fifo(sspi, SUN6I_FIFO_DEPTH); | 273 | sun6i_spi_fill_fifo(sspi, sspi->fifo_depth); |
| 269 | 274 | ||
| 270 | /* Enable the interrupts */ | 275 | /* Enable the interrupts */ |
| 271 | sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, SUN6I_INT_CTL_TC); | 276 | sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, SUN6I_INT_CTL_TC); |
| @@ -288,7 +293,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master, | |||
| 288 | goto out; | 293 | goto out; |
| 289 | } | 294 | } |
| 290 | 295 | ||
| 291 | sun6i_spi_drain_fifo(sspi, SUN6I_FIFO_DEPTH); | 296 | sun6i_spi_drain_fifo(sspi, sspi->fifo_depth); |
| 292 | 297 | ||
| 293 | out: | 298 | out: |
| 294 | sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, 0); | 299 | sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, 0); |
| @@ -398,6 +403,8 @@ static int sun6i_spi_probe(struct platform_device *pdev) | |||
| 398 | } | 403 | } |
| 399 | 404 | ||
| 400 | sspi->master = master; | 405 | sspi->master = master; |
| 406 | sspi->fifo_depth = (unsigned long)of_device_get_match_data(&pdev->dev); | ||
| 407 | |||
| 401 | master->max_speed_hz = 100 * 1000 * 1000; | 408 | master->max_speed_hz = 100 * 1000 * 1000; |
| 402 | master->min_speed_hz = 3 * 1000; | 409 | master->min_speed_hz = 3 * 1000; |
| 403 | master->set_cs = sun6i_spi_set_cs; | 410 | master->set_cs = sun6i_spi_set_cs; |
| @@ -470,7 +477,8 @@ static int sun6i_spi_remove(struct platform_device *pdev) | |||
| 470 | } | 477 | } |
| 471 | 478 | ||
| 472 | static const struct of_device_id sun6i_spi_match[] = { | 479 | static const struct of_device_id sun6i_spi_match[] = { |
| 473 | { .compatible = "allwinner,sun6i-a31-spi", }, | 480 | { .compatible = "allwinner,sun6i-a31-spi", .data = (void *)SUN6I_FIFO_DEPTH }, |
| 481 | { .compatible = "allwinner,sun8i-h3-spi", .data = (void *)SUN8I_FIFO_DEPTH }, | ||
| 474 | {} | 482 | {} |
| 475 | }; | 483 | }; |
| 476 | MODULE_DEVICE_TABLE(of, sun6i_spi_match); | 484 | MODULE_DEVICE_TABLE(of, sun6i_spi_match); |
diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index caeac66a3977..ec6fb09e2e17 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c | |||
| @@ -411,6 +411,7 @@ static int ti_qspi_dma_xfer(struct ti_qspi *qspi, dma_addr_t dma_dst, | |||
| 411 | tx->callback = ti_qspi_dma_callback; | 411 | tx->callback = ti_qspi_dma_callback; |
| 412 | tx->callback_param = qspi; | 412 | tx->callback_param = qspi; |
| 413 | cookie = tx->tx_submit(tx); | 413 | cookie = tx->tx_submit(tx); |
| 414 | reinit_completion(&qspi->transfer_complete); | ||
| 414 | 415 | ||
| 415 | ret = dma_submit_error(cookie); | 416 | ret = dma_submit_error(cookie); |
| 416 | if (ret) { | 417 | if (ret) { |
diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index c54ee6674471..fcb991034c3d 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c | |||
| @@ -1268,11 +1268,8 @@ static void pch_spi_free_resources(struct pch_spi_board_data *board_dat, | |||
| 1268 | static int pch_spi_get_resources(struct pch_spi_board_data *board_dat, | 1268 | static int pch_spi_get_resources(struct pch_spi_board_data *board_dat, |
| 1269 | struct pch_spi_data *data) | 1269 | struct pch_spi_data *data) |
| 1270 | { | 1270 | { |
| 1271 | int retval = 0; | ||
| 1272 | |||
| 1273 | dev_dbg(&board_dat->pdev->dev, "%s ENTRY\n", __func__); | 1271 | dev_dbg(&board_dat->pdev->dev, "%s ENTRY\n", __func__); |
| 1274 | 1272 | ||
| 1275 | |||
| 1276 | /* reset PCH SPI h/w */ | 1273 | /* reset PCH SPI h/w */ |
| 1277 | pch_spi_reset(data->master); | 1274 | pch_spi_reset(data->master); |
| 1278 | dev_dbg(&board_dat->pdev->dev, | 1275 | dev_dbg(&board_dat->pdev->dev, |
| @@ -1280,15 +1277,7 @@ static int pch_spi_get_resources(struct pch_spi_board_data *board_dat, | |||
| 1280 | 1277 | ||
| 1281 | dev_dbg(&board_dat->pdev->dev, "%s data->irq_reg_sts=true\n", __func__); | 1278 | dev_dbg(&board_dat->pdev->dev, "%s data->irq_reg_sts=true\n", __func__); |
| 1282 | 1279 | ||
| 1283 | if (retval != 0) { | 1280 | return 0; |
| 1284 | dev_err(&board_dat->pdev->dev, | ||
| 1285 | "%s FAIL:invoking pch_spi_free_resources\n", __func__); | ||
| 1286 | pch_spi_free_resources(board_dat, data); | ||
| 1287 | } | ||
| 1288 | |||
| 1289 | dev_dbg(&board_dat->pdev->dev, "%s Return=%d\n", __func__, retval); | ||
| 1290 | |||
| 1291 | return retval; | ||
| 1292 | } | 1281 | } |
| 1293 | 1282 | ||
| 1294 | static void pch_free_dma_buf(struct pch_spi_board_data *board_dat, | 1283 | static void pch_free_dma_buf(struct pch_spi_board_data *board_dat, |
diff --git a/drivers/spi/spi-xlp.c b/drivers/spi/spi-xlp.c index 4071a729eb2f..bea7a93a6046 100644 --- a/drivers/spi/spi-xlp.c +++ b/drivers/spi/spi-xlp.c | |||
| @@ -451,6 +451,7 @@ static const struct of_device_id xlp_spi_dt_id[] = { | |||
| 451 | { .compatible = "netlogic,xlp832-spi" }, | 451 | { .compatible = "netlogic,xlp832-spi" }, |
| 452 | { }, | 452 | { }, |
| 453 | }; | 453 | }; |
| 454 | MODULE_DEVICE_TABLE(of, xlp_spi_dt_id); | ||
| 454 | 455 | ||
| 455 | static struct platform_driver xlp_spi_driver = { | 456 | static struct platform_driver xlp_spi_driver = { |
| 456 | .probe = xlp_spi_probe, | 457 | .probe = xlp_spi_probe, |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 838783c3fed0..656dd3e3220c 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
| @@ -697,10 +697,15 @@ static void spi_set_cs(struct spi_device *spi, bool enable) | |||
| 697 | if (spi->mode & SPI_CS_HIGH) | 697 | if (spi->mode & SPI_CS_HIGH) |
| 698 | enable = !enable; | 698 | enable = !enable; |
| 699 | 699 | ||
| 700 | if (gpio_is_valid(spi->cs_gpio)) | 700 | if (gpio_is_valid(spi->cs_gpio)) { |
| 701 | gpio_set_value(spi->cs_gpio, !enable); | 701 | gpio_set_value(spi->cs_gpio, !enable); |
| 702 | else if (spi->master->set_cs) | 702 | /* Some SPI masters need both GPIO CS & slave_select */ |
| 703 | if ((spi->master->flags & SPI_MASTER_GPIO_SS) && | ||
| 704 | spi->master->set_cs) | ||
| 705 | spi->master->set_cs(spi, !enable); | ||
| 706 | } else if (spi->master->set_cs) { | ||
| 703 | spi->master->set_cs(spi, !enable); | 707 | spi->master->set_cs(spi, !enable); |
| 708 | } | ||
| 704 | } | 709 | } |
| 705 | 710 | ||
| 706 | #ifdef CONFIG_HAS_DMA | 711 | #ifdef CONFIG_HAS_DMA |
| @@ -720,6 +725,7 @@ static int spi_map_buf(struct spi_master *master, struct device *dev, | |||
| 720 | int desc_len; | 725 | int desc_len; |
| 721 | int sgs; | 726 | int sgs; |
| 722 | struct page *vm_page; | 727 | struct page *vm_page; |
| 728 | struct scatterlist *sg; | ||
| 723 | void *sg_buf; | 729 | void *sg_buf; |
| 724 | size_t min; | 730 | size_t min; |
| 725 | int i, ret; | 731 | int i, ret; |
| @@ -738,6 +744,7 @@ static int spi_map_buf(struct spi_master *master, struct device *dev, | |||
| 738 | if (ret != 0) | 744 | if (ret != 0) |
| 739 | return ret; | 745 | return ret; |
| 740 | 746 | ||
| 747 | sg = &sgt->sgl[0]; | ||
| 741 | for (i = 0; i < sgs; i++) { | 748 | for (i = 0; i < sgs; i++) { |
| 742 | 749 | ||
| 743 | if (vmalloced_buf || kmap_buf) { | 750 | if (vmalloced_buf || kmap_buf) { |
| @@ -751,16 +758,17 @@ static int spi_map_buf(struct spi_master *master, struct device *dev, | |||
| 751 | sg_free_table(sgt); | 758 | sg_free_table(sgt); |
| 752 | return -ENOMEM; | 759 | return -ENOMEM; |
| 753 | } | 760 | } |
| 754 | sg_set_page(&sgt->sgl[i], vm_page, | 761 | sg_set_page(sg, vm_page, |
| 755 | min, offset_in_page(buf)); | 762 | min, offset_in_page(buf)); |
| 756 | } else { | 763 | } else { |
| 757 | min = min_t(size_t, len, desc_len); | 764 | min = min_t(size_t, len, desc_len); |
| 758 | sg_buf = buf; | 765 | sg_buf = buf; |
| 759 | sg_set_buf(&sgt->sgl[i], sg_buf, min); | 766 | sg_set_buf(sg, sg_buf, min); |
| 760 | } | 767 | } |
| 761 | 768 | ||
| 762 | buf += min; | 769 | buf += min; |
| 763 | len -= min; | 770 | len -= min; |
| 771 | sg = sg_next(sg); | ||
| 764 | } | 772 | } |
| 765 | 773 | ||
| 766 | ret = dma_map_sg(dev, sgt->sgl, sgt->nents, dir); | 774 | ret = dma_map_sg(dev, sgt->sgl, sgt->nents, dir); |
| @@ -1034,8 +1042,14 @@ static int spi_transfer_one_message(struct spi_master *master, | |||
| 1034 | if (msg->status != -EINPROGRESS) | 1042 | if (msg->status != -EINPROGRESS) |
| 1035 | goto out; | 1043 | goto out; |
| 1036 | 1044 | ||
| 1037 | if (xfer->delay_usecs) | 1045 | if (xfer->delay_usecs) { |
| 1038 | udelay(xfer->delay_usecs); | 1046 | u16 us = xfer->delay_usecs; |
| 1047 | |||
| 1048 | if (us <= 10) | ||
| 1049 | udelay(us); | ||
| 1050 | else | ||
| 1051 | usleep_range(us, us + DIV_ROUND_UP(us, 10)); | ||
| 1052 | } | ||
| 1039 | 1053 | ||
| 1040 | if (xfer->cs_change) { | 1054 | if (xfer->cs_change) { |
| 1041 | if (list_is_last(&xfer->transfer_list, | 1055 | if (list_is_last(&xfer->transfer_list, |
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 2e05046f866b..9e2e099baf8c 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c | |||
| @@ -696,6 +696,7 @@ static struct class *spidev_class; | |||
| 696 | static const struct of_device_id spidev_dt_ids[] = { | 696 | static const struct of_device_id spidev_dt_ids[] = { |
| 697 | { .compatible = "rohm,dh2228fv" }, | 697 | { .compatible = "rohm,dh2228fv" }, |
| 698 | { .compatible = "lineartechnology,ltc2488" }, | 698 | { .compatible = "lineartechnology,ltc2488" }, |
| 699 | { .compatible = "ge,achc" }, | ||
| 699 | {}, | 700 | {}, |
| 700 | }; | 701 | }; |
| 701 | MODULE_DEVICE_TABLE(of, spidev_dt_ids); | 702 | MODULE_DEVICE_TABLE(of, spidev_dt_ids); |
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 4b743ac35396..75c6bd0ac605 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h | |||
| @@ -442,6 +442,7 @@ struct spi_master { | |||
| 442 | #define SPI_MASTER_NO_TX BIT(2) /* can't do buffer write */ | 442 | #define SPI_MASTER_NO_TX BIT(2) /* can't do buffer write */ |
| 443 | #define SPI_MASTER_MUST_RX BIT(3) /* requires rx */ | 443 | #define SPI_MASTER_MUST_RX BIT(3) /* requires rx */ |
| 444 | #define SPI_MASTER_MUST_TX BIT(4) /* requires tx */ | 444 | #define SPI_MASTER_MUST_TX BIT(4) /* requires tx */ |
| 445 | #define SPI_MASTER_GPIO_SS BIT(5) /* GPIO CS must select slave */ | ||
| 445 | 446 | ||
| 446 | /* | 447 | /* |
| 447 | * on some hardware transfer / message size may be constrained | 448 | * on some hardware transfer / message size may be constrained |
diff --git a/tools/spi/spidev_test.c b/tools/spi/spidev_test.c index f046b77cfefe..816f119c9b7b 100644 --- a/tools/spi/spidev_test.c +++ b/tools/spi/spidev_test.c | |||
| @@ -315,7 +315,7 @@ static void transfer_file(int fd, char *filename) | |||
| 315 | pabort("can't stat input file"); | 315 | pabort("can't stat input file"); |
| 316 | 316 | ||
| 317 | tx_fd = open(filename, O_RDONLY); | 317 | tx_fd = open(filename, O_RDONLY); |
| 318 | if (fd < 0) | 318 | if (tx_fd < 0) |
| 319 | pabort("can't open input file"); | 319 | pabort("can't open input file"); |
| 320 | 320 | ||
| 321 | tx = malloc(sb.st_size); | 321 | tx = malloc(sb.st_size); |
