diff options
37 files changed, 3046 insertions, 537 deletions
diff --git a/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt b/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt new file mode 100644 index 000000000000..ad7ac80a3841 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.txt | |||
| @@ -0,0 +1,233 @@ | |||
| 1 | Broadcom SPI controller | ||
| 2 | |||
| 3 | The Broadcom SPI controller is a SPI master found on various SOCs, including | ||
| 4 | BRCMSTB (BCM7XXX), Cygnus, NSP and NS2. The Broadcom Master SPI hw IP consits | ||
| 5 | of : | ||
| 6 | MSPI : SPI master controller can read and write to a SPI slave device | ||
| 7 | BSPI : Broadcom SPI in combination with the MSPI hw IP provides acceleration | ||
| 8 | for flash reads and be configured to do single, double, quad lane | ||
| 9 | io with 3-byte and 4-byte addressing support. | ||
| 10 | |||
| 11 | Supported Broadcom SoCs have one instance of MSPI+BSPI controller IP. | ||
| 12 | MSPI master can be used wihout BSPI. BRCMSTB SoCs have an additional instance | ||
| 13 | of a MSPI master without the BSPI to use with non flash slave devices that | ||
| 14 | use SPI protocol. | ||
| 15 | |||
| 16 | Required properties: | ||
| 17 | |||
| 18 | - #address-cells: | ||
| 19 | Must be <1>, as required by generic SPI binding. | ||
| 20 | |||
| 21 | - #size-cells: | ||
| 22 | Must be <0>, also as required by generic SPI binding. | ||
| 23 | |||
| 24 | - compatible: | ||
| 25 | Must be one of : | ||
| 26 | "brcm,spi-bcm-qspi", "brcm,spi-brcmstb-qspi" : MSPI+BSPI on BRCMSTB SoCs | ||
| 27 | "brcm,spi-bcm-qspi", "brcm,spi-brcmstb-mspi" : Second Instance of MSPI | ||
| 28 | BRCMSTB SoCs | ||
| 29 | "brcm,spi-bcm-qspi", "brcm,spi-nsp-qspi" : MSPI+BSPI on Cygnus, NSP | ||
| 30 | "brcm,spi-bcm-qspi", "brcm,spi-ns2-qspi" : NS2 SoCs | ||
| 31 | |||
| 32 | - reg: | ||
| 33 | Define the bases and ranges of the associated I/O address spaces. | ||
| 34 | The required range is MSPI controller registers. | ||
| 35 | |||
| 36 | - reg-names: | ||
| 37 | First name does not matter, but must be reserved for the MSPI controller | ||
| 38 | register range as mentioned in 'reg' above, and will typically contain | ||
| 39 | - "bspi_regs": BSPI register range, not required with compatible | ||
| 40 | "spi-brcmstb-mspi" | ||
| 41 | - "mspi_regs": MSPI register range is required for compatible strings | ||
| 42 | - "intr_regs", "intr_status_reg" : Interrupt and status register for | ||
| 43 | NSP, NS2, Cygnus SoC | ||
| 44 | |||
| 45 | - interrupts | ||
| 46 | The interrupts used by the MSPI and/or BSPI controller. | ||
| 47 | |||
| 48 | - interrupt-names: | ||
| 49 | Names of interrupts associated with MSPI | ||
| 50 | - "mspi_halted" : | ||
| 51 | - "mspi_done": Indicates that the requested SPI operation is complete. | ||
| 52 | - "spi_lr_fullness_reached" : Linear read BSPI pipe full | ||
| 53 | - "spi_lr_session_aborted" : Linear read BSPI pipe aborted | ||
| 54 | - "spi_lr_impatient" : Linear read BSPI requested when pipe empty | ||
| 55 | - "spi_lr_session_done" : Linear read BSPI session done | ||
| 56 | |||
| 57 | - clocks: | ||
| 58 | A phandle to the reference clock for this block. | ||
| 59 | |||
| 60 | Optional properties: | ||
| 61 | |||
| 62 | |||
| 63 | - native-endian | ||
| 64 | Defined when using BE SoC and device uses BE register read/write | ||
| 65 | |||
| 66 | Recommended optional m25p80 properties: | ||
| 67 | - spi-rx-bus-width: Definition as per | ||
| 68 | Documentation/devicetree/bindings/spi/spi-bus.txt | ||
| 69 | |||
| 70 | Examples: | ||
| 71 | |||
| 72 | BRCMSTB SoC Example: | ||
| 73 | |||
| 74 | SPI Master (MSPI+BSPI) for SPI-NOR access: | ||
| 75 | |||
| 76 | spi@f03e3400 { | ||
| 77 | #address-cells = <0x1>; | ||
| 78 | #size-cells = <0x0>; | ||
| 79 | compatible = "brcm,spi-brcmstb-qspi", "brcm,spi-brcmstb-qspi"; | ||
| 80 | reg = <0xf03e0920 0x4 0xf03e3400 0x188 0xf03e3200 0x50>; | ||
| 81 | reg-names = "cs_reg", "mspi", "bspi"; | ||
| 82 | interrupts = <0x6 0x5 0x4 0x3 0x2 0x1 0x0>; | ||
| 83 | interrupt-parent = <0x1c>; | ||
| 84 | interrupt-names = "mspi_halted", | ||
| 85 | "mspi_done", | ||
| 86 | "spi_lr_overread", | ||
| 87 | "spi_lr_session_done", | ||
| 88 | "spi_lr_impatient", | ||
| 89 | "spi_lr_session_aborted", | ||
| 90 | "spi_lr_fullness_reached"; | ||
| 91 | |||
| 92 | clocks = <&hif_spi>; | ||
| 93 | clock-names = "sw_spi"; | ||
| 94 | |||
| 95 | m25p80@0 { | ||
| 96 | #size-cells = <0x2>; | ||
| 97 | #address-cells = <0x2>; | ||
| 98 | compatible = "m25p80"; | ||
| 99 | reg = <0x0>; | ||
| 100 | spi-max-frequency = <0x2625a00>; | ||
| 101 | spi-cpol; | ||
| 102 | spi-cpha; | ||
| 103 | m25p,fast-read; | ||
| 104 | |||
| 105 | flash0.bolt@0 { | ||
| 106 | reg = <0x0 0x0 0x0 0x100000>; | ||
| 107 | }; | ||
| 108 | |||
| 109 | flash0.macadr@100000 { | ||
| 110 | reg = <0x0 0x100000 0x0 0x10000>; | ||
| 111 | }; | ||
| 112 | |||
| 113 | flash0.nvram@110000 { | ||
| 114 | reg = <0x0 0x110000 0x0 0x10000>; | ||
| 115 | }; | ||
| 116 | |||
| 117 | flash0.kernel@120000 { | ||
| 118 | reg = <0x0 0x120000 0x0 0x400000>; | ||
| 119 | }; | ||
| 120 | |||
| 121 | flash0.devtree@520000 { | ||
| 122 | reg = <0x0 0x520000 0x0 0x10000>; | ||
| 123 | }; | ||
| 124 | |||
| 125 | flash0.splash@530000 { | ||
| 126 | reg = <0x0 0x530000 0x0 0x80000>; | ||
| 127 | }; | ||
| 128 | |||
| 129 | flash0@0 { | ||
| 130 | reg = <0x0 0x0 0x0 0x4000000>; | ||
| 131 | }; | ||
| 132 | }; | ||
| 133 | }; | ||
| 134 | |||
| 135 | |||
| 136 | MSPI master for any SPI device : | ||
| 137 | |||
| 138 | spi@f0416000 { | ||
| 139 | #address-cells = <1>; | ||
| 140 | #size-cells = <0>; | ||
| 141 | clocks = <&upg_fixed>; | ||
| 142 | compatible = "brcm,spi-brcmstb-qspi", "brcm,spi-brcmstb-mspi"; | ||
| 143 | reg = <0xf0416000 0x180>; | ||
| 144 | reg-names = "mspi"; | ||
| 145 | interrupts = <0x14>; | ||
| 146 | interrupt-parent = <&irq0_aon_intc>; | ||
| 147 | interrupt-names = "mspi_done"; | ||
| 148 | }; | ||
| 149 | |||
| 150 | iProc SoC Example: | ||
| 151 | |||
| 152 | qspi: spi@18027200 { | ||
| 153 | compatible = "brcm,spi-bcm-qspi", "brcm,spi-nsp-qspi"; | ||
| 154 | reg = <0x18027200 0x184>, | ||
| 155 | <0x18027000 0x124>, | ||
| 156 | <0x1811c408 0x004>, | ||
| 157 | <0x180273a0 0x01c>; | ||
| 158 | reg-names = "mspi_regs", "bspi_regs", "intr_regs", "intr_status_reg"; | ||
| 159 | interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, | ||
| 160 | <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>, | ||
| 161 | <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>, | ||
| 162 | <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>, | ||
| 163 | <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>, | ||
| 164 | <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>, | ||
| 165 | <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; | ||
| 166 | interrupt-names = | ||
| 167 | "spi_lr_fullness_reached", | ||
| 168 | "spi_lr_session_aborted", | ||
| 169 | "spi_lr_impatient", | ||
| 170 | "spi_lr_session_done", | ||
| 171 | "mspi_done", | ||
| 172 | "mspi_halted"; | ||
| 173 | clocks = <&iprocmed>; | ||
| 174 | clock-names = "iprocmed"; | ||
| 175 | num-cs = <2>; | ||
| 176 | #address-cells = <1>; | ||
| 177 | #size-cells = <0>; | ||
| 178 | }; | ||
| 179 | |||
| 180 | |||
| 181 | NS2 SoC Example: | ||
| 182 | |||
| 183 | qspi: spi@66470200 { | ||
| 184 | compatible = "brcm,spi-bcm-qspi", "brcm,spi-ns2-qspi"; | ||
| 185 | reg = <0x66470200 0x184>, | ||
| 186 | <0x66470000 0x124>, | ||
| 187 | <0x67017408 0x004>, | ||
| 188 | <0x664703a0 0x01c>; | ||
| 189 | reg-names = "mspi", "bspi", "intr_regs", | ||
| 190 | "intr_status_reg"; | ||
| 191 | interrupts = <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>; | ||
| 192 | interrupt-names = "spi_l1_intr"; | ||
| 193 | clocks = <&iprocmed>; | ||
| 194 | clock-names = "iprocmed"; | ||
| 195 | num-cs = <2>; | ||
| 196 | #address-cells = <1>; | ||
| 197 | #size-cells = <0>; | ||
| 198 | }; | ||
| 199 | |||
| 200 | |||
| 201 | m25p80 node for NSP, NS2 | ||
| 202 | |||
| 203 | &qspi { | ||
| 204 | flash: m25p80@0 { | ||
| 205 | #address-cells = <1>; | ||
| 206 | #size-cells = <1>; | ||
| 207 | compatible = "m25p80"; | ||
| 208 | reg = <0x0>; | ||
| 209 | spi-max-frequency = <12500000>; | ||
| 210 | m25p,fast-read; | ||
| 211 | spi-cpol; | ||
| 212 | spi-cpha; | ||
| 213 | |||
| 214 | partition@0 { | ||
| 215 | label = "boot"; | ||
| 216 | reg = <0x00000000 0x000a0000>; | ||
| 217 | }; | ||
| 218 | |||
| 219 | partition@a0000 { | ||
| 220 | label = "env"; | ||
| 221 | reg = <0x000a0000 0x00060000>; | ||
| 222 | }; | ||
| 223 | |||
| 224 | partition@100000 { | ||
| 225 | label = "system"; | ||
| 226 | reg = <0x00100000 0x00600000>; | ||
| 227 | }; | ||
| 228 | |||
| 229 | partition@700000 { | ||
| 230 | label = "rootfs"; | ||
| 231 | reg = <0x00700000 0x01900000>; | ||
| 232 | }; | ||
| 233 | }; | ||
diff --git a/Documentation/devicetree/bindings/spi/jcore,spi.txt b/Documentation/devicetree/bindings/spi/jcore,spi.txt new file mode 100644 index 000000000000..93936d16e139 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/jcore,spi.txt | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | J-Core SPI master | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | |||
| 5 | - compatible: Must be "jcore,spi2". | ||
| 6 | |||
| 7 | - reg: Memory region for registers. | ||
| 8 | |||
| 9 | - #address-cells: Must be 1. | ||
| 10 | |||
| 11 | - #size-cells: Must be 0. | ||
| 12 | |||
| 13 | Optional properties: | ||
| 14 | |||
| 15 | - clocks: If a phandle named "ref_clk" is present, SPI clock speed | ||
| 16 | programming is relative to the frequency of the indicated clock. | ||
| 17 | Necessary only if the input clock rate is something other than a | ||
| 18 | fixed 50 MHz. | ||
| 19 | |||
| 20 | - clock-names: Clock names, one for each phandle in clocks. | ||
| 21 | |||
| 22 | See spi-bus.txt for additional properties not specific to this device. | ||
| 23 | |||
| 24 | Example: | ||
| 25 | |||
| 26 | spi@40 { | ||
| 27 | compatible = "jcore,spi2"; | ||
| 28 | #address-cells = <1>; | ||
| 29 | #size-cells = <0>; | ||
| 30 | reg = <0x40 0x8>; | ||
| 31 | spi-max-frequency = <25000000>; | ||
| 32 | clocks = <&bus_clk>; | ||
| 33 | clock-names = "ref_clk"; | ||
| 34 | } | ||
diff --git a/Documentation/devicetree/bindings/spi/spi-meson.txt b/Documentation/devicetree/bindings/spi/spi-meson.txt index bb52a86f3365..dc6d0313324a 100644 --- a/Documentation/devicetree/bindings/spi/spi-meson.txt +++ b/Documentation/devicetree/bindings/spi/spi-meson.txt | |||
| @@ -7,7 +7,7 @@ NOR memories, without DMA support and a 64-byte unified transmit / | |||
| 7 | receive buffer. | 7 | receive buffer. |
| 8 | 8 | ||
| 9 | Required properties: | 9 | Required properties: |
| 10 | - compatible: should be "amlogic,meson6-spifc" | 10 | - compatible: should be "amlogic,meson6-spifc" or "amlogic,meson-gxbb-spifc" |
| 11 | - reg: physical base address and length of the controller registers | 11 | - reg: physical base address and length of the controller registers |
| 12 | - clocks: phandle of the input clock for the baud rate generator | 12 | - clocks: phandle of the input clock for the baud rate generator |
| 13 | - #address-cells: should be 1 | 13 | - #address-cells: should be 1 |
diff --git a/MAINTAINERS b/MAINTAINERS index 8dfb2b45b403..49a5798f4290 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -11165,6 +11165,7 @@ F: Documentation/spi/ | |||
| 11165 | F: drivers/spi/ | 11165 | F: drivers/spi/ |
| 11166 | F: include/linux/spi/ | 11166 | F: include/linux/spi/ |
| 11167 | F: include/uapi/linux/spi/ | 11167 | F: include/uapi/linux/spi/ |
| 11168 | F: tools/spi/ | ||
| 11168 | 11169 | ||
| 11169 | SPIDERNET NETWORK DRIVER for CELL | 11170 | SPIDERNET NETWORK DRIVER for CELL |
| 11170 | M: Ishizaki Kou <kou.ishizaki@toshiba.co.jp> | 11171 | M: Ishizaki Kou <kou.ishizaki@toshiba.co.jp> |
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index d6fb8d4b7786..b7995474148c 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
| @@ -153,6 +153,16 @@ config SPI_BCM63XX_HSSPI | |||
| 153 | This enables support for the High Speed SPI controller present on | 153 | This enables support for the High Speed SPI controller present on |
| 154 | newer Broadcom BCM63XX SoCs. | 154 | newer Broadcom BCM63XX SoCs. |
| 155 | 155 | ||
| 156 | config SPI_BCM_QSPI | ||
| 157 | tristate "Broadcom BSPI and MSPI controller support" | ||
| 158 | depends on ARCH_BRCMSTB || ARCH_BCM || ARCH_BCM_IPROC || COMPILE_TEST | ||
| 159 | default ARCH_BCM_IPROC | ||
| 160 | help | ||
| 161 | Enables support for the Broadcom SPI flash and MSPI controller. | ||
| 162 | Select this option for any one of BRCMSTB, iProc NSP and NS2 SoCs | ||
| 163 | based platforms. This driver works for both SPI master for spi-nor | ||
| 164 | flash device as well as MSPI device. | ||
| 165 | |||
| 156 | config SPI_BITBANG | 166 | config SPI_BITBANG |
| 157 | tristate "Utilities for Bitbanging SPI masters" | 167 | tristate "Utilities for Bitbanging SPI masters" |
| 158 | help | 168 | help |
| @@ -285,6 +295,13 @@ config SPI_IMX | |||
| 285 | This enables using the Freescale i.MX SPI controllers in master | 295 | This enables using the Freescale i.MX SPI controllers in master |
| 286 | mode. | 296 | mode. |
| 287 | 297 | ||
| 298 | config SPI_JCORE | ||
| 299 | tristate "J-Core SPI Master" | ||
| 300 | depends on OF && (SUPERH || COMPILE_TEST) | ||
| 301 | help | ||
| 302 | This enables support for the SPI master controller in the J-Core | ||
| 303 | synthesizable, open source SoC. | ||
| 304 | |||
| 288 | config SPI_LM70_LLP | 305 | config SPI_LM70_LLP |
| 289 | tristate "Parallel port adapter for LM70 eval board (DEVELOPMENT)" | 306 | tristate "Parallel port adapter for LM70 eval board (DEVELOPMENT)" |
| 290 | depends on PARPORT | 307 | depends on PARPORT |
| @@ -549,7 +566,7 @@ config SPI_SC18IS602 | |||
| 549 | config SPI_SH_MSIOF | 566 | config SPI_SH_MSIOF |
| 550 | tristate "SuperH MSIOF SPI controller" | 567 | tristate "SuperH MSIOF SPI controller" |
| 551 | depends on HAVE_CLK && HAS_DMA | 568 | depends on HAVE_CLK && HAS_DMA |
| 552 | depends on SUPERH || ARCH_RENESAS || COMPILE_TEST | 569 | depends on ARCH_SHMOBILE || ARCH_RENESAS || COMPILE_TEST |
| 553 | help | 570 | help |
| 554 | SPI driver for SuperH and SH Mobile MSIOF blocks. | 571 | SPI driver for SuperH and SH Mobile MSIOF blocks. |
| 555 | 572 | ||
| @@ -631,6 +648,13 @@ config SPI_TEGRA20_SLINK | |||
| 631 | help | 648 | help |
| 632 | SPI driver for Nvidia Tegra20/Tegra30 SLINK Controller interface. | 649 | SPI driver for Nvidia Tegra20/Tegra30 SLINK Controller interface. |
| 633 | 650 | ||
| 651 | config SPI_THUNDERX | ||
| 652 | tristate "Cavium ThunderX SPI controller" | ||
| 653 | depends on PCI && 64BIT && (ARM64 || COMPILE_TEST) | ||
| 654 | help | ||
| 655 | SPI host driver for the hardware found on Cavium ThunderX | ||
| 656 | SOCs. | ||
| 657 | |||
| 634 | config SPI_TOPCLIFF_PCH | 658 | config SPI_TOPCLIFF_PCH |
| 635 | tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) SPI" | 659 | tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) SPI" |
| 636 | depends on PCI && (X86_32 || MIPS || COMPILE_TEST) | 660 | depends on PCI && (X86_32 || MIPS || COMPILE_TEST) |
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 185367ef6576..aa939d955521 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile | |||
| @@ -21,6 +21,7 @@ obj-$(CONFIG_SPI_BCM2835AUX) += spi-bcm2835aux.o | |||
| 21 | obj-$(CONFIG_SPI_BCM53XX) += spi-bcm53xx.o | 21 | obj-$(CONFIG_SPI_BCM53XX) += spi-bcm53xx.o |
| 22 | obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o | 22 | obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o |
| 23 | obj-$(CONFIG_SPI_BCM63XX_HSSPI) += spi-bcm63xx-hsspi.o | 23 | obj-$(CONFIG_SPI_BCM63XX_HSSPI) += spi-bcm63xx-hsspi.o |
| 24 | obj-$(CONFIG_SPI_BCM_QSPI) += spi-iproc-qspi.o spi-brcmstb-qspi.o spi-bcm-qspi.o | ||
| 24 | obj-$(CONFIG_SPI_BFIN5XX) += spi-bfin5xx.o | 25 | obj-$(CONFIG_SPI_BFIN5XX) += spi-bfin5xx.o |
| 25 | obj-$(CONFIG_SPI_ADI_V3) += spi-adi-v3.o | 26 | obj-$(CONFIG_SPI_ADI_V3) += spi-adi-v3.o |
| 26 | obj-$(CONFIG_SPI_BFIN_SPORT) += spi-bfin-sport.o | 27 | obj-$(CONFIG_SPI_BFIN_SPORT) += spi-bfin-sport.o |
| @@ -46,6 +47,7 @@ obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o | |||
| 46 | obj-$(CONFIG_SPI_GPIO) += spi-gpio.o | 47 | obj-$(CONFIG_SPI_GPIO) += spi-gpio.o |
| 47 | obj-$(CONFIG_SPI_IMG_SPFI) += spi-img-spfi.o | 48 | obj-$(CONFIG_SPI_IMG_SPFI) += spi-img-spfi.o |
| 48 | obj-$(CONFIG_SPI_IMX) += spi-imx.o | 49 | obj-$(CONFIG_SPI_IMX) += spi-imx.o |
| 50 | obj-$(CONFIG_SPI_JCORE) += spi-jcore.o | ||
| 49 | obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o | 51 | obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o |
| 50 | obj-$(CONFIG_SPI_LP8841_RTC) += spi-lp8841-rtc.o | 52 | obj-$(CONFIG_SPI_LP8841_RTC) += spi-lp8841-rtc.o |
| 51 | obj-$(CONFIG_SPI_MESON_SPIFC) += spi-meson-spifc.o | 53 | obj-$(CONFIG_SPI_MESON_SPIFC) += spi-meson-spifc.o |
| @@ -91,6 +93,8 @@ obj-$(CONFIG_SPI_TEGRA114) += spi-tegra114.o | |||
| 91 | obj-$(CONFIG_SPI_TEGRA20_SFLASH) += spi-tegra20-sflash.o | 93 | obj-$(CONFIG_SPI_TEGRA20_SFLASH) += spi-tegra20-sflash.o |
| 92 | obj-$(CONFIG_SPI_TEGRA20_SLINK) += spi-tegra20-slink.o | 94 | obj-$(CONFIG_SPI_TEGRA20_SLINK) += spi-tegra20-slink.o |
| 93 | obj-$(CONFIG_SPI_TLE62X0) += spi-tle62x0.o | 95 | obj-$(CONFIG_SPI_TLE62X0) += spi-tle62x0.o |
| 96 | spi-thunderx-objs := spi-cavium.o spi-cavium-thunderx.o | ||
| 97 | obj-$(CONFIG_SPI_THUNDERX) += spi-thunderx.o | ||
| 94 | obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi-topcliff-pch.o | 98 | obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi-topcliff-pch.o |
| 95 | obj-$(CONFIG_SPI_TXX9) += spi-txx9.o | 99 | obj-$(CONFIG_SPI_TXX9) += spi-txx9.o |
| 96 | obj-$(CONFIG_SPI_XCOMM) += spi-xcomm.o | 100 | obj-$(CONFIG_SPI_XCOMM) += spi-xcomm.o |
diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c new file mode 100644 index 000000000000..14f9dea3173f --- /dev/null +++ b/drivers/spi/spi-bcm-qspi.c | |||
| @@ -0,0 +1,1397 @@ | |||
| 1 | /* | ||
| 2 | * Driver for Broadcom BRCMSTB, NSP, NS2, Cygnus SPI Controllers | ||
| 3 | * | ||
| 4 | * Copyright 2016 Broadcom | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License, version 2, as | ||
| 8 | * published by the Free Software Foundation (the "GPL"). | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, but | ||
| 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | * General Public License version 2 (GPLv2) for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * version 2 (GPLv2) along with this source code. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/clk.h> | ||
| 20 | #include <linux/delay.h> | ||
| 21 | #include <linux/device.h> | ||
| 22 | #include <linux/init.h> | ||
| 23 | #include <linux/interrupt.h> | ||
| 24 | #include <linux/io.h> | ||
| 25 | #include <linux/ioport.h> | ||
| 26 | #include <linux/kernel.h> | ||
| 27 | #include <linux/module.h> | ||
| 28 | #include <linux/mtd/spi-nor.h> | ||
| 29 | #include <linux/of.h> | ||
| 30 | #include <linux/of_irq.h> | ||
| 31 | #include <linux/platform_device.h> | ||
| 32 | #include <linux/slab.h> | ||
| 33 | #include <linux/spi/spi.h> | ||
| 34 | #include <linux/sysfs.h> | ||
| 35 | #include <linux/types.h> | ||
| 36 | #include "spi-bcm-qspi.h" | ||
| 37 | |||
| 38 | #define DRIVER_NAME "bcm_qspi" | ||
| 39 | |||
| 40 | |||
| 41 | /* BSPI register offsets */ | ||
| 42 | #define BSPI_REVISION_ID 0x000 | ||
| 43 | #define BSPI_SCRATCH 0x004 | ||
| 44 | #define BSPI_MAST_N_BOOT_CTRL 0x008 | ||
| 45 | #define BSPI_BUSY_STATUS 0x00c | ||
| 46 | #define BSPI_INTR_STATUS 0x010 | ||
| 47 | #define BSPI_B0_STATUS 0x014 | ||
| 48 | #define BSPI_B0_CTRL 0x018 | ||
| 49 | #define BSPI_B1_STATUS 0x01c | ||
| 50 | #define BSPI_B1_CTRL 0x020 | ||
| 51 | #define BSPI_STRAP_OVERRIDE_CTRL 0x024 | ||
| 52 | #define BSPI_FLEX_MODE_ENABLE 0x028 | ||
| 53 | #define BSPI_BITS_PER_CYCLE 0x02c | ||
| 54 | #define BSPI_BITS_PER_PHASE 0x030 | ||
| 55 | #define BSPI_CMD_AND_MODE_BYTE 0x034 | ||
| 56 | #define BSPI_BSPI_FLASH_UPPER_ADDR_BYTE 0x038 | ||
| 57 | #define BSPI_BSPI_XOR_VALUE 0x03c | ||
| 58 | #define BSPI_BSPI_XOR_ENABLE 0x040 | ||
| 59 | #define BSPI_BSPI_PIO_MODE_ENABLE 0x044 | ||
| 60 | #define BSPI_BSPI_PIO_IODIR 0x048 | ||
| 61 | #define BSPI_BSPI_PIO_DATA 0x04c | ||
| 62 | |||
| 63 | /* RAF register offsets */ | ||
| 64 | #define BSPI_RAF_START_ADDR 0x100 | ||
| 65 | #define BSPI_RAF_NUM_WORDS 0x104 | ||
| 66 | #define BSPI_RAF_CTRL 0x108 | ||
| 67 | #define BSPI_RAF_FULLNESS 0x10c | ||
| 68 | #define BSPI_RAF_WATERMARK 0x110 | ||
| 69 | #define BSPI_RAF_STATUS 0x114 | ||
| 70 | #define BSPI_RAF_READ_DATA 0x118 | ||
| 71 | #define BSPI_RAF_WORD_CNT 0x11c | ||
| 72 | #define BSPI_RAF_CURR_ADDR 0x120 | ||
| 73 | |||
| 74 | /* Override mode masks */ | ||
| 75 | #define BSPI_STRAP_OVERRIDE_CTRL_OVERRIDE BIT(0) | ||
| 76 | #define BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL BIT(1) | ||
| 77 | #define BSPI_STRAP_OVERRIDE_CTRL_ADDR_4BYTE BIT(2) | ||
| 78 | #define BSPI_STRAP_OVERRIDE_CTRL_DATA_QUAD BIT(3) | ||
| 79 | #define BSPI_STRAP_OVERRIDE_CTRL_ENDAIN_MODE BIT(4) | ||
| 80 | |||
| 81 | #define BSPI_ADDRLEN_3BYTES 3 | ||
| 82 | #define BSPI_ADDRLEN_4BYTES 4 | ||
| 83 | |||
| 84 | #define BSPI_RAF_STATUS_FIFO_EMPTY_MASK BIT(1) | ||
| 85 | |||
| 86 | #define BSPI_RAF_CTRL_START_MASK BIT(0) | ||
| 87 | #define BSPI_RAF_CTRL_CLEAR_MASK BIT(1) | ||
| 88 | |||
| 89 | #define BSPI_BPP_MODE_SELECT_MASK BIT(8) | ||
| 90 | #define BSPI_BPP_ADDR_SELECT_MASK BIT(16) | ||
| 91 | |||
| 92 | #define BSPI_READ_LENGTH 256 | ||
| 93 | |||
| 94 | /* MSPI register offsets */ | ||
| 95 | #define MSPI_SPCR0_LSB 0x000 | ||
| 96 | #define MSPI_SPCR0_MSB 0x004 | ||
| 97 | #define MSPI_SPCR1_LSB 0x008 | ||
| 98 | #define MSPI_SPCR1_MSB 0x00c | ||
| 99 | #define MSPI_NEWQP 0x010 | ||
| 100 | #define MSPI_ENDQP 0x014 | ||
| 101 | #define MSPI_SPCR2 0x018 | ||
| 102 | #define MSPI_MSPI_STATUS 0x020 | ||
| 103 | #define MSPI_CPTQP 0x024 | ||
| 104 | #define MSPI_SPCR3 0x028 | ||
| 105 | #define MSPI_TXRAM 0x040 | ||
| 106 | #define MSPI_RXRAM 0x0c0 | ||
| 107 | #define MSPI_CDRAM 0x140 | ||
| 108 | #define MSPI_WRITE_LOCK 0x180 | ||
| 109 | |||
| 110 | #define MSPI_MASTER_BIT BIT(7) | ||
| 111 | |||
| 112 | #define MSPI_NUM_CDRAM 16 | ||
| 113 | #define MSPI_CDRAM_CONT_BIT BIT(7) | ||
| 114 | #define MSPI_CDRAM_BITSE_BIT BIT(6) | ||
| 115 | #define MSPI_CDRAM_PCS 0xf | ||
| 116 | |||
| 117 | #define MSPI_SPCR2_SPE BIT(6) | ||
| 118 | #define MSPI_SPCR2_CONT_AFTER_CMD BIT(7) | ||
| 119 | |||
| 120 | #define MSPI_MSPI_STATUS_SPIF BIT(0) | ||
| 121 | |||
| 122 | #define INTR_BASE_BIT_SHIFT 0x02 | ||
| 123 | #define INTR_COUNT 0x07 | ||
| 124 | |||
| 125 | #define NUM_CHIPSELECT 4 | ||
| 126 | #define QSPI_SPBR_MIN 8U | ||
| 127 | #define QSPI_SPBR_MAX 255U | ||
| 128 | |||
| 129 | #define OPCODE_DIOR 0xBB | ||
| 130 | #define OPCODE_QIOR 0xEB | ||
| 131 | #define OPCODE_DIOR_4B 0xBC | ||
| 132 | #define OPCODE_QIOR_4B 0xEC | ||
| 133 | |||
| 134 | #define MAX_CMD_SIZE 6 | ||
| 135 | |||
| 136 | #define ADDR_4MB_MASK GENMASK(22, 0) | ||
| 137 | |||
| 138 | /* stop at end of transfer, no other reason */ | ||
| 139 | #define TRANS_STATUS_BREAK_NONE 0 | ||
| 140 | /* stop at end of spi_message */ | ||
| 141 | #define TRANS_STATUS_BREAK_EOM 1 | ||
| 142 | /* stop at end of spi_transfer if delay */ | ||
| 143 | #define TRANS_STATUS_BREAK_DELAY 2 | ||
| 144 | /* stop at end of spi_transfer if cs_change */ | ||
| 145 | #define TRANS_STATUS_BREAK_CS_CHANGE 4 | ||
| 146 | /* stop if we run out of bytes */ | ||
| 147 | #define TRANS_STATUS_BREAK_NO_BYTES 8 | ||
| 148 | |||
| 149 | /* events that make us stop filling TX slots */ | ||
| 150 | #define TRANS_STATUS_BREAK_TX (TRANS_STATUS_BREAK_EOM | \ | ||
| 151 | TRANS_STATUS_BREAK_DELAY | \ | ||
| 152 | TRANS_STATUS_BREAK_CS_CHANGE) | ||
| 153 | |||
| 154 | /* events that make us deassert CS */ | ||
| 155 | #define TRANS_STATUS_BREAK_DESELECT (TRANS_STATUS_BREAK_EOM | \ | ||
| 156 | TRANS_STATUS_BREAK_CS_CHANGE) | ||
| 157 | |||
| 158 | struct bcm_qspi_parms { | ||
| 159 | u32 speed_hz; | ||
| 160 | u8 mode; | ||
| 161 | u8 bits_per_word; | ||
| 162 | }; | ||
| 163 | |||
| 164 | struct bcm_xfer_mode { | ||
| 165 | bool flex_mode; | ||
| 166 | unsigned int width; | ||
| 167 | unsigned int addrlen; | ||
| 168 | unsigned int hp; | ||
| 169 | }; | ||
| 170 | |||
| 171 | enum base_type { | ||
| 172 | MSPI, | ||
| 173 | BSPI, | ||
| 174 | CHIP_SELECT, | ||
| 175 | BASEMAX, | ||
| 176 | }; | ||
| 177 | |||
| 178 | enum irq_source { | ||
| 179 | SINGLE_L2, | ||
| 180 | MUXED_L1, | ||
| 181 | }; | ||
| 182 | |||
| 183 | struct bcm_qspi_irq { | ||
| 184 | const char *irq_name; | ||
| 185 | const irq_handler_t irq_handler; | ||
| 186 | int irq_source; | ||
| 187 | u32 mask; | ||
| 188 | }; | ||
| 189 | |||
| 190 | struct bcm_qspi_dev_id { | ||
| 191 | const struct bcm_qspi_irq *irqp; | ||
| 192 | void *dev; | ||
| 193 | }; | ||
| 194 | |||
| 195 | struct qspi_trans { | ||
| 196 | struct spi_transfer *trans; | ||
| 197 | int byte; | ||
| 198 | }; | ||
| 199 | |||
| 200 | struct bcm_qspi { | ||
| 201 | struct platform_device *pdev; | ||
| 202 | struct spi_master *master; | ||
| 203 | struct clk *clk; | ||
| 204 | u32 base_clk; | ||
| 205 | u32 max_speed_hz; | ||
| 206 | void __iomem *base[BASEMAX]; | ||
| 207 | |||
| 208 | /* Some SoCs provide custom interrupt status register(s) */ | ||
| 209 | struct bcm_qspi_soc_intc *soc_intc; | ||
| 210 | |||
| 211 | struct bcm_qspi_parms last_parms; | ||
| 212 | struct qspi_trans trans_pos; | ||
| 213 | int curr_cs; | ||
| 214 | int bspi_maj_rev; | ||
| 215 | int bspi_min_rev; | ||
| 216 | int bspi_enabled; | ||
| 217 | struct spi_flash_read_message *bspi_rf_msg; | ||
| 218 | u32 bspi_rf_msg_idx; | ||
| 219 | u32 bspi_rf_msg_len; | ||
| 220 | u32 bspi_rf_msg_status; | ||
| 221 | struct bcm_xfer_mode xfer_mode; | ||
| 222 | u32 s3_strap_override_ctrl; | ||
| 223 | bool bspi_mode; | ||
| 224 | bool big_endian; | ||
| 225 | int num_irqs; | ||
| 226 | struct bcm_qspi_dev_id *dev_ids; | ||
| 227 | struct completion mspi_done; | ||
| 228 | struct completion bspi_done; | ||
| 229 | }; | ||
| 230 | |||
| 231 | static inline bool has_bspi(struct bcm_qspi *qspi) | ||
| 232 | { | ||
| 233 | return qspi->bspi_mode; | ||
| 234 | } | ||
| 235 | |||
| 236 | /* Read qspi controller register*/ | ||
| 237 | static inline u32 bcm_qspi_read(struct bcm_qspi *qspi, enum base_type type, | ||
| 238 | unsigned int offset) | ||
| 239 | { | ||
| 240 | return bcm_qspi_readl(qspi->big_endian, qspi->base[type] + offset); | ||
| 241 | } | ||
| 242 | |||
| 243 | /* Write qspi controller register*/ | ||
| 244 | static inline void bcm_qspi_write(struct bcm_qspi *qspi, enum base_type type, | ||
| 245 | unsigned int offset, unsigned int data) | ||
| 246 | { | ||
| 247 | bcm_qspi_writel(qspi->big_endian, data, qspi->base[type] + offset); | ||
| 248 | } | ||
| 249 | |||
| 250 | /* BSPI helpers */ | ||
| 251 | static int bcm_qspi_bspi_busy_poll(struct bcm_qspi *qspi) | ||
| 252 | { | ||
| 253 | int i; | ||
| 254 | |||
| 255 | /* this should normally finish within 10us */ | ||
| 256 | for (i = 0; i < 1000; i++) { | ||
| 257 | if (!(bcm_qspi_read(qspi, BSPI, BSPI_BUSY_STATUS) & 1)) | ||
| 258 | return 0; | ||
| 259 | udelay(1); | ||
| 260 | } | ||
| 261 | dev_warn(&qspi->pdev->dev, "timeout waiting for !busy_status\n"); | ||
| 262 | return -EIO; | ||
| 263 | } | ||
| 264 | |||
| 265 | static inline bool bcm_qspi_bspi_ver_three(struct bcm_qspi *qspi) | ||
| 266 | { | ||
| 267 | if (qspi->bspi_maj_rev < 4) | ||
| 268 | return true; | ||
| 269 | return false; | ||
| 270 | } | ||
| 271 | |||
| 272 | static void bcm_qspi_bspi_flush_prefetch_buffers(struct bcm_qspi *qspi) | ||
| 273 | { | ||
| 274 | bcm_qspi_bspi_busy_poll(qspi); | ||
| 275 | /* Force rising edge for the b0/b1 'flush' field */ | ||
| 276 | bcm_qspi_write(qspi, BSPI, BSPI_B0_CTRL, 1); | ||
| 277 | bcm_qspi_write(qspi, BSPI, BSPI_B1_CTRL, 1); | ||
| 278 | bcm_qspi_write(qspi, BSPI, BSPI_B0_CTRL, 0); | ||
| 279 | bcm_qspi_write(qspi, BSPI, BSPI_B1_CTRL, 0); | ||
| 280 | } | ||
| 281 | |||
| 282 | static int bcm_qspi_bspi_lr_is_fifo_empty(struct bcm_qspi *qspi) | ||
| 283 | { | ||
| 284 | return (bcm_qspi_read(qspi, BSPI, BSPI_RAF_STATUS) & | ||
| 285 | BSPI_RAF_STATUS_FIFO_EMPTY_MASK); | ||
| 286 | } | ||
| 287 | |||
| 288 | static inline u32 bcm_qspi_bspi_lr_read_fifo(struct bcm_qspi *qspi) | ||
| 289 | { | ||
| 290 | u32 data = bcm_qspi_read(qspi, BSPI, BSPI_RAF_READ_DATA); | ||
| 291 | |||
| 292 | /* BSPI v3 LR is LE only, convert data to host endianness */ | ||
| 293 | if (bcm_qspi_bspi_ver_three(qspi)) | ||
| 294 | data = le32_to_cpu(data); | ||
| 295 | |||
| 296 | return data; | ||
| 297 | } | ||
| 298 | |||
| 299 | static inline void bcm_qspi_bspi_lr_start(struct bcm_qspi *qspi) | ||
| 300 | { | ||
| 301 | bcm_qspi_bspi_busy_poll(qspi); | ||
| 302 | bcm_qspi_write(qspi, BSPI, BSPI_RAF_CTRL, | ||
| 303 | BSPI_RAF_CTRL_START_MASK); | ||
| 304 | } | ||
| 305 | |||
| 306 | static inline void bcm_qspi_bspi_lr_clear(struct bcm_qspi *qspi) | ||
| 307 | { | ||
| 308 | bcm_qspi_write(qspi, BSPI, BSPI_RAF_CTRL, | ||
| 309 | BSPI_RAF_CTRL_CLEAR_MASK); | ||
| 310 | bcm_qspi_bspi_flush_prefetch_buffers(qspi); | ||
| 311 | } | ||
| 312 | |||
| 313 | static void bcm_qspi_bspi_lr_data_read(struct bcm_qspi *qspi) | ||
| 314 | { | ||
| 315 | u32 *buf = (u32 *)qspi->bspi_rf_msg->buf; | ||
| 316 | u32 data = 0; | ||
| 317 | |||
| 318 | dev_dbg(&qspi->pdev->dev, "xfer %p rx %p rxlen %d\n", qspi->bspi_rf_msg, | ||
| 319 | qspi->bspi_rf_msg->buf, qspi->bspi_rf_msg_len); | ||
| 320 | while (!bcm_qspi_bspi_lr_is_fifo_empty(qspi)) { | ||
| 321 | data = bcm_qspi_bspi_lr_read_fifo(qspi); | ||
| 322 | if (likely(qspi->bspi_rf_msg_len >= 4) && | ||
| 323 | IS_ALIGNED((uintptr_t)buf, 4)) { | ||
| 324 | buf[qspi->bspi_rf_msg_idx++] = data; | ||
| 325 | qspi->bspi_rf_msg_len -= 4; | ||
| 326 | } else { | ||
| 327 | /* Read out remaining bytes, make sure*/ | ||
| 328 | u8 *cbuf = (u8 *)&buf[qspi->bspi_rf_msg_idx]; | ||
| 329 | |||
| 330 | data = cpu_to_le32(data); | ||
| 331 | while (qspi->bspi_rf_msg_len) { | ||
| 332 | *cbuf++ = (u8)data; | ||
| 333 | data >>= 8; | ||
| 334 | qspi->bspi_rf_msg_len--; | ||
| 335 | } | ||
| 336 | } | ||
| 337 | } | ||
| 338 | } | ||
| 339 | |||
| 340 | static void bcm_qspi_bspi_set_xfer_params(struct bcm_qspi *qspi, u8 cmd_byte, | ||
| 341 | int bpp, int bpc, int flex_mode) | ||
| 342 | { | ||
| 343 | bcm_qspi_write(qspi, BSPI, BSPI_FLEX_MODE_ENABLE, 0); | ||
| 344 | bcm_qspi_write(qspi, BSPI, BSPI_BITS_PER_CYCLE, bpc); | ||
| 345 | bcm_qspi_write(qspi, BSPI, BSPI_BITS_PER_PHASE, bpp); | ||
| 346 | bcm_qspi_write(qspi, BSPI, BSPI_CMD_AND_MODE_BYTE, cmd_byte); | ||
| 347 | bcm_qspi_write(qspi, BSPI, BSPI_FLEX_MODE_ENABLE, flex_mode); | ||
| 348 | } | ||
| 349 | |||
| 350 | static int bcm_qspi_bspi_set_flex_mode(struct bcm_qspi *qspi, int width, | ||
| 351 | int addrlen, int hp) | ||
| 352 | { | ||
| 353 | int bpc = 0, bpp = 0; | ||
| 354 | u8 command = SPINOR_OP_READ_FAST; | ||
| 355 | int flex_mode = 1, rv = 0; | ||
| 356 | bool spans_4byte = false; | ||
| 357 | |||
| 358 | dev_dbg(&qspi->pdev->dev, "set flex mode w %x addrlen %x hp %d\n", | ||
| 359 | width, addrlen, hp); | ||
| 360 | |||
| 361 | if (addrlen == BSPI_ADDRLEN_4BYTES) { | ||
| 362 | bpp = BSPI_BPP_ADDR_SELECT_MASK; | ||
| 363 | spans_4byte = true; | ||
| 364 | } | ||
| 365 | |||
| 366 | bpp |= 8; | ||
| 367 | |||
| 368 | switch (width) { | ||
| 369 | case SPI_NBITS_SINGLE: | ||
| 370 | if (addrlen == BSPI_ADDRLEN_3BYTES) | ||
| 371 | /* default mode, does not need flex_cmd */ | ||
| 372 | flex_mode = 0; | ||
| 373 | else | ||
| 374 | command = SPINOR_OP_READ4_FAST; | ||
| 375 | break; | ||
| 376 | case SPI_NBITS_DUAL: | ||
| 377 | bpc = 0x00000001; | ||
| 378 | if (hp) { | ||
| 379 | bpc |= 0x00010100; /* address and mode are 2-bit */ | ||
| 380 | bpp = BSPI_BPP_MODE_SELECT_MASK; | ||
| 381 | command = OPCODE_DIOR; | ||
| 382 | if (spans_4byte) | ||
| 383 | command = OPCODE_DIOR_4B; | ||
| 384 | } else { | ||
| 385 | command = SPINOR_OP_READ_1_1_2; | ||
| 386 | if (spans_4byte) | ||
| 387 | command = SPINOR_OP_READ4_1_1_2; | ||
| 388 | } | ||
| 389 | break; | ||
| 390 | case SPI_NBITS_QUAD: | ||
| 391 | bpc = 0x00000002; | ||
| 392 | if (hp) { | ||
| 393 | bpc |= 0x00020200; /* address and mode are 4-bit */ | ||
| 394 | bpp = 4; /* dummy cycles */ | ||
| 395 | bpp |= BSPI_BPP_ADDR_SELECT_MASK; | ||
| 396 | command = OPCODE_QIOR; | ||
| 397 | if (spans_4byte) | ||
| 398 | command = OPCODE_QIOR_4B; | ||
| 399 | } else { | ||
| 400 | command = SPINOR_OP_READ_1_1_4; | ||
| 401 | if (spans_4byte) | ||
| 402 | command = SPINOR_OP_READ4_1_1_4; | ||
| 403 | } | ||
| 404 | break; | ||
| 405 | default: | ||
| 406 | rv = -EINVAL; | ||
| 407 | break; | ||
| 408 | } | ||
| 409 | |||
| 410 | if (rv == 0) | ||
| 411 | bcm_qspi_bspi_set_xfer_params(qspi, command, bpp, bpc, | ||
| 412 | flex_mode); | ||
| 413 | |||
| 414 | return rv; | ||
| 415 | } | ||
| 416 | |||
| 417 | static int bcm_qspi_bspi_set_override(struct bcm_qspi *qspi, int width, | ||
| 418 | int addrlen, int hp) | ||
| 419 | { | ||
| 420 | u32 data = bcm_qspi_read(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL); | ||
| 421 | |||
| 422 | dev_dbg(&qspi->pdev->dev, "set override mode w %x addrlen %x hp %d\n", | ||
| 423 | width, addrlen, hp); | ||
| 424 | |||
| 425 | switch (width) { | ||
| 426 | case SPI_NBITS_SINGLE: | ||
| 427 | /* clear quad/dual mode */ | ||
| 428 | data &= ~(BSPI_STRAP_OVERRIDE_CTRL_DATA_QUAD | | ||
| 429 | BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL); | ||
| 430 | break; | ||
| 431 | |||
| 432 | case SPI_NBITS_QUAD: | ||
| 433 | /* clear dual mode and set quad mode */ | ||
| 434 | data &= ~BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL; | ||
| 435 | data |= BSPI_STRAP_OVERRIDE_CTRL_DATA_QUAD; | ||
| 436 | break; | ||
| 437 | case SPI_NBITS_DUAL: | ||
| 438 | /* clear quad mode set dual mode */ | ||
| 439 | data &= ~BSPI_STRAP_OVERRIDE_CTRL_DATA_QUAD; | ||
| 440 | data |= BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL; | ||
| 441 | break; | ||
| 442 | default: | ||
| 443 | return -EINVAL; | ||
| 444 | } | ||
| 445 | |||
| 446 | if (addrlen == BSPI_ADDRLEN_4BYTES) | ||
| 447 | /* set 4byte mode*/ | ||
| 448 | data |= BSPI_STRAP_OVERRIDE_CTRL_ADDR_4BYTE; | ||
| 449 | else | ||
| 450 | /* clear 4 byte mode */ | ||
| 451 | data &= ~BSPI_STRAP_OVERRIDE_CTRL_ADDR_4BYTE; | ||
| 452 | |||
| 453 | /* set the override mode */ | ||
| 454 | data |= BSPI_STRAP_OVERRIDE_CTRL_OVERRIDE; | ||
| 455 | bcm_qspi_write(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL, data); | ||
| 456 | bcm_qspi_bspi_set_xfer_params(qspi, SPINOR_OP_READ_FAST, 0, 0, 0); | ||
| 457 | |||
| 458 | return 0; | ||
| 459 | } | ||
| 460 | |||
| 461 | static int bcm_qspi_bspi_set_mode(struct bcm_qspi *qspi, | ||
| 462 | int width, int addrlen, int hp) | ||
| 463 | { | ||
| 464 | int error = 0; | ||
| 465 | |||
| 466 | /* default mode */ | ||
| 467 | qspi->xfer_mode.flex_mode = true; | ||
| 468 | |||
| 469 | if (!bcm_qspi_bspi_ver_three(qspi)) { | ||
| 470 | u32 val, mask; | ||
| 471 | |||
| 472 | val = bcm_qspi_read(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL); | ||
| 473 | mask = BSPI_STRAP_OVERRIDE_CTRL_OVERRIDE; | ||
| 474 | if (val & mask || qspi->s3_strap_override_ctrl & mask) { | ||
| 475 | qspi->xfer_mode.flex_mode = false; | ||
| 476 | bcm_qspi_write(qspi, BSPI, BSPI_FLEX_MODE_ENABLE, | ||
| 477 | 0); | ||
| 478 | |||
| 479 | if ((val | qspi->s3_strap_override_ctrl) & | ||
| 480 | BSPI_STRAP_OVERRIDE_CTRL_DATA_DUAL) | ||
| 481 | width = SPI_NBITS_DUAL; | ||
| 482 | else if ((val | qspi->s3_strap_override_ctrl) & | ||
| 483 | BSPI_STRAP_OVERRIDE_CTRL_DATA_QUAD) | ||
| 484 | width = SPI_NBITS_QUAD; | ||
| 485 | |||
| 486 | error = bcm_qspi_bspi_set_override(qspi, width, addrlen, | ||
| 487 | hp); | ||
| 488 | } | ||
| 489 | } | ||
| 490 | |||
| 491 | if (qspi->xfer_mode.flex_mode) | ||
| 492 | error = bcm_qspi_bspi_set_flex_mode(qspi, width, addrlen, hp); | ||
| 493 | |||
| 494 | if (error) { | ||
| 495 | dev_warn(&qspi->pdev->dev, | ||
| 496 | "INVALID COMBINATION: width=%d addrlen=%d hp=%d\n", | ||
| 497 | width, addrlen, hp); | ||
| 498 | } else if (qspi->xfer_mode.width != width || | ||
| 499 | qspi->xfer_mode.addrlen != addrlen || | ||
| 500 | qspi->xfer_mode.hp != hp) { | ||
| 501 | qspi->xfer_mode.width = width; | ||
| 502 | qspi->xfer_mode.addrlen = addrlen; | ||
| 503 | qspi->xfer_mode.hp = hp; | ||
| 504 | dev_dbg(&qspi->pdev->dev, | ||
| 505 | "cs:%d %d-lane output, %d-byte address%s\n", | ||
| 506 | qspi->curr_cs, | ||
| 507 | qspi->xfer_mode.width, | ||
| 508 | qspi->xfer_mode.addrlen, | ||
| 509 | qspi->xfer_mode.hp != -1 ? ", hp mode" : ""); | ||
| 510 | } | ||
| 511 | |||
| 512 | return error; | ||
| 513 | } | ||
| 514 | |||
| 515 | static void bcm_qspi_enable_bspi(struct bcm_qspi *qspi) | ||
| 516 | { | ||
| 517 | if (!has_bspi(qspi) || (qspi->bspi_enabled)) | ||
| 518 | return; | ||
| 519 | |||
| 520 | qspi->bspi_enabled = 1; | ||
| 521 | if ((bcm_qspi_read(qspi, BSPI, BSPI_MAST_N_BOOT_CTRL) & 1) == 0) | ||
| 522 | return; | ||
| 523 | |||
| 524 | bcm_qspi_bspi_flush_prefetch_buffers(qspi); | ||
| 525 | udelay(1); | ||
| 526 | bcm_qspi_write(qspi, BSPI, BSPI_MAST_N_BOOT_CTRL, 0); | ||
| 527 | udelay(1); | ||
| 528 | } | ||
| 529 | |||
| 530 | static void bcm_qspi_disable_bspi(struct bcm_qspi *qspi) | ||
| 531 | { | ||
| 532 | if (!has_bspi(qspi) || (!qspi->bspi_enabled)) | ||
| 533 | return; | ||
| 534 | |||
| 535 | qspi->bspi_enabled = 0; | ||
| 536 | if ((bcm_qspi_read(qspi, BSPI, BSPI_MAST_N_BOOT_CTRL) & 1)) | ||
| 537 | return; | ||
| 538 | |||
| 539 | bcm_qspi_bspi_busy_poll(qspi); | ||
| 540 | bcm_qspi_write(qspi, BSPI, BSPI_MAST_N_BOOT_CTRL, 1); | ||
| 541 | udelay(1); | ||
| 542 | } | ||
| 543 | |||
| 544 | static void bcm_qspi_chip_select(struct bcm_qspi *qspi, int cs) | ||
| 545 | { | ||
| 546 | u32 data = 0; | ||
| 547 | |||
| 548 | if (qspi->curr_cs == cs) | ||
| 549 | return; | ||
| 550 | if (qspi->base[CHIP_SELECT]) { | ||
| 551 | data = bcm_qspi_read(qspi, CHIP_SELECT, 0); | ||
| 552 | data = (data & ~0xff) | (1 << cs); | ||
| 553 | bcm_qspi_write(qspi, CHIP_SELECT, 0, data); | ||
| 554 | usleep_range(10, 20); | ||
| 555 | } | ||
| 556 | qspi->curr_cs = cs; | ||
| 557 | } | ||
| 558 | |||
| 559 | /* MSPI helpers */ | ||
| 560 | static void bcm_qspi_hw_set_parms(struct bcm_qspi *qspi, | ||
| 561 | const struct bcm_qspi_parms *xp) | ||
| 562 | { | ||
| 563 | u32 spcr, spbr = 0; | ||
| 564 | |||
| 565 | if (xp->speed_hz) | ||
| 566 | spbr = qspi->base_clk / (2 * xp->speed_hz); | ||
| 567 | |||
| 568 | spcr = clamp_val(spbr, QSPI_SPBR_MIN, QSPI_SPBR_MAX); | ||
| 569 | bcm_qspi_write(qspi, MSPI, MSPI_SPCR0_LSB, spcr); | ||
| 570 | |||
| 571 | spcr = MSPI_MASTER_BIT; | ||
| 572 | /* for 16 bit the data should be zero */ | ||
| 573 | if (xp->bits_per_word != 16) | ||
| 574 | spcr |= xp->bits_per_word << 2; | ||
| 575 | spcr |= xp->mode & 3; | ||
| 576 | bcm_qspi_write(qspi, MSPI, MSPI_SPCR0_MSB, spcr); | ||
| 577 | |||
| 578 | qspi->last_parms = *xp; | ||
| 579 | } | ||
| 580 | |||
| 581 | static void bcm_qspi_update_parms(struct bcm_qspi *qspi, | ||
| 582 | struct spi_device *spi, | ||
| 583 | struct spi_transfer *trans) | ||
| 584 | { | ||
| 585 | struct bcm_qspi_parms xp; | ||
| 586 | |||
| 587 | xp.speed_hz = trans->speed_hz; | ||
| 588 | xp.bits_per_word = trans->bits_per_word; | ||
| 589 | xp.mode = spi->mode; | ||
| 590 | |||
| 591 | bcm_qspi_hw_set_parms(qspi, &xp); | ||
| 592 | } | ||
| 593 | |||
| 594 | static int bcm_qspi_setup(struct spi_device *spi) | ||
| 595 | { | ||
| 596 | struct bcm_qspi_parms *xp; | ||
| 597 | |||
| 598 | if (spi->bits_per_word > 16) | ||
| 599 | return -EINVAL; | ||
| 600 | |||
| 601 | xp = spi_get_ctldata(spi); | ||
| 602 | if (!xp) { | ||
| 603 | xp = kzalloc(sizeof(*xp), GFP_KERNEL); | ||
| 604 | if (!xp) | ||
| 605 | return -ENOMEM; | ||
| 606 | spi_set_ctldata(spi, xp); | ||
| 607 | } | ||
| 608 | xp->speed_hz = spi->max_speed_hz; | ||
| 609 | xp->mode = spi->mode; | ||
| 610 | |||
| 611 | if (spi->bits_per_word) | ||
| 612 | xp->bits_per_word = spi->bits_per_word; | ||
| 613 | else | ||
| 614 | xp->bits_per_word = 8; | ||
| 615 | |||
| 616 | return 0; | ||
| 617 | } | ||
| 618 | |||
| 619 | static int update_qspi_trans_byte_count(struct bcm_qspi *qspi, | ||
| 620 | struct qspi_trans *qt, int flags) | ||
| 621 | { | ||
| 622 | int ret = TRANS_STATUS_BREAK_NONE; | ||
| 623 | |||
| 624 | /* count the last transferred bytes */ | ||
| 625 | if (qt->trans->bits_per_word <= 8) | ||
| 626 | qt->byte++; | ||
| 627 | else | ||
| 628 | qt->byte += 2; | ||
| 629 | |||
| 630 | if (qt->byte >= qt->trans->len) { | ||
| 631 | /* we're at the end of the spi_transfer */ | ||
| 632 | |||
| 633 | /* in TX mode, need to pause for a delay or CS change */ | ||
| 634 | if (qt->trans->delay_usecs && | ||
| 635 | (flags & TRANS_STATUS_BREAK_DELAY)) | ||
| 636 | ret |= TRANS_STATUS_BREAK_DELAY; | ||
| 637 | if (qt->trans->cs_change && | ||
| 638 | (flags & TRANS_STATUS_BREAK_CS_CHANGE)) | ||
| 639 | ret |= TRANS_STATUS_BREAK_CS_CHANGE; | ||
| 640 | if (ret) | ||
| 641 | goto done; | ||
| 642 | |||
| 643 | dev_dbg(&qspi->pdev->dev, "advance msg exit\n"); | ||
| 644 | if (spi_transfer_is_last(qspi->master, qt->trans)) | ||
| 645 | ret = TRANS_STATUS_BREAK_EOM; | ||
| 646 | else | ||
| 647 | ret = TRANS_STATUS_BREAK_NO_BYTES; | ||
| 648 | |||
| 649 | qt->trans = NULL; | ||
| 650 | } | ||
| 651 | |||
| 652 | done: | ||
| 653 | dev_dbg(&qspi->pdev->dev, "trans %p len %d byte %d ret %x\n", | ||
| 654 | qt->trans, qt->trans ? qt->trans->len : 0, qt->byte, ret); | ||
| 655 | return ret; | ||
| 656 | } | ||
| 657 | |||
| 658 | static inline u8 read_rxram_slot_u8(struct bcm_qspi *qspi, int slot) | ||
| 659 | { | ||
| 660 | u32 slot_offset = MSPI_RXRAM + (slot << 3) + 0x4; | ||
| 661 | |||
| 662 | /* mask out reserved bits */ | ||
| 663 | return bcm_qspi_read(qspi, MSPI, slot_offset) & 0xff; | ||
| 664 | } | ||
| 665 | |||
| 666 | static inline u16 read_rxram_slot_u16(struct bcm_qspi *qspi, int slot) | ||
| 667 | { | ||
| 668 | u32 reg_offset = MSPI_RXRAM; | ||
| 669 | u32 lsb_offset = reg_offset + (slot << 3) + 0x4; | ||
| 670 | u32 msb_offset = reg_offset + (slot << 3); | ||
| 671 | |||
| 672 | return (bcm_qspi_read(qspi, MSPI, lsb_offset) & 0xff) | | ||
| 673 | ((bcm_qspi_read(qspi, MSPI, msb_offset) & 0xff) << 8); | ||
| 674 | } | ||
| 675 | |||
| 676 | static void read_from_hw(struct bcm_qspi *qspi, int slots) | ||
| 677 | { | ||
| 678 | struct qspi_trans tp; | ||
| 679 | int slot; | ||
| 680 | |||
| 681 | bcm_qspi_disable_bspi(qspi); | ||
| 682 | |||
| 683 | if (slots > MSPI_NUM_CDRAM) { | ||
| 684 | /* should never happen */ | ||
| 685 | dev_err(&qspi->pdev->dev, "%s: too many slots!\n", __func__); | ||
| 686 | return; | ||
| 687 | } | ||
| 688 | |||
| 689 | tp = qspi->trans_pos; | ||
| 690 | |||
| 691 | for (slot = 0; slot < slots; slot++) { | ||
| 692 | if (tp.trans->bits_per_word <= 8) { | ||
| 693 | u8 *buf = tp.trans->rx_buf; | ||
| 694 | |||
| 695 | if (buf) | ||
| 696 | buf[tp.byte] = read_rxram_slot_u8(qspi, slot); | ||
| 697 | dev_dbg(&qspi->pdev->dev, "RD %02x\n", | ||
| 698 | buf ? buf[tp.byte] : 0xff); | ||
| 699 | } else { | ||
| 700 | u16 *buf = tp.trans->rx_buf; | ||
| 701 | |||
| 702 | if (buf) | ||
| 703 | buf[tp.byte / 2] = read_rxram_slot_u16(qspi, | ||
| 704 | slot); | ||
| 705 | dev_dbg(&qspi->pdev->dev, "RD %04x\n", | ||
| 706 | buf ? buf[tp.byte] : 0xffff); | ||
| 707 | } | ||
| 708 | |||
| 709 | update_qspi_trans_byte_count(qspi, &tp, | ||
| 710 | TRANS_STATUS_BREAK_NONE); | ||
| 711 | } | ||
| 712 | |||
| 713 | qspi->trans_pos = tp; | ||
| 714 | } | ||
| 715 | |||
| 716 | static inline void write_txram_slot_u8(struct bcm_qspi *qspi, int slot, | ||
| 717 | u8 val) | ||
| 718 | { | ||
| 719 | u32 reg_offset = MSPI_TXRAM + (slot << 3); | ||
| 720 | |||
| 721 | /* mask out reserved bits */ | ||
| 722 | bcm_qspi_write(qspi, MSPI, reg_offset, val); | ||
| 723 | } | ||
| 724 | |||
| 725 | static inline void write_txram_slot_u16(struct bcm_qspi *qspi, int slot, | ||
| 726 | u16 val) | ||
| 727 | { | ||
| 728 | u32 reg_offset = MSPI_TXRAM; | ||
| 729 | u32 msb_offset = reg_offset + (slot << 3); | ||
| 730 | u32 lsb_offset = reg_offset + (slot << 3) + 0x4; | ||
| 731 | |||
| 732 | bcm_qspi_write(qspi, MSPI, msb_offset, (val >> 8)); | ||
| 733 | bcm_qspi_write(qspi, MSPI, lsb_offset, (val & 0xff)); | ||
| 734 | } | ||
| 735 | |||
| 736 | static inline u32 read_cdram_slot(struct bcm_qspi *qspi, int slot) | ||
| 737 | { | ||
| 738 | return bcm_qspi_read(qspi, MSPI, MSPI_CDRAM + (slot << 2)); | ||
| 739 | } | ||
| 740 | |||
| 741 | static inline void write_cdram_slot(struct bcm_qspi *qspi, int slot, u32 val) | ||
| 742 | { | ||
| 743 | bcm_qspi_write(qspi, MSPI, (MSPI_CDRAM + (slot << 2)), val); | ||
| 744 | } | ||
| 745 | |||
| 746 | /* Return number of slots written */ | ||
| 747 | static int write_to_hw(struct bcm_qspi *qspi, struct spi_device *spi) | ||
| 748 | { | ||
| 749 | struct qspi_trans tp; | ||
| 750 | int slot = 0, tstatus = 0; | ||
| 751 | u32 mspi_cdram = 0; | ||
| 752 | |||
| 753 | bcm_qspi_disable_bspi(qspi); | ||
| 754 | tp = qspi->trans_pos; | ||
| 755 | bcm_qspi_update_parms(qspi, spi, tp.trans); | ||
| 756 | |||
| 757 | /* Run until end of transfer or reached the max data */ | ||
| 758 | while (!tstatus && slot < MSPI_NUM_CDRAM) { | ||
| 759 | if (tp.trans->bits_per_word <= 8) { | ||
| 760 | const u8 *buf = tp.trans->tx_buf; | ||
| 761 | u8 val = buf ? buf[tp.byte] : 0xff; | ||
| 762 | |||
| 763 | write_txram_slot_u8(qspi, slot, val); | ||
| 764 | dev_dbg(&qspi->pdev->dev, "WR %02x\n", val); | ||
| 765 | } else { | ||
| 766 | const u16 *buf = tp.trans->tx_buf; | ||
| 767 | u16 val = buf ? buf[tp.byte / 2] : 0xffff; | ||
| 768 | |||
| 769 | write_txram_slot_u16(qspi, slot, val); | ||
| 770 | dev_dbg(&qspi->pdev->dev, "WR %04x\n", val); | ||
| 771 | } | ||
| 772 | mspi_cdram = MSPI_CDRAM_CONT_BIT; | ||
| 773 | mspi_cdram |= (~(1 << spi->chip_select) & | ||
| 774 | MSPI_CDRAM_PCS); | ||
| 775 | mspi_cdram |= ((tp.trans->bits_per_word <= 8) ? 0 : | ||
| 776 | MSPI_CDRAM_BITSE_BIT); | ||
| 777 | |||
| 778 | write_cdram_slot(qspi, slot, mspi_cdram); | ||
| 779 | |||
| 780 | tstatus = update_qspi_trans_byte_count(qspi, &tp, | ||
| 781 | TRANS_STATUS_BREAK_TX); | ||
| 782 | slot++; | ||
| 783 | } | ||
| 784 | |||
| 785 | if (!slot) { | ||
| 786 | dev_err(&qspi->pdev->dev, "%s: no data to send?", __func__); | ||
| 787 | goto done; | ||
| 788 | } | ||
| 789 | |||
| 790 | dev_dbg(&qspi->pdev->dev, "submitting %d slots\n", slot); | ||
| 791 | bcm_qspi_write(qspi, MSPI, MSPI_NEWQP, 0); | ||
| 792 | bcm_qspi_write(qspi, MSPI, MSPI_ENDQP, slot - 1); | ||
| 793 | |||
| 794 | if (tstatus & TRANS_STATUS_BREAK_DESELECT) { | ||
| 795 | mspi_cdram = read_cdram_slot(qspi, slot - 1) & | ||
| 796 | ~MSPI_CDRAM_CONT_BIT; | ||
| 797 | write_cdram_slot(qspi, slot - 1, mspi_cdram); | ||
| 798 | } | ||
| 799 | |||
| 800 | if (has_bspi(qspi)) | ||
| 801 | bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 1); | ||
| 802 | |||
| 803 | /* Must flush previous writes before starting MSPI operation */ | ||
| 804 | mb(); | ||
| 805 | /* Set cont | spe | spifie */ | ||
| 806 | bcm_qspi_write(qspi, MSPI, MSPI_SPCR2, 0xe0); | ||
| 807 | |||
| 808 | done: | ||
| 809 | return slot; | ||
| 810 | } | ||
| 811 | |||
| 812 | static int bcm_qspi_bspi_flash_read(struct spi_device *spi, | ||
| 813 | struct spi_flash_read_message *msg) | ||
| 814 | { | ||
| 815 | struct bcm_qspi *qspi = spi_master_get_devdata(spi->master); | ||
| 816 | u32 addr = 0, len, len_words; | ||
| 817 | int ret = 0; | ||
| 818 | unsigned long timeo = msecs_to_jiffies(100); | ||
| 819 | struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc; | ||
| 820 | |||
| 821 | if (bcm_qspi_bspi_ver_three(qspi)) | ||
| 822 | if (msg->addr_width == BSPI_ADDRLEN_4BYTES) | ||
| 823 | return -EIO; | ||
| 824 | |||
| 825 | bcm_qspi_chip_select(qspi, spi->chip_select); | ||
| 826 | bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 0); | ||
| 827 | |||
| 828 | /* | ||
| 829 | * when using flex mode mode we need to send | ||
| 830 | * the upper address byte to bspi | ||
| 831 | */ | ||
| 832 | if (bcm_qspi_bspi_ver_three(qspi) == false) { | ||
| 833 | addr = msg->from & 0xff000000; | ||
| 834 | bcm_qspi_write(qspi, BSPI, | ||
| 835 | BSPI_BSPI_FLASH_UPPER_ADDR_BYTE, addr); | ||
| 836 | } | ||
| 837 | |||
| 838 | if (!qspi->xfer_mode.flex_mode) | ||
| 839 | addr = msg->from; | ||
| 840 | else | ||
| 841 | addr = msg->from & 0x00ffffff; | ||
| 842 | |||
| 843 | /* set BSPI RAF buffer max read length */ | ||
| 844 | len = msg->len; | ||
| 845 | if (len > BSPI_READ_LENGTH) | ||
| 846 | len = BSPI_READ_LENGTH; | ||
| 847 | |||
| 848 | if (bcm_qspi_bspi_ver_three(qspi) == true) | ||
| 849 | addr = (addr + 0xc00000) & 0xffffff; | ||
| 850 | |||
| 851 | reinit_completion(&qspi->bspi_done); | ||
| 852 | bcm_qspi_enable_bspi(qspi); | ||
| 853 | len_words = (len + 3) >> 2; | ||
| 854 | qspi->bspi_rf_msg = msg; | ||
| 855 | qspi->bspi_rf_msg_status = 0; | ||
| 856 | qspi->bspi_rf_msg_idx = 0; | ||
| 857 | qspi->bspi_rf_msg_len = len; | ||
| 858 | dev_dbg(&qspi->pdev->dev, "bspi xfr addr 0x%x len 0x%x", addr, len); | ||
| 859 | |||
| 860 | bcm_qspi_write(qspi, BSPI, BSPI_RAF_START_ADDR, addr); | ||
| 861 | bcm_qspi_write(qspi, BSPI, BSPI_RAF_NUM_WORDS, len_words); | ||
| 862 | bcm_qspi_write(qspi, BSPI, BSPI_RAF_WATERMARK, 0); | ||
| 863 | |||
| 864 | if (qspi->soc_intc) { | ||
| 865 | /* | ||
| 866 | * clear soc MSPI and BSPI interrupts and enable | ||
| 867 | * BSPI interrupts. | ||
| 868 | */ | ||
| 869 | soc_intc->bcm_qspi_int_ack(soc_intc, MSPI_BSPI_DONE); | ||
| 870 | soc_intc->bcm_qspi_int_set(soc_intc, BSPI_DONE, true); | ||
| 871 | } | ||
| 872 | |||
| 873 | /* Must flush previous writes before starting BSPI operation */ | ||
| 874 | mb(); | ||
| 875 | |||
| 876 | bcm_qspi_bspi_lr_start(qspi); | ||
| 877 | if (!wait_for_completion_timeout(&qspi->bspi_done, timeo)) { | ||
| 878 | dev_err(&qspi->pdev->dev, "timeout waiting for BSPI\n"); | ||
| 879 | ret = -ETIMEDOUT; | ||
| 880 | } else { | ||
| 881 | /* set the return length for the caller */ | ||
| 882 | msg->retlen = len; | ||
| 883 | } | ||
| 884 | |||
| 885 | return ret; | ||
| 886 | } | ||
| 887 | |||
| 888 | static int bcm_qspi_flash_read(struct spi_device *spi, | ||
| 889 | struct spi_flash_read_message *msg) | ||
| 890 | { | ||
| 891 | struct bcm_qspi *qspi = spi_master_get_devdata(spi->master); | ||
| 892 | int ret = 0; | ||
| 893 | bool mspi_read = false; | ||
| 894 | u32 io_width, addrlen, addr, len; | ||
| 895 | u_char *buf; | ||
| 896 | |||
| 897 | buf = msg->buf; | ||
| 898 | addr = msg->from; | ||
| 899 | len = msg->len; | ||
| 900 | |||
| 901 | if (bcm_qspi_bspi_ver_three(qspi) == true) { | ||
| 902 | /* | ||
| 903 | * The address coming into this function is a raw flash offset. | ||
| 904 | * But for BSPI <= V3, we need to convert it to a remapped BSPI | ||
| 905 | * address. If it crosses a 4MB boundary, just revert back to | ||
| 906 | * using MSPI. | ||
| 907 | */ | ||
| 908 | addr = (addr + 0xc00000) & 0xffffff; | ||
| 909 | |||
| 910 | if ((~ADDR_4MB_MASK & addr) ^ | ||
| 911 | (~ADDR_4MB_MASK & (addr + len - 1))) | ||
| 912 | mspi_read = true; | ||
| 913 | } | ||
| 914 | |||
| 915 | /* non-aligned and very short transfers are handled by MSPI */ | ||
| 916 | if (!IS_ALIGNED((uintptr_t)addr, 4) || !IS_ALIGNED((uintptr_t)buf, 4) || | ||
| 917 | len < 4) | ||
| 918 | mspi_read = true; | ||
| 919 | |||
| 920 | if (mspi_read) | ||
| 921 | /* this will make the m25p80 read to fallback to mspi read */ | ||
| 922 | return -EAGAIN; | ||
| 923 | |||
| 924 | io_width = msg->data_nbits ? msg->data_nbits : SPI_NBITS_SINGLE; | ||
| 925 | addrlen = msg->addr_width; | ||
| 926 | ret = bcm_qspi_bspi_set_mode(qspi, io_width, addrlen, -1); | ||
| 927 | |||
| 928 | if (!ret) | ||
| 929 | ret = bcm_qspi_bspi_flash_read(spi, msg); | ||
| 930 | |||
| 931 | return ret; | ||
| 932 | } | ||
| 933 | |||
| 934 | static int bcm_qspi_transfer_one(struct spi_master *master, | ||
| 935 | struct spi_device *spi, | ||
| 936 | struct spi_transfer *trans) | ||
| 937 | { | ||
| 938 | struct bcm_qspi *qspi = spi_master_get_devdata(master); | ||
| 939 | int slots; | ||
| 940 | unsigned long timeo = msecs_to_jiffies(100); | ||
| 941 | |||
| 942 | bcm_qspi_chip_select(qspi, spi->chip_select); | ||
| 943 | qspi->trans_pos.trans = trans; | ||
| 944 | qspi->trans_pos.byte = 0; | ||
| 945 | |||
| 946 | while (qspi->trans_pos.byte < trans->len) { | ||
| 947 | reinit_completion(&qspi->mspi_done); | ||
| 948 | |||
| 949 | slots = write_to_hw(qspi, spi); | ||
| 950 | if (!wait_for_completion_timeout(&qspi->mspi_done, timeo)) { | ||
| 951 | dev_err(&qspi->pdev->dev, "timeout waiting for MSPI\n"); | ||
| 952 | return -ETIMEDOUT; | ||
| 953 | } | ||
| 954 | |||
| 955 | read_from_hw(qspi, slots); | ||
| 956 | } | ||
| 957 | |||
| 958 | return 0; | ||
| 959 | } | ||
| 960 | |||
| 961 | static void bcm_qspi_cleanup(struct spi_device *spi) | ||
| 962 | { | ||
| 963 | struct bcm_qspi_parms *xp = spi_get_ctldata(spi); | ||
| 964 | |||
| 965 | kfree(xp); | ||
| 966 | } | ||
| 967 | |||
| 968 | static irqreturn_t bcm_qspi_mspi_l2_isr(int irq, void *dev_id) | ||
| 969 | { | ||
| 970 | struct bcm_qspi_dev_id *qspi_dev_id = dev_id; | ||
| 971 | struct bcm_qspi *qspi = qspi_dev_id->dev; | ||
| 972 | u32 status = bcm_qspi_read(qspi, MSPI, MSPI_MSPI_STATUS); | ||
| 973 | |||
| 974 | if (status & MSPI_MSPI_STATUS_SPIF) { | ||
| 975 | struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc; | ||
| 976 | /* clear interrupt */ | ||
| 977 | status &= ~MSPI_MSPI_STATUS_SPIF; | ||
| 978 | bcm_qspi_write(qspi, MSPI, MSPI_MSPI_STATUS, status); | ||
| 979 | if (qspi->soc_intc) | ||
| 980 | soc_intc->bcm_qspi_int_ack(soc_intc, MSPI_DONE); | ||
| 981 | complete(&qspi->mspi_done); | ||
| 982 | return IRQ_HANDLED; | ||
| 983 | } | ||
| 984 | |||
| 985 | return IRQ_NONE; | ||
| 986 | } | ||
| 987 | |||
| 988 | static irqreturn_t bcm_qspi_bspi_lr_l2_isr(int irq, void *dev_id) | ||
| 989 | { | ||
| 990 | struct bcm_qspi_dev_id *qspi_dev_id = dev_id; | ||
| 991 | struct bcm_qspi *qspi = qspi_dev_id->dev; | ||
| 992 | struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc; | ||
| 993 | u32 status = qspi_dev_id->irqp->mask; | ||
| 994 | |||
| 995 | if (qspi->bspi_enabled && qspi->bspi_rf_msg) { | ||
| 996 | bcm_qspi_bspi_lr_data_read(qspi); | ||
| 997 | if (qspi->bspi_rf_msg_len == 0) { | ||
| 998 | qspi->bspi_rf_msg = NULL; | ||
| 999 | if (qspi->soc_intc) { | ||
| 1000 | /* disable soc BSPI interrupt */ | ||
| 1001 | soc_intc->bcm_qspi_int_set(soc_intc, BSPI_DONE, | ||
| 1002 | false); | ||
| 1003 | /* indicate done */ | ||
| 1004 | status = INTR_BSPI_LR_SESSION_DONE_MASK; | ||
| 1005 | } | ||
| 1006 | |||
| 1007 | if (qspi->bspi_rf_msg_status) | ||
| 1008 | bcm_qspi_bspi_lr_clear(qspi); | ||
| 1009 | else | ||
| 1010 | bcm_qspi_bspi_flush_prefetch_buffers(qspi); | ||
| 1011 | } | ||
| 1012 | |||
| 1013 | if (qspi->soc_intc) | ||
| 1014 | /* clear soc BSPI interrupt */ | ||
| 1015 | soc_intc->bcm_qspi_int_ack(soc_intc, BSPI_DONE); | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | status &= INTR_BSPI_LR_SESSION_DONE_MASK; | ||
| 1019 | if (qspi->bspi_enabled && status && qspi->bspi_rf_msg_len == 0) | ||
| 1020 | complete(&qspi->bspi_done); | ||
| 1021 | |||
| 1022 | return IRQ_HANDLED; | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | static irqreturn_t bcm_qspi_bspi_lr_err_l2_isr(int irq, void *dev_id) | ||
| 1026 | { | ||
| 1027 | struct bcm_qspi_dev_id *qspi_dev_id = dev_id; | ||
| 1028 | struct bcm_qspi *qspi = qspi_dev_id->dev; | ||
| 1029 | struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc; | ||
| 1030 | |||
| 1031 | dev_err(&qspi->pdev->dev, "BSPI INT error\n"); | ||
| 1032 | qspi->bspi_rf_msg_status = -EIO; | ||
| 1033 | if (qspi->soc_intc) | ||
| 1034 | /* clear soc interrupt */ | ||
| 1035 | soc_intc->bcm_qspi_int_ack(soc_intc, BSPI_ERR); | ||
| 1036 | |||
| 1037 | complete(&qspi->bspi_done); | ||
| 1038 | return IRQ_HANDLED; | ||
| 1039 | } | ||
| 1040 | |||
| 1041 | static irqreturn_t bcm_qspi_l1_isr(int irq, void *dev_id) | ||
| 1042 | { | ||
| 1043 | struct bcm_qspi_dev_id *qspi_dev_id = dev_id; | ||
| 1044 | struct bcm_qspi *qspi = qspi_dev_id->dev; | ||
| 1045 | struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc; | ||
| 1046 | irqreturn_t ret = IRQ_NONE; | ||
| 1047 | |||
| 1048 | if (soc_intc) { | ||
| 1049 | u32 status = soc_intc->bcm_qspi_get_int_status(soc_intc); | ||
| 1050 | |||
| 1051 | if (status & MSPI_DONE) | ||
| 1052 | ret = bcm_qspi_mspi_l2_isr(irq, dev_id); | ||
| 1053 | else if (status & BSPI_DONE) | ||
| 1054 | ret = bcm_qspi_bspi_lr_l2_isr(irq, dev_id); | ||
| 1055 | else if (status & BSPI_ERR) | ||
| 1056 | ret = bcm_qspi_bspi_lr_err_l2_isr(irq, dev_id); | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | return ret; | ||
| 1060 | } | ||
| 1061 | |||
| 1062 | static const struct bcm_qspi_irq qspi_irq_tab[] = { | ||
| 1063 | { | ||
| 1064 | .irq_name = "spi_lr_fullness_reached", | ||
| 1065 | .irq_handler = bcm_qspi_bspi_lr_l2_isr, | ||
| 1066 | .mask = INTR_BSPI_LR_FULLNESS_REACHED_MASK, | ||
| 1067 | }, | ||
| 1068 | { | ||
| 1069 | .irq_name = "spi_lr_session_aborted", | ||
| 1070 | .irq_handler = bcm_qspi_bspi_lr_err_l2_isr, | ||
| 1071 | .mask = INTR_BSPI_LR_SESSION_ABORTED_MASK, | ||
| 1072 | }, | ||
| 1073 | { | ||
| 1074 | .irq_name = "spi_lr_impatient", | ||
| 1075 | .irq_handler = bcm_qspi_bspi_lr_err_l2_isr, | ||
| 1076 | .mask = INTR_BSPI_LR_IMPATIENT_MASK, | ||
| 1077 | }, | ||
| 1078 | { | ||
| 1079 | .irq_name = "spi_lr_session_done", | ||
| 1080 | .irq_handler = bcm_qspi_bspi_lr_l2_isr, | ||
| 1081 | .mask = INTR_BSPI_LR_SESSION_DONE_MASK, | ||
| 1082 | }, | ||
| 1083 | #ifdef QSPI_INT_DEBUG | ||
| 1084 | /* this interrupt is for debug purposes only, dont request irq */ | ||
| 1085 | { | ||
| 1086 | .irq_name = "spi_lr_overread", | ||
| 1087 | .irq_handler = bcm_qspi_bspi_lr_err_l2_isr, | ||
| 1088 | .mask = INTR_BSPI_LR_OVERREAD_MASK, | ||
| 1089 | }, | ||
| 1090 | #endif | ||
| 1091 | { | ||
| 1092 | .irq_name = "mspi_done", | ||
| 1093 | .irq_handler = bcm_qspi_mspi_l2_isr, | ||
| 1094 | .mask = INTR_MSPI_DONE_MASK, | ||
| 1095 | }, | ||
| 1096 | { | ||
| 1097 | .irq_name = "mspi_halted", | ||
| 1098 | .irq_handler = bcm_qspi_mspi_l2_isr, | ||
| 1099 | .mask = INTR_MSPI_HALTED_MASK, | ||
| 1100 | }, | ||
| 1101 | { | ||
| 1102 | /* single muxed L1 interrupt source */ | ||
| 1103 | .irq_name = "spi_l1_intr", | ||
| 1104 | .irq_handler = bcm_qspi_l1_isr, | ||
| 1105 | .irq_source = MUXED_L1, | ||
| 1106 | .mask = QSPI_INTERRUPTS_ALL, | ||
| 1107 | }, | ||
| 1108 | }; | ||
| 1109 | |||
| 1110 | static void bcm_qspi_bspi_init(struct bcm_qspi *qspi) | ||
| 1111 | { | ||
| 1112 | u32 val = 0; | ||
| 1113 | |||
| 1114 | val = bcm_qspi_read(qspi, BSPI, BSPI_REVISION_ID); | ||
| 1115 | qspi->bspi_maj_rev = (val >> 8) & 0xff; | ||
| 1116 | qspi->bspi_min_rev = val & 0xff; | ||
| 1117 | if (!(bcm_qspi_bspi_ver_three(qspi))) { | ||
| 1118 | /* Force mapping of BSPI address -> flash offset */ | ||
| 1119 | bcm_qspi_write(qspi, BSPI, BSPI_BSPI_XOR_VALUE, 0); | ||
| 1120 | bcm_qspi_write(qspi, BSPI, BSPI_BSPI_XOR_ENABLE, 1); | ||
| 1121 | } | ||
| 1122 | qspi->bspi_enabled = 1; | ||
| 1123 | bcm_qspi_disable_bspi(qspi); | ||
| 1124 | bcm_qspi_write(qspi, BSPI, BSPI_B0_CTRL, 0); | ||
| 1125 | bcm_qspi_write(qspi, BSPI, BSPI_B1_CTRL, 0); | ||
| 1126 | } | ||
| 1127 | |||
| 1128 | static void bcm_qspi_hw_init(struct bcm_qspi *qspi) | ||
| 1129 | { | ||
| 1130 | struct bcm_qspi_parms parms; | ||
| 1131 | |||
| 1132 | bcm_qspi_write(qspi, MSPI, MSPI_SPCR1_LSB, 0); | ||
| 1133 | bcm_qspi_write(qspi, MSPI, MSPI_SPCR1_MSB, 0); | ||
| 1134 | bcm_qspi_write(qspi, MSPI, MSPI_NEWQP, 0); | ||
| 1135 | bcm_qspi_write(qspi, MSPI, MSPI_ENDQP, 0); | ||
| 1136 | bcm_qspi_write(qspi, MSPI, MSPI_SPCR2, 0x20); | ||
| 1137 | |||
| 1138 | parms.mode = SPI_MODE_3; | ||
| 1139 | parms.bits_per_word = 8; | ||
| 1140 | parms.speed_hz = qspi->max_speed_hz; | ||
| 1141 | bcm_qspi_hw_set_parms(qspi, &parms); | ||
| 1142 | |||
| 1143 | if (has_bspi(qspi)) | ||
| 1144 | bcm_qspi_bspi_init(qspi); | ||
| 1145 | } | ||
| 1146 | |||
| 1147 | static void bcm_qspi_hw_uninit(struct bcm_qspi *qspi) | ||
| 1148 | { | ||
| 1149 | bcm_qspi_write(qspi, MSPI, MSPI_SPCR2, 0); | ||
| 1150 | if (has_bspi(qspi)) | ||
| 1151 | bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 0); | ||
| 1152 | |||
| 1153 | } | ||
| 1154 | |||
| 1155 | static const struct of_device_id bcm_qspi_of_match[] = { | ||
| 1156 | { .compatible = "brcm,spi-bcm-qspi" }, | ||
| 1157 | {}, | ||
| 1158 | }; | ||
| 1159 | MODULE_DEVICE_TABLE(of, bcm_qspi_of_match); | ||
| 1160 | |||
| 1161 | int bcm_qspi_probe(struct platform_device *pdev, | ||
| 1162 | struct bcm_qspi_soc_intc *soc_intc) | ||
| 1163 | { | ||
| 1164 | struct device *dev = &pdev->dev; | ||
| 1165 | struct bcm_qspi *qspi; | ||
| 1166 | struct spi_master *master; | ||
| 1167 | struct resource *res; | ||
| 1168 | int irq, ret = 0, num_ints = 0; | ||
| 1169 | u32 val; | ||
| 1170 | const char *name = NULL; | ||
| 1171 | int num_irqs = ARRAY_SIZE(qspi_irq_tab); | ||
| 1172 | |||
| 1173 | /* We only support device-tree instantiation */ | ||
| 1174 | if (!dev->of_node) | ||
| 1175 | return -ENODEV; | ||
| 1176 | |||
| 1177 | if (!of_match_node(bcm_qspi_of_match, dev->of_node)) | ||
| 1178 | return -ENODEV; | ||
| 1179 | |||
| 1180 | master = spi_alloc_master(dev, sizeof(struct bcm_qspi)); | ||
| 1181 | if (!master) { | ||
| 1182 | dev_err(dev, "error allocating spi_master\n"); | ||
| 1183 | return -ENOMEM; | ||
| 1184 | } | ||
| 1185 | |||
| 1186 | qspi = spi_master_get_devdata(master); | ||
| 1187 | qspi->pdev = pdev; | ||
| 1188 | qspi->trans_pos.trans = NULL; | ||
| 1189 | qspi->trans_pos.byte = 0; | ||
| 1190 | qspi->master = master; | ||
| 1191 | |||
| 1192 | master->bus_num = -1; | ||
| 1193 | master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_RX_DUAL | SPI_RX_QUAD; | ||
| 1194 | master->setup = bcm_qspi_setup; | ||
| 1195 | master->transfer_one = bcm_qspi_transfer_one; | ||
| 1196 | master->spi_flash_read = bcm_qspi_flash_read; | ||
| 1197 | master->cleanup = bcm_qspi_cleanup; | ||
| 1198 | master->dev.of_node = dev->of_node; | ||
| 1199 | master->num_chipselect = NUM_CHIPSELECT; | ||
| 1200 | |||
| 1201 | qspi->big_endian = of_device_is_big_endian(dev->of_node); | ||
| 1202 | |||
| 1203 | if (!of_property_read_u32(dev->of_node, "num-cs", &val)) | ||
| 1204 | master->num_chipselect = val; | ||
| 1205 | |||
| 1206 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hif_mspi"); | ||
| 1207 | if (!res) | ||
| 1208 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | ||
| 1209 | "mspi"); | ||
| 1210 | |||
| 1211 | if (res) { | ||
| 1212 | qspi->base[MSPI] = devm_ioremap_resource(dev, res); | ||
| 1213 | if (IS_ERR(qspi->base[MSPI])) { | ||
| 1214 | ret = PTR_ERR(qspi->base[MSPI]); | ||
| 1215 | goto qspi_probe_err; | ||
| 1216 | } | ||
| 1217 | } else { | ||
| 1218 | goto qspi_probe_err; | ||
| 1219 | } | ||
| 1220 | |||
| 1221 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bspi"); | ||
| 1222 | if (res) { | ||
| 1223 | qspi->base[BSPI] = devm_ioremap_resource(dev, res); | ||
| 1224 | if (IS_ERR(qspi->base[BSPI])) { | ||
| 1225 | ret = PTR_ERR(qspi->base[BSPI]); | ||
| 1226 | goto qspi_probe_err; | ||
| 1227 | } | ||
| 1228 | qspi->bspi_mode = true; | ||
| 1229 | } else { | ||
| 1230 | qspi->bspi_mode = false; | ||
| 1231 | } | ||
| 1232 | |||
| 1233 | dev_info(dev, "using %smspi mode\n", qspi->bspi_mode ? "bspi-" : ""); | ||
| 1234 | |||
| 1235 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cs_reg"); | ||
| 1236 | if (res) { | ||
| 1237 | qspi->base[CHIP_SELECT] = devm_ioremap_resource(dev, res); | ||
| 1238 | if (IS_ERR(qspi->base[CHIP_SELECT])) { | ||
| 1239 | ret = PTR_ERR(qspi->base[CHIP_SELECT]); | ||
| 1240 | goto qspi_probe_err; | ||
| 1241 | } | ||
| 1242 | } | ||
| 1243 | |||
| 1244 | qspi->dev_ids = kcalloc(num_irqs, sizeof(struct bcm_qspi_dev_id), | ||
| 1245 | GFP_KERNEL); | ||
| 1246 | if (!qspi->dev_ids) { | ||
| 1247 | ret = -ENOMEM; | ||
| 1248 | goto qspi_probe_err; | ||
| 1249 | } | ||
| 1250 | |||
| 1251 | for (val = 0; val < num_irqs; val++) { | ||
| 1252 | irq = -1; | ||
| 1253 | name = qspi_irq_tab[val].irq_name; | ||
| 1254 | if (qspi_irq_tab[val].irq_source == SINGLE_L2) { | ||
| 1255 | /* get the l2 interrupts */ | ||
| 1256 | irq = platform_get_irq_byname(pdev, name); | ||
| 1257 | } else if (!num_ints && soc_intc) { | ||
| 1258 | /* all mspi, bspi intrs muxed to one L1 intr */ | ||
| 1259 | irq = platform_get_irq(pdev, 0); | ||
| 1260 | } | ||
| 1261 | |||
| 1262 | if (irq >= 0) { | ||
| 1263 | ret = devm_request_irq(&pdev->dev, irq, | ||
| 1264 | qspi_irq_tab[val].irq_handler, 0, | ||
| 1265 | name, | ||
| 1266 | &qspi->dev_ids[val]); | ||
| 1267 | if (ret < 0) { | ||
| 1268 | dev_err(&pdev->dev, "IRQ %s not found\n", name); | ||
| 1269 | goto qspi_probe_err; | ||
| 1270 | } | ||
| 1271 | |||
| 1272 | qspi->dev_ids[val].dev = qspi; | ||
| 1273 | qspi->dev_ids[val].irqp = &qspi_irq_tab[val]; | ||
| 1274 | num_ints++; | ||
| 1275 | dev_dbg(&pdev->dev, "registered IRQ %s %d\n", | ||
| 1276 | qspi_irq_tab[val].irq_name, | ||
| 1277 | irq); | ||
| 1278 | } | ||
| 1279 | } | ||
| 1280 | |||
| 1281 | if (!num_ints) { | ||
| 1282 | dev_err(&pdev->dev, "no IRQs registered, cannot init driver\n"); | ||
| 1283 | ret = -EINVAL; | ||
| 1284 | goto qspi_probe_err; | ||
| 1285 | } | ||
| 1286 | |||
| 1287 | /* | ||
| 1288 | * Some SoCs integrate spi controller (e.g., its interrupt bits) | ||
| 1289 | * in specific ways | ||
| 1290 | */ | ||
| 1291 | if (soc_intc) { | ||
| 1292 | qspi->soc_intc = soc_intc; | ||
| 1293 | soc_intc->bcm_qspi_int_set(soc_intc, MSPI_DONE, true); | ||
| 1294 | } else { | ||
| 1295 | qspi->soc_intc = NULL; | ||
| 1296 | } | ||
| 1297 | |||
| 1298 | qspi->clk = devm_clk_get(&pdev->dev, NULL); | ||
| 1299 | if (IS_ERR(qspi->clk)) { | ||
| 1300 | dev_warn(dev, "unable to get clock\n"); | ||
| 1301 | ret = PTR_ERR(qspi->clk); | ||
| 1302 | goto qspi_probe_err; | ||
| 1303 | } | ||
| 1304 | |||
| 1305 | ret = clk_prepare_enable(qspi->clk); | ||
| 1306 | if (ret) { | ||
| 1307 | dev_err(dev, "failed to prepare clock\n"); | ||
| 1308 | goto qspi_probe_err; | ||
| 1309 | } | ||
| 1310 | |||
| 1311 | qspi->base_clk = clk_get_rate(qspi->clk); | ||
| 1312 | qspi->max_speed_hz = qspi->base_clk / (QSPI_SPBR_MIN * 2); | ||
| 1313 | |||
| 1314 | bcm_qspi_hw_init(qspi); | ||
| 1315 | init_completion(&qspi->mspi_done); | ||
| 1316 | init_completion(&qspi->bspi_done); | ||
| 1317 | qspi->curr_cs = -1; | ||
| 1318 | |||
| 1319 | platform_set_drvdata(pdev, qspi); | ||
| 1320 | |||
| 1321 | qspi->xfer_mode.width = -1; | ||
| 1322 | qspi->xfer_mode.addrlen = -1; | ||
| 1323 | qspi->xfer_mode.hp = -1; | ||
| 1324 | |||
| 1325 | ret = devm_spi_register_master(&pdev->dev, master); | ||
| 1326 | if (ret < 0) { | ||
| 1327 | dev_err(dev, "can't register master\n"); | ||
| 1328 | goto qspi_reg_err; | ||
| 1329 | } | ||
| 1330 | |||
| 1331 | return 0; | ||
| 1332 | |||
| 1333 | qspi_reg_err: | ||
| 1334 | bcm_qspi_hw_uninit(qspi); | ||
| 1335 | clk_disable_unprepare(qspi->clk); | ||
| 1336 | qspi_probe_err: | ||
| 1337 | spi_master_put(master); | ||
| 1338 | kfree(qspi->dev_ids); | ||
| 1339 | return ret; | ||
| 1340 | } | ||
| 1341 | /* probe function to be called by SoC specific platform driver probe */ | ||
| 1342 | EXPORT_SYMBOL_GPL(bcm_qspi_probe); | ||
| 1343 | |||
| 1344 | int bcm_qspi_remove(struct platform_device *pdev) | ||
| 1345 | { | ||
| 1346 | struct bcm_qspi *qspi = platform_get_drvdata(pdev); | ||
| 1347 | |||
| 1348 | platform_set_drvdata(pdev, NULL); | ||
| 1349 | bcm_qspi_hw_uninit(qspi); | ||
| 1350 | clk_disable_unprepare(qspi->clk); | ||
| 1351 | kfree(qspi->dev_ids); | ||
| 1352 | spi_unregister_master(qspi->master); | ||
| 1353 | |||
| 1354 | return 0; | ||
| 1355 | } | ||
| 1356 | /* function to be called by SoC specific platform driver remove() */ | ||
| 1357 | EXPORT_SYMBOL_GPL(bcm_qspi_remove); | ||
| 1358 | |||
| 1359 | static int __maybe_unused bcm_qspi_suspend(struct device *dev) | ||
| 1360 | { | ||
| 1361 | struct bcm_qspi *qspi = dev_get_drvdata(dev); | ||
| 1362 | |||
| 1363 | spi_master_suspend(qspi->master); | ||
| 1364 | clk_disable(qspi->clk); | ||
| 1365 | bcm_qspi_hw_uninit(qspi); | ||
| 1366 | |||
| 1367 | return 0; | ||
| 1368 | }; | ||
| 1369 | |||
| 1370 | static int __maybe_unused bcm_qspi_resume(struct device *dev) | ||
| 1371 | { | ||
| 1372 | struct bcm_qspi *qspi = dev_get_drvdata(dev); | ||
| 1373 | int ret = 0; | ||
| 1374 | |||
| 1375 | bcm_qspi_hw_init(qspi); | ||
| 1376 | bcm_qspi_chip_select(qspi, qspi->curr_cs); | ||
| 1377 | if (qspi->soc_intc) | ||
| 1378 | /* enable MSPI interrupt */ | ||
| 1379 | qspi->soc_intc->bcm_qspi_int_set(qspi->soc_intc, MSPI_DONE, | ||
| 1380 | true); | ||
| 1381 | |||
| 1382 | ret = clk_enable(qspi->clk); | ||
| 1383 | if (!ret) | ||
| 1384 | spi_master_resume(qspi->master); | ||
| 1385 | |||
| 1386 | return ret; | ||
| 1387 | } | ||
| 1388 | |||
| 1389 | SIMPLE_DEV_PM_OPS(bcm_qspi_pm_ops, bcm_qspi_suspend, bcm_qspi_resume); | ||
| 1390 | |||
| 1391 | /* pm_ops to be called by SoC specific platform driver */ | ||
| 1392 | EXPORT_SYMBOL_GPL(bcm_qspi_pm_ops); | ||
| 1393 | |||
| 1394 | MODULE_AUTHOR("Kamal Dasu"); | ||
| 1395 | MODULE_DESCRIPTION("Broadcom QSPI driver"); | ||
| 1396 | MODULE_LICENSE("GPL v2"); | ||
| 1397 | MODULE_ALIAS("platform:" DRIVER_NAME); | ||
diff --git a/drivers/spi/spi-bcm-qspi.h b/drivers/spi/spi-bcm-qspi.h new file mode 100644 index 000000000000..7abfc75a3860 --- /dev/null +++ b/drivers/spi/spi-bcm-qspi.h | |||
| @@ -0,0 +1,115 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2016 Broadcom | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License, version 2, as | ||
| 6 | * published by the Free Software Foundation (the "GPL"). | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, but | ||
| 9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 11 | * General Public License version 2 (GPLv2) for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * version 2 (GPLv2) along with this source code. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #ifndef __SPI_BCM_QSPI_H__ | ||
| 18 | #define __SPI_BCM_QSPI_H__ | ||
| 19 | |||
| 20 | #include <linux/types.h> | ||
| 21 | #include <linux/io.h> | ||
| 22 | |||
| 23 | /* BSPI interrupt masks */ | ||
| 24 | #define INTR_BSPI_LR_OVERREAD_MASK BIT(4) | ||
| 25 | #define INTR_BSPI_LR_SESSION_DONE_MASK BIT(3) | ||
| 26 | #define INTR_BSPI_LR_IMPATIENT_MASK BIT(2) | ||
| 27 | #define INTR_BSPI_LR_SESSION_ABORTED_MASK BIT(1) | ||
| 28 | #define INTR_BSPI_LR_FULLNESS_REACHED_MASK BIT(0) | ||
| 29 | |||
| 30 | #define BSPI_LR_INTERRUPTS_DATA \ | ||
| 31 | (INTR_BSPI_LR_SESSION_DONE_MASK | \ | ||
| 32 | INTR_BSPI_LR_FULLNESS_REACHED_MASK) | ||
| 33 | |||
| 34 | #define BSPI_LR_INTERRUPTS_ERROR \ | ||
| 35 | (INTR_BSPI_LR_OVERREAD_MASK | \ | ||
| 36 | INTR_BSPI_LR_IMPATIENT_MASK | \ | ||
| 37 | INTR_BSPI_LR_SESSION_ABORTED_MASK) | ||
| 38 | |||
| 39 | #define BSPI_LR_INTERRUPTS_ALL \ | ||
| 40 | (BSPI_LR_INTERRUPTS_ERROR | \ | ||
| 41 | BSPI_LR_INTERRUPTS_DATA) | ||
| 42 | |||
| 43 | /* MSPI Interrupt masks */ | ||
| 44 | #define INTR_MSPI_HALTED_MASK BIT(6) | ||
| 45 | #define INTR_MSPI_DONE_MASK BIT(5) | ||
| 46 | |||
| 47 | #define MSPI_INTERRUPTS_ALL \ | ||
| 48 | (INTR_MSPI_DONE_MASK | \ | ||
| 49 | INTR_MSPI_HALTED_MASK) | ||
| 50 | |||
| 51 | #define QSPI_INTERRUPTS_ALL \ | ||
| 52 | (MSPI_INTERRUPTS_ALL | \ | ||
| 53 | BSPI_LR_INTERRUPTS_ALL) | ||
| 54 | |||
| 55 | struct platform_device; | ||
| 56 | struct dev_pm_ops; | ||
| 57 | |||
| 58 | enum { | ||
| 59 | MSPI_DONE = 0x1, | ||
| 60 | BSPI_DONE = 0x2, | ||
| 61 | BSPI_ERR = 0x4, | ||
| 62 | MSPI_BSPI_DONE = 0x7 | ||
| 63 | }; | ||
| 64 | |||
| 65 | struct bcm_qspi_soc_intc { | ||
| 66 | void (*bcm_qspi_int_ack)(struct bcm_qspi_soc_intc *soc_intc, int type); | ||
| 67 | void (*bcm_qspi_int_set)(struct bcm_qspi_soc_intc *soc_intc, int type, | ||
| 68 | bool en); | ||
| 69 | u32 (*bcm_qspi_get_int_status)(struct bcm_qspi_soc_intc *soc_intc); | ||
| 70 | }; | ||
| 71 | |||
| 72 | /* Read controller register*/ | ||
| 73 | static inline u32 bcm_qspi_readl(bool be, void __iomem *addr) | ||
| 74 | { | ||
| 75 | if (be) | ||
| 76 | return ioread32be(addr); | ||
| 77 | else | ||
| 78 | return readl_relaxed(addr); | ||
| 79 | } | ||
| 80 | |||
| 81 | /* Write controller register*/ | ||
| 82 | static inline void bcm_qspi_writel(bool be, | ||
| 83 | unsigned int data, void __iomem *addr) | ||
| 84 | { | ||
| 85 | if (be) | ||
| 86 | iowrite32be(data, addr); | ||
| 87 | else | ||
| 88 | writel_relaxed(data, addr); | ||
| 89 | } | ||
| 90 | |||
| 91 | static inline u32 get_qspi_mask(int type) | ||
| 92 | { | ||
| 93 | switch (type) { | ||
| 94 | case MSPI_DONE: | ||
| 95 | return INTR_MSPI_DONE_MASK; | ||
| 96 | case BSPI_DONE: | ||
| 97 | return BSPI_LR_INTERRUPTS_ALL; | ||
| 98 | case MSPI_BSPI_DONE: | ||
| 99 | return QSPI_INTERRUPTS_ALL; | ||
| 100 | case BSPI_ERR: | ||
| 101 | return BSPI_LR_INTERRUPTS_ERROR; | ||
| 102 | } | ||
| 103 | |||
| 104 | return 0; | ||
| 105 | } | ||
| 106 | |||
| 107 | /* The common driver functions to be called by the SoC platform driver */ | ||
| 108 | int bcm_qspi_probe(struct platform_device *pdev, | ||
| 109 | struct bcm_qspi_soc_intc *soc_intc); | ||
| 110 | int bcm_qspi_remove(struct platform_device *pdev); | ||
| 111 | |||
| 112 | /* pm_ops used by the SoC platform driver called on PM suspend/resume */ | ||
| 113 | extern const struct dev_pm_ops bcm_qspi_pm_ops; | ||
| 114 | |||
| 115 | #endif /* __SPI_BCM_QSPI_H__ */ | ||
diff --git a/drivers/spi/spi-brcmstb-qspi.c b/drivers/spi/spi-brcmstb-qspi.c new file mode 100644 index 000000000000..c7df92e7cf6f --- /dev/null +++ b/drivers/spi/spi-brcmstb-qspi.c | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2016 Broadcom | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License, version 2, as | ||
| 6 | * published by the Free Software Foundation (the "GPL"). | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, but | ||
| 9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 11 | * General Public License version 2 (GPLv2) for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * version 2 (GPLv2) along with this source code. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/device.h> | ||
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/platform_device.h> | ||
| 20 | #include <linux/of.h> | ||
| 21 | #include "spi-bcm-qspi.h" | ||
| 22 | |||
| 23 | static const struct of_device_id brcmstb_qspi_of_match[] = { | ||
| 24 | { .compatible = "brcm,spi-brcmstb-qspi" }, | ||
| 25 | { .compatible = "brcm,spi-brcmstb-mspi" }, | ||
| 26 | {}, | ||
| 27 | }; | ||
| 28 | MODULE_DEVICE_TABLE(of, brcmstb_qspi_of_match); | ||
| 29 | |||
| 30 | static int brcmstb_qspi_probe(struct platform_device *pdev) | ||
| 31 | { | ||
| 32 | return bcm_qspi_probe(pdev, NULL); | ||
| 33 | } | ||
| 34 | |||
| 35 | static int brcmstb_qspi_remove(struct platform_device *pdev) | ||
| 36 | { | ||
| 37 | return bcm_qspi_remove(pdev); | ||
| 38 | } | ||
| 39 | |||
| 40 | static struct platform_driver brcmstb_qspi_driver = { | ||
| 41 | .probe = brcmstb_qspi_probe, | ||
| 42 | .remove = brcmstb_qspi_remove, | ||
| 43 | .driver = { | ||
| 44 | .name = "brcmstb_qspi", | ||
| 45 | .pm = &bcm_qspi_pm_ops, | ||
| 46 | .of_match_table = brcmstb_qspi_of_match, | ||
| 47 | } | ||
| 48 | }; | ||
| 49 | module_platform_driver(brcmstb_qspi_driver); | ||
| 50 | |||
| 51 | MODULE_LICENSE("GPL v2"); | ||
| 52 | MODULE_AUTHOR("Kamal Dasu"); | ||
| 53 | MODULE_DESCRIPTION("Broadcom SPI driver for settop SoC"); | ||
diff --git a/drivers/spi/spi-cavium-thunderx.c b/drivers/spi/spi-cavium-thunderx.c new file mode 100644 index 000000000000..877937706240 --- /dev/null +++ b/drivers/spi/spi-cavium-thunderx.c | |||
| @@ -0,0 +1,120 @@ | |||
| 1 | /* | ||
| 2 | * Cavium ThunderX SPI driver. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2016 Cavium Inc. | ||
| 5 | * Authors: Jan Glauber <jglauber@cavium.com> | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <linux/module.h> | ||
| 9 | #include <linux/pci.h> | ||
| 10 | #include <linux/spi/spi.h> | ||
| 11 | |||
| 12 | #include "spi-cavium.h" | ||
| 13 | |||
| 14 | #define DRV_NAME "spi-thunderx" | ||
| 15 | |||
| 16 | #define SYS_FREQ_DEFAULT 700000000 /* 700 Mhz */ | ||
| 17 | |||
| 18 | static int thunderx_spi_probe(struct pci_dev *pdev, | ||
| 19 | const struct pci_device_id *ent) | ||
| 20 | { | ||
| 21 | struct device *dev = &pdev->dev; | ||
| 22 | struct spi_master *master; | ||
| 23 | struct octeon_spi *p; | ||
| 24 | int ret; | ||
| 25 | |||
| 26 | master = spi_alloc_master(dev, sizeof(struct octeon_spi)); | ||
| 27 | if (!master) | ||
| 28 | return -ENOMEM; | ||
| 29 | |||
| 30 | p = spi_master_get_devdata(master); | ||
| 31 | |||
| 32 | ret = pcim_enable_device(pdev); | ||
| 33 | if (ret) | ||
| 34 | goto error; | ||
| 35 | |||
| 36 | ret = pci_request_regions(pdev, DRV_NAME); | ||
| 37 | if (ret) | ||
| 38 | goto error; | ||
| 39 | |||
| 40 | p->register_base = pcim_iomap(pdev, 0, pci_resource_len(pdev, 0)); | ||
| 41 | if (!p->register_base) { | ||
| 42 | ret = -EINVAL; | ||
| 43 | goto error; | ||
| 44 | } | ||
| 45 | |||
| 46 | p->regs.config = 0x1000; | ||
| 47 | p->regs.status = 0x1008; | ||
| 48 | p->regs.tx = 0x1010; | ||
| 49 | p->regs.data = 0x1080; | ||
| 50 | |||
| 51 | p->clk = devm_clk_get(dev, NULL); | ||
| 52 | if (IS_ERR(p->clk)) { | ||
| 53 | ret = PTR_ERR(p->clk); | ||
| 54 | goto error; | ||
| 55 | } | ||
| 56 | |||
| 57 | ret = clk_prepare_enable(p->clk); | ||
| 58 | if (ret) | ||
| 59 | goto error; | ||
| 60 | |||
| 61 | p->sys_freq = clk_get_rate(p->clk); | ||
| 62 | if (!p->sys_freq) | ||
| 63 | p->sys_freq = SYS_FREQ_DEFAULT; | ||
| 64 | dev_info(dev, "Set system clock to %u\n", p->sys_freq); | ||
| 65 | |||
| 66 | master->num_chipselect = 4; | ||
| 67 | master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_CS_HIGH | | ||
| 68 | SPI_LSB_FIRST | SPI_3WIRE; | ||
| 69 | master->transfer_one_message = octeon_spi_transfer_one_message; | ||
| 70 | master->bits_per_word_mask = SPI_BPW_MASK(8); | ||
| 71 | master->max_speed_hz = OCTEON_SPI_MAX_CLOCK_HZ; | ||
| 72 | master->dev.of_node = pdev->dev.of_node; | ||
| 73 | |||
| 74 | pci_set_drvdata(pdev, master); | ||
| 75 | |||
| 76 | ret = devm_spi_register_master(dev, master); | ||
| 77 | if (ret) | ||
| 78 | goto error; | ||
| 79 | |||
| 80 | return 0; | ||
| 81 | |||
| 82 | error: | ||
| 83 | clk_disable_unprepare(p->clk); | ||
| 84 | spi_master_put(master); | ||
| 85 | return ret; | ||
| 86 | } | ||
| 87 | |||
| 88 | static void thunderx_spi_remove(struct pci_dev *pdev) | ||
| 89 | { | ||
| 90 | struct spi_master *master = pci_get_drvdata(pdev); | ||
| 91 | struct octeon_spi *p; | ||
| 92 | |||
| 93 | p = spi_master_get_devdata(master); | ||
| 94 | if (!p) | ||
| 95 | return; | ||
| 96 | |||
| 97 | clk_disable_unprepare(p->clk); | ||
| 98 | /* Put everything in a known state. */ | ||
| 99 | writeq(0, p->register_base + OCTEON_SPI_CFG(p)); | ||
| 100 | } | ||
| 101 | |||
| 102 | static const struct pci_device_id thunderx_spi_pci_id_table[] = { | ||
| 103 | { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, 0xa00b) }, | ||
| 104 | { 0, } | ||
| 105 | }; | ||
| 106 | |||
| 107 | MODULE_DEVICE_TABLE(pci, thunderx_spi_pci_id_table); | ||
| 108 | |||
| 109 | static struct pci_driver thunderx_spi_driver = { | ||
| 110 | .name = DRV_NAME, | ||
| 111 | .id_table = thunderx_spi_pci_id_table, | ||
| 112 | .probe = thunderx_spi_probe, | ||
| 113 | .remove = thunderx_spi_remove, | ||
| 114 | }; | ||
| 115 | |||
| 116 | module_pci_driver(thunderx_spi_driver); | ||
| 117 | |||
| 118 | MODULE_DESCRIPTION("Cavium, Inc. ThunderX SPI bus driver"); | ||
| 119 | MODULE_AUTHOR("Jan Glauber"); | ||
| 120 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/spi/spi-cavium.h b/drivers/spi/spi-cavium.h index 88c5f36e7ea7..1f91d61b745b 100644 --- a/drivers/spi/spi-cavium.h +++ b/drivers/spi/spi-cavium.h | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | #ifndef __SPI_CAVIUM_H | 1 | #ifndef __SPI_CAVIUM_H |
| 2 | #define __SPI_CAVIUM_H | 2 | #define __SPI_CAVIUM_H |
| 3 | 3 | ||
| 4 | #include <linux/clk.h> | ||
| 5 | |||
| 4 | #define OCTEON_SPI_MAX_BYTES 9 | 6 | #define OCTEON_SPI_MAX_BYTES 9 |
| 5 | #define OCTEON_SPI_MAX_CLOCK_HZ 16000000 | 7 | #define OCTEON_SPI_MAX_CLOCK_HZ 16000000 |
| 6 | 8 | ||
| @@ -17,6 +19,7 @@ struct octeon_spi { | |||
| 17 | u64 cs_enax; | 19 | u64 cs_enax; |
| 18 | int sys_freq; | 20 | int sys_freq; |
| 19 | struct octeon_spi_regs regs; | 21 | struct octeon_spi_regs regs; |
| 22 | struct clk *clk; | ||
| 20 | }; | 23 | }; |
| 21 | 24 | ||
| 22 | #define OCTEON_SPI_CFG(x) (x->regs.config) | 25 | #define OCTEON_SPI_CFG(x) (x->regs.config) |
diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index c09bb745693a..27960e46135d 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c | |||
| @@ -283,7 +283,6 @@ static int dw_spi_transfer_one(struct spi_master *master, | |||
| 283 | struct chip_data *chip = spi_get_ctldata(spi); | 283 | struct chip_data *chip = spi_get_ctldata(spi); |
| 284 | u8 imask = 0; | 284 | u8 imask = 0; |
| 285 | u16 txlevel = 0; | 285 | u16 txlevel = 0; |
| 286 | u16 clk_div; | ||
| 287 | u32 cr0; | 286 | u32 cr0; |
| 288 | int ret; | 287 | int ret; |
| 289 | 288 | ||
| @@ -298,13 +297,13 @@ static int dw_spi_transfer_one(struct spi_master *master, | |||
| 298 | spi_enable_chip(dws, 0); | 297 | spi_enable_chip(dws, 0); |
| 299 | 298 | ||
| 300 | /* Handle per transfer options for bpw and speed */ | 299 | /* Handle per transfer options for bpw and speed */ |
| 301 | if (transfer->speed_hz != chip->speed_hz) { | 300 | if (transfer->speed_hz != dws->current_freq) { |
| 302 | /* clk_div doesn't support odd number */ | 301 | if (transfer->speed_hz != chip->speed_hz) { |
| 303 | clk_div = (dws->max_freq / transfer->speed_hz + 1) & 0xfffe; | 302 | /* clk_div doesn't support odd number */ |
| 304 | 303 | chip->clk_div = (DIV_ROUND_UP(dws->max_freq, transfer->speed_hz) + 1) & 0xfffe; | |
| 305 | chip->speed_hz = transfer->speed_hz; | 304 | chip->speed_hz = transfer->speed_hz; |
| 306 | chip->clk_div = clk_div; | 305 | } |
| 307 | 306 | dws->current_freq = transfer->speed_hz; | |
| 308 | spi_set_clk(dws, chip->clk_div); | 307 | spi_set_clk(dws, chip->clk_div); |
| 309 | } | 308 | } |
| 310 | if (transfer->bits_per_word == 8) { | 309 | if (transfer->bits_per_word == 8) { |
diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 61bc3cbab38d..c21ca02f8ec5 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h | |||
| @@ -123,6 +123,7 @@ struct dw_spi { | |||
| 123 | u8 n_bytes; /* current is a 1/2 bytes op */ | 123 | u8 n_bytes; /* current is a 1/2 bytes op */ |
| 124 | u32 dma_width; | 124 | u32 dma_width; |
| 125 | irqreturn_t (*transfer_handler)(struct dw_spi *dws); | 125 | irqreturn_t (*transfer_handler)(struct dw_spi *dws); |
| 126 | u32 current_freq; /* frequency in hz */ | ||
| 126 | 127 | ||
| 127 | /* DMA info */ | 128 | /* DMA info */ |
| 128 | int dma_inited; | 129 | int dma_inited; |
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 9e9dadb52b3d..35c0dd945668 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c | |||
| @@ -159,7 +159,7 @@ struct fsl_dspi { | |||
| 159 | u8 cs; | 159 | u8 cs; |
| 160 | u16 void_write_data; | 160 | u16 void_write_data; |
| 161 | u32 cs_change; | 161 | u32 cs_change; |
| 162 | struct fsl_dspi_devtype_data *devtype_data; | 162 | const struct fsl_dspi_devtype_data *devtype_data; |
| 163 | 163 | ||
| 164 | wait_queue_head_t waitq; | 164 | wait_queue_head_t waitq; |
| 165 | u32 waitflags; | 165 | u32 waitflags; |
| @@ -624,10 +624,13 @@ static int dspi_resume(struct device *dev) | |||
| 624 | { | 624 | { |
| 625 | struct spi_master *master = dev_get_drvdata(dev); | 625 | struct spi_master *master = dev_get_drvdata(dev); |
| 626 | struct fsl_dspi *dspi = spi_master_get_devdata(master); | 626 | struct fsl_dspi *dspi = spi_master_get_devdata(master); |
| 627 | int ret; | ||
| 627 | 628 | ||
| 628 | pinctrl_pm_select_default_state(dev); | 629 | pinctrl_pm_select_default_state(dev); |
| 629 | 630 | ||
| 630 | clk_prepare_enable(dspi->clk); | 631 | ret = clk_prepare_enable(dspi->clk); |
| 632 | if (ret) | ||
| 633 | return ret; | ||
| 631 | spi_master_resume(master); | 634 | spi_master_resume(master); |
| 632 | 635 | ||
| 633 | return 0; | 636 | return 0; |
| @@ -651,8 +654,6 @@ static int dspi_probe(struct platform_device *pdev) | |||
| 651 | struct resource *res; | 654 | struct resource *res; |
| 652 | void __iomem *base; | 655 | void __iomem *base; |
| 653 | int ret = 0, cs_num, bus_num; | 656 | int ret = 0, cs_num, bus_num; |
| 654 | const struct of_device_id *of_id = | ||
| 655 | of_match_device(fsl_dspi_dt_ids, &pdev->dev); | ||
| 656 | 657 | ||
| 657 | master = spi_alloc_master(&pdev->dev, sizeof(struct fsl_dspi)); | 658 | master = spi_alloc_master(&pdev->dev, sizeof(struct fsl_dspi)); |
| 658 | if (!master) | 659 | if (!master) |
| @@ -686,7 +687,7 @@ static int dspi_probe(struct platform_device *pdev) | |||
| 686 | } | 687 | } |
| 687 | master->bus_num = bus_num; | 688 | master->bus_num = bus_num; |
| 688 | 689 | ||
| 689 | dspi->devtype_data = (struct fsl_dspi_devtype_data *)of_id->data; | 690 | dspi->devtype_data = of_device_get_match_data(&pdev->dev); |
| 690 | if (!dspi->devtype_data) { | 691 | if (!dspi->devtype_data) { |
| 691 | dev_err(&pdev->dev, "can't get devtype_data\n"); | 692 | dev_err(&pdev->dev, "can't get devtype_data\n"); |
| 692 | ret = -EFAULT; | 693 | ret = -EFAULT; |
| @@ -728,7 +729,9 @@ static int dspi_probe(struct platform_device *pdev) | |||
| 728 | dev_err(&pdev->dev, "unable to get clock\n"); | 729 | dev_err(&pdev->dev, "unable to get clock\n"); |
| 729 | goto out_master_put; | 730 | goto out_master_put; |
| 730 | } | 731 | } |
| 731 | clk_prepare_enable(dspi->clk); | 732 | ret = clk_prepare_enable(dspi->clk); |
| 733 | if (ret) | ||
| 734 | goto out_master_put; | ||
| 732 | 735 | ||
| 733 | master->max_speed_hz = | 736 | master->max_speed_hz = |
| 734 | clk_get_rate(dspi->clk) / dspi->devtype_data->max_clock_factor; | 737 | clk_get_rate(dspi->clk) / dspi->devtype_data->max_clock_factor; |
| @@ -760,7 +763,6 @@ static int dspi_remove(struct platform_device *pdev) | |||
| 760 | /* Disconnect from the SPI framework */ | 763 | /* Disconnect from the SPI framework */ |
| 761 | clk_disable_unprepare(dspi->clk); | 764 | clk_disable_unprepare(dspi->clk); |
| 762 | spi_unregister_master(dspi->master); | 765 | spi_unregister_master(dspi->master); |
| 763 | spi_master_put(dspi->master); | ||
| 764 | 766 | ||
| 765 | return 0; | 767 | return 0; |
| 766 | } | 768 | } |
diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index 8d85a3c343da..7451585a080e 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c | |||
| @@ -12,7 +12,6 @@ | |||
| 12 | #include <linux/err.h> | 12 | #include <linux/err.h> |
| 13 | #include <linux/fsl_devices.h> | 13 | #include <linux/fsl_devices.h> |
| 14 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
| 15 | #include <linux/irq.h> | ||
| 16 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 17 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
| 18 | #include <linux/of.h> | 17 | #include <linux/of.h> |
| @@ -27,40 +26,29 @@ | |||
| 27 | #include "spi-fsl-lib.h" | 26 | #include "spi-fsl-lib.h" |
| 28 | 27 | ||
| 29 | /* eSPI Controller registers */ | 28 | /* eSPI Controller registers */ |
| 30 | struct fsl_espi_reg { | 29 | #define ESPI_SPMODE 0x00 /* eSPI mode register */ |
| 31 | __be32 mode; /* 0x000 - eSPI mode register */ | 30 | #define ESPI_SPIE 0x04 /* eSPI event register */ |
| 32 | __be32 event; /* 0x004 - eSPI event register */ | 31 | #define ESPI_SPIM 0x08 /* eSPI mask register */ |
| 33 | __be32 mask; /* 0x008 - eSPI mask register */ | 32 | #define ESPI_SPCOM 0x0c /* eSPI command register */ |
| 34 | __be32 command; /* 0x00c - eSPI command register */ | 33 | #define ESPI_SPITF 0x10 /* eSPI transmit FIFO access register*/ |
| 35 | __be32 transmit; /* 0x010 - eSPI transmit FIFO access register*/ | 34 | #define ESPI_SPIRF 0x14 /* eSPI receive FIFO access register*/ |
| 36 | __be32 receive; /* 0x014 - eSPI receive FIFO access register*/ | 35 | #define ESPI_SPMODE0 0x20 /* eSPI cs0 mode register */ |
| 37 | u8 res[8]; /* 0x018 - 0x01c reserved */ | ||
| 38 | __be32 csmode[4]; /* 0x020 - 0x02c eSPI cs mode register */ | ||
| 39 | }; | ||
| 40 | 36 | ||
| 41 | struct fsl_espi_transfer { | 37 | #define ESPI_SPMODEx(x) (ESPI_SPMODE0 + (x) * 4) |
| 42 | const void *tx_buf; | ||
| 43 | void *rx_buf; | ||
| 44 | unsigned len; | ||
| 45 | unsigned n_tx; | ||
| 46 | unsigned n_rx; | ||
| 47 | unsigned actual_length; | ||
| 48 | int status; | ||
| 49 | }; | ||
| 50 | 38 | ||
| 51 | /* eSPI Controller mode register definitions */ | 39 | /* eSPI Controller mode register definitions */ |
| 52 | #define SPMODE_ENABLE (1 << 31) | 40 | #define SPMODE_ENABLE BIT(31) |
| 53 | #define SPMODE_LOOP (1 << 30) | 41 | #define SPMODE_LOOP BIT(30) |
| 54 | #define SPMODE_TXTHR(x) ((x) << 8) | 42 | #define SPMODE_TXTHR(x) ((x) << 8) |
| 55 | #define SPMODE_RXTHR(x) ((x) << 0) | 43 | #define SPMODE_RXTHR(x) ((x) << 0) |
| 56 | 44 | ||
| 57 | /* eSPI Controller CS mode register definitions */ | 45 | /* eSPI Controller CS mode register definitions */ |
| 58 | #define CSMODE_CI_INACTIVEHIGH (1 << 31) | 46 | #define CSMODE_CI_INACTIVEHIGH BIT(31) |
| 59 | #define CSMODE_CP_BEGIN_EDGECLK (1 << 30) | 47 | #define CSMODE_CP_BEGIN_EDGECLK BIT(30) |
| 60 | #define CSMODE_REV (1 << 29) | 48 | #define CSMODE_REV BIT(29) |
| 61 | #define CSMODE_DIV16 (1 << 28) | 49 | #define CSMODE_DIV16 BIT(28) |
| 62 | #define CSMODE_PM(x) ((x) << 24) | 50 | #define CSMODE_PM(x) ((x) << 24) |
| 63 | #define CSMODE_POL_1 (1 << 20) | 51 | #define CSMODE_POL_1 BIT(20) |
| 64 | #define CSMODE_LEN(x) ((x) << 16) | 52 | #define CSMODE_LEN(x) ((x) << 16) |
| 65 | #define CSMODE_BEF(x) ((x) << 12) | 53 | #define CSMODE_BEF(x) ((x) << 12) |
| 66 | #define CSMODE_AFT(x) ((x) << 8) | 54 | #define CSMODE_AFT(x) ((x) << 8) |
| @@ -72,29 +60,114 @@ struct fsl_espi_transfer { | |||
| 72 | | CSMODE_AFT(0) | CSMODE_CG(1)) | 60 | | CSMODE_AFT(0) | CSMODE_CG(1)) |
| 73 | 61 | ||
| 74 | /* SPIE register values */ | 62 | /* SPIE register values */ |
| 75 | #define SPIE_NE 0x00000200 /* Not empty */ | ||
| 76 | #define SPIE_NF 0x00000100 /* Not full */ | ||
| 77 | |||
| 78 | /* SPIM register values */ | ||
| 79 | #define SPIM_NE 0x00000200 /* Not empty */ | ||
| 80 | #define SPIM_NF 0x00000100 /* Not full */ | ||
| 81 | #define SPIE_RXCNT(reg) ((reg >> 24) & 0x3F) | 63 | #define SPIE_RXCNT(reg) ((reg >> 24) & 0x3F) |
| 82 | #define SPIE_TXCNT(reg) ((reg >> 16) & 0x3F) | 64 | #define SPIE_TXCNT(reg) ((reg >> 16) & 0x3F) |
| 65 | #define SPIE_TXE BIT(15) /* TX FIFO empty */ | ||
| 66 | #define SPIE_DON BIT(14) /* TX done */ | ||
| 67 | #define SPIE_RXT BIT(13) /* RX FIFO threshold */ | ||
| 68 | #define SPIE_RXF BIT(12) /* RX FIFO full */ | ||
| 69 | #define SPIE_TXT BIT(11) /* TX FIFO threshold*/ | ||
| 70 | #define SPIE_RNE BIT(9) /* RX FIFO not empty */ | ||
| 71 | #define SPIE_TNF BIT(8) /* TX FIFO not full */ | ||
| 72 | |||
| 73 | /* SPIM register values */ | ||
| 74 | #define SPIM_TXE BIT(15) /* TX FIFO empty */ | ||
| 75 | #define SPIM_DON BIT(14) /* TX done */ | ||
| 76 | #define SPIM_RXT BIT(13) /* RX FIFO threshold */ | ||
| 77 | #define SPIM_RXF BIT(12) /* RX FIFO full */ | ||
| 78 | #define SPIM_TXT BIT(11) /* TX FIFO threshold*/ | ||
| 79 | #define SPIM_RNE BIT(9) /* RX FIFO not empty */ | ||
| 80 | #define SPIM_TNF BIT(8) /* TX FIFO not full */ | ||
| 83 | 81 | ||
| 84 | /* SPCOM register values */ | 82 | /* SPCOM register values */ |
| 85 | #define SPCOM_CS(x) ((x) << 30) | 83 | #define SPCOM_CS(x) ((x) << 30) |
| 84 | #define SPCOM_DO BIT(28) /* Dual output */ | ||
| 85 | #define SPCOM_TO BIT(27) /* TX only */ | ||
| 86 | #define SPCOM_RXSKIP(x) ((x) << 16) | ||
| 86 | #define SPCOM_TRANLEN(x) ((x) << 0) | 87 | #define SPCOM_TRANLEN(x) ((x) << 0) |
| 88 | |||
| 87 | #define SPCOM_TRANLEN_MAX 0x10000 /* Max transaction length */ | 89 | #define SPCOM_TRANLEN_MAX 0x10000 /* Max transaction length */ |
| 88 | 90 | ||
| 89 | #define AUTOSUSPEND_TIMEOUT 2000 | 91 | #define AUTOSUSPEND_TIMEOUT 2000 |
| 90 | 92 | ||
| 93 | static inline u32 fsl_espi_read_reg(struct mpc8xxx_spi *mspi, int offset) | ||
| 94 | { | ||
| 95 | return ioread32be(mspi->reg_base + offset); | ||
| 96 | } | ||
| 97 | |||
| 98 | static inline u8 fsl_espi_read_reg8(struct mpc8xxx_spi *mspi, int offset) | ||
| 99 | { | ||
| 100 | return ioread8(mspi->reg_base + offset); | ||
| 101 | } | ||
| 102 | |||
| 103 | static inline void fsl_espi_write_reg(struct mpc8xxx_spi *mspi, int offset, | ||
| 104 | u32 val) | ||
| 105 | { | ||
| 106 | iowrite32be(val, mspi->reg_base + offset); | ||
| 107 | } | ||
| 108 | |||
| 109 | static inline void fsl_espi_write_reg8(struct mpc8xxx_spi *mspi, int offset, | ||
| 110 | u8 val) | ||
| 111 | { | ||
| 112 | iowrite8(val, mspi->reg_base + offset); | ||
| 113 | } | ||
| 114 | |||
| 115 | static void fsl_espi_copy_to_buf(struct spi_message *m, | ||
| 116 | struct mpc8xxx_spi *mspi) | ||
| 117 | { | ||
| 118 | struct spi_transfer *t; | ||
| 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 | } | ||
| 129 | |||
| 130 | static void fsl_espi_copy_from_buf(struct spi_message *m, | ||
| 131 | struct mpc8xxx_spi *mspi) | ||
| 132 | { | ||
| 133 | struct spi_transfer *t; | ||
| 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 | } | ||
| 142 | |||
| 143 | static int fsl_espi_check_message(struct spi_message *m) | ||
| 144 | { | ||
| 145 | struct mpc8xxx_spi *mspi = spi_master_get_devdata(m->spi->master); | ||
| 146 | struct spi_transfer *t, *first; | ||
| 147 | |||
| 148 | if (m->frame_length > SPCOM_TRANLEN_MAX) { | ||
| 149 | dev_err(mspi->dev, "message too long, size is %u bytes\n", | ||
| 150 | m->frame_length); | ||
| 151 | return -EMSGSIZE; | ||
| 152 | } | ||
| 153 | |||
| 154 | first = list_first_entry(&m->transfers, struct spi_transfer, | ||
| 155 | transfer_list); | ||
| 156 | list_for_each_entry(t, &m->transfers, transfer_list) { | ||
| 157 | if (first->bits_per_word != t->bits_per_word || | ||
| 158 | first->speed_hz != t->speed_hz) { | ||
| 159 | dev_err(mspi->dev, "bits_per_word/speed_hz should be the same for all transfers\n"); | ||
| 160 | return -EINVAL; | ||
| 161 | } | ||
| 162 | } | ||
| 163 | |||
| 164 | return 0; | ||
| 165 | } | ||
| 166 | |||
| 91 | static void fsl_espi_change_mode(struct spi_device *spi) | 167 | static void fsl_espi_change_mode(struct spi_device *spi) |
| 92 | { | 168 | { |
| 93 | struct mpc8xxx_spi *mspi = spi_master_get_devdata(spi->master); | 169 | struct mpc8xxx_spi *mspi = spi_master_get_devdata(spi->master); |
| 94 | struct spi_mpc8xxx_cs *cs = spi->controller_state; | 170 | struct spi_mpc8xxx_cs *cs = spi->controller_state; |
| 95 | struct fsl_espi_reg *reg_base = mspi->reg_base; | ||
| 96 | __be32 __iomem *mode = ®_base->csmode[spi->chip_select]; | ||
| 97 | __be32 __iomem *espi_mode = ®_base->mode; | ||
| 98 | u32 tmp; | 171 | u32 tmp; |
| 99 | unsigned long flags; | 172 | unsigned long flags; |
| 100 | 173 | ||
| @@ -102,10 +175,11 @@ static void fsl_espi_change_mode(struct spi_device *spi) | |||
| 102 | local_irq_save(flags); | 175 | local_irq_save(flags); |
| 103 | 176 | ||
| 104 | /* Turn off SPI unit prior changing mode */ | 177 | /* Turn off SPI unit prior changing mode */ |
| 105 | tmp = mpc8xxx_spi_read_reg(espi_mode); | 178 | tmp = fsl_espi_read_reg(mspi, ESPI_SPMODE); |
| 106 | mpc8xxx_spi_write_reg(espi_mode, tmp & ~SPMODE_ENABLE); | 179 | fsl_espi_write_reg(mspi, ESPI_SPMODE, tmp & ~SPMODE_ENABLE); |
| 107 | mpc8xxx_spi_write_reg(mode, cs->hw_mode); | 180 | fsl_espi_write_reg(mspi, ESPI_SPMODEx(spi->chip_select), |
| 108 | mpc8xxx_spi_write_reg(espi_mode, tmp); | 181 | cs->hw_mode); |
| 182 | fsl_espi_write_reg(mspi, ESPI_SPMODE, tmp); | ||
| 109 | 183 | ||
| 110 | local_irq_restore(flags); | 184 | local_irq_restore(flags); |
| 111 | } | 185 | } |
| @@ -131,27 +205,15 @@ static u32 fsl_espi_tx_buf_lsb(struct mpc8xxx_spi *mpc8xxx_spi) | |||
| 131 | return data; | 205 | return data; |
| 132 | } | 206 | } |
| 133 | 207 | ||
| 134 | static int fsl_espi_setup_transfer(struct spi_device *spi, | 208 | static void fsl_espi_setup_transfer(struct spi_device *spi, |
| 135 | struct spi_transfer *t) | 209 | struct spi_transfer *t) |
| 136 | { | 210 | { |
| 137 | struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); | 211 | struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); |
| 138 | int bits_per_word = 0; | 212 | int bits_per_word = t ? t->bits_per_word : spi->bits_per_word; |
| 213 | u32 hz = t ? t->speed_hz : spi->max_speed_hz; | ||
| 139 | u8 pm; | 214 | u8 pm; |
| 140 | u32 hz = 0; | ||
| 141 | struct spi_mpc8xxx_cs *cs = spi->controller_state; | 215 | struct spi_mpc8xxx_cs *cs = spi->controller_state; |
| 142 | 216 | ||
| 143 | if (t) { | ||
| 144 | bits_per_word = t->bits_per_word; | ||
| 145 | hz = t->speed_hz; | ||
| 146 | } | ||
| 147 | |||
| 148 | /* spi_transfer level calls that work per-word */ | ||
| 149 | if (!bits_per_word) | ||
| 150 | bits_per_word = spi->bits_per_word; | ||
| 151 | |||
| 152 | if (!hz) | ||
| 153 | hz = spi->max_speed_hz; | ||
| 154 | |||
| 155 | cs->rx_shift = 0; | 217 | cs->rx_shift = 0; |
| 156 | cs->tx_shift = 0; | 218 | cs->tx_shift = 0; |
| 157 | cs->get_rx = mpc8xxx_spi_rx_buf_u32; | 219 | cs->get_rx = mpc8xxx_spi_rx_buf_u32; |
| @@ -169,12 +231,10 @@ static int fsl_espi_setup_transfer(struct spi_device *spi, | |||
| 169 | mpc8xxx_spi->get_rx = cs->get_rx; | 231 | mpc8xxx_spi->get_rx = cs->get_rx; |
| 170 | mpc8xxx_spi->get_tx = cs->get_tx; | 232 | mpc8xxx_spi->get_tx = cs->get_tx; |
| 171 | 233 | ||
| 172 | bits_per_word = bits_per_word - 1; | ||
| 173 | |||
| 174 | /* mask out bits we are going to set */ | 234 | /* mask out bits we are going to set */ |
| 175 | cs->hw_mode &= ~(CSMODE_LEN(0xF) | CSMODE_DIV16 | CSMODE_PM(0xF)); | 235 | cs->hw_mode &= ~(CSMODE_LEN(0xF) | CSMODE_DIV16 | CSMODE_PM(0xF)); |
| 176 | 236 | ||
| 177 | cs->hw_mode |= CSMODE_LEN(bits_per_word); | 237 | cs->hw_mode |= CSMODE_LEN(bits_per_word - 1); |
| 178 | 238 | ||
| 179 | if ((mpc8xxx_spi->spibrg / hz) > 64) { | 239 | if ((mpc8xxx_spi->spibrg / hz) > 64) { |
| 180 | cs->hw_mode |= CSMODE_DIV16; | 240 | cs->hw_mode |= CSMODE_DIV16; |
| @@ -196,36 +256,16 @@ static int fsl_espi_setup_transfer(struct spi_device *spi, | |||
| 196 | cs->hw_mode |= CSMODE_PM(pm); | 256 | cs->hw_mode |= CSMODE_PM(pm); |
| 197 | 257 | ||
| 198 | fsl_espi_change_mode(spi); | 258 | fsl_espi_change_mode(spi); |
| 199 | return 0; | ||
| 200 | } | ||
| 201 | |||
| 202 | static int fsl_espi_cpu_bufs(struct mpc8xxx_spi *mspi, struct spi_transfer *t, | ||
| 203 | unsigned int len) | ||
| 204 | { | ||
| 205 | u32 word; | ||
| 206 | struct fsl_espi_reg *reg_base = mspi->reg_base; | ||
| 207 | |||
| 208 | mspi->count = len; | ||
| 209 | |||
| 210 | /* enable rx ints */ | ||
| 211 | mpc8xxx_spi_write_reg(®_base->mask, SPIM_NE); | ||
| 212 | |||
| 213 | /* transmit word */ | ||
| 214 | word = mspi->get_tx(mspi); | ||
| 215 | mpc8xxx_spi_write_reg(®_base->transmit, word); | ||
| 216 | |||
| 217 | return 0; | ||
| 218 | } | 259 | } |
| 219 | 260 | ||
| 220 | static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t) | 261 | static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t) |
| 221 | { | 262 | { |
| 222 | struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); | 263 | struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); |
| 223 | struct fsl_espi_reg *reg_base = mpc8xxx_spi->reg_base; | 264 | u32 word; |
| 224 | unsigned int len = t->len; | ||
| 225 | int ret; | 265 | int ret; |
| 226 | 266 | ||
| 227 | mpc8xxx_spi->len = t->len; | 267 | mpc8xxx_spi->len = t->len; |
| 228 | len = roundup(len, 4) / 4; | 268 | mpc8xxx_spi->count = roundup(t->len, 4) / 4; |
| 229 | 269 | ||
| 230 | mpc8xxx_spi->tx = t->tx_buf; | 270 | mpc8xxx_spi->tx = t->tx_buf; |
| 231 | mpc8xxx_spi->rx = t->rx_buf; | 271 | mpc8xxx_spi->rx = t->rx_buf; |
| @@ -233,17 +273,15 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
| 233 | reinit_completion(&mpc8xxx_spi->done); | 273 | reinit_completion(&mpc8xxx_spi->done); |
| 234 | 274 | ||
| 235 | /* Set SPCOM[CS] and SPCOM[TRANLEN] field */ | 275 | /* Set SPCOM[CS] and SPCOM[TRANLEN] field */ |
| 236 | if (t->len > SPCOM_TRANLEN_MAX) { | 276 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPCOM, |
| 237 | dev_err(mpc8xxx_spi->dev, "Transaction length (%d)" | ||
| 238 | " beyond the SPCOM[TRANLEN] field\n", t->len); | ||
| 239 | return -EINVAL; | ||
| 240 | } | ||
| 241 | mpc8xxx_spi_write_reg(®_base->command, | ||
| 242 | (SPCOM_CS(spi->chip_select) | SPCOM_TRANLEN(t->len - 1))); | 277 | (SPCOM_CS(spi->chip_select) | SPCOM_TRANLEN(t->len - 1))); |
| 243 | 278 | ||
| 244 | ret = fsl_espi_cpu_bufs(mpc8xxx_spi, t, len); | 279 | /* enable rx ints */ |
| 245 | if (ret) | 280 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, SPIM_RNE); |
| 246 | return ret; | 281 | |
| 282 | /* transmit word */ | ||
| 283 | word = mpc8xxx_spi->get_tx(mpc8xxx_spi); | ||
| 284 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPITF, word); | ||
| 247 | 285 | ||
| 248 | /* Won't hang up forever, SPI bus sometimes got lost interrupts... */ | 286 | /* Won't hang up forever, SPI bus sometimes got lost interrupts... */ |
| 249 | ret = wait_for_completion_timeout(&mpc8xxx_spi->done, 2 * HZ); | 287 | ret = wait_for_completion_timeout(&mpc8xxx_spi->done, 2 * HZ); |
| @@ -253,230 +291,76 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
| 253 | mpc8xxx_spi->count); | 291 | mpc8xxx_spi->count); |
| 254 | 292 | ||
| 255 | /* disable rx ints */ | 293 | /* disable rx ints */ |
| 256 | mpc8xxx_spi_write_reg(®_base->mask, 0); | 294 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, 0); |
| 257 | 295 | ||
| 258 | return mpc8xxx_spi->count; | 296 | return mpc8xxx_spi->count > 0 ? -EMSGSIZE : 0; |
| 259 | } | 297 | } |
| 260 | 298 | ||
| 261 | static inline void fsl_espi_addr2cmd(unsigned int addr, u8 *cmd) | 299 | static int fsl_espi_trans(struct spi_message *m, struct spi_transfer *trans) |
| 262 | { | ||
| 263 | if (cmd) { | ||
| 264 | cmd[1] = (u8)(addr >> 16); | ||
| 265 | cmd[2] = (u8)(addr >> 8); | ||
| 266 | cmd[3] = (u8)(addr >> 0); | ||
| 267 | } | ||
| 268 | } | ||
| 269 | |||
| 270 | static inline unsigned int fsl_espi_cmd2addr(u8 *cmd) | ||
| 271 | { | ||
| 272 | if (cmd) | ||
| 273 | return cmd[1] << 16 | cmd[2] << 8 | cmd[3] << 0; | ||
| 274 | |||
| 275 | return 0; | ||
| 276 | } | ||
| 277 | |||
| 278 | static void fsl_espi_do_trans(struct spi_message *m, | ||
| 279 | struct fsl_espi_transfer *tr) | ||
| 280 | { | 300 | { |
| 301 | struct mpc8xxx_spi *mspi = spi_master_get_devdata(m->spi->master); | ||
| 281 | struct spi_device *spi = m->spi; | 302 | struct spi_device *spi = m->spi; |
| 282 | struct mpc8xxx_spi *mspi = spi_master_get_devdata(spi->master); | 303 | int ret; |
| 283 | struct fsl_espi_transfer *espi_trans = tr; | ||
| 284 | struct spi_message message; | ||
| 285 | struct spi_transfer *t, *first, trans; | ||
| 286 | int status = 0; | ||
| 287 | |||
| 288 | spi_message_init(&message); | ||
| 289 | memset(&trans, 0, sizeof(trans)); | ||
| 290 | |||
| 291 | first = list_first_entry(&m->transfers, struct spi_transfer, | ||
| 292 | transfer_list); | ||
| 293 | list_for_each_entry(t, &m->transfers, transfer_list) { | ||
| 294 | if ((first->bits_per_word != t->bits_per_word) || | ||
| 295 | (first->speed_hz != t->speed_hz)) { | ||
| 296 | espi_trans->status = -EINVAL; | ||
| 297 | dev_err(mspi->dev, | ||
| 298 | "bits_per_word/speed_hz should be same for the same SPI transfer\n"); | ||
| 299 | return; | ||
| 300 | } | ||
| 301 | |||
| 302 | trans.speed_hz = t->speed_hz; | ||
| 303 | trans.bits_per_word = t->bits_per_word; | ||
| 304 | trans.delay_usecs = max(first->delay_usecs, t->delay_usecs); | ||
| 305 | } | ||
| 306 | |||
| 307 | trans.len = espi_trans->len; | ||
| 308 | trans.tx_buf = espi_trans->tx_buf; | ||
| 309 | trans.rx_buf = espi_trans->rx_buf; | ||
| 310 | spi_message_add_tail(&trans, &message); | ||
| 311 | |||
| 312 | list_for_each_entry(t, &message.transfers, transfer_list) { | ||
| 313 | if (t->bits_per_word || t->speed_hz) { | ||
| 314 | status = -EINVAL; | ||
| 315 | |||
| 316 | status = fsl_espi_setup_transfer(spi, t); | ||
| 317 | if (status < 0) | ||
| 318 | break; | ||
| 319 | } | ||
| 320 | 304 | ||
| 321 | if (t->len) | 305 | fsl_espi_copy_to_buf(m, mspi); |
| 322 | status = fsl_espi_bufs(spi, t); | 306 | fsl_espi_setup_transfer(spi, trans); |
| 323 | 307 | ||
| 324 | if (status) { | 308 | ret = fsl_espi_bufs(spi, trans); |
| 325 | status = -EMSGSIZE; | ||
| 326 | break; | ||
| 327 | } | ||
| 328 | 309 | ||
| 329 | if (t->delay_usecs) | 310 | if (trans->delay_usecs) |
| 330 | udelay(t->delay_usecs); | 311 | udelay(trans->delay_usecs); |
| 331 | } | ||
| 332 | 312 | ||
| 333 | espi_trans->status = status; | ||
| 334 | fsl_espi_setup_transfer(spi, NULL); | 313 | fsl_espi_setup_transfer(spi, NULL); |
| 335 | } | ||
| 336 | |||
| 337 | static void fsl_espi_cmd_trans(struct spi_message *m, | ||
| 338 | struct fsl_espi_transfer *trans, u8 *rx_buff) | ||
| 339 | { | ||
| 340 | struct spi_transfer *t; | ||
| 341 | u8 *local_buf; | ||
| 342 | int i = 0; | ||
| 343 | struct fsl_espi_transfer *espi_trans = trans; | ||
| 344 | |||
| 345 | local_buf = kzalloc(SPCOM_TRANLEN_MAX, GFP_KERNEL); | ||
| 346 | if (!local_buf) { | ||
| 347 | espi_trans->status = -ENOMEM; | ||
| 348 | return; | ||
| 349 | } | ||
| 350 | |||
| 351 | list_for_each_entry(t, &m->transfers, transfer_list) { | ||
| 352 | if (t->tx_buf) { | ||
| 353 | memcpy(local_buf + i, t->tx_buf, t->len); | ||
| 354 | i += t->len; | ||
| 355 | } | ||
| 356 | } | ||
| 357 | |||
| 358 | espi_trans->tx_buf = local_buf; | ||
| 359 | espi_trans->rx_buf = local_buf; | ||
| 360 | fsl_espi_do_trans(m, espi_trans); | ||
| 361 | 314 | ||
| 362 | espi_trans->actual_length = espi_trans->len; | 315 | if (!ret) |
| 363 | kfree(local_buf); | 316 | fsl_espi_copy_from_buf(m, mspi); |
| 364 | } | ||
| 365 | |||
| 366 | static void fsl_espi_rw_trans(struct spi_message *m, | ||
| 367 | struct fsl_espi_transfer *trans, u8 *rx_buff) | ||
| 368 | { | ||
| 369 | struct fsl_espi_transfer *espi_trans = trans; | ||
| 370 | unsigned int total_len = espi_trans->len; | ||
| 371 | struct spi_transfer *t; | ||
| 372 | u8 *local_buf; | ||
| 373 | u8 *rx_buf = rx_buff; | ||
| 374 | unsigned int trans_len; | ||
| 375 | unsigned int addr; | ||
| 376 | unsigned int tx_only; | ||
| 377 | unsigned int rx_pos = 0; | ||
| 378 | unsigned int pos; | ||
| 379 | int i, loop; | ||
| 380 | |||
| 381 | local_buf = kzalloc(SPCOM_TRANLEN_MAX, GFP_KERNEL); | ||
| 382 | if (!local_buf) { | ||
| 383 | espi_trans->status = -ENOMEM; | ||
| 384 | return; | ||
| 385 | } | ||
| 386 | |||
| 387 | for (pos = 0, loop = 0; pos < total_len; pos += trans_len, loop++) { | ||
| 388 | trans_len = total_len - pos; | ||
| 389 | |||
| 390 | i = 0; | ||
| 391 | tx_only = 0; | ||
| 392 | list_for_each_entry(t, &m->transfers, transfer_list) { | ||
| 393 | if (t->tx_buf) { | ||
| 394 | memcpy(local_buf + i, t->tx_buf, t->len); | ||
| 395 | i += t->len; | ||
| 396 | if (!t->rx_buf) | ||
| 397 | tx_only += t->len; | ||
| 398 | } | ||
| 399 | } | ||
| 400 | |||
| 401 | /* Add additional TX bytes to compensate SPCOM_TRANLEN_MAX */ | ||
| 402 | if (loop > 0) | ||
| 403 | trans_len += tx_only; | ||
| 404 | |||
| 405 | if (trans_len > SPCOM_TRANLEN_MAX) | ||
| 406 | trans_len = SPCOM_TRANLEN_MAX; | ||
| 407 | |||
| 408 | /* Update device offset */ | ||
| 409 | if (pos > 0) { | ||
| 410 | addr = fsl_espi_cmd2addr(local_buf); | ||
| 411 | addr += rx_pos; | ||
| 412 | fsl_espi_addr2cmd(addr, local_buf); | ||
| 413 | } | ||
| 414 | |||
| 415 | espi_trans->len = trans_len; | ||
| 416 | espi_trans->tx_buf = local_buf; | ||
| 417 | espi_trans->rx_buf = local_buf; | ||
| 418 | fsl_espi_do_trans(m, espi_trans); | ||
| 419 | |||
| 420 | /* If there is at least one RX byte then copy it to rx_buf */ | ||
| 421 | if (tx_only < SPCOM_TRANLEN_MAX) | ||
| 422 | memcpy(rx_buf + rx_pos, espi_trans->rx_buf + tx_only, | ||
| 423 | trans_len - tx_only); | ||
| 424 | |||
| 425 | rx_pos += trans_len - tx_only; | ||
| 426 | |||
| 427 | if (loop > 0) | ||
| 428 | espi_trans->actual_length += espi_trans->len - tx_only; | ||
| 429 | else | ||
| 430 | espi_trans->actual_length += espi_trans->len; | ||
| 431 | } | ||
| 432 | 317 | ||
| 433 | kfree(local_buf); | 318 | return ret; |
| 434 | } | 319 | } |
| 435 | 320 | ||
| 436 | static int fsl_espi_do_one_msg(struct spi_master *master, | 321 | static int fsl_espi_do_one_msg(struct spi_master *master, |
| 437 | struct spi_message *m) | 322 | struct spi_message *m) |
| 438 | { | 323 | { |
| 439 | struct spi_transfer *t; | 324 | struct mpc8xxx_spi *mspi = spi_master_get_devdata(m->spi->master); |
| 440 | u8 *rx_buf = NULL; | 325 | unsigned int delay_usecs = 0; |
| 441 | unsigned int n_tx = 0; | 326 | struct spi_transfer *t, trans = {}; |
| 442 | unsigned int n_rx = 0; | 327 | int ret; |
| 443 | unsigned int xfer_len = 0; | 328 | |
| 444 | struct fsl_espi_transfer espi_trans; | 329 | ret = fsl_espi_check_message(m); |
| 330 | if (ret) | ||
| 331 | goto out; | ||
| 445 | 332 | ||
| 446 | list_for_each_entry(t, &m->transfers, transfer_list) { | 333 | list_for_each_entry(t, &m->transfers, transfer_list) { |
| 447 | if (t->tx_buf) | 334 | if (t->delay_usecs > delay_usecs) |
| 448 | n_tx += t->len; | 335 | delay_usecs = t->delay_usecs; |
| 449 | if (t->rx_buf) { | ||
| 450 | n_rx += t->len; | ||
| 451 | rx_buf = t->rx_buf; | ||
| 452 | } | ||
| 453 | if ((t->tx_buf) || (t->rx_buf)) | ||
| 454 | xfer_len += t->len; | ||
| 455 | } | 336 | } |
| 456 | 337 | ||
| 457 | espi_trans.n_tx = n_tx; | 338 | t = list_first_entry(&m->transfers, struct spi_transfer, |
| 458 | espi_trans.n_rx = n_rx; | 339 | transfer_list); |
| 459 | espi_trans.len = xfer_len; | 340 | |
| 460 | espi_trans.actual_length = 0; | 341 | trans.len = m->frame_length; |
| 461 | espi_trans.status = 0; | 342 | trans.speed_hz = t->speed_hz; |
| 343 | trans.bits_per_word = t->bits_per_word; | ||
| 344 | trans.delay_usecs = delay_usecs; | ||
| 345 | trans.tx_buf = mspi->local_buf; | ||
| 346 | trans.rx_buf = mspi->local_buf; | ||
| 347 | |||
| 348 | if (trans.len) | ||
| 349 | ret = fsl_espi_trans(m, &trans); | ||
| 462 | 350 | ||
| 463 | if (!rx_buf) | 351 | m->actual_length = ret ? 0 : trans.len; |
| 464 | fsl_espi_cmd_trans(m, &espi_trans, NULL); | 352 | out: |
| 465 | else | 353 | if (m->status == -EINPROGRESS) |
| 466 | fsl_espi_rw_trans(m, &espi_trans, rx_buf); | 354 | m->status = ret; |
| 467 | 355 | ||
| 468 | m->actual_length = espi_trans.actual_length; | ||
| 469 | m->status = espi_trans.status; | ||
| 470 | spi_finalize_current_message(master); | 356 | spi_finalize_current_message(master); |
| 471 | return 0; | 357 | |
| 358 | return ret; | ||
| 472 | } | 359 | } |
| 473 | 360 | ||
| 474 | static int fsl_espi_setup(struct spi_device *spi) | 361 | static int fsl_espi_setup(struct spi_device *spi) |
| 475 | { | 362 | { |
| 476 | struct mpc8xxx_spi *mpc8xxx_spi; | 363 | struct mpc8xxx_spi *mpc8xxx_spi; |
| 477 | struct fsl_espi_reg *reg_base; | ||
| 478 | int retval; | ||
| 479 | u32 hw_mode; | ||
| 480 | u32 loop_mode; | 364 | u32 loop_mode; |
| 481 | struct spi_mpc8xxx_cs *cs = spi_get_ctldata(spi); | 365 | struct spi_mpc8xxx_cs *cs = spi_get_ctldata(spi); |
| 482 | 366 | ||
| @@ -491,13 +375,11 @@ static int fsl_espi_setup(struct spi_device *spi) | |||
| 491 | } | 375 | } |
| 492 | 376 | ||
| 493 | mpc8xxx_spi = spi_master_get_devdata(spi->master); | 377 | mpc8xxx_spi = spi_master_get_devdata(spi->master); |
| 494 | reg_base = mpc8xxx_spi->reg_base; | ||
| 495 | 378 | ||
| 496 | pm_runtime_get_sync(mpc8xxx_spi->dev); | 379 | pm_runtime_get_sync(mpc8xxx_spi->dev); |
| 497 | 380 | ||
| 498 | hw_mode = cs->hw_mode; /* Save original settings */ | 381 | cs->hw_mode = fsl_espi_read_reg(mpc8xxx_spi, |
| 499 | cs->hw_mode = mpc8xxx_spi_read_reg( | 382 | ESPI_SPMODEx(spi->chip_select)); |
| 500 | ®_base->csmode[spi->chip_select]); | ||
| 501 | /* mask out bits we are going to set */ | 383 | /* mask out bits we are going to set */ |
| 502 | cs->hw_mode &= ~(CSMODE_CP_BEGIN_EDGECLK | CSMODE_CI_INACTIVEHIGH | 384 | cs->hw_mode &= ~(CSMODE_CP_BEGIN_EDGECLK | CSMODE_CI_INACTIVEHIGH |
| 503 | | CSMODE_REV); | 385 | | CSMODE_REV); |
| @@ -510,21 +392,17 @@ static int fsl_espi_setup(struct spi_device *spi) | |||
| 510 | cs->hw_mode |= CSMODE_REV; | 392 | cs->hw_mode |= CSMODE_REV; |
| 511 | 393 | ||
| 512 | /* Handle the loop mode */ | 394 | /* Handle the loop mode */ |
| 513 | loop_mode = mpc8xxx_spi_read_reg(®_base->mode); | 395 | loop_mode = fsl_espi_read_reg(mpc8xxx_spi, ESPI_SPMODE); |
| 514 | loop_mode &= ~SPMODE_LOOP; | 396 | loop_mode &= ~SPMODE_LOOP; |
| 515 | if (spi->mode & SPI_LOOP) | 397 | if (spi->mode & SPI_LOOP) |
| 516 | loop_mode |= SPMODE_LOOP; | 398 | loop_mode |= SPMODE_LOOP; |
| 517 | mpc8xxx_spi_write_reg(®_base->mode, loop_mode); | 399 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPMODE, loop_mode); |
| 518 | 400 | ||
| 519 | retval = fsl_espi_setup_transfer(spi, NULL); | 401 | fsl_espi_setup_transfer(spi, NULL); |
| 520 | 402 | ||
| 521 | pm_runtime_mark_last_busy(mpc8xxx_spi->dev); | 403 | pm_runtime_mark_last_busy(mpc8xxx_spi->dev); |
| 522 | pm_runtime_put_autosuspend(mpc8xxx_spi->dev); | 404 | pm_runtime_put_autosuspend(mpc8xxx_spi->dev); |
| 523 | 405 | ||
| 524 | if (retval < 0) { | ||
| 525 | cs->hw_mode = hw_mode; /* Restore settings */ | ||
| 526 | return retval; | ||
| 527 | } | ||
| 528 | return 0; | 406 | return 0; |
| 529 | } | 407 | } |
| 530 | 408 | ||
| @@ -536,12 +414,10 @@ static void fsl_espi_cleanup(struct spi_device *spi) | |||
| 536 | spi_set_ctldata(spi, NULL); | 414 | spi_set_ctldata(spi, NULL); |
| 537 | } | 415 | } |
| 538 | 416 | ||
| 539 | void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) | 417 | static void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) |
| 540 | { | 418 | { |
| 541 | struct fsl_espi_reg *reg_base = mspi->reg_base; | ||
| 542 | |||
| 543 | /* We need handle RX first */ | 419 | /* We need handle RX first */ |
| 544 | if (events & SPIE_NE) { | 420 | if (events & SPIE_RNE) { |
| 545 | u32 rx_data, tmp; | 421 | u32 rx_data, tmp; |
| 546 | u8 rx_data_8; | 422 | u8 rx_data_8; |
| 547 | int rx_nr_bytes = 4; | 423 | int rx_nr_bytes = 4; |
| @@ -551,7 +427,7 @@ void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) | |||
| 551 | if (SPIE_RXCNT(events) < min(4, mspi->len)) { | 427 | if (SPIE_RXCNT(events) < min(4, mspi->len)) { |
| 552 | ret = spin_event_timeout( | 428 | ret = spin_event_timeout( |
| 553 | !(SPIE_RXCNT(events = | 429 | !(SPIE_RXCNT(events = |
| 554 | mpc8xxx_spi_read_reg(®_base->event)) < | 430 | fsl_espi_read_reg(mspi, ESPI_SPIE)) < |
| 555 | min(4, mspi->len)), | 431 | min(4, mspi->len)), |
| 556 | 10000, 0); /* 10 msec */ | 432 | 10000, 0); /* 10 msec */ |
| 557 | if (!ret) | 433 | if (!ret) |
| @@ -560,10 +436,10 @@ void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) | |||
| 560 | } | 436 | } |
| 561 | 437 | ||
| 562 | if (mspi->len >= 4) { | 438 | if (mspi->len >= 4) { |
| 563 | rx_data = mpc8xxx_spi_read_reg(®_base->receive); | 439 | rx_data = fsl_espi_read_reg(mspi, ESPI_SPIRF); |
| 564 | } else if (mspi->len <= 0) { | 440 | } else if (mspi->len <= 0) { |
| 565 | dev_err(mspi->dev, | 441 | dev_err(mspi->dev, |
| 566 | "unexpected RX(SPIE_NE) interrupt occurred,\n" | 442 | "unexpected RX(SPIE_RNE) interrupt occurred,\n" |
| 567 | "(local rxlen %d bytes, reg rxlen %d bytes)\n", | 443 | "(local rxlen %d bytes, reg rxlen %d bytes)\n", |
| 568 | min(4, mspi->len), SPIE_RXCNT(events)); | 444 | min(4, mspi->len), SPIE_RXCNT(events)); |
| 569 | rx_nr_bytes = 0; | 445 | rx_nr_bytes = 0; |
| @@ -572,7 +448,8 @@ void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) | |||
| 572 | tmp = mspi->len; | 448 | tmp = mspi->len; |
| 573 | rx_data = 0; | 449 | rx_data = 0; |
| 574 | while (tmp--) { | 450 | while (tmp--) { |
| 575 | rx_data_8 = in_8((u8 *)®_base->receive); | 451 | rx_data_8 = fsl_espi_read_reg8(mspi, |
| 452 | ESPI_SPIRF); | ||
| 576 | rx_data |= (rx_data_8 << (tmp * 8)); | 453 | rx_data |= (rx_data_8 << (tmp * 8)); |
| 577 | } | 454 | } |
| 578 | 455 | ||
| @@ -585,30 +462,24 @@ void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) | |||
| 585 | mspi->get_rx(rx_data, mspi); | 462 | mspi->get_rx(rx_data, mspi); |
| 586 | } | 463 | } |
| 587 | 464 | ||
| 588 | if (!(events & SPIE_NF)) { | 465 | if (!(events & SPIE_TNF)) { |
| 589 | int ret; | 466 | int ret; |
| 590 | 467 | ||
| 591 | /* spin until TX is done */ | 468 | /* spin until TX is done */ |
| 592 | ret = spin_event_timeout(((events = mpc8xxx_spi_read_reg( | 469 | ret = spin_event_timeout(((events = fsl_espi_read_reg( |
| 593 | ®_base->event)) & SPIE_NF), 1000, 0); | 470 | mspi, ESPI_SPIE)) & SPIE_TNF), 1000, 0); |
| 594 | if (!ret) { | 471 | if (!ret) { |
| 595 | dev_err(mspi->dev, "tired waiting for SPIE_NF\n"); | 472 | dev_err(mspi->dev, "tired waiting for SPIE_TNF\n"); |
| 596 | |||
| 597 | /* Clear the SPIE bits */ | ||
| 598 | mpc8xxx_spi_write_reg(®_base->event, events); | ||
| 599 | complete(&mspi->done); | 473 | complete(&mspi->done); |
| 600 | return; | 474 | return; |
| 601 | } | 475 | } |
| 602 | } | 476 | } |
| 603 | 477 | ||
| 604 | /* Clear the events */ | ||
| 605 | mpc8xxx_spi_write_reg(®_base->event, events); | ||
| 606 | |||
| 607 | mspi->count -= 1; | 478 | mspi->count -= 1; |
| 608 | if (mspi->count) { | 479 | if (mspi->count) { |
| 609 | u32 word = mspi->get_tx(mspi); | 480 | u32 word = mspi->get_tx(mspi); |
| 610 | 481 | ||
| 611 | mpc8xxx_spi_write_reg(®_base->transmit, word); | 482 | fsl_espi_write_reg(mspi, ESPI_SPITF, word); |
| 612 | } else { | 483 | } else { |
| 613 | complete(&mspi->done); | 484 | complete(&mspi->done); |
| 614 | } | 485 | } |
| @@ -617,20 +488,21 @@ void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) | |||
| 617 | static irqreturn_t fsl_espi_irq(s32 irq, void *context_data) | 488 | static irqreturn_t fsl_espi_irq(s32 irq, void *context_data) |
| 618 | { | 489 | { |
| 619 | struct mpc8xxx_spi *mspi = context_data; | 490 | struct mpc8xxx_spi *mspi = context_data; |
| 620 | struct fsl_espi_reg *reg_base = mspi->reg_base; | ||
| 621 | irqreturn_t ret = IRQ_NONE; | ||
| 622 | u32 events; | 491 | u32 events; |
| 623 | 492 | ||
| 624 | /* Get interrupt events(tx/rx) */ | 493 | /* Get interrupt events(tx/rx) */ |
| 625 | events = mpc8xxx_spi_read_reg(®_base->event); | 494 | events = fsl_espi_read_reg(mspi, ESPI_SPIE); |
| 626 | if (events) | 495 | if (!events) |
| 627 | ret = IRQ_HANDLED; | 496 | return IRQ_NONE; |
| 628 | 497 | ||
| 629 | dev_vdbg(mspi->dev, "%s: events %x\n", __func__, events); | 498 | dev_vdbg(mspi->dev, "%s: events %x\n", __func__, events); |
| 630 | 499 | ||
| 631 | fsl_espi_cpu_irq(mspi, events); | 500 | fsl_espi_cpu_irq(mspi, events); |
| 632 | 501 | ||
| 633 | return ret; | 502 | /* Clear the events */ |
| 503 | fsl_espi_write_reg(mspi, ESPI_SPIE, events); | ||
| 504 | |||
| 505 | return IRQ_HANDLED; | ||
| 634 | } | 506 | } |
| 635 | 507 | ||
| 636 | #ifdef CONFIG_PM | 508 | #ifdef CONFIG_PM |
| @@ -638,12 +510,11 @@ static int fsl_espi_runtime_suspend(struct device *dev) | |||
| 638 | { | 510 | { |
| 639 | struct spi_master *master = dev_get_drvdata(dev); | 511 | struct spi_master *master = dev_get_drvdata(dev); |
| 640 | struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master); | 512 | struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master); |
| 641 | struct fsl_espi_reg *reg_base = mpc8xxx_spi->reg_base; | ||
| 642 | u32 regval; | 513 | u32 regval; |
| 643 | 514 | ||
| 644 | regval = mpc8xxx_spi_read_reg(®_base->mode); | 515 | regval = fsl_espi_read_reg(mpc8xxx_spi, ESPI_SPMODE); |
| 645 | regval &= ~SPMODE_ENABLE; | 516 | regval &= ~SPMODE_ENABLE; |
| 646 | mpc8xxx_spi_write_reg(®_base->mode, regval); | 517 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPMODE, regval); |
| 647 | 518 | ||
| 648 | return 0; | 519 | return 0; |
| 649 | } | 520 | } |
| @@ -652,39 +523,35 @@ static int fsl_espi_runtime_resume(struct device *dev) | |||
| 652 | { | 523 | { |
| 653 | struct spi_master *master = dev_get_drvdata(dev); | 524 | struct spi_master *master = dev_get_drvdata(dev); |
| 654 | struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master); | 525 | struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master); |
| 655 | struct fsl_espi_reg *reg_base = mpc8xxx_spi->reg_base; | ||
| 656 | u32 regval; | 526 | u32 regval; |
| 657 | 527 | ||
| 658 | regval = mpc8xxx_spi_read_reg(®_base->mode); | 528 | regval = fsl_espi_read_reg(mpc8xxx_spi, ESPI_SPMODE); |
| 659 | regval |= SPMODE_ENABLE; | 529 | regval |= SPMODE_ENABLE; |
| 660 | mpc8xxx_spi_write_reg(®_base->mode, regval); | 530 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPMODE, regval); |
| 661 | 531 | ||
| 662 | return 0; | 532 | return 0; |
| 663 | } | 533 | } |
| 664 | #endif | 534 | #endif |
| 665 | 535 | ||
| 666 | static size_t fsl_espi_max_transfer_size(struct spi_device *spi) | 536 | static size_t fsl_espi_max_message_size(struct spi_device *spi) |
| 667 | { | 537 | { |
| 668 | return SPCOM_TRANLEN_MAX; | 538 | return SPCOM_TRANLEN_MAX; |
| 669 | } | 539 | } |
| 670 | 540 | ||
| 671 | static struct spi_master * fsl_espi_probe(struct device *dev, | 541 | static int fsl_espi_probe(struct device *dev, struct resource *mem, |
| 672 | struct resource *mem, unsigned int irq) | 542 | unsigned int irq) |
| 673 | { | 543 | { |
| 674 | struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); | 544 | struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); |
| 675 | struct spi_master *master; | 545 | struct spi_master *master; |
| 676 | struct mpc8xxx_spi *mpc8xxx_spi; | 546 | struct mpc8xxx_spi *mpc8xxx_spi; |
| 677 | struct fsl_espi_reg *reg_base; | ||
| 678 | struct device_node *nc; | 547 | struct device_node *nc; |
| 679 | const __be32 *prop; | 548 | const __be32 *prop; |
| 680 | u32 regval, csmode; | 549 | u32 regval, csmode; |
| 681 | int i, len, ret = 0; | 550 | int i, len, ret; |
| 682 | 551 | ||
| 683 | master = spi_alloc_master(dev, sizeof(struct mpc8xxx_spi)); | 552 | master = spi_alloc_master(dev, sizeof(struct mpc8xxx_spi)); |
| 684 | if (!master) { | 553 | if (!master) |
| 685 | ret = -ENOMEM; | 554 | return -ENOMEM; |
| 686 | goto err; | ||
| 687 | } | ||
| 688 | 555 | ||
| 689 | dev_set_drvdata(dev, master); | 556 | dev_set_drvdata(dev, master); |
| 690 | 557 | ||
| @@ -695,18 +562,23 @@ static struct spi_master * fsl_espi_probe(struct device *dev, | |||
| 695 | master->cleanup = fsl_espi_cleanup; | 562 | master->cleanup = fsl_espi_cleanup; |
| 696 | master->transfer_one_message = fsl_espi_do_one_msg; | 563 | master->transfer_one_message = fsl_espi_do_one_msg; |
| 697 | master->auto_runtime_pm = true; | 564 | master->auto_runtime_pm = true; |
| 698 | master->max_transfer_size = fsl_espi_max_transfer_size; | 565 | master->max_message_size = fsl_espi_max_message_size; |
| 699 | 566 | ||
| 700 | mpc8xxx_spi = spi_master_get_devdata(master); | 567 | mpc8xxx_spi = spi_master_get_devdata(master); |
| 701 | 568 | ||
| 569 | mpc8xxx_spi->local_buf = | ||
| 570 | devm_kmalloc(dev, SPCOM_TRANLEN_MAX, GFP_KERNEL); | ||
| 571 | if (!mpc8xxx_spi->local_buf) { | ||
| 572 | ret = -ENOMEM; | ||
| 573 | goto err_probe; | ||
| 574 | } | ||
| 575 | |||
| 702 | mpc8xxx_spi->reg_base = devm_ioremap_resource(dev, mem); | 576 | mpc8xxx_spi->reg_base = devm_ioremap_resource(dev, mem); |
| 703 | if (IS_ERR(mpc8xxx_spi->reg_base)) { | 577 | if (IS_ERR(mpc8xxx_spi->reg_base)) { |
| 704 | ret = PTR_ERR(mpc8xxx_spi->reg_base); | 578 | ret = PTR_ERR(mpc8xxx_spi->reg_base); |
| 705 | goto err_probe; | 579 | goto err_probe; |
| 706 | } | 580 | } |
| 707 | 581 | ||
| 708 | reg_base = mpc8xxx_spi->reg_base; | ||
| 709 | |||
| 710 | /* Register for SPI Interrupt */ | 582 | /* Register for SPI Interrupt */ |
| 711 | ret = devm_request_irq(dev, mpc8xxx_spi->irq, fsl_espi_irq, | 583 | ret = devm_request_irq(dev, mpc8xxx_spi->irq, fsl_espi_irq, |
| 712 | 0, "fsl_espi", mpc8xxx_spi); | 584 | 0, "fsl_espi", mpc8xxx_spi); |
| @@ -719,10 +591,10 @@ static struct spi_master * fsl_espi_probe(struct device *dev, | |||
| 719 | } | 591 | } |
| 720 | 592 | ||
| 721 | /* SPI controller initializations */ | 593 | /* SPI controller initializations */ |
| 722 | mpc8xxx_spi_write_reg(®_base->mode, 0); | 594 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPMODE, 0); |
| 723 | mpc8xxx_spi_write_reg(®_base->mask, 0); | 595 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, 0); |
| 724 | mpc8xxx_spi_write_reg(®_base->command, 0); | 596 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPCOM, 0); |
| 725 | mpc8xxx_spi_write_reg(®_base->event, 0xffffffff); | 597 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIE, 0xffffffff); |
| 726 | 598 | ||
| 727 | /* Init eSPI CS mode register */ | 599 | /* Init eSPI CS mode register */ |
| 728 | for_each_available_child_of_node(master->dev.of_node, nc) { | 600 | for_each_available_child_of_node(master->dev.of_node, nc) { |
| @@ -747,7 +619,7 @@ static struct spi_master * fsl_espi_probe(struct device *dev, | |||
| 747 | csmode &= ~(CSMODE_AFT(0xf)); | 619 | csmode &= ~(CSMODE_AFT(0xf)); |
| 748 | csmode |= CSMODE_AFT(be32_to_cpup(prop)); | 620 | csmode |= CSMODE_AFT(be32_to_cpup(prop)); |
| 749 | } | 621 | } |
| 750 | mpc8xxx_spi_write_reg(®_base->csmode[i], csmode); | 622 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPMODEx(i), csmode); |
| 751 | 623 | ||
| 752 | dev_info(dev, "cs=%d, init_csmode=0x%x\n", i, csmode); | 624 | dev_info(dev, "cs=%d, init_csmode=0x%x\n", i, csmode); |
| 753 | } | 625 | } |
| @@ -755,7 +627,7 @@ static struct spi_master * fsl_espi_probe(struct device *dev, | |||
| 755 | /* Enable SPI interface */ | 627 | /* Enable SPI interface */ |
| 756 | regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE; | 628 | regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE; |
| 757 | 629 | ||
| 758 | mpc8xxx_spi_write_reg(®_base->mode, regval); | 630 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPMODE, regval); |
| 759 | 631 | ||
| 760 | pm_runtime_set_autosuspend_delay(dev, AUTOSUSPEND_TIMEOUT); | 632 | pm_runtime_set_autosuspend_delay(dev, AUTOSUSPEND_TIMEOUT); |
| 761 | pm_runtime_use_autosuspend(dev); | 633 | pm_runtime_use_autosuspend(dev); |
| @@ -767,12 +639,13 @@ static struct spi_master * fsl_espi_probe(struct device *dev, | |||
| 767 | if (ret < 0) | 639 | if (ret < 0) |
| 768 | goto err_pm; | 640 | goto err_pm; |
| 769 | 641 | ||
| 770 | dev_info(dev, "at 0x%p (irq = %d)\n", reg_base, mpc8xxx_spi->irq); | 642 | dev_info(dev, "at 0x%p (irq = %d)\n", mpc8xxx_spi->reg_base, |
| 643 | mpc8xxx_spi->irq); | ||
| 771 | 644 | ||
| 772 | pm_runtime_mark_last_busy(dev); | 645 | pm_runtime_mark_last_busy(dev); |
| 773 | pm_runtime_put_autosuspend(dev); | 646 | pm_runtime_put_autosuspend(dev); |
| 774 | 647 | ||
| 775 | return master; | 648 | return 0; |
| 776 | 649 | ||
| 777 | err_pm: | 650 | err_pm: |
| 778 | pm_runtime_put_noidle(dev); | 651 | pm_runtime_put_noidle(dev); |
| @@ -780,8 +653,7 @@ err_pm: | |||
| 780 | pm_runtime_set_suspended(dev); | 653 | pm_runtime_set_suspended(dev); |
| 781 | err_probe: | 654 | err_probe: |
| 782 | spi_master_put(master); | 655 | spi_master_put(master); |
| 783 | err: | 656 | return ret; |
| 784 | return ERR_PTR(ret); | ||
| 785 | } | 657 | } |
| 786 | 658 | ||
| 787 | static int of_fsl_espi_get_chipselects(struct device *dev) | 659 | static int of_fsl_espi_get_chipselects(struct device *dev) |
| @@ -807,10 +679,9 @@ static int of_fsl_espi_probe(struct platform_device *ofdev) | |||
| 807 | { | 679 | { |
| 808 | struct device *dev = &ofdev->dev; | 680 | struct device *dev = &ofdev->dev; |
| 809 | struct device_node *np = ofdev->dev.of_node; | 681 | struct device_node *np = ofdev->dev.of_node; |
| 810 | struct spi_master *master; | ||
| 811 | struct resource mem; | 682 | struct resource mem; |
| 812 | unsigned int irq; | 683 | unsigned int irq; |
| 813 | int ret = -ENOMEM; | 684 | int ret; |
| 814 | 685 | ||
| 815 | ret = of_mpc8xxx_spi_probe(ofdev); | 686 | ret = of_mpc8xxx_spi_probe(ofdev); |
| 816 | if (ret) | 687 | if (ret) |
| @@ -818,28 +689,17 @@ static int of_fsl_espi_probe(struct platform_device *ofdev) | |||
| 818 | 689 | ||
| 819 | ret = of_fsl_espi_get_chipselects(dev); | 690 | ret = of_fsl_espi_get_chipselects(dev); |
| 820 | if (ret) | 691 | if (ret) |
| 821 | goto err; | 692 | return ret; |
| 822 | 693 | ||
| 823 | ret = of_address_to_resource(np, 0, &mem); | 694 | ret = of_address_to_resource(np, 0, &mem); |
| 824 | if (ret) | 695 | if (ret) |
| 825 | goto err; | 696 | return ret; |
| 826 | 697 | ||
| 827 | irq = irq_of_parse_and_map(np, 0); | 698 | irq = irq_of_parse_and_map(np, 0); |
| 828 | if (!irq) { | 699 | if (!irq) |
| 829 | ret = -EINVAL; | 700 | return -EINVAL; |
| 830 | goto err; | ||
| 831 | } | ||
| 832 | |||
| 833 | master = fsl_espi_probe(dev, &mem, irq); | ||
| 834 | if (IS_ERR(master)) { | ||
| 835 | ret = PTR_ERR(master); | ||
| 836 | goto err; | ||
| 837 | } | ||
| 838 | |||
| 839 | return 0; | ||
| 840 | 701 | ||
| 841 | err: | 702 | return fsl_espi_probe(dev, &mem, irq); |
| 842 | return ret; | ||
| 843 | } | 703 | } |
| 844 | 704 | ||
| 845 | static int of_fsl_espi_remove(struct platform_device *dev) | 705 | static int of_fsl_espi_remove(struct platform_device *dev) |
| @@ -873,27 +733,26 @@ static int of_fsl_espi_resume(struct device *dev) | |||
| 873 | struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); | 733 | struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); |
| 874 | struct spi_master *master = dev_get_drvdata(dev); | 734 | struct spi_master *master = dev_get_drvdata(dev); |
| 875 | struct mpc8xxx_spi *mpc8xxx_spi; | 735 | struct mpc8xxx_spi *mpc8xxx_spi; |
| 876 | struct fsl_espi_reg *reg_base; | ||
| 877 | u32 regval; | 736 | u32 regval; |
| 878 | int i, ret; | 737 | int i, ret; |
| 879 | 738 | ||
| 880 | mpc8xxx_spi = spi_master_get_devdata(master); | 739 | mpc8xxx_spi = spi_master_get_devdata(master); |
| 881 | reg_base = mpc8xxx_spi->reg_base; | ||
| 882 | 740 | ||
| 883 | /* SPI controller initializations */ | 741 | /* SPI controller initializations */ |
| 884 | mpc8xxx_spi_write_reg(®_base->mode, 0); | 742 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPMODE, 0); |
| 885 | mpc8xxx_spi_write_reg(®_base->mask, 0); | 743 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIM, 0); |
| 886 | mpc8xxx_spi_write_reg(®_base->command, 0); | 744 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPCOM, 0); |
| 887 | mpc8xxx_spi_write_reg(®_base->event, 0xffffffff); | 745 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPIE, 0xffffffff); |
| 888 | 746 | ||
| 889 | /* Init eSPI CS mode register */ | 747 | /* Init eSPI CS mode register */ |
| 890 | for (i = 0; i < pdata->max_chipselect; i++) | 748 | for (i = 0; i < pdata->max_chipselect; i++) |
| 891 | mpc8xxx_spi_write_reg(®_base->csmode[i], CSMODE_INIT_VAL); | 749 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPMODEx(i), |
| 750 | CSMODE_INIT_VAL); | ||
| 892 | 751 | ||
| 893 | /* Enable SPI interface */ | 752 | /* Enable SPI interface */ |
| 894 | regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE; | 753 | regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE; |
| 895 | 754 | ||
| 896 | mpc8xxx_spi_write_reg(®_base->mode, regval); | 755 | fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPMODE, regval); |
| 897 | 756 | ||
| 898 | ret = pm_runtime_force_resume(dev); | 757 | ret = pm_runtime_force_resume(dev); |
| 899 | if (ret < 0) | 758 | if (ret < 0) |
diff --git a/drivers/spi/spi-fsl-lib.h b/drivers/spi/spi-fsl-lib.h index 84f5dcb7a897..2925c8089fd9 100644 --- a/drivers/spi/spi-fsl-lib.h +++ b/drivers/spi/spi-fsl-lib.h | |||
| @@ -23,13 +23,14 @@ | |||
| 23 | /* SPI/eSPI Controller driver's private data. */ | 23 | /* SPI/eSPI Controller driver's private data. */ |
| 24 | struct mpc8xxx_spi { | 24 | struct mpc8xxx_spi { |
| 25 | struct device *dev; | 25 | struct device *dev; |
| 26 | void *reg_base; | 26 | void __iomem *reg_base; |
| 27 | 27 | ||
| 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) | 31 | #if IS_ENABLED(CONFIG_SPI_FSL_ESPI) |
| 32 | int len; | 32 | int len; |
| 33 | u8 *local_buf; | ||
| 33 | #endif | 34 | #endif |
| 34 | 35 | ||
| 35 | int subblock; | 36 | int subblock; |
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index f63cb30f9010..deb782f6556c 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c | |||
| @@ -186,17 +186,19 @@ static unsigned int spi_imx_clkdiv_1(unsigned int fin, | |||
| 186 | 186 | ||
| 187 | /* MX1, MX31, MX35, MX51 CSPI */ | 187 | /* MX1, MX31, MX35, MX51 CSPI */ |
| 188 | static unsigned int spi_imx_clkdiv_2(unsigned int fin, | 188 | static unsigned int spi_imx_clkdiv_2(unsigned int fin, |
| 189 | unsigned int fspi) | 189 | unsigned int fspi, unsigned int *fres) |
| 190 | { | 190 | { |
| 191 | int i, div = 4; | 191 | int i, div = 4; |
| 192 | 192 | ||
| 193 | for (i = 0; i < 7; i++) { | 193 | for (i = 0; i < 7; i++) { |
| 194 | if (fspi * div >= fin) | 194 | if (fspi * div >= fin) |
| 195 | return i; | 195 | goto out; |
| 196 | div <<= 1; | 196 | div <<= 1; |
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | return 7; | 199 | out: |
| 200 | *fres = fin / div; | ||
| 201 | return i; | ||
| 200 | } | 202 | } |
| 201 | 203 | ||
| 202 | static int spi_imx_bytes_per_word(const int bpw) | 204 | static int spi_imx_bytes_per_word(const int bpw) |
| @@ -453,6 +455,9 @@ static void mx51_ecspi_reset(struct spi_imx_data *spi_imx) | |||
| 453 | #define MX31_CSPISTATUS 0x14 | 455 | #define MX31_CSPISTATUS 0x14 |
| 454 | #define MX31_STATUS_RR (1 << 3) | 456 | #define MX31_STATUS_RR (1 << 3) |
| 455 | 457 | ||
| 458 | #define MX31_CSPI_TESTREG 0x1C | ||
| 459 | #define MX31_TEST_LBC (1 << 14) | ||
| 460 | |||
| 456 | /* These functions also work for the i.MX35, but be aware that | 461 | /* These functions also work for the i.MX35, but be aware that |
| 457 | * the i.MX35 has a slightly different register layout for bits | 462 | * the i.MX35 has a slightly different register layout for bits |
| 458 | * we do not use here. | 463 | * we do not use here. |
| @@ -482,9 +487,11 @@ static int mx31_config(struct spi_device *spi, struct spi_imx_config *config) | |||
| 482 | { | 487 | { |
| 483 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); | 488 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); |
| 484 | unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER; | 489 | unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER; |
| 490 | unsigned int clk; | ||
| 485 | 491 | ||
| 486 | reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) << | 492 | reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz, &clk) << |
| 487 | MX31_CSPICTRL_DR_SHIFT; | 493 | MX31_CSPICTRL_DR_SHIFT; |
| 494 | spi_imx->spi_bus_clk = clk; | ||
| 488 | 495 | ||
| 489 | if (is_imx35_cspi(spi_imx)) { | 496 | if (is_imx35_cspi(spi_imx)) { |
| 490 | reg |= (config->bpw - 1) << MX35_CSPICTRL_BL_SHIFT; | 497 | reg |= (config->bpw - 1) << MX35_CSPICTRL_BL_SHIFT; |
| @@ -506,6 +513,13 @@ static int mx31_config(struct spi_device *spi, struct spi_imx_config *config) | |||
| 506 | 513 | ||
| 507 | writel(reg, spi_imx->base + MXC_CSPICTRL); | 514 | writel(reg, spi_imx->base + MXC_CSPICTRL); |
| 508 | 515 | ||
| 516 | reg = readl(spi_imx->base + MX31_CSPI_TESTREG); | ||
| 517 | if (spi->mode & SPI_LOOP) | ||
| 518 | reg |= MX31_TEST_LBC; | ||
| 519 | else | ||
| 520 | reg &= ~MX31_TEST_LBC; | ||
| 521 | writel(reg, spi_imx->base + MX31_CSPI_TESTREG); | ||
| 522 | |||
| 509 | return 0; | 523 | return 0; |
| 510 | } | 524 | } |
| 511 | 525 | ||
| @@ -625,9 +639,12 @@ static int mx1_config(struct spi_device *spi, struct spi_imx_config *config) | |||
| 625 | { | 639 | { |
| 626 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); | 640 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); |
| 627 | unsigned int reg = MX1_CSPICTRL_ENABLE | MX1_CSPICTRL_MASTER; | 641 | unsigned int reg = MX1_CSPICTRL_ENABLE | MX1_CSPICTRL_MASTER; |
| 642 | unsigned int clk; | ||
| 628 | 643 | ||
| 629 | reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) << | 644 | reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz, &clk) << |
| 630 | MX1_CSPICTRL_DR_SHIFT; | 645 | MX1_CSPICTRL_DR_SHIFT; |
| 646 | spi_imx->spi_bus_clk = clk; | ||
| 647 | |||
| 631 | reg |= config->bpw - 1; | 648 | reg |= config->bpw - 1; |
| 632 | 649 | ||
| 633 | if (spi->mode & SPI_CPHA) | 650 | if (spi->mode & SPI_CPHA) |
| @@ -1179,7 +1196,7 @@ static int spi_imx_probe(struct platform_device *pdev) | |||
| 1179 | spi_imx->bitbang.master->prepare_message = spi_imx_prepare_message; | 1196 | spi_imx->bitbang.master->prepare_message = spi_imx_prepare_message; |
| 1180 | spi_imx->bitbang.master->unprepare_message = spi_imx_unprepare_message; | 1197 | spi_imx->bitbang.master->unprepare_message = spi_imx_unprepare_message; |
| 1181 | spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; | 1198 | spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; |
| 1182 | if (is_imx51_ecspi(spi_imx)) | 1199 | if (is_imx35_cspi(spi_imx) || is_imx51_ecspi(spi_imx)) |
| 1183 | spi_imx->bitbang.master->mode_bits |= SPI_LOOP; | 1200 | spi_imx->bitbang.master->mode_bits |= SPI_LOOP; |
| 1184 | 1201 | ||
| 1185 | init_completion(&spi_imx->xfer_done); | 1202 | init_completion(&spi_imx->xfer_done); |
| @@ -1251,6 +1268,12 @@ static int spi_imx_probe(struct platform_device *pdev) | |||
| 1251 | goto out_clk_put; | 1268 | goto out_clk_put; |
| 1252 | } | 1269 | } |
| 1253 | 1270 | ||
| 1271 | if (!master->cs_gpios) { | ||
| 1272 | dev_err(&pdev->dev, "No CS GPIOs available\n"); | ||
| 1273 | ret = -EINVAL; | ||
| 1274 | goto out_clk_put; | ||
| 1275 | } | ||
| 1276 | |||
| 1254 | for (i = 0; i < master->num_chipselect; i++) { | 1277 | for (i = 0; i < master->num_chipselect; i++) { |
| 1255 | if (!gpio_is_valid(master->cs_gpios[i])) | 1278 | if (!gpio_is_valid(master->cs_gpios[i])) |
| 1256 | continue; | 1279 | continue; |
diff --git a/drivers/spi/spi-iproc-qspi.c b/drivers/spi/spi-iproc-qspi.c new file mode 100644 index 000000000000..be6ccb204a66 --- /dev/null +++ b/drivers/spi/spi-iproc-qspi.c | |||
| @@ -0,0 +1,163 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2016 Broadcom Limited | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/device.h> | ||
| 15 | #include <linux/io.h> | ||
| 16 | #include <linux/ioport.h> | ||
| 17 | #include <linux/module.h> | ||
| 18 | #include <linux/of.h> | ||
| 19 | #include <linux/of_address.h> | ||
| 20 | #include <linux/platform_device.h> | ||
| 21 | #include <linux/slab.h> | ||
| 22 | |||
| 23 | #include "spi-bcm-qspi.h" | ||
| 24 | |||
| 25 | #define INTR_BASE_BIT_SHIFT 0x02 | ||
| 26 | #define INTR_COUNT 0x07 | ||
| 27 | |||
| 28 | struct bcm_iproc_intc { | ||
| 29 | struct bcm_qspi_soc_intc soc_intc; | ||
| 30 | struct platform_device *pdev; | ||
| 31 | void __iomem *int_reg; | ||
| 32 | void __iomem *int_status_reg; | ||
| 33 | spinlock_t soclock; | ||
| 34 | bool big_endian; | ||
| 35 | }; | ||
| 36 | |||
| 37 | static u32 bcm_iproc_qspi_get_l2_int_status(struct bcm_qspi_soc_intc *soc_intc) | ||
| 38 | { | ||
| 39 | struct bcm_iproc_intc *priv = | ||
| 40 | container_of(soc_intc, struct bcm_iproc_intc, soc_intc); | ||
| 41 | void __iomem *mmio = priv->int_status_reg; | ||
| 42 | int i; | ||
| 43 | u32 val = 0, sts = 0; | ||
| 44 | |||
| 45 | for (i = 0; i < INTR_COUNT; i++) { | ||
| 46 | if (bcm_qspi_readl(priv->big_endian, mmio + (i * 4))) | ||
| 47 | val |= 1UL << i; | ||
| 48 | } | ||
| 49 | |||
| 50 | if (val & INTR_MSPI_DONE_MASK) | ||
| 51 | sts |= MSPI_DONE; | ||
| 52 | |||
| 53 | if (val & BSPI_LR_INTERRUPTS_ALL) | ||
| 54 | sts |= BSPI_DONE; | ||
| 55 | |||
| 56 | if (val & BSPI_LR_INTERRUPTS_ERROR) | ||
| 57 | sts |= BSPI_ERR; | ||
| 58 | |||
| 59 | return sts; | ||
| 60 | } | ||
| 61 | |||
| 62 | static void bcm_iproc_qspi_int_ack(struct bcm_qspi_soc_intc *soc_intc, int type) | ||
| 63 | { | ||
| 64 | struct bcm_iproc_intc *priv = | ||
| 65 | container_of(soc_intc, struct bcm_iproc_intc, soc_intc); | ||
| 66 | void __iomem *mmio = priv->int_status_reg; | ||
| 67 | u32 mask = get_qspi_mask(type); | ||
| 68 | int i; | ||
| 69 | |||
| 70 | for (i = 0; i < INTR_COUNT; i++) { | ||
| 71 | if (mask & (1UL << i)) | ||
| 72 | bcm_qspi_writel(priv->big_endian, 1, mmio + (i * 4)); | ||
| 73 | } | ||
| 74 | } | ||
| 75 | |||
| 76 | static void bcm_iproc_qspi_int_set(struct bcm_qspi_soc_intc *soc_intc, int type, | ||
| 77 | bool en) | ||
| 78 | { | ||
| 79 | struct bcm_iproc_intc *priv = | ||
| 80 | container_of(soc_intc, struct bcm_iproc_intc, soc_intc); | ||
| 81 | void __iomem *mmio = priv->int_reg; | ||
| 82 | u32 mask = get_qspi_mask(type); | ||
| 83 | u32 val; | ||
| 84 | unsigned long flags; | ||
| 85 | |||
| 86 | spin_lock_irqsave(&priv->soclock, flags); | ||
| 87 | |||
| 88 | val = bcm_qspi_readl(priv->big_endian, mmio); | ||
| 89 | |||
| 90 | if (en) | ||
| 91 | val = val | (mask << INTR_BASE_BIT_SHIFT); | ||
| 92 | else | ||
| 93 | val = val & ~(mask << INTR_BASE_BIT_SHIFT); | ||
| 94 | |||
| 95 | bcm_qspi_writel(priv->big_endian, val, mmio); | ||
| 96 | |||
| 97 | spin_unlock_irqrestore(&priv->soclock, flags); | ||
| 98 | } | ||
| 99 | |||
| 100 | static int bcm_iproc_probe(struct platform_device *pdev) | ||
| 101 | { | ||
| 102 | struct device *dev = &pdev->dev; | ||
| 103 | struct bcm_iproc_intc *priv; | ||
| 104 | struct bcm_qspi_soc_intc *soc_intc; | ||
| 105 | struct resource *res; | ||
| 106 | |||
| 107 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
| 108 | if (!priv) | ||
| 109 | return -ENOMEM; | ||
| 110 | soc_intc = &priv->soc_intc; | ||
| 111 | priv->pdev = pdev; | ||
| 112 | |||
| 113 | spin_lock_init(&priv->soclock); | ||
| 114 | |||
| 115 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr_regs"); | ||
| 116 | priv->int_reg = devm_ioremap_resource(dev, res); | ||
| 117 | if (IS_ERR(priv->int_reg)) | ||
| 118 | return PTR_ERR(priv->int_reg); | ||
| 119 | |||
| 120 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | ||
| 121 | "intr_status_reg"); | ||
| 122 | priv->int_status_reg = devm_ioremap_resource(dev, res); | ||
| 123 | if (IS_ERR(priv->int_status_reg)) | ||
| 124 | return PTR_ERR(priv->int_status_reg); | ||
| 125 | |||
| 126 | priv->big_endian = of_device_is_big_endian(dev->of_node); | ||
| 127 | |||
| 128 | bcm_iproc_qspi_int_ack(soc_intc, MSPI_BSPI_DONE); | ||
| 129 | bcm_iproc_qspi_int_set(soc_intc, MSPI_BSPI_DONE, false); | ||
| 130 | |||
| 131 | soc_intc->bcm_qspi_int_ack = bcm_iproc_qspi_int_ack; | ||
| 132 | soc_intc->bcm_qspi_int_set = bcm_iproc_qspi_int_set; | ||
| 133 | soc_intc->bcm_qspi_get_int_status = bcm_iproc_qspi_get_l2_int_status; | ||
| 134 | |||
| 135 | return bcm_qspi_probe(pdev, soc_intc); | ||
| 136 | } | ||
| 137 | |||
| 138 | static int bcm_iproc_remove(struct platform_device *pdev) | ||
| 139 | { | ||
| 140 | return bcm_qspi_remove(pdev); | ||
| 141 | } | ||
| 142 | |||
| 143 | static const struct of_device_id bcm_iproc_of_match[] = { | ||
| 144 | { .compatible = "brcm,spi-nsp-qspi" }, | ||
| 145 | { .compatible = "brcm,spi-ns2-qspi" }, | ||
| 146 | {}, | ||
| 147 | }; | ||
| 148 | MODULE_DEVICE_TABLE(of, bcm_iproc_of_match); | ||
| 149 | |||
| 150 | static struct platform_driver bcm_iproc_driver = { | ||
| 151 | .probe = bcm_iproc_probe, | ||
| 152 | .remove = bcm_iproc_remove, | ||
| 153 | .driver = { | ||
| 154 | .name = "bcm_iproc", | ||
| 155 | .pm = &bcm_qspi_pm_ops, | ||
| 156 | .of_match_table = bcm_iproc_of_match, | ||
| 157 | } | ||
| 158 | }; | ||
| 159 | module_platform_driver(bcm_iproc_driver); | ||
| 160 | |||
| 161 | MODULE_LICENSE("GPL v2"); | ||
| 162 | MODULE_AUTHOR("Kamal Dasu"); | ||
| 163 | MODULE_DESCRIPTION("SPI flash driver for Broadcom iProc SoCs"); | ||
diff --git a/drivers/spi/spi-jcore.c b/drivers/spi/spi-jcore.c new file mode 100644 index 000000000000..f8117b80fa22 --- /dev/null +++ b/drivers/spi/spi-jcore.c | |||
| @@ -0,0 +1,231 @@ | |||
| 1 | /* | ||
| 2 | * J-Core SPI controller driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012-2016 Smart Energy Instruments, Inc. | ||
| 5 | * | ||
| 6 | * Current version by Rich Felker | ||
| 7 | * Based loosely on initial version by Oleksandr G Zhadan | ||
| 8 | * | ||
| 9 | */ | ||
| 10 | #include <linux/init.h> | ||
| 11 | #include <linux/interrupt.h> | ||
| 12 | #include <linux/errno.h> | ||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/platform_device.h> | ||
| 15 | #include <linux/spi/spi.h> | ||
| 16 | #include <linux/clk.h> | ||
| 17 | #include <linux/err.h> | ||
| 18 | #include <linux/io.h> | ||
| 19 | #include <linux/of.h> | ||
| 20 | #include <linux/delay.h> | ||
| 21 | |||
| 22 | #define DRV_NAME "jcore_spi" | ||
| 23 | |||
| 24 | #define CTRL_REG 0x0 | ||
| 25 | #define DATA_REG 0x4 | ||
| 26 | |||
| 27 | #define JCORE_SPI_CTRL_XMIT 0x02 | ||
| 28 | #define JCORE_SPI_STAT_BUSY 0x02 | ||
| 29 | #define JCORE_SPI_CTRL_LOOP 0x08 | ||
| 30 | #define JCORE_SPI_CTRL_CS_BITS 0x15 | ||
| 31 | |||
| 32 | #define JCORE_SPI_WAIT_RDY_MAX_LOOP 2000000 | ||
| 33 | |||
| 34 | struct jcore_spi { | ||
| 35 | struct spi_master *master; | ||
| 36 | void __iomem *base; | ||
| 37 | unsigned int cs_reg; | ||
| 38 | unsigned int speed_reg; | ||
| 39 | unsigned int speed_hz; | ||
| 40 | unsigned int clock_freq; | ||
| 41 | }; | ||
| 42 | |||
| 43 | static int jcore_spi_wait(void __iomem *ctrl_reg) | ||
| 44 | { | ||
| 45 | unsigned timeout = JCORE_SPI_WAIT_RDY_MAX_LOOP; | ||
| 46 | |||
| 47 | do { | ||
| 48 | if (!(readl(ctrl_reg) & JCORE_SPI_STAT_BUSY)) | ||
| 49 | return 0; | ||
| 50 | cpu_relax(); | ||
| 51 | } while (--timeout); | ||
| 52 | |||
| 53 | return -EBUSY; | ||
| 54 | } | ||
| 55 | |||
| 56 | static void jcore_spi_program(struct jcore_spi *hw) | ||
| 57 | { | ||
| 58 | void __iomem *ctrl_reg = hw->base + CTRL_REG; | ||
| 59 | |||
| 60 | if (jcore_spi_wait(ctrl_reg)) | ||
| 61 | dev_err(hw->master->dev.parent, | ||
| 62 | "timeout waiting to program ctrl reg.\n"); | ||
| 63 | |||
| 64 | writel(hw->cs_reg | hw->speed_reg, ctrl_reg); | ||
| 65 | } | ||
| 66 | |||
| 67 | static void jcore_spi_chipsel(struct spi_device *spi, bool value) | ||
| 68 | { | ||
| 69 | struct jcore_spi *hw = spi_master_get_devdata(spi->master); | ||
| 70 | u32 csbit = 1U << (2 * spi->chip_select); | ||
| 71 | |||
| 72 | dev_dbg(hw->master->dev.parent, "chipselect %d\n", spi->chip_select); | ||
| 73 | |||
| 74 | if (value) | ||
| 75 | hw->cs_reg |= csbit; | ||
| 76 | else | ||
| 77 | hw->cs_reg &= ~csbit; | ||
| 78 | |||
| 79 | jcore_spi_program(hw); | ||
| 80 | } | ||
| 81 | |||
| 82 | static void jcore_spi_baudrate(struct jcore_spi *hw, int speed) | ||
| 83 | { | ||
| 84 | if (speed == hw->speed_hz) return; | ||
| 85 | hw->speed_hz = speed; | ||
| 86 | if (speed >= hw->clock_freq / 2) | ||
| 87 | hw->speed_reg = 0; | ||
| 88 | else | ||
| 89 | hw->speed_reg = ((hw->clock_freq / 2 / speed) - 1) << 27; | ||
| 90 | jcore_spi_program(hw); | ||
| 91 | dev_dbg(hw->master->dev.parent, "speed=%d reg=0x%x\n", | ||
| 92 | speed, hw->speed_reg); | ||
| 93 | } | ||
| 94 | |||
| 95 | static int jcore_spi_txrx(struct spi_master *master, struct spi_device *spi, | ||
| 96 | struct spi_transfer *t) | ||
| 97 | { | ||
| 98 | struct jcore_spi *hw = spi_master_get_devdata(master); | ||
| 99 | |||
| 100 | void __iomem *ctrl_reg = hw->base + CTRL_REG; | ||
| 101 | void __iomem *data_reg = hw->base + DATA_REG; | ||
| 102 | u32 xmit; | ||
| 103 | |||
| 104 | /* data buffers */ | ||
| 105 | const unsigned char *tx; | ||
| 106 | unsigned char *rx; | ||
| 107 | unsigned int len; | ||
| 108 | unsigned int count; | ||
| 109 | |||
| 110 | jcore_spi_baudrate(hw, t->speed_hz); | ||
| 111 | |||
| 112 | xmit = hw->cs_reg | hw->speed_reg | JCORE_SPI_CTRL_XMIT; | ||
| 113 | tx = t->tx_buf; | ||
| 114 | rx = t->rx_buf; | ||
| 115 | len = t->len; | ||
| 116 | |||
| 117 | for (count = 0; count < len; count++) { | ||
| 118 | if (jcore_spi_wait(ctrl_reg)) | ||
| 119 | break; | ||
| 120 | |||
| 121 | writel(tx ? *tx++ : 0, data_reg); | ||
| 122 | writel(xmit, ctrl_reg); | ||
| 123 | |||
| 124 | if (jcore_spi_wait(ctrl_reg)) | ||
| 125 | break; | ||
| 126 | |||
| 127 | if (rx) | ||
| 128 | *rx++ = readl(data_reg); | ||
| 129 | } | ||
| 130 | |||
| 131 | spi_finalize_current_transfer(master); | ||
| 132 | |||
| 133 | if (count < len) | ||
| 134 | return -EREMOTEIO; | ||
| 135 | |||
| 136 | return 0; | ||
| 137 | } | ||
| 138 | |||
| 139 | static int jcore_spi_probe(struct platform_device *pdev) | ||
| 140 | { | ||
| 141 | struct device_node *node = pdev->dev.of_node; | ||
| 142 | struct jcore_spi *hw; | ||
| 143 | struct spi_master *master; | ||
| 144 | struct resource *res; | ||
| 145 | u32 clock_freq; | ||
| 146 | struct clk *clk; | ||
| 147 | int err = -ENODEV; | ||
| 148 | |||
| 149 | master = spi_alloc_master(&pdev->dev, sizeof(struct jcore_spi)); | ||
| 150 | if (!master) | ||
| 151 | return err; | ||
| 152 | |||
| 153 | /* Setup the master state. */ | ||
| 154 | master->num_chipselect = 3; | ||
| 155 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; | ||
| 156 | master->transfer_one = jcore_spi_txrx; | ||
| 157 | master->set_cs = jcore_spi_chipsel; | ||
| 158 | master->dev.of_node = node; | ||
| 159 | master->bus_num = pdev->id; | ||
| 160 | |||
| 161 | hw = spi_master_get_devdata(master); | ||
| 162 | hw->master = master; | ||
| 163 | platform_set_drvdata(pdev, hw); | ||
| 164 | |||
| 165 | /* Find and map our resources */ | ||
| 166 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 167 | if (!res) | ||
| 168 | goto exit_busy; | ||
| 169 | if (!devm_request_mem_region(&pdev->dev, res->start, | ||
| 170 | resource_size(res), pdev->name)) | ||
| 171 | goto exit_busy; | ||
| 172 | hw->base = devm_ioremap_nocache(&pdev->dev, res->start, | ||
| 173 | resource_size(res)); | ||
| 174 | if (!hw->base) | ||
| 175 | goto exit_busy; | ||
| 176 | |||
| 177 | /* | ||
| 178 | * The SPI clock rate controlled via a configurable clock divider | ||
| 179 | * which is applied to the reference clock. A 50 MHz reference is | ||
| 180 | * most suitable for obtaining standard SPI clock rates, but some | ||
| 181 | * designs may have a different reference clock, and the DT must | ||
| 182 | * make the driver aware so that it can properly program the | ||
| 183 | * requested rate. If the clock is omitted, 50 MHz is assumed. | ||
| 184 | */ | ||
| 185 | clock_freq = 50000000; | ||
| 186 | clk = devm_clk_get(&pdev->dev, "ref_clk"); | ||
| 187 | if (!IS_ERR_OR_NULL(clk)) { | ||
| 188 | if (clk_enable(clk) == 0) | ||
| 189 | clock_freq = clk_get_rate(clk); | ||
| 190 | else | ||
| 191 | dev_warn(&pdev->dev, "could not enable ref_clk\n"); | ||
| 192 | } | ||
| 193 | hw->clock_freq = clock_freq; | ||
| 194 | |||
| 195 | /* Initialize all CS bits to high. */ | ||
| 196 | hw->cs_reg = JCORE_SPI_CTRL_CS_BITS; | ||
| 197 | jcore_spi_baudrate(hw, 400000); | ||
| 198 | |||
| 199 | /* Register our spi controller */ | ||
| 200 | err = devm_spi_register_master(&pdev->dev, master); | ||
| 201 | if (err) | ||
| 202 | goto exit; | ||
| 203 | |||
| 204 | return 0; | ||
| 205 | |||
| 206 | exit_busy: | ||
| 207 | err = -EBUSY; | ||
| 208 | exit: | ||
| 209 | spi_master_put(master); | ||
| 210 | return err; | ||
| 211 | } | ||
| 212 | |||
| 213 | static const struct of_device_id jcore_spi_of_match[] = { | ||
| 214 | { .compatible = "jcore,spi2" }, | ||
| 215 | {}, | ||
| 216 | }; | ||
| 217 | |||
| 218 | static struct platform_driver jcore_spi_driver = { | ||
| 219 | .probe = jcore_spi_probe, | ||
| 220 | .driver = { | ||
| 221 | .name = DRV_NAME, | ||
| 222 | .of_match_table = jcore_spi_of_match, | ||
| 223 | }, | ||
| 224 | }; | ||
| 225 | |||
| 226 | module_platform_driver(jcore_spi_driver); | ||
| 227 | |||
| 228 | MODULE_DESCRIPTION("J-Core SPI driver"); | ||
| 229 | MODULE_AUTHOR("Rich Felker <dalias@libc.org>"); | ||
| 230 | MODULE_LICENSE("GPL"); | ||
| 231 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/spi/spi-loopback-test.c b/drivers/spi/spi-loopback-test.c index faa1b133b0f1..50e620f4e8fe 100644 --- a/drivers/spi/spi-loopback-test.c +++ b/drivers/spi/spi-loopback-test.c | |||
| @@ -405,7 +405,7 @@ struct rx_ranges { | |||
| 405 | u8 *end; | 405 | u8 *end; |
| 406 | }; | 406 | }; |
| 407 | 407 | ||
| 408 | int rx_ranges_cmp(void *priv, struct list_head *a, struct list_head *b) | 408 | static int rx_ranges_cmp(void *priv, struct list_head *a, struct list_head *b) |
| 409 | { | 409 | { |
| 410 | struct rx_ranges *rx_a = list_entry(a, struct rx_ranges, list); | 410 | struct rx_ranges *rx_a = list_entry(a, struct rx_ranges, list); |
| 411 | struct rx_ranges *rx_b = list_entry(b, struct rx_ranges, list); | 411 | struct rx_ranges *rx_b = list_entry(b, struct rx_ranges, list); |
diff --git a/drivers/spi/spi-meson-spifc.c b/drivers/spi/spi-meson-spifc.c index 2465259f6241..616566e793c6 100644 --- a/drivers/spi/spi-meson-spifc.c +++ b/drivers/spi/spi-meson-spifc.c | |||
| @@ -442,6 +442,7 @@ static const struct dev_pm_ops meson_spifc_pm_ops = { | |||
| 442 | 442 | ||
| 443 | static const struct of_device_id meson_spifc_dt_match[] = { | 443 | static const struct of_device_id meson_spifc_dt_match[] = { |
| 444 | { .compatible = "amlogic,meson6-spifc", }, | 444 | { .compatible = "amlogic,meson6-spifc", }, |
| 445 | { .compatible = "amlogic,meson-gxbb-spifc", }, | ||
| 445 | { }, | 446 | { }, |
| 446 | }; | 447 | }; |
| 447 | MODULE_DEVICE_TABLE(of, meson_spifc_dt_match); | 448 | MODULE_DEVICE_TABLE(of, meson_spifc_dt_match); |
diff --git a/drivers/spi/spi-pic32-sqi.c b/drivers/spi/spi-pic32-sqi.c index c41abddab318..bd1c6b53283f 100644 --- a/drivers/spi/spi-pic32-sqi.c +++ b/drivers/spi/spi-pic32-sqi.c | |||
| @@ -253,15 +253,13 @@ static struct ring_desc *ring_desc_get(struct pic32_sqi *sqi) | |||
| 253 | return NULL; | 253 | return NULL; |
| 254 | 254 | ||
| 255 | rdesc = list_first_entry(&sqi->bd_list_free, struct ring_desc, list); | 255 | rdesc = list_first_entry(&sqi->bd_list_free, struct ring_desc, list); |
| 256 | list_del(&rdesc->list); | 256 | list_move_tail(&rdesc->list, &sqi->bd_list_used); |
| 257 | list_add_tail(&rdesc->list, &sqi->bd_list_used); | ||
| 258 | return rdesc; | 257 | return rdesc; |
| 259 | } | 258 | } |
| 260 | 259 | ||
| 261 | static void ring_desc_put(struct pic32_sqi *sqi, struct ring_desc *rdesc) | 260 | static void ring_desc_put(struct pic32_sqi *sqi, struct ring_desc *rdesc) |
| 262 | { | 261 | { |
| 263 | list_del(&rdesc->list); | 262 | list_move(&rdesc->list, &sqi->bd_list_free); |
| 264 | list_add(&rdesc->list, &sqi->bd_list_free); | ||
| 265 | } | 263 | } |
| 266 | 264 | ||
| 267 | static int pic32_sqi_one_transfer(struct pic32_sqi *sqi, | 265 | static int pic32_sqi_one_transfer(struct pic32_sqi *sqi, |
diff --git a/drivers/spi/spi-pxa2xx-dma.c b/drivers/spi/spi-pxa2xx-dma.c index db3ae1dd829e..04f3eecf5cf3 100644 --- a/drivers/spi/spi-pxa2xx-dma.c +++ b/drivers/spi/spi-pxa2xx-dma.c | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data, | 23 | static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data, |
| 24 | bool error) | 24 | bool error) |
| 25 | { | 25 | { |
| 26 | struct spi_message *msg = drv_data->cur_msg; | 26 | struct spi_message *msg = drv_data->master->cur_msg; |
| 27 | 27 | ||
| 28 | /* | 28 | /* |
| 29 | * It is possible that one CPU is handling ROR interrupt and other | 29 | * It is possible that one CPU is handling ROR interrupt and other |
| @@ -76,7 +76,8 @@ static struct dma_async_tx_descriptor * | |||
| 76 | pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data, | 76 | pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data, |
| 77 | enum dma_transfer_direction dir) | 77 | enum dma_transfer_direction dir) |
| 78 | { | 78 | { |
| 79 | struct chip_data *chip = drv_data->cur_chip; | 79 | struct chip_data *chip = |
| 80 | spi_get_ctldata(drv_data->master->cur_msg->spi); | ||
| 80 | struct spi_transfer *xfer = drv_data->cur_transfer; | 81 | struct spi_transfer *xfer = drv_data->cur_transfer; |
| 81 | enum dma_slave_buswidth width; | 82 | enum dma_slave_buswidth width; |
| 82 | struct dma_slave_config cfg; | 83 | struct dma_slave_config cfg; |
| @@ -146,7 +147,7 @@ irqreturn_t pxa2xx_spi_dma_transfer(struct driver_data *drv_data) | |||
| 146 | int pxa2xx_spi_dma_prepare(struct driver_data *drv_data, u32 dma_burst) | 147 | int pxa2xx_spi_dma_prepare(struct driver_data *drv_data, u32 dma_burst) |
| 147 | { | 148 | { |
| 148 | struct dma_async_tx_descriptor *tx_desc, *rx_desc; | 149 | struct dma_async_tx_descriptor *tx_desc, *rx_desc; |
| 149 | int err = 0; | 150 | int err; |
| 150 | 151 | ||
| 151 | tx_desc = pxa2xx_spi_dma_prepare_one(drv_data, DMA_MEM_TO_DEV); | 152 | tx_desc = pxa2xx_spi_dma_prepare_one(drv_data, DMA_MEM_TO_DEV); |
| 152 | if (!tx_desc) { | 153 | if (!tx_desc) { |
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 87150a1049bd..dd7b5b47291d 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/spi/spi.h> | 28 | #include <linux/spi/spi.h> |
| 29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
| 30 | #include <linux/gpio.h> | 30 | #include <linux/gpio.h> |
| 31 | #include <linux/gpio/consumer.h> | ||
| 31 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
| 32 | #include <linux/clk.h> | 33 | #include <linux/clk.h> |
| 33 | #include <linux/pm_runtime.h> | 34 | #include <linux/pm_runtime.h> |
| @@ -62,6 +63,13 @@ MODULE_ALIAS("platform:pxa2xx-spi"); | |||
| 62 | | QUARK_X1000_SSCR1_TFT \ | 63 | | QUARK_X1000_SSCR1_TFT \ |
| 63 | | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM) | 64 | | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM) |
| 64 | 65 | ||
| 66 | #define CE4100_SSCR1_CHANGE_MASK (SSCR1_TTELP | SSCR1_TTE | SSCR1_SCFR \ | ||
| 67 | | SSCR1_ECRA | SSCR1_ECRB | SSCR1_SCLKDIR \ | ||
| 68 | | SSCR1_SFRMDIR | SSCR1_RWOT | SSCR1_TRAIL \ | ||
| 69 | | SSCR1_IFS | SSCR1_STRF | SSCR1_EFWR \ | ||
| 70 | | CE4100_SSCR1_RFT | CE4100_SSCR1_TFT | SSCR1_MWDS \ | ||
| 71 | | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM) | ||
| 72 | |||
| 65 | #define LPSS_GENERAL_REG_RXTO_HOLDOFF_DISABLE BIT(24) | 73 | #define LPSS_GENERAL_REG_RXTO_HOLDOFF_DISABLE BIT(24) |
| 66 | #define LPSS_CS_CONTROL_SW_MODE BIT(0) | 74 | #define LPSS_CS_CONTROL_SW_MODE BIT(0) |
| 67 | #define LPSS_CS_CONTROL_CS_HIGH BIT(1) | 75 | #define LPSS_CS_CONTROL_CS_HIGH BIT(1) |
| @@ -175,6 +183,8 @@ static u32 pxa2xx_spi_get_ssrc1_change_mask(const struct driver_data *drv_data) | |||
| 175 | switch (drv_data->ssp_type) { | 183 | switch (drv_data->ssp_type) { |
| 176 | case QUARK_X1000_SSP: | 184 | case QUARK_X1000_SSP: |
| 177 | return QUARK_X1000_SSCR1_CHANGE_MASK; | 185 | return QUARK_X1000_SSCR1_CHANGE_MASK; |
| 186 | case CE4100_SSP: | ||
| 187 | return CE4100_SSCR1_CHANGE_MASK; | ||
| 178 | default: | 188 | default: |
| 179 | return SSCR1_CHANGE_MASK; | 189 | return SSCR1_CHANGE_MASK; |
| 180 | } | 190 | } |
| @@ -186,6 +196,8 @@ pxa2xx_spi_get_rx_default_thre(const struct driver_data *drv_data) | |||
| 186 | switch (drv_data->ssp_type) { | 196 | switch (drv_data->ssp_type) { |
| 187 | case QUARK_X1000_SSP: | 197 | case QUARK_X1000_SSP: |
| 188 | return RX_THRESH_QUARK_X1000_DFLT; | 198 | return RX_THRESH_QUARK_X1000_DFLT; |
| 199 | case CE4100_SSP: | ||
| 200 | return RX_THRESH_CE4100_DFLT; | ||
| 189 | default: | 201 | default: |
| 190 | return RX_THRESH_DFLT; | 202 | return RX_THRESH_DFLT; |
| 191 | } | 203 | } |
| @@ -199,6 +211,9 @@ static bool pxa2xx_spi_txfifo_full(const struct driver_data *drv_data) | |||
| 199 | case QUARK_X1000_SSP: | 211 | case QUARK_X1000_SSP: |
| 200 | mask = QUARK_X1000_SSSR_TFL_MASK; | 212 | mask = QUARK_X1000_SSSR_TFL_MASK; |
| 201 | break; | 213 | break; |
| 214 | case CE4100_SSP: | ||
| 215 | mask = CE4100_SSSR_TFL_MASK; | ||
| 216 | break; | ||
| 202 | default: | 217 | default: |
| 203 | mask = SSSR_TFL_MASK; | 218 | mask = SSSR_TFL_MASK; |
| 204 | break; | 219 | break; |
| @@ -216,6 +231,9 @@ static void pxa2xx_spi_clear_rx_thre(const struct driver_data *drv_data, | |||
| 216 | case QUARK_X1000_SSP: | 231 | case QUARK_X1000_SSP: |
| 217 | mask = QUARK_X1000_SSCR1_RFT; | 232 | mask = QUARK_X1000_SSCR1_RFT; |
| 218 | break; | 233 | break; |
| 234 | case CE4100_SSP: | ||
| 235 | mask = CE4100_SSCR1_RFT; | ||
| 236 | break; | ||
| 219 | default: | 237 | default: |
| 220 | mask = SSCR1_RFT; | 238 | mask = SSCR1_RFT; |
| 221 | break; | 239 | break; |
| @@ -230,6 +248,9 @@ static void pxa2xx_spi_set_rx_thre(const struct driver_data *drv_data, | |||
| 230 | case QUARK_X1000_SSP: | 248 | case QUARK_X1000_SSP: |
| 231 | *sccr1_reg |= QUARK_X1000_SSCR1_RxTresh(threshold); | 249 | *sccr1_reg |= QUARK_X1000_SSCR1_RxTresh(threshold); |
| 232 | break; | 250 | break; |
| 251 | case CE4100_SSP: | ||
| 252 | *sccr1_reg |= CE4100_SSCR1_RxTresh(threshold); | ||
| 253 | break; | ||
| 233 | default: | 254 | default: |
| 234 | *sccr1_reg |= SSCR1_RxTresh(threshold); | 255 | *sccr1_reg |= SSCR1_RxTresh(threshold); |
| 235 | break; | 256 | break; |
| @@ -316,7 +337,7 @@ static void lpss_ssp_select_cs(struct driver_data *drv_data, | |||
| 316 | 337 | ||
| 317 | value = __lpss_ssp_read_priv(drv_data, config->reg_cs_ctrl); | 338 | value = __lpss_ssp_read_priv(drv_data, config->reg_cs_ctrl); |
| 318 | 339 | ||
| 319 | cs = drv_data->cur_msg->spi->chip_select; | 340 | cs = drv_data->master->cur_msg->spi->chip_select; |
| 320 | cs <<= config->cs_sel_shift; | 341 | cs <<= config->cs_sel_shift; |
| 321 | if (cs != (value & config->cs_sel_mask)) { | 342 | if (cs != (value & config->cs_sel_mask)) { |
| 322 | /* | 343 | /* |
| @@ -355,10 +376,11 @@ static void lpss_ssp_cs_control(struct driver_data *drv_data, bool enable) | |||
| 355 | 376 | ||
| 356 | static void cs_assert(struct driver_data *drv_data) | 377 | static void cs_assert(struct driver_data *drv_data) |
| 357 | { | 378 | { |
| 358 | struct chip_data *chip = drv_data->cur_chip; | 379 | struct chip_data *chip = |
| 380 | spi_get_ctldata(drv_data->master->cur_msg->spi); | ||
| 359 | 381 | ||
| 360 | if (drv_data->ssp_type == CE4100_SSP) { | 382 | if (drv_data->ssp_type == CE4100_SSP) { |
| 361 | pxa2xx_spi_write(drv_data, SSSR, drv_data->cur_chip->frm); | 383 | pxa2xx_spi_write(drv_data, SSSR, chip->frm); |
| 362 | return; | 384 | return; |
| 363 | } | 385 | } |
| 364 | 386 | ||
| @@ -378,7 +400,8 @@ static void cs_assert(struct driver_data *drv_data) | |||
| 378 | 400 | ||
| 379 | static void cs_deassert(struct driver_data *drv_data) | 401 | static void cs_deassert(struct driver_data *drv_data) |
| 380 | { | 402 | { |
| 381 | struct chip_data *chip = drv_data->cur_chip; | 403 | struct chip_data *chip = |
| 404 | spi_get_ctldata(drv_data->master->cur_msg->spi); | ||
| 382 | 405 | ||
| 383 | if (drv_data->ssp_type == CE4100_SSP) | 406 | if (drv_data->ssp_type == CE4100_SSP) |
| 384 | return; | 407 | return; |
| @@ -508,7 +531,7 @@ static int u32_reader(struct driver_data *drv_data) | |||
| 508 | 531 | ||
| 509 | void *pxa2xx_spi_next_transfer(struct driver_data *drv_data) | 532 | void *pxa2xx_spi_next_transfer(struct driver_data *drv_data) |
| 510 | { | 533 | { |
| 511 | struct spi_message *msg = drv_data->cur_msg; | 534 | struct spi_message *msg = drv_data->master->cur_msg; |
| 512 | struct spi_transfer *trans = drv_data->cur_transfer; | 535 | struct spi_transfer *trans = drv_data->cur_transfer; |
| 513 | 536 | ||
| 514 | /* Move to next transfer */ | 537 | /* Move to next transfer */ |
| @@ -529,8 +552,7 @@ static void giveback(struct driver_data *drv_data) | |||
| 529 | struct spi_message *msg; | 552 | struct spi_message *msg; |
| 530 | unsigned long timeout; | 553 | unsigned long timeout; |
| 531 | 554 | ||
| 532 | msg = drv_data->cur_msg; | 555 | msg = drv_data->master->cur_msg; |
| 533 | drv_data->cur_msg = NULL; | ||
| 534 | drv_data->cur_transfer = NULL; | 556 | drv_data->cur_transfer = NULL; |
| 535 | 557 | ||
| 536 | last_transfer = list_last_entry(&msg->transfers, struct spi_transfer, | 558 | last_transfer = list_last_entry(&msg->transfers, struct spi_transfer, |
| @@ -575,13 +597,13 @@ static void giveback(struct driver_data *drv_data) | |||
| 575 | cs_deassert(drv_data); | 597 | cs_deassert(drv_data); |
| 576 | } | 598 | } |
| 577 | 599 | ||
| 578 | drv_data->cur_chip = NULL; | ||
| 579 | spi_finalize_current_message(drv_data->master); | 600 | spi_finalize_current_message(drv_data->master); |
| 580 | } | 601 | } |
| 581 | 602 | ||
| 582 | static void reset_sccr1(struct driver_data *drv_data) | 603 | static void reset_sccr1(struct driver_data *drv_data) |
| 583 | { | 604 | { |
| 584 | struct chip_data *chip = drv_data->cur_chip; | 605 | struct chip_data *chip = |
| 606 | spi_get_ctldata(drv_data->master->cur_msg->spi); | ||
| 585 | u32 sccr1_reg; | 607 | u32 sccr1_reg; |
| 586 | 608 | ||
| 587 | sccr1_reg = pxa2xx_spi_read(drv_data, SSCR1) & ~drv_data->int_cr1; | 609 | sccr1_reg = pxa2xx_spi_read(drv_data, SSCR1) & ~drv_data->int_cr1; |
| @@ -589,6 +611,9 @@ static void reset_sccr1(struct driver_data *drv_data) | |||
| 589 | case QUARK_X1000_SSP: | 611 | case QUARK_X1000_SSP: |
| 590 | sccr1_reg &= ~QUARK_X1000_SSCR1_RFT; | 612 | sccr1_reg &= ~QUARK_X1000_SSCR1_RFT; |
| 591 | break; | 613 | break; |
| 614 | case CE4100_SSP: | ||
| 615 | sccr1_reg &= ~CE4100_SSCR1_RFT; | ||
| 616 | break; | ||
| 592 | default: | 617 | default: |
| 593 | sccr1_reg &= ~SSCR1_RFT; | 618 | sccr1_reg &= ~SSCR1_RFT; |
| 594 | break; | 619 | break; |
| @@ -610,7 +635,7 @@ static void int_error_stop(struct driver_data *drv_data, const char* msg) | |||
| 610 | 635 | ||
| 611 | dev_err(&drv_data->pdev->dev, "%s\n", msg); | 636 | dev_err(&drv_data->pdev->dev, "%s\n", msg); |
| 612 | 637 | ||
| 613 | drv_data->cur_msg->state = ERROR_STATE; | 638 | drv_data->master->cur_msg->state = ERROR_STATE; |
| 614 | tasklet_schedule(&drv_data->pump_transfers); | 639 | tasklet_schedule(&drv_data->pump_transfers); |
| 615 | } | 640 | } |
| 616 | 641 | ||
| @@ -623,7 +648,7 @@ static void int_transfer_complete(struct driver_data *drv_data) | |||
| 623 | pxa2xx_spi_write(drv_data, SSTO, 0); | 648 | pxa2xx_spi_write(drv_data, SSTO, 0); |
| 624 | 649 | ||
| 625 | /* Update total byte transferred return count actual bytes read */ | 650 | /* Update total byte transferred return count actual bytes read */ |
| 626 | drv_data->cur_msg->actual_length += drv_data->len - | 651 | drv_data->master->cur_msg->actual_length += drv_data->len - |
| 627 | (drv_data->rx_end - drv_data->rx); | 652 | (drv_data->rx_end - drv_data->rx); |
| 628 | 653 | ||
| 629 | /* Transfer delays and chip select release are | 654 | /* Transfer delays and chip select release are |
| @@ -631,7 +656,7 @@ static void int_transfer_complete(struct driver_data *drv_data) | |||
| 631 | */ | 656 | */ |
| 632 | 657 | ||
| 633 | /* Move to next transfer */ | 658 | /* Move to next transfer */ |
| 634 | drv_data->cur_msg->state = pxa2xx_spi_next_transfer(drv_data); | 659 | drv_data->master->cur_msg->state = pxa2xx_spi_next_transfer(drv_data); |
| 635 | 660 | ||
| 636 | /* Schedule transfer tasklet */ | 661 | /* Schedule transfer tasklet */ |
| 637 | tasklet_schedule(&drv_data->pump_transfers); | 662 | tasklet_schedule(&drv_data->pump_transfers); |
| @@ -746,7 +771,7 @@ static irqreturn_t ssp_int(int irq, void *dev_id) | |||
| 746 | if (!(status & mask)) | 771 | if (!(status & mask)) |
| 747 | return IRQ_NONE; | 772 | return IRQ_NONE; |
| 748 | 773 | ||
| 749 | if (!drv_data->cur_msg) { | 774 | if (!drv_data->master->cur_msg) { |
| 750 | 775 | ||
| 751 | pxa2xx_spi_write(drv_data, SSCR0, | 776 | pxa2xx_spi_write(drv_data, SSCR0, |
| 752 | pxa2xx_spi_read(drv_data, SSCR0) | 777 | pxa2xx_spi_read(drv_data, SSCR0) |
| @@ -905,7 +930,8 @@ static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate) | |||
| 905 | static unsigned int pxa2xx_ssp_get_clk_div(struct driver_data *drv_data, | 930 | static unsigned int pxa2xx_ssp_get_clk_div(struct driver_data *drv_data, |
| 906 | int rate) | 931 | int rate) |
| 907 | { | 932 | { |
| 908 | struct chip_data *chip = drv_data->cur_chip; | 933 | struct chip_data *chip = |
| 934 | spi_get_ctldata(drv_data->master->cur_msg->spi); | ||
| 909 | unsigned int clk_div; | 935 | unsigned int clk_div; |
| 910 | 936 | ||
| 911 | switch (drv_data->ssp_type) { | 937 | switch (drv_data->ssp_type) { |
| @@ -934,25 +960,23 @@ static void pump_transfers(unsigned long data) | |||
| 934 | { | 960 | { |
| 935 | struct driver_data *drv_data = (struct driver_data *)data; | 961 | struct driver_data *drv_data = (struct driver_data *)data; |
| 936 | struct spi_master *master = drv_data->master; | 962 | struct spi_master *master = drv_data->master; |
| 937 | struct spi_message *message = NULL; | 963 | struct spi_message *message = master->cur_msg; |
| 938 | struct spi_transfer *transfer = NULL; | 964 | struct chip_data *chip = spi_get_ctldata(message->spi); |
| 939 | struct spi_transfer *previous = NULL; | 965 | u32 dma_thresh = chip->dma_threshold; |
| 940 | struct chip_data *chip = NULL; | 966 | u32 dma_burst = chip->dma_burst_size; |
| 941 | u32 clk_div = 0; | 967 | u32 change_mask = pxa2xx_spi_get_ssrc1_change_mask(drv_data); |
| 942 | u8 bits = 0; | 968 | struct spi_transfer *transfer; |
| 943 | u32 speed = 0; | 969 | struct spi_transfer *previous; |
| 970 | u32 clk_div; | ||
| 971 | u8 bits; | ||
| 972 | u32 speed; | ||
| 944 | u32 cr0; | 973 | u32 cr0; |
| 945 | u32 cr1; | 974 | u32 cr1; |
| 946 | u32 dma_thresh = drv_data->cur_chip->dma_threshold; | ||
| 947 | u32 dma_burst = drv_data->cur_chip->dma_burst_size; | ||
| 948 | u32 change_mask = pxa2xx_spi_get_ssrc1_change_mask(drv_data); | ||
| 949 | int err; | 975 | int err; |
| 950 | int dma_mapped; | 976 | int dma_mapped; |
| 951 | 977 | ||
| 952 | /* Get current state information */ | 978 | /* Get current state information */ |
| 953 | message = drv_data->cur_msg; | ||
| 954 | transfer = drv_data->cur_transfer; | 979 | transfer = drv_data->cur_transfer; |
| 955 | chip = drv_data->cur_chip; | ||
| 956 | 980 | ||
| 957 | /* Handle for abort */ | 981 | /* Handle for abort */ |
| 958 | if (message->state == ERROR_STATE) { | 982 | if (message->state == ERROR_STATE) { |
| @@ -1146,17 +1170,12 @@ static int pxa2xx_spi_transfer_one_message(struct spi_master *master, | |||
| 1146 | { | 1170 | { |
| 1147 | struct driver_data *drv_data = spi_master_get_devdata(master); | 1171 | struct driver_data *drv_data = spi_master_get_devdata(master); |
| 1148 | 1172 | ||
| 1149 | drv_data->cur_msg = msg; | ||
| 1150 | /* Initial message state*/ | 1173 | /* Initial message state*/ |
| 1151 | drv_data->cur_msg->state = START_STATE; | 1174 | msg->state = START_STATE; |
| 1152 | drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next, | 1175 | drv_data->cur_transfer = list_entry(msg->transfers.next, |
| 1153 | struct spi_transfer, | 1176 | struct spi_transfer, |
| 1154 | transfer_list); | 1177 | transfer_list); |
| 1155 | 1178 | ||
| 1156 | /* prepare to setup the SSP, in pump_transfers, using the per | ||
| 1157 | * chip configuration */ | ||
| 1158 | drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi); | ||
| 1159 | |||
| 1160 | /* Mark as busy and launch transfers */ | 1179 | /* Mark as busy and launch transfers */ |
| 1161 | tasklet_schedule(&drv_data->pump_transfers); | 1180 | tasklet_schedule(&drv_data->pump_transfers); |
| 1162 | return 0; | 1181 | return 0; |
| @@ -1176,9 +1195,26 @@ static int pxa2xx_spi_unprepare_transfer(struct spi_master *master) | |||
| 1176 | static int setup_cs(struct spi_device *spi, struct chip_data *chip, | 1195 | static int setup_cs(struct spi_device *spi, struct chip_data *chip, |
| 1177 | struct pxa2xx_spi_chip *chip_info) | 1196 | struct pxa2xx_spi_chip *chip_info) |
| 1178 | { | 1197 | { |
| 1198 | struct driver_data *drv_data = spi_master_get_devdata(spi->master); | ||
| 1179 | int err = 0; | 1199 | int err = 0; |
| 1180 | 1200 | ||
| 1181 | if (chip == NULL || chip_info == NULL) | 1201 | if (chip == NULL) |
| 1202 | return 0; | ||
| 1203 | |||
| 1204 | if (drv_data->cs_gpiods) { | ||
| 1205 | struct gpio_desc *gpiod; | ||
| 1206 | |||
| 1207 | gpiod = drv_data->cs_gpiods[spi->chip_select]; | ||
| 1208 | if (gpiod) { | ||
| 1209 | chip->gpio_cs = desc_to_gpio(gpiod); | ||
| 1210 | chip->gpio_cs_inverted = spi->mode & SPI_CS_HIGH; | ||
| 1211 | gpiod_set_value(gpiod, chip->gpio_cs_inverted); | ||
| 1212 | } | ||
| 1213 | |||
| 1214 | return 0; | ||
| 1215 | } | ||
| 1216 | |||
| 1217 | if (chip_info == NULL) | ||
| 1182 | return 0; | 1218 | return 0; |
| 1183 | 1219 | ||
| 1184 | /* NOTE: setup() can be called multiple times, possibly with | 1220 | /* NOTE: setup() can be called multiple times, possibly with |
| @@ -1213,7 +1249,7 @@ static int setup_cs(struct spi_device *spi, struct chip_data *chip, | |||
| 1213 | 1249 | ||
| 1214 | static int setup(struct spi_device *spi) | 1250 | static int setup(struct spi_device *spi) |
| 1215 | { | 1251 | { |
| 1216 | struct pxa2xx_spi_chip *chip_info = NULL; | 1252 | struct pxa2xx_spi_chip *chip_info; |
| 1217 | struct chip_data *chip; | 1253 | struct chip_data *chip; |
| 1218 | const struct lpss_config *config; | 1254 | const struct lpss_config *config; |
| 1219 | struct driver_data *drv_data = spi_master_get_devdata(spi->master); | 1255 | struct driver_data *drv_data = spi_master_get_devdata(spi->master); |
| @@ -1225,6 +1261,11 @@ static int setup(struct spi_device *spi) | |||
| 1225 | tx_hi_thres = 0; | 1261 | tx_hi_thres = 0; |
| 1226 | rx_thres = RX_THRESH_QUARK_X1000_DFLT; | 1262 | rx_thres = RX_THRESH_QUARK_X1000_DFLT; |
| 1227 | break; | 1263 | break; |
| 1264 | case CE4100_SSP: | ||
| 1265 | tx_thres = TX_THRESH_CE4100_DFLT; | ||
| 1266 | tx_hi_thres = 0; | ||
| 1267 | rx_thres = RX_THRESH_CE4100_DFLT; | ||
| 1268 | break; | ||
| 1228 | case LPSS_LPT_SSP: | 1269 | case LPSS_LPT_SSP: |
| 1229 | case LPSS_BYT_SSP: | 1270 | case LPSS_BYT_SSP: |
| 1230 | case LPSS_BSW_SSP: | 1271 | case LPSS_BSW_SSP: |
| @@ -1309,6 +1350,10 @@ static int setup(struct spi_device *spi) | |||
| 1309 | | (QUARK_X1000_SSCR1_TxTresh(tx_thres) | 1350 | | (QUARK_X1000_SSCR1_TxTresh(tx_thres) |
| 1310 | & QUARK_X1000_SSCR1_TFT); | 1351 | & QUARK_X1000_SSCR1_TFT); |
| 1311 | break; | 1352 | break; |
| 1353 | case CE4100_SSP: | ||
| 1354 | chip->threshold = (CE4100_SSCR1_RxTresh(rx_thres) & CE4100_SSCR1_RFT) | | ||
| 1355 | (CE4100_SSCR1_TxTresh(tx_thres) & CE4100_SSCR1_TFT); | ||
| 1356 | break; | ||
| 1312 | default: | 1357 | default: |
| 1313 | chip->threshold = (SSCR1_RxTresh(rx_thres) & SSCR1_RFT) | | 1358 | chip->threshold = (SSCR1_RxTresh(rx_thres) & SSCR1_RFT) | |
| 1314 | (SSCR1_TxTresh(tx_thres) & SSCR1_TFT); | 1359 | (SSCR1_TxTresh(tx_thres) & SSCR1_TFT); |
| @@ -1352,7 +1397,8 @@ static void cleanup(struct spi_device *spi) | |||
| 1352 | if (!chip) | 1397 | if (!chip) |
| 1353 | return; | 1398 | return; |
| 1354 | 1399 | ||
| 1355 | if (drv_data->ssp_type != CE4100_SSP && gpio_is_valid(chip->gpio_cs)) | 1400 | if (drv_data->ssp_type != CE4100_SSP && !drv_data->cs_gpiods && |
| 1401 | gpio_is_valid(chip->gpio_cs)) | ||
| 1356 | gpio_free(chip->gpio_cs); | 1402 | gpio_free(chip->gpio_cs); |
| 1357 | 1403 | ||
| 1358 | kfree(chip); | 1404 | kfree(chip); |
| @@ -1530,7 +1576,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) | |||
| 1530 | struct driver_data *drv_data; | 1576 | struct driver_data *drv_data; |
| 1531 | struct ssp_device *ssp; | 1577 | struct ssp_device *ssp; |
| 1532 | const struct lpss_config *config; | 1578 | const struct lpss_config *config; |
| 1533 | int status; | 1579 | int status, count; |
| 1534 | u32 tmp; | 1580 | u32 tmp; |
| 1535 | 1581 | ||
| 1536 | platform_info = dev_get_platdata(dev); | 1582 | platform_info = dev_get_platdata(dev); |
| @@ -1630,15 +1676,20 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) | |||
| 1630 | pxa2xx_spi_write(drv_data, SSCR0, 0); | 1676 | pxa2xx_spi_write(drv_data, SSCR0, 0); |
| 1631 | switch (drv_data->ssp_type) { | 1677 | switch (drv_data->ssp_type) { |
| 1632 | case QUARK_X1000_SSP: | 1678 | case QUARK_X1000_SSP: |
| 1633 | tmp = QUARK_X1000_SSCR1_RxTresh(RX_THRESH_QUARK_X1000_DFLT) | 1679 | tmp = QUARK_X1000_SSCR1_RxTresh(RX_THRESH_QUARK_X1000_DFLT) | |
| 1634 | | QUARK_X1000_SSCR1_TxTresh(TX_THRESH_QUARK_X1000_DFLT); | 1680 | QUARK_X1000_SSCR1_TxTresh(TX_THRESH_QUARK_X1000_DFLT); |
| 1635 | pxa2xx_spi_write(drv_data, SSCR1, tmp); | 1681 | pxa2xx_spi_write(drv_data, SSCR1, tmp); |
| 1636 | 1682 | ||
| 1637 | /* using the Motorola SPI protocol and use 8 bit frame */ | 1683 | /* using the Motorola SPI protocol and use 8 bit frame */ |
| 1638 | pxa2xx_spi_write(drv_data, SSCR0, | 1684 | tmp = QUARK_X1000_SSCR0_Motorola | QUARK_X1000_SSCR0_DataSize(8); |
| 1639 | QUARK_X1000_SSCR0_Motorola | 1685 | pxa2xx_spi_write(drv_data, SSCR0, tmp); |
| 1640 | | QUARK_X1000_SSCR0_DataSize(8)); | ||
| 1641 | break; | 1686 | break; |
| 1687 | case CE4100_SSP: | ||
| 1688 | tmp = CE4100_SSCR1_RxTresh(RX_THRESH_CE4100_DFLT) | | ||
| 1689 | CE4100_SSCR1_TxTresh(TX_THRESH_CE4100_DFLT); | ||
| 1690 | pxa2xx_spi_write(drv_data, SSCR1, tmp); | ||
| 1691 | tmp = SSCR0_SCR(2) | SSCR0_Motorola | SSCR0_DataSize(8); | ||
| 1692 | pxa2xx_spi_write(drv_data, SSCR0, tmp); | ||
| 1642 | default: | 1693 | default: |
| 1643 | tmp = SSCR1_RxTresh(RX_THRESH_DFLT) | | 1694 | tmp = SSCR1_RxTresh(RX_THRESH_DFLT) | |
| 1644 | SSCR1_TxTresh(TX_THRESH_DFLT); | 1695 | SSCR1_TxTresh(TX_THRESH_DFLT); |
| @@ -1669,6 +1720,39 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) | |||
| 1669 | } | 1720 | } |
| 1670 | master->num_chipselect = platform_info->num_chipselect; | 1721 | master->num_chipselect = platform_info->num_chipselect; |
| 1671 | 1722 | ||
| 1723 | count = gpiod_count(&pdev->dev, "cs"); | ||
| 1724 | if (count > 0) { | ||
| 1725 | int i; | ||
| 1726 | |||
| 1727 | master->num_chipselect = max_t(int, count, | ||
| 1728 | master->num_chipselect); | ||
| 1729 | |||
| 1730 | drv_data->cs_gpiods = devm_kcalloc(&pdev->dev, | ||
| 1731 | master->num_chipselect, sizeof(struct gpio_desc *), | ||
| 1732 | GFP_KERNEL); | ||
| 1733 | if (!drv_data->cs_gpiods) { | ||
| 1734 | status = -ENOMEM; | ||
| 1735 | goto out_error_clock_enabled; | ||
| 1736 | } | ||
| 1737 | |||
| 1738 | for (i = 0; i < master->num_chipselect; i++) { | ||
| 1739 | struct gpio_desc *gpiod; | ||
| 1740 | |||
| 1741 | gpiod = devm_gpiod_get_index(dev, "cs", i, | ||
| 1742 | GPIOD_OUT_HIGH); | ||
| 1743 | if (IS_ERR(gpiod)) { | ||
| 1744 | /* Means use native chip select */ | ||
| 1745 | if (PTR_ERR(gpiod) == -ENOENT) | ||
| 1746 | continue; | ||
| 1747 | |||
| 1748 | status = (int)PTR_ERR(gpiod); | ||
| 1749 | goto out_error_clock_enabled; | ||
| 1750 | } else { | ||
| 1751 | drv_data->cs_gpiods[i] = gpiod; | ||
| 1752 | } | ||
| 1753 | } | ||
| 1754 | } | ||
| 1755 | |||
| 1672 | tasklet_init(&drv_data->pump_transfers, pump_transfers, | 1756 | tasklet_init(&drv_data->pump_transfers, pump_transfers, |
| 1673 | (unsigned long)drv_data); | 1757 | (unsigned long)drv_data); |
| 1674 | 1758 | ||
| @@ -1742,7 +1826,7 @@ static int pxa2xx_spi_suspend(struct device *dev) | |||
| 1742 | { | 1826 | { |
| 1743 | struct driver_data *drv_data = dev_get_drvdata(dev); | 1827 | struct driver_data *drv_data = dev_get_drvdata(dev); |
| 1744 | struct ssp_device *ssp = drv_data->ssp; | 1828 | struct ssp_device *ssp = drv_data->ssp; |
| 1745 | int status = 0; | 1829 | int status; |
| 1746 | 1830 | ||
| 1747 | status = spi_master_suspend(drv_data->master); | 1831 | status = spi_master_suspend(drv_data->master); |
| 1748 | if (status != 0) | 1832 | if (status != 0) |
| @@ -1759,7 +1843,7 @@ static int pxa2xx_spi_resume(struct device *dev) | |||
| 1759 | { | 1843 | { |
| 1760 | struct driver_data *drv_data = dev_get_drvdata(dev); | 1844 | struct driver_data *drv_data = dev_get_drvdata(dev); |
| 1761 | struct ssp_device *ssp = drv_data->ssp; | 1845 | struct ssp_device *ssp = drv_data->ssp; |
| 1762 | int status = 0; | 1846 | int status; |
| 1763 | 1847 | ||
| 1764 | /* Enable the SSP clock */ | 1848 | /* Enable the SSP clock */ |
| 1765 | if (!pm_runtime_suspended(dev)) | 1849 | if (!pm_runtime_suspended(dev)) |
diff --git a/drivers/spi/spi-pxa2xx.h b/drivers/spi/spi-pxa2xx.h index d217ad55cc12..ce31b8199bb3 100644 --- a/drivers/spi/spi-pxa2xx.h +++ b/drivers/spi/spi-pxa2xx.h | |||
| @@ -53,9 +53,7 @@ struct driver_data { | |||
| 53 | atomic_t dma_running; | 53 | atomic_t dma_running; |
| 54 | 54 | ||
| 55 | /* Current message transfer state info */ | 55 | /* Current message transfer state info */ |
| 56 | struct spi_message *cur_msg; | ||
| 57 | struct spi_transfer *cur_transfer; | 56 | struct spi_transfer *cur_transfer; |
| 58 | struct chip_data *cur_chip; | ||
| 59 | size_t len; | 57 | size_t len; |
| 60 | void *tx; | 58 | void *tx; |
| 61 | void *tx_end; | 59 | void *tx_end; |
| @@ -68,6 +66,9 @@ struct driver_data { | |||
| 68 | void (*cs_control)(u32 command); | 66 | void (*cs_control)(u32 command); |
| 69 | 67 | ||
| 70 | void __iomem *lpss_base; | 68 | void __iomem *lpss_base; |
| 69 | |||
| 70 | /* GPIOs for chip selects */ | ||
| 71 | struct gpio_desc **cs_gpiods; | ||
| 71 | }; | 72 | }; |
| 72 | 73 | ||
| 73 | struct chip_data { | 74 | struct chip_data { |
diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c index 7f1555621f8e..1bfa889b8427 100644 --- a/drivers/spi/spi-qup.c +++ b/drivers/spi/spi-qup.c | |||
| @@ -982,8 +982,10 @@ static int spi_qup_suspend(struct device *device) | |||
| 982 | if (ret) | 982 | if (ret) |
| 983 | return ret; | 983 | return ret; |
| 984 | 984 | ||
| 985 | clk_disable_unprepare(controller->cclk); | 985 | if (!pm_runtime_suspended(device)) { |
| 986 | clk_disable_unprepare(controller->iclk); | 986 | clk_disable_unprepare(controller->cclk); |
| 987 | clk_disable_unprepare(controller->iclk); | ||
| 988 | } | ||
| 987 | return 0; | 989 | return 0; |
| 988 | } | 990 | } |
| 989 | 991 | ||
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 818843336932..a816f07e168e 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c | |||
| @@ -295,14 +295,24 @@ static int rspi_set_config_register(struct rspi_data *rspi, int access_size) | |||
| 295 | static int rspi_rz_set_config_register(struct rspi_data *rspi, int access_size) | 295 | static int rspi_rz_set_config_register(struct rspi_data *rspi, int access_size) |
| 296 | { | 296 | { |
| 297 | int spbr; | 297 | int spbr; |
| 298 | int div = 0; | ||
| 299 | unsigned long clksrc; | ||
| 298 | 300 | ||
| 299 | /* Sets output mode, MOSI signal, and (optionally) loopback */ | 301 | /* Sets output mode, MOSI signal, and (optionally) loopback */ |
| 300 | rspi_write8(rspi, rspi->sppcr, RSPI_SPPCR); | 302 | rspi_write8(rspi, rspi->sppcr, RSPI_SPPCR); |
| 301 | 303 | ||
| 304 | clksrc = clk_get_rate(rspi->clk); | ||
| 305 | while (div < 3) { | ||
| 306 | if (rspi->max_speed_hz >= clksrc/4) /* 4=(CLK/2)/2 */ | ||
| 307 | break; | ||
| 308 | div++; | ||
| 309 | clksrc /= 2; | ||
| 310 | } | ||
| 311 | |||
| 302 | /* Sets transfer bit rate */ | 312 | /* Sets transfer bit rate */ |
| 303 | spbr = DIV_ROUND_UP(clk_get_rate(rspi->clk), | 313 | spbr = DIV_ROUND_UP(clksrc, 2 * rspi->max_speed_hz) - 1; |
| 304 | 2 * rspi->max_speed_hz) - 1; | ||
| 305 | rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR); | 314 | rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR); |
| 315 | rspi->spcmd |= div << 2; | ||
| 306 | 316 | ||
| 307 | /* Disable dummy transmission, set byte access */ | 317 | /* Disable dummy transmission, set byte access */ |
| 308 | rspi_write8(rspi, SPDCR_SPLBYTE, RSPI_SPDCR); | 318 | rspi_write8(rspi, SPDCR_SPLBYTE, RSPI_SPDCR); |
diff --git a/drivers/spi/spi-sc18is602.c b/drivers/spi/spi-sc18is602.c index 36af4d48a700..f63714ffb62f 100644 --- a/drivers/spi/spi-sc18is602.c +++ b/drivers/spi/spi-sc18is602.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/pm_runtime.h> | 23 | #include <linux/pm_runtime.h> |
| 24 | #include <linux/of.h> | 24 | #include <linux/of.h> |
| 25 | #include <linux/platform_data/sc18is602.h> | 25 | #include <linux/platform_data/sc18is602.h> |
| 26 | #include <linux/gpio/consumer.h> | ||
| 26 | 27 | ||
| 27 | enum chips { sc18is602, sc18is602b, sc18is603 }; | 28 | enum chips { sc18is602, sc18is602b, sc18is603 }; |
| 28 | 29 | ||
| @@ -50,6 +51,8 @@ struct sc18is602 { | |||
| 50 | u8 buffer[SC18IS602_BUFSIZ + 1]; | 51 | u8 buffer[SC18IS602_BUFSIZ + 1]; |
| 51 | int tlen; /* Data queued for tx in buffer */ | 52 | int tlen; /* Data queued for tx in buffer */ |
| 52 | int rindex; /* Receive data index in buffer */ | 53 | int rindex; /* Receive data index in buffer */ |
| 54 | |||
| 55 | struct gpio_desc *reset; | ||
| 53 | }; | 56 | }; |
| 54 | 57 | ||
| 55 | static int sc18is602_wait_ready(struct sc18is602 *hw, int len) | 58 | static int sc18is602_wait_ready(struct sc18is602 *hw, int len) |
| @@ -257,6 +260,12 @@ static int sc18is602_probe(struct i2c_client *client, | |||
| 257 | hw = spi_master_get_devdata(master); | 260 | hw = spi_master_get_devdata(master); |
| 258 | i2c_set_clientdata(client, hw); | 261 | i2c_set_clientdata(client, hw); |
| 259 | 262 | ||
| 263 | /* assert reset and then release */ | ||
| 264 | hw->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); | ||
| 265 | if (IS_ERR(hw->reset)) | ||
| 266 | return PTR_ERR(hw->reset); | ||
| 267 | gpiod_set_value_cansleep(hw->reset, 0); | ||
| 268 | |||
| 260 | hw->master = master; | 269 | hw->master = master; |
| 261 | hw->client = client; | 270 | hw->client = client; |
| 262 | hw->dev = dev; | 271 | hw->dev = dev; |
diff --git a/drivers/spi/spi-st-ssc4.c b/drivers/spi/spi-st-ssc4.c index a56eca0e95a6..e54b59638458 100644 --- a/drivers/spi/spi-st-ssc4.c +++ b/drivers/spi/spi-st-ssc4.c | |||
| @@ -175,10 +175,7 @@ static int spi_st_transfer_one(struct spi_master *master, | |||
| 175 | 175 | ||
| 176 | static void spi_st_cleanup(struct spi_device *spi) | 176 | static void spi_st_cleanup(struct spi_device *spi) |
| 177 | { | 177 | { |
| 178 | int cs = spi->cs_gpio; | 178 | gpio_free(spi->cs_gpio); |
| 179 | |||
| 180 | if (gpio_is_valid(cs)) | ||
| 181 | devm_gpio_free(&spi->dev, cs); | ||
| 182 | } | 179 | } |
| 183 | 180 | ||
| 184 | /* the spi->mode bits understood by this driver: */ | 181 | /* the spi->mode bits understood by this driver: */ |
| @@ -201,14 +198,15 @@ static int spi_st_setup(struct spi_device *spi) | |||
| 201 | return -EINVAL; | 198 | return -EINVAL; |
| 202 | } | 199 | } |
| 203 | 200 | ||
| 204 | if (devm_gpio_request(&spi->dev, cs, dev_name(&spi->dev))) { | 201 | ret = gpio_request(cs, dev_name(&spi->dev)); |
| 202 | if (ret) { | ||
| 205 | dev_err(&spi->dev, "could not request gpio:%d\n", cs); | 203 | dev_err(&spi->dev, "could not request gpio:%d\n", cs); |
| 206 | return -EINVAL; | 204 | return ret; |
| 207 | } | 205 | } |
| 208 | 206 | ||
| 209 | ret = gpio_direction_output(cs, spi->mode & SPI_CS_HIGH); | 207 | ret = gpio_direction_output(cs, spi->mode & SPI_CS_HIGH); |
| 210 | if (ret) | 208 | if (ret) |
| 211 | return ret; | 209 | goto out_free_gpio; |
| 212 | 210 | ||
| 213 | spi_st_clk = clk_get_rate(spi_st->clk); | 211 | spi_st_clk = clk_get_rate(spi_st->clk); |
| 214 | 212 | ||
| @@ -217,7 +215,8 @@ static int spi_st_setup(struct spi_device *spi) | |||
| 217 | if (sscbrg < 0x07 || sscbrg > BIT(16)) { | 215 | if (sscbrg < 0x07 || sscbrg > BIT(16)) { |
| 218 | dev_err(&spi->dev, | 216 | dev_err(&spi->dev, |
| 219 | "baudrate %d outside valid range %d\n", sscbrg, hz); | 217 | "baudrate %d outside valid range %d\n", sscbrg, hz); |
| 220 | return -EINVAL; | 218 | ret = -EINVAL; |
| 219 | goto out_free_gpio; | ||
| 221 | } | 220 | } |
| 222 | 221 | ||
| 223 | spi_st->baud = spi_st_clk / (2 * sscbrg); | 222 | spi_st->baud = spi_st_clk / (2 * sscbrg); |
| @@ -266,6 +265,10 @@ static int spi_st_setup(struct spi_device *spi) | |||
| 266 | readl_relaxed(spi_st->base + SSC_RBUF); | 265 | readl_relaxed(spi_st->base + SSC_RBUF); |
| 267 | 266 | ||
| 268 | return 0; | 267 | return 0; |
| 268 | |||
| 269 | out_free_gpio: | ||
| 270 | gpio_free(cs); | ||
| 271 | return ret; | ||
| 269 | } | 272 | } |
| 270 | 273 | ||
| 271 | /* Interrupt fired when TX shift register becomes empty */ | 274 | /* Interrupt fired when TX shift register becomes empty */ |
diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index ac0b072815a3..caeac66a3977 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c | |||
| @@ -41,6 +41,8 @@ struct ti_qspi_regs { | |||
| 41 | }; | 41 | }; |
| 42 | 42 | ||
| 43 | struct ti_qspi { | 43 | struct ti_qspi { |
| 44 | struct completion transfer_complete; | ||
| 45 | |||
| 44 | /* list synchronization */ | 46 | /* list synchronization */ |
| 45 | struct mutex list_lock; | 47 | struct mutex list_lock; |
| 46 | 48 | ||
| @@ -54,6 +56,9 @@ struct ti_qspi { | |||
| 54 | 56 | ||
| 55 | struct ti_qspi_regs ctx_reg; | 57 | struct ti_qspi_regs ctx_reg; |
| 56 | 58 | ||
| 59 | dma_addr_t mmap_phys_base; | ||
| 60 | struct dma_chan *rx_chan; | ||
| 61 | |||
| 57 | u32 spi_max_frequency; | 62 | u32 spi_max_frequency; |
| 58 | u32 cmd; | 63 | u32 cmd; |
| 59 | u32 dc; | 64 | u32 dc; |
| @@ -379,6 +384,72 @@ static int qspi_transfer_msg(struct ti_qspi *qspi, struct spi_transfer *t, | |||
| 379 | return 0; | 384 | return 0; |
| 380 | } | 385 | } |
| 381 | 386 | ||
| 387 | static void ti_qspi_dma_callback(void *param) | ||
| 388 | { | ||
| 389 | struct ti_qspi *qspi = param; | ||
| 390 | |||
| 391 | complete(&qspi->transfer_complete); | ||
| 392 | } | ||
| 393 | |||
| 394 | static int ti_qspi_dma_xfer(struct ti_qspi *qspi, dma_addr_t dma_dst, | ||
| 395 | dma_addr_t dma_src, size_t len) | ||
| 396 | { | ||
| 397 | struct dma_chan *chan = qspi->rx_chan; | ||
| 398 | struct dma_device *dma_dev = chan->device; | ||
| 399 | dma_cookie_t cookie; | ||
| 400 | enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; | ||
| 401 | struct dma_async_tx_descriptor *tx; | ||
| 402 | int ret; | ||
| 403 | |||
| 404 | tx = dma_dev->device_prep_dma_memcpy(chan, dma_dst, dma_src, | ||
| 405 | len, flags); | ||
| 406 | if (!tx) { | ||
| 407 | dev_err(qspi->dev, "device_prep_dma_memcpy error\n"); | ||
| 408 | return -EIO; | ||
| 409 | } | ||
| 410 | |||
| 411 | tx->callback = ti_qspi_dma_callback; | ||
| 412 | tx->callback_param = qspi; | ||
| 413 | cookie = tx->tx_submit(tx); | ||
| 414 | |||
| 415 | ret = dma_submit_error(cookie); | ||
| 416 | if (ret) { | ||
| 417 | dev_err(qspi->dev, "dma_submit_error %d\n", cookie); | ||
| 418 | return -EIO; | ||
| 419 | } | ||
| 420 | |||
| 421 | dma_async_issue_pending(chan); | ||
| 422 | ret = wait_for_completion_timeout(&qspi->transfer_complete, | ||
| 423 | msecs_to_jiffies(len)); | ||
| 424 | if (ret <= 0) { | ||
| 425 | dmaengine_terminate_sync(chan); | ||
| 426 | dev_err(qspi->dev, "DMA wait_for_completion_timeout\n"); | ||
| 427 | return -ETIMEDOUT; | ||
| 428 | } | ||
| 429 | |||
| 430 | return 0; | ||
| 431 | } | ||
| 432 | |||
| 433 | static int ti_qspi_dma_xfer_sg(struct ti_qspi *qspi, struct sg_table rx_sg, | ||
| 434 | loff_t from) | ||
| 435 | { | ||
| 436 | struct scatterlist *sg; | ||
| 437 | dma_addr_t dma_src = qspi->mmap_phys_base + from; | ||
| 438 | dma_addr_t dma_dst; | ||
| 439 | int i, len, ret; | ||
| 440 | |||
| 441 | for_each_sg(rx_sg.sgl, sg, rx_sg.nents, i) { | ||
| 442 | dma_dst = sg_dma_address(sg); | ||
| 443 | len = sg_dma_len(sg); | ||
| 444 | ret = ti_qspi_dma_xfer(qspi, dma_dst, dma_src, len); | ||
| 445 | if (ret) | ||
| 446 | return ret; | ||
| 447 | dma_src += len; | ||
| 448 | } | ||
| 449 | |||
| 450 | return 0; | ||
| 451 | } | ||
| 452 | |||
| 382 | static void ti_qspi_enable_memory_map(struct spi_device *spi) | 453 | static void ti_qspi_enable_memory_map(struct spi_device *spi) |
| 383 | { | 454 | { |
| 384 | struct ti_qspi *qspi = spi_master_get_devdata(spi->master); | 455 | struct ti_qspi *qspi = spi_master_get_devdata(spi->master); |
| @@ -426,7 +497,7 @@ static void ti_qspi_setup_mmap_read(struct spi_device *spi, | |||
| 426 | QSPI_SPI_SETUP_REG(spi->chip_select)); | 497 | QSPI_SPI_SETUP_REG(spi->chip_select)); |
| 427 | } | 498 | } |
| 428 | 499 | ||
| 429 | static int ti_qspi_spi_flash_read(struct spi_device *spi, | 500 | static int ti_qspi_spi_flash_read(struct spi_device *spi, |
| 430 | struct spi_flash_read_message *msg) | 501 | struct spi_flash_read_message *msg) |
| 431 | { | 502 | { |
| 432 | struct ti_qspi *qspi = spi_master_get_devdata(spi->master); | 503 | struct ti_qspi *qspi = spi_master_get_devdata(spi->master); |
| @@ -437,9 +508,23 @@ static int ti_qspi_spi_flash_read(struct spi_device *spi, | |||
| 437 | if (!qspi->mmap_enabled) | 508 | if (!qspi->mmap_enabled) |
| 438 | ti_qspi_enable_memory_map(spi); | 509 | ti_qspi_enable_memory_map(spi); |
| 439 | ti_qspi_setup_mmap_read(spi, msg); | 510 | ti_qspi_setup_mmap_read(spi, msg); |
| 440 | memcpy_fromio(msg->buf, qspi->mmap_base + msg->from, msg->len); | 511 | |
| 512 | if (qspi->rx_chan) { | ||
| 513 | if (msg->cur_msg_mapped) { | ||
| 514 | ret = ti_qspi_dma_xfer_sg(qspi, msg->rx_sg, msg->from); | ||
| 515 | if (ret) | ||
| 516 | goto err_unlock; | ||
| 517 | } else { | ||
| 518 | dev_err(qspi->dev, "Invalid address for DMA\n"); | ||
| 519 | ret = -EIO; | ||
| 520 | goto err_unlock; | ||
| 521 | } | ||
| 522 | } else { | ||
| 523 | memcpy_fromio(msg->buf, qspi->mmap_base + msg->from, msg->len); | ||
| 524 | } | ||
| 441 | msg->retlen = msg->len; | 525 | msg->retlen = msg->len; |
| 442 | 526 | ||
| 527 | err_unlock: | ||
| 443 | mutex_unlock(&qspi->list_lock); | 528 | mutex_unlock(&qspi->list_lock); |
| 444 | 529 | ||
| 445 | return ret; | 530 | return ret; |
| @@ -536,6 +621,7 @@ static int ti_qspi_probe(struct platform_device *pdev) | |||
| 536 | struct device_node *np = pdev->dev.of_node; | 621 | struct device_node *np = pdev->dev.of_node; |
| 537 | u32 max_freq; | 622 | u32 max_freq; |
| 538 | int ret = 0, num_cs, irq; | 623 | int ret = 0, num_cs, irq; |
| 624 | dma_cap_mask_t mask; | ||
| 539 | 625 | ||
| 540 | master = spi_alloc_master(&pdev->dev, sizeof(*qspi)); | 626 | master = spi_alloc_master(&pdev->dev, sizeof(*qspi)); |
| 541 | if (!master) | 627 | if (!master) |
| @@ -550,6 +636,7 @@ static int ti_qspi_probe(struct platform_device *pdev) | |||
| 550 | master->dev.of_node = pdev->dev.of_node; | 636 | master->dev.of_node = pdev->dev.of_node; |
| 551 | master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) | | 637 | master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) | |
| 552 | SPI_BPW_MASK(8); | 638 | SPI_BPW_MASK(8); |
| 639 | master->spi_flash_read = ti_qspi_spi_flash_read; | ||
| 553 | 640 | ||
| 554 | if (!of_property_read_u32(np, "num-cs", &num_cs)) | 641 | if (!of_property_read_u32(np, "num-cs", &num_cs)) |
| 555 | master->num_chipselect = num_cs; | 642 | master->num_chipselect = num_cs; |
| @@ -592,17 +679,6 @@ static int ti_qspi_probe(struct platform_device *pdev) | |||
| 592 | goto free_master; | 679 | goto free_master; |
| 593 | } | 680 | } |
| 594 | 681 | ||
| 595 | if (res_mmap) { | ||
| 596 | qspi->mmap_base = devm_ioremap_resource(&pdev->dev, | ||
| 597 | res_mmap); | ||
| 598 | master->spi_flash_read = ti_qspi_spi_flash_read; | ||
| 599 | if (IS_ERR(qspi->mmap_base)) { | ||
| 600 | dev_err(&pdev->dev, | ||
| 601 | "falling back to PIO mode\n"); | ||
| 602 | master->spi_flash_read = NULL; | ||
| 603 | } | ||
| 604 | } | ||
| 605 | qspi->mmap_enabled = false; | ||
| 606 | 682 | ||
| 607 | if (of_property_read_bool(np, "syscon-chipselects")) { | 683 | if (of_property_read_bool(np, "syscon-chipselects")) { |
| 608 | qspi->ctrl_base = | 684 | qspi->ctrl_base = |
| @@ -633,11 +709,37 @@ static int ti_qspi_probe(struct platform_device *pdev) | |||
| 633 | if (!of_property_read_u32(np, "spi-max-frequency", &max_freq)) | 709 | if (!of_property_read_u32(np, "spi-max-frequency", &max_freq)) |
| 634 | qspi->spi_max_frequency = max_freq; | 710 | qspi->spi_max_frequency = max_freq; |
| 635 | 711 | ||
| 636 | ret = devm_spi_register_master(&pdev->dev, master); | 712 | dma_cap_zero(mask); |
| 637 | if (ret) | 713 | dma_cap_set(DMA_MEMCPY, mask); |
| 638 | goto free_master; | ||
| 639 | 714 | ||
| 640 | return 0; | 715 | qspi->rx_chan = dma_request_chan_by_mask(&mask); |
| 716 | if (!qspi->rx_chan) { | ||
| 717 | dev_err(qspi->dev, | ||
| 718 | "No Rx DMA available, trying mmap mode\n"); | ||
| 719 | ret = 0; | ||
| 720 | goto no_dma; | ||
| 721 | } | ||
| 722 | master->dma_rx = qspi->rx_chan; | ||
| 723 | init_completion(&qspi->transfer_complete); | ||
| 724 | if (res_mmap) | ||
| 725 | qspi->mmap_phys_base = (dma_addr_t)res_mmap->start; | ||
| 726 | |||
| 727 | no_dma: | ||
| 728 | if (!qspi->rx_chan && res_mmap) { | ||
| 729 | qspi->mmap_base = devm_ioremap_resource(&pdev->dev, res_mmap); | ||
| 730 | if (IS_ERR(qspi->mmap_base)) { | ||
| 731 | dev_info(&pdev->dev, | ||
| 732 | "mmap failed with error %ld using PIO mode\n", | ||
| 733 | PTR_ERR(qspi->mmap_base)); | ||
| 734 | qspi->mmap_base = NULL; | ||
| 735 | master->spi_flash_read = NULL; | ||
| 736 | } | ||
| 737 | } | ||
| 738 | qspi->mmap_enabled = false; | ||
| 739 | |||
| 740 | ret = devm_spi_register_master(&pdev->dev, master); | ||
| 741 | if (!ret) | ||
| 742 | return 0; | ||
| 641 | 743 | ||
| 642 | free_master: | 744 | free_master: |
| 643 | spi_master_put(master); | 745 | spi_master_put(master); |
| @@ -656,6 +758,9 @@ static int ti_qspi_remove(struct platform_device *pdev) | |||
| 656 | pm_runtime_put_sync(&pdev->dev); | 758 | pm_runtime_put_sync(&pdev->dev); |
| 657 | pm_runtime_disable(&pdev->dev); | 759 | pm_runtime_disable(&pdev->dev); |
| 658 | 760 | ||
| 761 | if (qspi->rx_chan) | ||
| 762 | dma_release_channel(qspi->rx_chan); | ||
| 763 | |||
| 659 | return 0; | 764 | return 0; |
| 660 | } | 765 | } |
| 661 | 766 | ||
diff --git a/drivers/spi/spi-txx9.c b/drivers/spi/spi-txx9.c index 7492ea346b43..51759d3fd45f 100644 --- a/drivers/spi/spi-txx9.c +++ b/drivers/spi/spi-txx9.c | |||
| @@ -346,7 +346,7 @@ static int txx9spi_probe(struct platform_device *dev) | |||
| 346 | c->clk = NULL; | 346 | c->clk = NULL; |
| 347 | goto exit; | 347 | goto exit; |
| 348 | } | 348 | } |
| 349 | ret = clk_enable(c->clk); | 349 | ret = clk_prepare_enable(c->clk); |
| 350 | if (ret) { | 350 | if (ret) { |
| 351 | c->clk = NULL; | 351 | c->clk = NULL; |
| 352 | goto exit; | 352 | goto exit; |
| @@ -395,7 +395,7 @@ static int txx9spi_probe(struct platform_device *dev) | |||
| 395 | exit_busy: | 395 | exit_busy: |
| 396 | ret = -EBUSY; | 396 | ret = -EBUSY; |
| 397 | exit: | 397 | exit: |
| 398 | clk_disable(c->clk); | 398 | clk_disable_unprepare(c->clk); |
| 399 | spi_master_put(master); | 399 | spi_master_put(master); |
| 400 | return ret; | 400 | return ret; |
| 401 | } | 401 | } |
| @@ -406,7 +406,7 @@ static int txx9spi_remove(struct platform_device *dev) | |||
| 406 | struct txx9spi *c = spi_master_get_devdata(master); | 406 | struct txx9spi *c = spi_master_get_devdata(master); |
| 407 | 407 | ||
| 408 | flush_work(&c->work); | 408 | flush_work(&c->work); |
| 409 | clk_disable(c->clk); | 409 | clk_disable_unprepare(c->clk); |
| 410 | return 0; | 410 | return 0; |
| 411 | } | 411 | } |
| 412 | 412 | ||
diff --git a/drivers/spi/spi-xlp.c b/drivers/spi/spi-xlp.c index 8f04feca6ee3..4071a729eb2f 100644 --- a/drivers/spi/spi-xlp.c +++ b/drivers/spi/spi-xlp.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
| 13 | */ | 13 | */ |
| 14 | #include <linux/acpi.h> | ||
| 14 | #include <linux/clk.h> | 15 | #include <linux/clk.h> |
| 15 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 16 | #include <linux/module.h> | 17 | #include <linux/module.h> |
| @@ -405,8 +406,9 @@ static int xlp_spi_probe(struct platform_device *pdev) | |||
| 405 | clk = devm_clk_get(&pdev->dev, NULL); | 406 | clk = devm_clk_get(&pdev->dev, NULL); |
| 406 | if (IS_ERR(clk)) { | 407 | if (IS_ERR(clk)) { |
| 407 | dev_err(&pdev->dev, "could not get spi clock\n"); | 408 | dev_err(&pdev->dev, "could not get spi clock\n"); |
| 408 | return -ENODEV; | 409 | return PTR_ERR(clk); |
| 409 | } | 410 | } |
| 411 | |||
| 410 | xspi->spi_clk = clk_get_rate(clk); | 412 | xspi->spi_clk = clk_get_rate(clk); |
| 411 | 413 | ||
| 412 | master = spi_alloc_master(&pdev->dev, 0); | 414 | master = spi_alloc_master(&pdev->dev, 0); |
| @@ -437,6 +439,14 @@ static int xlp_spi_probe(struct platform_device *pdev) | |||
| 437 | return 0; | 439 | return 0; |
| 438 | } | 440 | } |
| 439 | 441 | ||
| 442 | #ifdef CONFIG_ACPI | ||
| 443 | static const struct acpi_device_id xlp_spi_acpi_match[] = { | ||
| 444 | { "BRCM900D", 0 }, | ||
| 445 | { }, | ||
| 446 | }; | ||
| 447 | MODULE_DEVICE_TABLE(acpi, xlp_spi_acpi_match); | ||
| 448 | #endif | ||
| 449 | |||
| 440 | static const struct of_device_id xlp_spi_dt_id[] = { | 450 | static const struct of_device_id xlp_spi_dt_id[] = { |
| 441 | { .compatible = "netlogic,xlp832-spi" }, | 451 | { .compatible = "netlogic,xlp832-spi" }, |
| 442 | { }, | 452 | { }, |
| @@ -447,6 +457,7 @@ static struct platform_driver xlp_spi_driver = { | |||
| 447 | .driver = { | 457 | .driver = { |
| 448 | .name = "xlp-spi", | 458 | .name = "xlp-spi", |
| 449 | .of_match_table = xlp_spi_dt_id, | 459 | .of_match_table = xlp_spi_dt_id, |
| 460 | .acpi_match_table = ACPI_PTR(xlp_spi_acpi_match), | ||
| 450 | }, | 461 | }, |
| 451 | }; | 462 | }; |
| 452 | module_platform_driver(xlp_spi_driver); | 463 | module_platform_driver(xlp_spi_driver); |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 200ca228d885..8146ccd35a1a 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | #include <linux/kthread.h> | 37 | #include <linux/kthread.h> |
| 38 | #include <linux/ioport.h> | 38 | #include <linux/ioport.h> |
| 39 | #include <linux/acpi.h> | 39 | #include <linux/acpi.h> |
| 40 | #include <linux/highmem.h> | ||
| 40 | 41 | ||
| 41 | #define CREATE_TRACE_POINTS | 42 | #define CREATE_TRACE_POINTS |
| 42 | #include <trace/events/spi.h> | 43 | #include <trace/events/spi.h> |
| @@ -709,6 +710,13 @@ static int spi_map_buf(struct spi_master *master, struct device *dev, | |||
| 709 | { | 710 | { |
| 710 | const bool vmalloced_buf = is_vmalloc_addr(buf); | 711 | const bool vmalloced_buf = is_vmalloc_addr(buf); |
| 711 | unsigned int max_seg_size = dma_get_max_seg_size(dev); | 712 | unsigned int max_seg_size = dma_get_max_seg_size(dev); |
| 713 | #ifdef CONFIG_HIGHMEM | ||
| 714 | const bool kmap_buf = ((unsigned long)buf >= PKMAP_BASE && | ||
| 715 | (unsigned long)buf < (PKMAP_BASE + | ||
| 716 | (LAST_PKMAP * PAGE_SIZE))); | ||
| 717 | #else | ||
| 718 | const bool kmap_buf = false; | ||
| 719 | #endif | ||
| 712 | int desc_len; | 720 | int desc_len; |
| 713 | int sgs; | 721 | int sgs; |
| 714 | struct page *vm_page; | 722 | struct page *vm_page; |
| @@ -716,7 +724,7 @@ static int spi_map_buf(struct spi_master *master, struct device *dev, | |||
| 716 | size_t min; | 724 | size_t min; |
| 717 | int i, ret; | 725 | int i, ret; |
| 718 | 726 | ||
| 719 | if (vmalloced_buf) { | 727 | if (vmalloced_buf || kmap_buf) { |
| 720 | desc_len = min_t(int, max_seg_size, PAGE_SIZE); | 728 | desc_len = min_t(int, max_seg_size, PAGE_SIZE); |
| 721 | sgs = DIV_ROUND_UP(len + offset_in_page(buf), desc_len); | 729 | sgs = DIV_ROUND_UP(len + offset_in_page(buf), desc_len); |
| 722 | } else if (virt_addr_valid(buf)) { | 730 | } else if (virt_addr_valid(buf)) { |
| @@ -732,10 +740,13 @@ static int spi_map_buf(struct spi_master *master, struct device *dev, | |||
| 732 | 740 | ||
| 733 | for (i = 0; i < sgs; i++) { | 741 | for (i = 0; i < sgs; i++) { |
| 734 | 742 | ||
| 735 | if (vmalloced_buf) { | 743 | if (vmalloced_buf || kmap_buf) { |
| 736 | min = min_t(size_t, | 744 | min = min_t(size_t, |
| 737 | len, desc_len - offset_in_page(buf)); | 745 | len, desc_len - offset_in_page(buf)); |
| 738 | vm_page = vmalloc_to_page(buf); | 746 | if (vmalloced_buf) |
| 747 | vm_page = vmalloc_to_page(buf); | ||
| 748 | else | ||
| 749 | vm_page = kmap_to_page(buf); | ||
| 739 | if (!vm_page) { | 750 | if (!vm_page) { |
| 740 | sg_free_table(sgt); | 751 | sg_free_table(sgt); |
| 741 | return -ENOMEM; | 752 | return -ENOMEM; |
diff --git a/include/linux/pxa2xx_ssp.h b/include/linux/pxa2xx_ssp.h index 2a097d176ba9..2d6f0c39ed68 100644 --- a/include/linux/pxa2xx_ssp.h +++ b/include/linux/pxa2xx_ssp.h | |||
| @@ -83,7 +83,6 @@ | |||
| 83 | #define SSSR_RFS (1 << 6) /* Receive FIFO Service Request */ | 83 | #define SSSR_RFS (1 << 6) /* Receive FIFO Service Request */ |
| 84 | #define SSSR_ROR (1 << 7) /* Receive FIFO Overrun */ | 84 | #define SSSR_ROR (1 << 7) /* Receive FIFO Overrun */ |
| 85 | 85 | ||
| 86 | #ifdef CONFIG_ARCH_PXA | ||
| 87 | #define RX_THRESH_DFLT 8 | 86 | #define RX_THRESH_DFLT 8 |
| 88 | #define TX_THRESH_DFLT 8 | 87 | #define TX_THRESH_DFLT 8 |
| 89 | 88 | ||
| @@ -95,19 +94,16 @@ | |||
| 95 | #define SSCR1_RFT (0x00003c00) /* Receive FIFO Threshold (mask) */ | 94 | #define SSCR1_RFT (0x00003c00) /* Receive FIFO Threshold (mask) */ |
| 96 | #define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */ | 95 | #define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */ |
| 97 | 96 | ||
| 98 | #else | 97 | #define RX_THRESH_CE4100_DFLT 2 |
| 99 | 98 | #define TX_THRESH_CE4100_DFLT 2 | |
| 100 | #define RX_THRESH_DFLT 2 | ||
| 101 | #define TX_THRESH_DFLT 2 | ||
| 102 | 99 | ||
| 103 | #define SSSR_TFL_MASK (0x3 << 8) /* Transmit FIFO Level mask */ | 100 | #define CE4100_SSSR_TFL_MASK (0x3 << 8) /* Transmit FIFO Level mask */ |
| 104 | #define SSSR_RFL_MASK (0x3 << 12) /* Receive FIFO Level mask */ | 101 | #define CE4100_SSSR_RFL_MASK (0x3 << 12) /* Receive FIFO Level mask */ |
| 105 | 102 | ||
| 106 | #define SSCR1_TFT (0x000000c0) /* Transmit FIFO Threshold (mask) */ | 103 | #define CE4100_SSCR1_TFT (0x000000c0) /* Transmit FIFO Threshold (mask) */ |
| 107 | #define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..4] */ | 104 | #define CE4100_SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..4] */ |
| 108 | #define SSCR1_RFT (0x00000c00) /* Receive FIFO Threshold (mask) */ | 105 | #define CE4100_SSCR1_RFT (0x00000c00) /* Receive FIFO Threshold (mask) */ |
| 109 | #define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..4] */ | 106 | #define CE4100_SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..4] */ |
| 110 | #endif | ||
| 111 | 107 | ||
| 112 | /* QUARK_X1000 SSCR0 bit definition */ | 108 | /* QUARK_X1000 SSCR0 bit definition */ |
| 113 | #define QUARK_X1000_SSCR0_DSS (0x1F) /* Data Size Select (mask) */ | 109 | #define QUARK_X1000_SSCR0_DSS (0x1F) /* Data Size Select (mask) */ |
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 072cb2aa2413..4b743ac35396 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h | |||
| @@ -312,6 +312,8 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) | |||
| 312 | * @flags: other constraints relevant to this driver | 312 | * @flags: other constraints relevant to this driver |
| 313 | * @max_transfer_size: function that returns the max transfer size for | 313 | * @max_transfer_size: function that returns the max transfer size for |
| 314 | * a &spi_device; may be %NULL, so the default %SIZE_MAX will be used. | 314 | * a &spi_device; may be %NULL, so the default %SIZE_MAX will be used. |
| 315 | * @max_message_size: function that returns the max message size for | ||
| 316 | * a &spi_device; may be %NULL, so the default %SIZE_MAX will be used. | ||
| 315 | * @io_mutex: mutex for physical bus access | 317 | * @io_mutex: mutex for physical bus access |
| 316 | * @bus_lock_spinlock: spinlock for SPI bus locking | 318 | * @bus_lock_spinlock: spinlock for SPI bus locking |
| 317 | * @bus_lock_mutex: mutex for exclusion of multiple callers | 319 | * @bus_lock_mutex: mutex for exclusion of multiple callers |
| @@ -442,10 +444,11 @@ struct spi_master { | |||
| 442 | #define SPI_MASTER_MUST_TX BIT(4) /* requires tx */ | 444 | #define SPI_MASTER_MUST_TX BIT(4) /* requires tx */ |
| 443 | 445 | ||
| 444 | /* | 446 | /* |
| 445 | * on some hardware transfer size may be constrained | 447 | * on some hardware transfer / message size may be constrained |
| 446 | * the limit may depend on device transfer settings | 448 | * the limit may depend on device transfer settings |
| 447 | */ | 449 | */ |
| 448 | size_t (*max_transfer_size)(struct spi_device *spi); | 450 | size_t (*max_transfer_size)(struct spi_device *spi); |
| 451 | size_t (*max_message_size)(struct spi_device *spi); | ||
| 449 | 452 | ||
| 450 | /* I/O mutex */ | 453 | /* I/O mutex */ |
| 451 | struct mutex io_mutex; | 454 | struct mutex io_mutex; |
| @@ -905,12 +908,26 @@ extern int spi_async_locked(struct spi_device *spi, | |||
| 905 | struct spi_message *message); | 908 | struct spi_message *message); |
| 906 | 909 | ||
| 907 | static inline size_t | 910 | static inline size_t |
| 908 | spi_max_transfer_size(struct spi_device *spi) | 911 | spi_max_message_size(struct spi_device *spi) |
| 909 | { | 912 | { |
| 910 | struct spi_master *master = spi->master; | 913 | struct spi_master *master = spi->master; |
| 911 | if (!master->max_transfer_size) | 914 | if (!master->max_message_size) |
| 912 | return SIZE_MAX; | 915 | return SIZE_MAX; |
| 913 | return master->max_transfer_size(spi); | 916 | return master->max_message_size(spi); |
| 917 | } | ||
| 918 | |||
| 919 | static inline size_t | ||
| 920 | spi_max_transfer_size(struct spi_device *spi) | ||
| 921 | { | ||
| 922 | struct spi_master *master = spi->master; | ||
| 923 | size_t tr_max = SIZE_MAX; | ||
| 924 | size_t msg_max = spi_max_message_size(spi); | ||
| 925 | |||
| 926 | if (master->max_transfer_size) | ||
| 927 | tr_max = master->max_transfer_size(spi); | ||
| 928 | |||
| 929 | /* transfer size limit must not be greater than messsage size limit */ | ||
| 930 | return min(tr_max, msg_max); | ||
| 914 | } | 931 | } |
| 915 | 932 | ||
| 916 | /*---------------------------------------------------------------------------*/ | 933 | /*---------------------------------------------------------------------------*/ |
| @@ -980,6 +997,30 @@ extern int spi_bus_lock(struct spi_master *master); | |||
| 980 | extern int spi_bus_unlock(struct spi_master *master); | 997 | extern int spi_bus_unlock(struct spi_master *master); |
| 981 | 998 | ||
| 982 | /** | 999 | /** |
| 1000 | * spi_sync_transfer - synchronous SPI data transfer | ||
| 1001 | * @spi: device with which data will be exchanged | ||
| 1002 | * @xfers: An array of spi_transfers | ||
| 1003 | * @num_xfers: Number of items in the xfer array | ||
| 1004 | * Context: can sleep | ||
| 1005 | * | ||
| 1006 | * Does a synchronous SPI data transfer of the given spi_transfer array. | ||
| 1007 | * | ||
| 1008 | * For more specific semantics see spi_sync(). | ||
| 1009 | * | ||
| 1010 | * Return: Return: zero on success, else a negative error code. | ||
| 1011 | */ | ||
| 1012 | static inline int | ||
| 1013 | spi_sync_transfer(struct spi_device *spi, struct spi_transfer *xfers, | ||
| 1014 | unsigned int num_xfers) | ||
| 1015 | { | ||
| 1016 | struct spi_message msg; | ||
| 1017 | |||
| 1018 | spi_message_init_with_transfers(&msg, xfers, num_xfers); | ||
| 1019 | |||
| 1020 | return spi_sync(spi, &msg); | ||
| 1021 | } | ||
| 1022 | |||
| 1023 | /** | ||
| 983 | * spi_write - SPI synchronous write | 1024 | * spi_write - SPI synchronous write |
| 984 | * @spi: device to which data will be written | 1025 | * @spi: device to which data will be written |
| 985 | * @buf: data buffer | 1026 | * @buf: data buffer |
| @@ -998,11 +1039,8 @@ spi_write(struct spi_device *spi, const void *buf, size_t len) | |||
| 998 | .tx_buf = buf, | 1039 | .tx_buf = buf, |
| 999 | .len = len, | 1040 | .len = len, |
| 1000 | }; | 1041 | }; |
| 1001 | struct spi_message m; | ||
| 1002 | 1042 | ||
| 1003 | spi_message_init(&m); | 1043 | return spi_sync_transfer(spi, &t, 1); |
| 1004 | spi_message_add_tail(&t, &m); | ||
| 1005 | return spi_sync(spi, &m); | ||
| 1006 | } | 1044 | } |
| 1007 | 1045 | ||
| 1008 | /** | 1046 | /** |
| @@ -1024,35 +1062,8 @@ spi_read(struct spi_device *spi, void *buf, size_t len) | |||
| 1024 | .rx_buf = buf, | 1062 | .rx_buf = buf, |
| 1025 | .len = len, | 1063 | .len = len, |
| 1026 | }; | 1064 | }; |
| 1027 | struct spi_message m; | ||
| 1028 | |||
| 1029 | spi_message_init(&m); | ||
| 1030 | spi_message_add_tail(&t, &m); | ||
| 1031 | return spi_sync(spi, &m); | ||
| 1032 | } | ||
| 1033 | 1065 | ||
| 1034 | /** | 1066 | return spi_sync_transfer(spi, &t, 1); |
| 1035 | * spi_sync_transfer - synchronous SPI data transfer | ||
| 1036 | * @spi: device with which data will be exchanged | ||
| 1037 | * @xfers: An array of spi_transfers | ||
| 1038 | * @num_xfers: Number of items in the xfer array | ||
| 1039 | * Context: can sleep | ||
| 1040 | * | ||
| 1041 | * Does a synchronous SPI data transfer of the given spi_transfer array. | ||
| 1042 | * | ||
| 1043 | * For more specific semantics see spi_sync(). | ||
| 1044 | * | ||
| 1045 | * Return: Return: zero on success, else a negative error code. | ||
| 1046 | */ | ||
| 1047 | static inline int | ||
| 1048 | spi_sync_transfer(struct spi_device *spi, struct spi_transfer *xfers, | ||
| 1049 | unsigned int num_xfers) | ||
| 1050 | { | ||
| 1051 | struct spi_message msg; | ||
| 1052 | |||
| 1053 | spi_message_init_with_transfers(&msg, xfers, num_xfers); | ||
| 1054 | |||
| 1055 | return spi_sync(spi, &msg); | ||
| 1056 | } | 1067 | } |
| 1057 | 1068 | ||
| 1058 | /* this copies txbuf and rxbuf data; for small transfers only! */ | 1069 | /* this copies txbuf and rxbuf data; for small transfers only! */ |
diff --git a/tools/spi/Makefile b/tools/spi/Makefile index cd0db62e4d9d..3815b18ba070 100644 --- a/tools/spi/Makefile +++ b/tools/spi/Makefile | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | CC = $(CROSS_COMPILE)gcc | ||
| 2 | |||
| 1 | all: spidev_test spidev_fdx | 3 | all: spidev_test spidev_fdx |
| 2 | 4 | ||
| 3 | clean: | 5 | clean: |
diff --git a/tools/spi/spidev_test.c b/tools/spi/spidev_test.c index 8a73d8185316..f046b77cfefe 100644 --- a/tools/spi/spidev_test.c +++ b/tools/spi/spidev_test.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <getopt.h> | 19 | #include <getopt.h> |
| 20 | #include <fcntl.h> | 20 | #include <fcntl.h> |
| 21 | #include <sys/ioctl.h> | 21 | #include <sys/ioctl.h> |
| 22 | #include <linux/ioctl.h> | ||
| 22 | #include <sys/stat.h> | 23 | #include <sys/stat.h> |
| 23 | #include <linux/types.h> | 24 | #include <linux/types.h> |
| 24 | #include <linux/spi/spidev.h> | 25 | #include <linux/spi/spidev.h> |
| @@ -284,7 +285,7 @@ static void parse_opts(int argc, char *argv[]) | |||
| 284 | 285 | ||
| 285 | static void transfer_escaped_string(int fd, char *str) | 286 | static void transfer_escaped_string(int fd, char *str) |
| 286 | { | 287 | { |
| 287 | size_t size = strlen(str + 1); | 288 | size_t size = strlen(str); |
| 288 | uint8_t *tx; | 289 | uint8_t *tx; |
| 289 | uint8_t *rx; | 290 | uint8_t *rx; |
| 290 | 291 | ||
