Merge branch 'spi-5.5' into spi-next
authorMark Brown <broonie@kernel.org>
Fri, 22 Nov 2019 19:56:35 +0000 (19:56 +0000)
committerMark Brown <broonie@kernel.org>
Fri, 22 Nov 2019 19:56:35 +0000 (19:56 +0000)
73 files changed:
Documentation/devicetree/bindings/spi/renesas,hspi.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/spi/renesas,rzn1-spi.txt [new file with mode: 0644]
Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/spi/sh-hspi.txt [deleted file]
Documentation/devicetree/bindings/spi/sh-msiof.txt [deleted file]
Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.txt
Documentation/devicetree/bindings/spi/spi-sifive.txt [deleted file]
Documentation/devicetree/bindings/spi/spi-sifive.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/spi/spi-stm32-qspi.txt [deleted file]
Documentation/devicetree/bindings/spi/spi-xilinx.txt
Documentation/devicetree/bindings/spi/st,stm32-qspi.yaml [new file with mode: 0644]
arch/arm/plat-pxa/ssp.c
drivers/iio/imu/adis.c
drivers/spi/Kconfig
drivers/spi/spi-at91-usart.c
drivers/spi/spi-atmel.c
drivers/spi/spi-axi-spi-engine.c
drivers/spi/spi-bcm-qspi.c
drivers/spi/spi-bcm63xx-hsspi.c
drivers/spi/spi-bcm63xx.c
drivers/spi/spi-cavium.c
drivers/spi/spi-dw-mmio.c
drivers/spi/spi-dw-pci.c
drivers/spi/spi-dw.c
drivers/spi/spi-dw.h
drivers/spi/spi-falcon.c
drivers/spi/spi-fsl-dspi.c
drivers/spi/spi-fsl-espi.c
drivers/spi/spi-fsl-lpspi.c
drivers/spi/spi-fsl-qspi.c
drivers/spi/spi-fsl-spi.c
drivers/spi/spi-gpio.c
drivers/spi/spi-img-spfi.c
drivers/spi/spi-imx.c
drivers/spi/spi-lantiq-ssc.c
drivers/spi/spi-loopback-test.c
drivers/spi/spi-mem.c
drivers/spi/spi-mpc512x-psc.c
drivers/spi/spi-mpc52xx-psc.c
drivers/spi/spi-mt65xx.c
drivers/spi/spi-mxic.c
drivers/spi/spi-npcm-pspi.c
drivers/spi/spi-nxp-fspi.c
drivers/spi/spi-omap-100k.c
drivers/spi/spi-omap2-mcspi.c
drivers/spi/spi-orion.c
drivers/spi/spi-pic32.c
drivers/spi/spi-pl022.c
drivers/spi/spi-pxa2xx.c
drivers/spi/spi-qup.c
drivers/spi/spi-s3c64xx.c
drivers/spi/spi-sc18is602.c
drivers/spi/spi-sh-hspi.c
drivers/spi/spi-slave-mt27xx.c
drivers/spi/spi-sprd-adi.c
drivers/spi/spi-sprd.c
drivers/spi/spi-st-ssc4.c
drivers/spi/spi-tegra114.c
drivers/spi/spi-tegra20-sflash.c
drivers/spi/spi-tegra20-slink.c
drivers/spi/spi-topcliff-pch.c
drivers/spi/spi-txx9.c
drivers/spi/spi-xcomm.c
drivers/spi/spi-xilinx.c
drivers/spi/spi-xtensa-xtfpga.c
drivers/spi/spi-zynq-qspi.c
drivers/spi/spi.c
drivers/spi/spidev.c
include/linux/platform_data/spi-mt65xx.h
include/linux/pxa2xx_ssp.h
include/linux/spi/spi.h
sound/soc/pxa/mmp-sspa.c
sound/soc/pxa/pxa-ssp.c

diff --git a/Documentation/devicetree/bindings/spi/renesas,hspi.yaml b/Documentation/devicetree/bindings/spi/renesas,hspi.yaml
new file mode 100644 (file)
index 0000000..c429cf4
--- /dev/null
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/renesas,hspi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas HSPI
+
+maintainers:
+  - Geert Uytterhoeven <geert+renesas@glider.be>
+
+allOf:
+  - $ref: spi-controller.yaml#
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - renesas,hspi-r8a7778 # R-Car M1A
+        - renesas,hspi-r8a7779 # R-Car H1
+      - const: renesas,hspi
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - '#address-cells'
+  - '#size-cells'
+
+examples:
+  - |
+    #include <dt-bindings/clock/r8a7778-clock.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    hspi0: spi@fffc7000 {
+        compatible = "renesas,hspi-r8a7778", "renesas,hspi";
+        reg = <0xfffc7000 0x18>;
+        interrupts = <0 63 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&mstp0_clks R8A7778_CLK_HSPI>;
+        power-domains = <&cpg_clocks>;
+        #address-cells = <1>;
+        #size-cells = <0>;
+    };
+
diff --git a/Documentation/devicetree/bindings/spi/renesas,rzn1-spi.txt b/Documentation/devicetree/bindings/spi/renesas,rzn1-spi.txt
new file mode 100644 (file)
index 0000000..fb1a672
--- /dev/null
@@ -0,0 +1,11 @@
+Renesas RZ/N1 SPI Controller
+
+This controller is based on the Synopsys DW Synchronous Serial Interface and
+inherits all properties defined in snps,dw-apb-ssi.txt except for the
+compatible property.
+
+Required properties:
+- compatible : The device specific string followed by the generic RZ/N1 string.
+   Therefore it must be one of:
+   "renesas,r9a06g032-spi", "renesas,rzn1-spi"
+   "renesas,r9a06g033-spi", "renesas,rzn1-spi"
diff --git a/Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml b/Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml
new file mode 100644 (file)
index 0000000..b6c1dd2
--- /dev/null
@@ -0,0 +1,159 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/renesas,sh-msiof.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas MSIOF SPI controller
+
+maintainers:
+  - Geert Uytterhoeven <geert+renesas@glider.be>
+
+allOf:
+  - $ref: spi-controller.yaml#
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: renesas,msiof-sh73a0     # SH-Mobile AG5
+          - const: renesas,sh-mobile-msiof  # generic SH-Mobile compatible
+                                            # device
+      - items:
+          - enum:
+              - renesas,msiof-r8a7743       # RZ/G1M
+              - renesas,msiof-r8a7744       # RZ/G1N
+              - renesas,msiof-r8a7745       # RZ/G1E
+              - renesas,msiof-r8a77470      # RZ/G1C
+              - renesas,msiof-r8a7790       # R-Car H2
+              - renesas,msiof-r8a7791       # R-Car M2-W
+              - renesas,msiof-r8a7792       # R-Car V2H
+              - renesas,msiof-r8a7793       # R-Car M2-N
+              - renesas,msiof-r8a7794       # R-Car E2
+          - const: renesas,rcar-gen2-msiof  # generic R-Car Gen2 and RZ/G1
+                                            # compatible device
+      - items:
+          - enum:
+              - renesas,msiof-r8a774a1      # RZ/G2M
+              - renesas,msiof-r8a774b1      # RZ/G2N
+              - renesas,msiof-r8a774c0      # RZ/G2E
+              - renesas,msiof-r8a7795       # R-Car H3
+              - renesas,msiof-r8a7796       # R-Car M3-W
+              - renesas,msiof-r8a77965      # R-Car M3-N
+              - renesas,msiof-r8a77970      # R-Car V3M
+              - renesas,msiof-r8a77980      # R-Car V3H
+              - renesas,msiof-r8a77990      # R-Car E3
+              - renesas,msiof-r8a77995      # R-Car D3
+          - const: renesas,rcar-gen3-msiof  # generic R-Car Gen3 and RZ/G2
+                                            # compatible device
+      - items:
+          - const: renesas,sh-msiof  # deprecated
+
+  reg:
+    minItems: 1
+    maxItems: 2
+    oneOf:
+      - items:
+          - description: CPU and DMA engine registers
+      - items:
+          - description: CPU registers
+          - description: DMA engine registers
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  num-cs:
+    description: |
+      Total number of chip selects (default is 1).
+      Up to 3 native chip selects are supported:
+        0: MSIOF_SYNC
+        1: MSIOF_SS1
+        2: MSIOF_SS2
+      Hardware limitations related to chip selects:
+        - Native chip selects are always deasserted in between transfers
+          that are part of the same message.  Use cs-gpios to work around
+          this.
+        - All slaves using native chip selects must use the same spi-cs-high
+          configuration.  Use cs-gpios to work around this.
+        - When using GPIO chip selects, at least one native chip select must
+          be left unused, as it will be driven anyway.
+    minimum: 1
+    maximum: 3
+    default: 1
+
+  dmas:
+    minItems: 2
+    maxItems: 4
+
+  dma-names:
+    minItems: 2
+    maxItems: 4
+    items:
+      enum: [ tx, rx ]
+
+  renesas,dtdl:
+    description: delay sync signal (setup) in transmit mode.
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - enum:
+          - 0    # no bit delay
+          - 50   # 0.5-clock-cycle delay
+          - 100  # 1-clock-cycle delay
+          - 150  # 1.5-clock-cycle delay
+          - 200  # 2-clock-cycle delay
+
+  renesas,syncdl:
+    description: delay sync signal (hold) in transmit mode
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - enum:
+          - 0    # no bit delay
+          - 50   # 0.5-clock-cycle delay
+          - 100  # 1-clock-cycle delay
+          - 150  # 1.5-clock-cycle delay
+          - 200  # 2-clock-cycle delay
+          - 300  # 3-clock-cycle delay
+
+  renesas,tx-fifo-size:
+    # deprecated for soctype-specific bindings
+    description: |
+      Override the default TX fifo size.  Unit is words.  Ignored if 0.
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - maxItems: 1
+    default: 64
+
+  renesas,rx-fifo-size:
+    # deprecated for soctype-specific bindings
+    description: |
+      Override the default RX fifo size.  Unit is words.  Ignored if 0.
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - maxItems: 1
+    default: 64
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - '#address-cells'
+  - '#size-cells'
+
+examples:
+  - |
+    #include <dt-bindings/clock/r8a7791-clock.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    msiof0: spi@e6e20000 {
+        compatible = "renesas,msiof-r8a7791", "renesas,rcar-gen2-msiof";
+        reg = <0 0xe6e20000 0 0x0064>;
+        interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&mstp0_clks R8A7791_CLK_MSIOF0>;
+        dmas = <&dmac0 0x51>, <&dmac0 0x52>;
+        dma-names = "tx", "rx";
+        #address-cells = <1>;
+        #size-cells = <0>;
+    };
diff --git a/Documentation/devicetree/bindings/spi/sh-hspi.txt b/Documentation/devicetree/bindings/spi/sh-hspi.txt
deleted file mode 100644 (file)
index b9d1e4d..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-Renesas HSPI.
-
-Required properties:
-- compatible       : "renesas,hspi-<soctype>", "renesas,hspi" as fallback.
-                    Examples with soctypes are:
-                      - "renesas,hspi-r8a7778" (R-Car M1)
-                      - "renesas,hspi-r8a7779" (R-Car H1)
-- reg              : Offset and length of the register set for the device
-- interrupts       : Interrupt specifier
-- #address-cells   : Must be <1>
-- #size-cells      : Must be <0>
-
-Pinctrl properties might be needed, too.  See
-Documentation/devicetree/bindings/pinctrl/renesas,*.
-
-Example:
-
-       hspi0: spi@fffc7000 {
-               compatible = "renesas,hspi-r8a7778", "renesas,hspi";
-               reg = <0xfffc7000 0x18>;
-               interrupt-parent = <&gic>;
-               interrupts = <0 63 IRQ_TYPE_LEVEL_HIGH>;
-               #address-cells = <1>;
-               #size-cells = <0>;
-       };
-
diff --git a/Documentation/devicetree/bindings/spi/sh-msiof.txt b/Documentation/devicetree/bindings/spi/sh-msiof.txt
deleted file mode 100644 (file)
index 18e14ee..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-Renesas MSIOF spi controller
-
-Required properties:
-- compatible           : "renesas,msiof-r8a7743" (RZ/G1M)
-                        "renesas,msiof-r8a7744" (RZ/G1N)
-                        "renesas,msiof-r8a7745" (RZ/G1E)
-                        "renesas,msiof-r8a77470" (RZ/G1C)
-                        "renesas,msiof-r8a774a1" (RZ/G2M)
-                        "renesas,msiof-r8a774c0" (RZ/G2E)
-                        "renesas,msiof-r8a7790" (R-Car H2)
-                        "renesas,msiof-r8a7791" (R-Car M2-W)
-                        "renesas,msiof-r8a7792" (R-Car V2H)
-                        "renesas,msiof-r8a7793" (R-Car M2-N)
-                        "renesas,msiof-r8a7794" (R-Car E2)
-                        "renesas,msiof-r8a7795" (R-Car H3)
-                        "renesas,msiof-r8a7796" (R-Car M3-W)
-                        "renesas,msiof-r8a77965" (R-Car M3-N)
-                        "renesas,msiof-r8a77970" (R-Car V3M)
-                        "renesas,msiof-r8a77980" (R-Car V3H)
-                        "renesas,msiof-r8a77990" (R-Car E3)
-                        "renesas,msiof-r8a77995" (R-Car D3)
-                        "renesas,msiof-sh73a0" (SH-Mobile AG5)
-                        "renesas,sh-mobile-msiof" (generic SH-Mobile compatibile device)
-                        "renesas,rcar-gen2-msiof" (generic R-Car Gen2 and RZ/G1 compatible device)
-                        "renesas,rcar-gen3-msiof" (generic R-Car Gen3 and RZ/G2 compatible device)
-                        "renesas,sh-msiof"      (deprecated)
-
-                        When compatible with the generic version, nodes
-                        must list the SoC-specific version corresponding
-                        to the platform first followed by the generic
-                        version.
-
-- reg                  : A list of offsets and lengths of the register sets for
-                        the device.
-                        If only one register set is present, it is to be used
-                        by both the CPU and the DMA engine.
-                        If two register sets are present, the first is to be
-                        used by the CPU, and the second is to be used by the
-                        DMA engine.
-- interrupts           : Interrupt specifier
-- #address-cells       : Must be <1>
-- #size-cells          : Must be <0>
-
-Optional properties:
-- clocks               : Must contain a reference to the functional clock.
-- num-cs               : Total number of chip selects (default is 1).
-                        Up to 3 native chip selects are supported:
-                          0: MSIOF_SYNC
-                          1: MSIOF_SS1
-                          2: MSIOF_SS2
-                        Hardware limitations related to chip selects:
-                          - Native chip selects are always deasserted in
-                            between transfers that are part of the same
-                            message.  Use cs-gpios to work around this.
-                          - All slaves using native chip selects must use the
-                            same spi-cs-high configuration.  Use cs-gpios to
-                            work around this.
-                          - When using GPIO chip selects, at least one native
-                            chip select must be left unused, as it will be
-                            driven anyway.
-- dmas                 : Must contain a list of two references to DMA
-                        specifiers, one for transmission, and one for
-                        reception.
-- dma-names            : Must contain a list of two DMA names, "tx" and "rx".
-- spi-slave            : Empty property indicating the SPI controller is used
-                        in slave mode.
-- renesas,dtdl         : delay sync signal (setup) in transmit mode.
-                        Must contain one of the following values:
-                        0   (no bit delay)
-                        50  (0.5-clock-cycle delay)
-                        100 (1-clock-cycle delay)
-                        150 (1.5-clock-cycle delay)
-                        200 (2-clock-cycle delay)
-
-- renesas,syncdl       : delay sync signal (hold) in transmit mode.
-                        Must contain one of the following values:
-                        0   (no bit delay)
-                        50  (0.5-clock-cycle delay)
-                        100 (1-clock-cycle delay)
-                        150 (1.5-clock-cycle delay)
-                        200 (2-clock-cycle delay)
-                        300 (3-clock-cycle delay)
-
-Optional properties, deprecated for soctype-specific bindings:
-- renesas,tx-fifo-size : Overrides the default tx fifo size given in words
-                        (default is 64)
-- renesas,rx-fifo-size : Overrides the default rx fifo size given in words
-                        (default is 64)
-
-Pinctrl properties might be needed, too.  See
-Documentation/devicetree/bindings/pinctrl/renesas,*.
-
-Example:
-
-       msiof0: spi@e6e20000 {
-               compatible = "renesas,msiof-r8a7791",
-                            "renesas,rcar-gen2-msiof";
-               reg = <0 0xe6e20000 0 0x0064>;
-               interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&mstp0_clks R8A7791_CLK_MSIOF0>;
-               dmas = <&dmac0 0x51>, <&dmac0 0x52>;
-               dma-names = "tx", "rx";
-               #address-cells = <1>;
-               #size-cells = <0>;
-       };
index f54c8c3..3ed08ee 100644 (file)
@@ -16,7 +16,8 @@ Required properties:
 Optional properties:
 - clock-names : Contains the names of the clocks:
     "ssi_clk", for the core clock used to generate the external SPI clock.
-    "pclk", the interface clock, required for register access.
+    "pclk", the interface clock, required for register access. If a clock domain
+     used to enable this clock then it should be named "pclk_clkdomain".
 - cs-gpios : Specifies the gpio pins to be used for chipselects.
 - num-cs : The number of chipselects. If omitted, this will default to 4.
 - reg-io-width : The I/O register width (in bytes) implemented by this
diff --git a/Documentation/devicetree/bindings/spi/spi-sifive.txt b/Documentation/devicetree/bindings/spi/spi-sifive.txt
deleted file mode 100644 (file)
index 3f5c6e4..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-SiFive SPI controller Device Tree Bindings
-------------------------------------------
-
-Required properties:
-- compatible           : Should be "sifive,<chip>-spi" and "sifive,spi<version>".
-                         Supported compatible strings are:
-                         "sifive,fu540-c000-spi" for the SiFive SPI v0 as integrated
-                         onto the SiFive FU540 chip, and "sifive,spi0" for the SiFive
-                         SPI v0 IP block with no chip integration tweaks.
-                         Please refer to sifive-blocks-ip-versioning.txt for details
-- reg                  : Physical base address and size of SPI registers map
-                         A second (optional) range can indicate memory mapped flash
-- interrupts           : Must contain one entry
-- interrupt-parent     : Must be core interrupt controller
-- clocks               : Must reference the frequency given to the controller
-- #address-cells       : Must be '1', indicating which CS to use
-- #size-cells          : Must be '0'
-
-Optional properties:
-- sifive,fifo-depth            : Depth of hardware queues; defaults to 8
-- sifive,max-bits-per-word     : Maximum bits per word; defaults to 8
-
-SPI RTL that corresponds to the IP block version numbers can be found here:
-https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/spi
-
-Example:
-       spi: spi@10040000 {
-               compatible = "sifive,fu540-c000-spi", "sifive,spi0";
-               reg = <0x0 0x10040000 0x0 0x1000 0x0 0x20000000 0x0 0x10000000>;
-               interrupt-parent = <&plic>;
-               interrupts = <51>;
-               clocks = <&tlclk>;
-               #address-cells = <1>;
-               #size-cells = <0>;
-               sifive,fifo-depth = <8>;
-               sifive,max-bits-per-word = <8>;
-       };
diff --git a/Documentation/devicetree/bindings/spi/spi-sifive.yaml b/Documentation/devicetree/bindings/spi/spi-sifive.yaml
new file mode 100644 (file)
index 0000000..140e435
--- /dev/null
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/spi-sifive.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SiFive SPI controller
+
+maintainers:
+  - Pragnesh Patel <pragnesh.patel@sifive.com>
+  - Paul Walmsley  <paul.walmsley@sifive.com>
+  - Palmer Dabbelt <palmer@sifive.com>
+
+allOf:
+  - $ref: "spi-controller.yaml#"
+
+properties:
+  compatible:
+    items:
+      - const: sifive,fu540-c000-spi
+      - const: sifive,spi0
+
+    description:
+      Should be "sifive,<chip>-spi" and "sifive,spi<version>".
+      Supported compatible strings are -
+      "sifive,fu540-c000-spi" for the SiFive SPI v0 as integrated
+      onto the SiFive FU540 chip, and "sifive,spi0" for the SiFive
+      SPI v0 IP block with no chip integration tweaks.
+      Please refer to sifive-blocks-ip-versioning.txt for details
+
+      SPI RTL that corresponds to the IP block version numbers can be found here -
+      https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/spi
+
+  reg:
+    maxItems: 1
+
+    description:
+      Physical base address and size of SPI registers map
+      A second (optional) range can indicate memory mapped flash
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+    description:
+      Must reference the frequency given to the controller
+
+  sifive,fifo-depth:
+    description:
+      Depth of hardware queues; defaults to 8
+    allOf:
+      - $ref: "/schemas/types.yaml#/definitions/uint32"
+      - enum: [ 8 ]
+      - default: 8
+
+  sifive,max-bits-per-word:
+    description:
+      Maximum bits per word; defaults to 8
+    allOf:
+      - $ref: "/schemas/types.yaml#/definitions/uint32"
+      - enum: [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]
+      - default: 8
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+
+examples:
+  - |
+    spi: spi@10040000 {
+      compatible = "sifive,fu540-c000-spi", "sifive,spi0";
+      reg = <0x0 0x10040000 0x0 0x1000 0x0 0x20000000 0x0 0x10000000>;
+      interrupt-parent = <&plic>;
+      interrupts = <51>;
+      clocks = <&tlclk>;
+      #address-cells = <1>;
+      #size-cells = <0>;
+      sifive,fifo-depth = <8>;
+      sifive,max-bits-per-word = <8>;
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/spi/spi-stm32-qspi.txt b/Documentation/devicetree/bindings/spi/spi-stm32-qspi.txt
deleted file mode 100644 (file)
index bfc038b..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-* STMicroelectronics Quad Serial Peripheral Interface(QSPI)
-
-Required properties:
-- compatible: should be "st,stm32f469-qspi"
-- reg: the first contains the register location and length.
-       the second contains the memory mapping address and length
-- reg-names: should contain the reg names "qspi" "qspi_mm"
-- interrupts: should contain the interrupt for the device
-- clocks: the phandle of the clock needed by the QSPI controller
-- A pinctrl must be defined to set pins in mode of operation for QSPI transfer
-
-Optional properties:
-- resets: must contain the phandle to the reset controller.
-
-A spi flash (NOR/NAND) must be a child of spi node and could have some
-properties. Also see jedec,spi-nor.txt.
-
-Required properties:
-- reg: chip-Select number (QSPI controller may connect 2 flashes)
-- spi-max-frequency: max frequency of spi bus
-
-Optional properties:
-- spi-rx-bus-width: see ./spi-bus.txt for the description
-- dmas: DMA specifiers for tx and rx dma. See the DMA client binding,
-Documentation/devicetree/bindings/dma/dma.txt.
-- dma-names: DMA request names should include "tx" and "rx" if present.
-
-Example:
-
-qspi: spi@a0001000 {
-       compatible = "st,stm32f469-qspi";
-       reg = <0xa0001000 0x1000>, <0x90000000 0x10000000>;
-       reg-names = "qspi", "qspi_mm";
-       interrupts = <91>;
-       resets = <&rcc STM32F4_AHB3_RESET(QSPI)>;
-       clocks = <&rcc 0 STM32F4_AHB3_CLOCK(QSPI)>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_qspi0>;
-
-       flash@0 {
-               compatible = "jedec,spi-nor";
-               reg = <0>;
-               spi-rx-bus-width = <4>;
-               spi-max-frequency = <108000000>;
-               ...
-       };
-};
index dc924a5..5f4ed3e 100644 (file)
@@ -8,7 +8,8 @@ Required properties:
                          number.
 
 Optional properties:
-- xlnx,num-ss-bits     : Number of chip selects used.
+- xlnx,num-ss-bits      : Number of chip selects used.
+- xlnx,num-transfer-bits : Number of bits per transfer. This will be 8 if not specified
 
 Example:
        axi_quad_spi@41e00000 {
@@ -17,5 +18,6 @@ Example:
                        interrupts = <0 31 1>;
                        reg = <0x41e00000 0x10000>;
                        xlnx,num-ss-bits = <0x1>;
+                       xlnx,num-transfer-bits = <32>;
        };
 
diff --git a/Documentation/devicetree/bindings/spi/st,stm32-qspi.yaml b/Documentation/devicetree/bindings/spi/st,stm32-qspi.yaml
new file mode 100644 (file)
index 0000000..3665a5f
--- /dev/null
@@ -0,0 +1,83 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/st,stm32-qspi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics STM32 Quad Serial Peripheral Interface (QSPI) bindings
+
+maintainers:
+  - Christophe Kerello <christophe.kerello@st.com>
+  - Patrice Chotard <patrice.chotard@st.com>
+
+allOf:
+  - $ref: "spi-controller.yaml#"
+
+properties:
+  compatible:
+    const: st,stm32f469-qspi
+
+  reg:
+    items:
+      - description: registers
+      - description: memory mapping
+
+  reg-names:
+    items:
+     - const: qspi
+     - const: qspi_mm
+
+  clocks:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+  dmas:
+    items:
+      - description: tx DMA channel
+      - description: rx DMA channel
+
+  dma-names:
+    items:
+      - const: tx
+      - const: rx
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - clocks
+  - interrupts
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/stm32mp1-clks.h>
+    #include <dt-bindings/reset/stm32mp1-resets.h>
+    spi@58003000 {
+      compatible = "st,stm32f469-qspi";
+      reg = <0x58003000 0x1000>, <0x70000000 0x10000000>;
+      reg-names = "qspi", "qspi_mm";
+      interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+      dmas = <&mdma1 22 0x10 0x100002 0x0 0x0>,
+             <&mdma1 22 0x10 0x100008 0x0 0x0>;
+      dma-names = "tx", "rx";
+      clocks = <&rcc QSPI_K>;
+      resets = <&rcc QSPI_R>;
+
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      flash@0 {
+        compatible = "jedec,spi-nor";
+        reg = <0>;
+        spi-rx-bus-width = <4>;
+        spi-max-frequency = <108000000>;
+      };
+    };
+
+...
index 9a6e492..5634403 100644 (file)
@@ -89,7 +89,7 @@ void pxa_ssp_free(struct ssp_device *ssp)
                ssp->use_count--;
                ssp->label = NULL;
        } else
-               dev_err(&ssp->pdev->dev, "device already free\n");
+               dev_err(ssp->dev, "device already free\n");
        mutex_unlock(&ssp_lock);
 }
 EXPORT_SYMBOL(pxa_ssp_free);
@@ -118,7 +118,7 @@ static int pxa_ssp_probe(struct platform_device *pdev)
        if (ssp == NULL)
                return -ENOMEM;
 
-       ssp->pdev = pdev;
+       ssp->dev = dev;
 
        ssp->clk = devm_clk_get(dev, NULL);
        if (IS_ERR(ssp->clk))
index 1631c25..2cd2cc2 100644 (file)
@@ -39,24 +39,24 @@ int adis_write_reg(struct adis *adis, unsigned int reg,
                        .len = 2,
                        .cs_change = 1,
                        .delay_usecs = adis->data->write_delay,
-                       .cs_change_delay = adis->data->cs_change_delay,
-                       .cs_change_delay_unit = SPI_DELAY_UNIT_USECS,
+                       .cs_change_delay.value = adis->data->cs_change_delay,
+                       .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
                }, {
                        .tx_buf = adis->tx + 2,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
                        .delay_usecs = adis->data->write_delay,
-                       .cs_change_delay = adis->data->cs_change_delay,
-                       .cs_change_delay_unit = SPI_DELAY_UNIT_USECS,
+                       .cs_change_delay.value = adis->data->cs_change_delay,
+                       .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
                }, {
                        .tx_buf = adis->tx + 4,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
                        .delay_usecs = adis->data->write_delay,
-                       .cs_change_delay = adis->data->cs_change_delay,
-                       .cs_change_delay_unit = SPI_DELAY_UNIT_USECS,
+                       .cs_change_delay.value = adis->data->cs_change_delay,
+                       .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
                }, {
                        .tx_buf = adis->tx + 6,
                        .bits_per_word = 8,
@@ -139,16 +139,16 @@ int adis_read_reg(struct adis *adis, unsigned int reg,
                        .len = 2,
                        .cs_change = 1,
                        .delay_usecs = adis->data->write_delay,
-                       .cs_change_delay = adis->data->cs_change_delay,
-                       .cs_change_delay_unit = SPI_DELAY_UNIT_USECS,
+                       .cs_change_delay.value = adis->data->cs_change_delay,
+                       .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
                }, {
                        .tx_buf = adis->tx + 2,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
                        .delay_usecs = adis->data->read_delay,
-                       .cs_change_delay = adis->data->cs_change_delay,
-                       .cs_change_delay_unit = SPI_DELAY_UNIT_USECS,
+                       .cs_change_delay.value = adis->data->cs_change_delay,
+                       .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
                }, {
                        .tx_buf = adis->tx + 4,
                        .rx_buf = adis->rx,
@@ -156,8 +156,8 @@ int adis_read_reg(struct adis *adis, unsigned int reg,
                        .len = 2,
                        .cs_change = 1,
                        .delay_usecs = adis->data->read_delay,
-                       .cs_change_delay = adis->data->cs_change_delay,
-                       .cs_change_delay_unit = SPI_DELAY_UNIT_USECS,
+                       .cs_change_delay.value = adis->data->cs_change_delay,
+                       .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
                }, {
                        .rx_buf = adis->rx + 2,
                        .bits_per_word = 8,
index 6f7fdcb..870f779 100644 (file)
@@ -80,6 +80,7 @@ config SPI_ARMADA_3700
 config SPI_ATMEL
        tristate "Atmel SPI Controller"
        depends on ARCH_AT91 || COMPILE_TEST
+       depends on OF
        help
          This selects a driver for the Atmel SPI Controller, present on
          many AT91 ARM chips.
@@ -143,7 +144,7 @@ config SPI_BCM63XX
        tristate "Broadcom BCM63xx SPI controller"
        depends on BCM63XX || COMPILE_TEST
        help
-          Enable support for the SPI controller on the Broadcom BCM63xx SoCs.
+         Enable support for the SPI controller on the Broadcom BCM63xx SoCs.
 
 config SPI_BCM63XX_HSSPI
        tristate "Broadcom BCM63XX HS SPI controller driver"
@@ -234,11 +235,11 @@ config SPI_DLN2
        tristate "Diolan DLN-2 USB SPI adapter"
        depends on MFD_DLN2
        help
-         If you say yes to this option, support will be included for Diolan
-         DLN2, a USB to SPI interface.
+        If you say yes to this option, support will be included for Diolan
+        DLN2, a USB to SPI interface.
 
-         This driver can also be built as a module.  If so, the module
-         will be called spi-dln2.
+        This driver can also be built as a module.  If so, the module
+        will be called spi-dln2.
 
 config SPI_EFM32
        tristate "EFM32 SPI controller"
@@ -747,10 +748,10 @@ config SPI_SYNQUACER
          It also supports the new dual-bit and quad-bit SPI protocol.
 
 config SPI_MXIC
-        tristate "Macronix MX25F0A SPI controller"
-        depends on SPI_MASTER
-        help
-          This selects the Macronix MX25F0A SPI controller driver.
+       tristate "Macronix MX25F0A SPI controller"
+       depends on SPI_MASTER
+       help
+         This selects the Macronix MX25F0A SPI controller driver.
 
 config SPI_MXS
        tristate "Freescale MXS SPI controller"
index a40bb2e..8803342 100644 (file)
@@ -132,7 +132,7 @@ static int at91_usart_spi_configure_dma(struct spi_controller *ctlr,
        dma_cap_zero(mask);
        dma_cap_set(DMA_SLAVE, mask);
 
-       ctlr->dma_tx = dma_request_slave_channel_reason(dev, "tx");
+       ctlr->dma_tx = dma_request_chan(dev, "tx");
        if (IS_ERR_OR_NULL(ctlr->dma_tx)) {
                if (IS_ERR(ctlr->dma_tx)) {
                        err = PTR_ERR(ctlr->dma_tx);
@@ -145,7 +145,7 @@ static int at91_usart_spi_configure_dma(struct spi_controller *ctlr,
                goto at91_usart_spi_error_clear;
        }
 
-       ctlr->dma_rx = dma_request_slave_channel_reason(dev, "rx");
+       ctlr->dma_rx = dma_request_chan(dev, "rx");
        if (IS_ERR_OR_NULL(ctlr->dma_rx)) {
                if (IS_ERR(ctlr->dma_rx)) {
                        err = PTR_ERR(ctlr->dma_rx);
index 2f8c79c..56f0ca3 100644 (file)
          | SPI_BF(name, value))
 
 /* Register access macros */
-#ifdef CONFIG_AVR32
-#define spi_readl(port, reg) \
-       __raw_readl((port)->regs + SPI_##reg)
-#define spi_writel(port, reg, value) \
-       __raw_writel((value), (port)->regs + SPI_##reg)
-
-#define spi_readw(port, reg) \
-       __raw_readw((port)->regs + SPI_##reg)
-#define spi_writew(port, reg, value) \
-       __raw_writew((value), (port)->regs + SPI_##reg)
-
-#define spi_readb(port, reg) \
-       __raw_readb((port)->regs + SPI_##reg)
-#define spi_writeb(port, reg, value) \
-       __raw_writeb((value), (port)->regs + SPI_##reg)
-#else
 #define spi_readl(port, reg) \
        readl_relaxed((port)->regs + SPI_##reg)
 #define spi_writel(port, reg, value) \
        writel_relaxed((value), (port)->regs + SPI_##reg)
-
-#define spi_readw(port, reg) \
-       readw_relaxed((port)->regs + SPI_##reg)
 #define spi_writew(port, reg, value) \
        writew_relaxed((value), (port)->regs + SPI_##reg)
 
-#define spi_readb(port, reg) \
-       readb_relaxed((port)->regs + SPI_##reg)
-#define spi_writeb(port, reg, value) \
-       writeb_relaxed((value), (port)->regs + SPI_##reg)
-#endif
 /* use PIO for small transfers, avoiding DMA setup/teardown overhead and
  * cache operations; better heuristics consider wordsize and bitrate.
  */
@@ -299,16 +275,16 @@ struct atmel_spi {
 
        bool                    use_dma;
        bool                    use_pdc;
-       bool                    use_cs_gpios;
 
        bool                    keep_cs;
 
        u32                     fifo_size;
+       u8                      native_cs_free;
+       u8                      native_cs_for_gpio;
 };
 
 /* Controller-specific per-slave state */
 struct atmel_spi_device {
-       struct gpio_desc        *npcs_pin;
        u32                     csr;
 };
 
@@ -335,11 +311,9 @@ static bool atmel_spi_is_v2(struct atmel_spi *as)
  * transmitted")  Not so!  Workaround uses nCSx pins as GPIOs; or newer
  * controllers have CSAAT and friends.
  *
- * Since the CSAAT functionality is a bit weird on newer controllers as
- * well, we use GPIO to control nCSx pins on all controllers, updating
- * MR.PCS to avoid confusing the controller.  Using GPIOs also lets us
- * support active-high chipselects despite the controller's belief that
- * only active-low devices/systems exists.
+ * Even controller newer than ar91rm9200, using GPIOs can make sens as
+ * it lets us support active-high chipselects despite the controller's
+ * belief that only active-low devices/systems exists.
  *
  * However, at91rm9200 has a second erratum whereby nCS0 doesn't work
  * right when driven with GPIO.  ("Mode Fault does not allow more than one
@@ -351,30 +325,36 @@ static bool atmel_spi_is_v2(struct atmel_spi *as)
 static void cs_activate(struct atmel_spi *as, struct spi_device *spi)
 {
        struct atmel_spi_device *asd = spi->controller_state;
+       int chip_select;
        u32 mr;
 
+       if (spi->cs_gpiod)
+               chip_select = as->native_cs_for_gpio;
+       else
+               chip_select = spi->chip_select;
+
        if (atmel_spi_is_v2(as)) {
-               spi_writel(as, CSR0 + 4 * spi->chip_select, asd->csr);
+               spi_writel(as, CSR0 + 4 * chip_select, asd->csr);
                /* For the low SPI version, there is a issue that PDC transfer
                 * on CS1,2,3 needs SPI_CSR0.BITS config as SPI_CSR1,2,3.BITS
                 */
                spi_writel(as, CSR0, asd->csr);
                if (as->caps.has_wdrbt) {
                        spi_writel(as, MR,
-                                       SPI_BF(PCS, ~(0x01 << spi->chip_select))
+                                       SPI_BF(PCS, ~(0x01 << chip_select))
                                        | SPI_BIT(WDRBT)
                                        | SPI_BIT(MODFDIS)
                                        | SPI_BIT(MSTR));
                } else {
                        spi_writel(as, MR,
-                                       SPI_BF(PCS, ~(0x01 << spi->chip_select))
+                                       SPI_BF(PCS, ~(0x01 << chip_select))
                                        | SPI_BIT(MODFDIS)
                                        | SPI_BIT(MSTR));
                }
 
                mr = spi_readl(as, MR);
-               if (as->use_cs_gpios)
-                       gpiod_set_value(asd->npcs_pin, 1);
+               if (spi->cs_gpiod)
+                       gpiod_set_value(spi->cs_gpiod, 1);
        } else {
                u32 cpol = (spi->mode & SPI_CPOL) ? SPI_BIT(CPOL) : 0;
                int i;
@@ -389,9 +369,9 @@ static void cs_activate(struct atmel_spi *as, struct spi_device *spi)
                }
 
                mr = spi_readl(as, MR);
-               mr = SPI_BFINS(PCS, ~(1 << spi->chip_select), mr);
-               if (as->use_cs_gpios && spi->chip_select != 0)
-                       gpiod_set_value(asd->npcs_pin, 1);
+               mr = SPI_BFINS(PCS, ~(1 << chip_select), mr);
+               if (spi->cs_gpiod)
+                       gpiod_set_value(spi->cs_gpiod, 1);
                spi_writel(as, MR, mr);
        }
 
@@ -400,24 +380,29 @@ static void cs_activate(struct atmel_spi *as, struct spi_device *spi)
 
 static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi)
 {
-       struct atmel_spi_device *asd = spi->controller_state;
+       int chip_select;
        u32 mr;
 
+       if (spi->cs_gpiod)
+               chip_select = as->native_cs_for_gpio;
+       else
+               chip_select = spi->chip_select;
+
        /* only deactivate *this* device; sometimes transfers to
         * another device may be active when this routine is called.
         */
        mr = spi_readl(as, MR);
-       if (~SPI_BFEXT(PCS, mr) & (1 << spi->chip_select)) {
+       if (~SPI_BFEXT(PCS, mr) & (1 << chip_select)) {
                mr = SPI_BFINS(PCS, 0xf, mr);
                spi_writel(as, MR, mr);
        }
 
        dev_dbg(&spi->dev, "DEactivate NPCS, mr %08x\n", mr);
 
-       if (!as->use_cs_gpios)
+       if (!spi->cs_gpiod)
                spi_writel(as, CR, SPI_BIT(LASTXFER));
-       else if (atmel_spi_is_v2(as) || spi->chip_select != 0)
-               gpiod_set_value(asd->npcs_pin, 0);
+       else
+               gpiod_set_value(spi->cs_gpiod, 0);
 }
 
 static void atmel_spi_lock(struct atmel_spi *as) __acquires(&as->lock)
@@ -526,7 +511,7 @@ static int atmel_spi_configure_dma(struct spi_master *master,
        dma_cap_zero(mask);
        dma_cap_set(DMA_SLAVE, mask);
 
-       master->dma_tx = dma_request_slave_channel_reason(dev, "tx");
+       master->dma_tx = dma_request_chan(dev, "tx");
        if (IS_ERR(master->dma_tx)) {
                err = PTR_ERR(master->dma_tx);
                if (err == -EPROBE_DEFER) {
@@ -843,6 +828,12 @@ static int atmel_spi_set_xfer_speed(struct atmel_spi *as,
 {
        u32                     scbr, csr;
        unsigned long           bus_hz;
+       int chip_select;
+
+       if (spi->cs_gpiod)
+               chip_select = as->native_cs_for_gpio;
+       else
+               chip_select = spi->chip_select;
 
        /* v1 chips start out at half the peripheral bus speed. */
        bus_hz = as->spi_clk;
@@ -871,9 +862,9 @@ static int atmel_spi_set_xfer_speed(struct atmel_spi *as,
                        xfer->speed_hz, scbr, bus_hz);
                return -EINVAL;
        }
-       csr = spi_readl(as, CSR0 + 4 * spi->chip_select);
+       csr = spi_readl(as, CSR0 + 4 * chip_select);
        csr = SPI_BFINS(SCBR, scbr, csr);
-       spi_writel(as, CSR0 + 4 * spi->chip_select, csr);
+       spi_writel(as, CSR0 + 4 * chip_select, csr);
 
        return 0;
 }
@@ -1172,40 +1163,105 @@ atmel_spi_pdc_interrupt(int irq, void *dev_id)
        return ret;
 }
 
+static int atmel_word_delay_csr(struct spi_device *spi, struct atmel_spi *as)
+{
+       struct spi_delay *delay = &spi->word_delay;
+       u32 value = delay->value;
+
+       switch (delay->unit) {
+       case SPI_DELAY_UNIT_NSECS:
+               value /= 1000;
+               break;
+       case SPI_DELAY_UNIT_USECS:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return (as->spi_clk / 1000000 * value) >> 5;
+}
+
+static void initialize_native_cs_for_gpio(struct atmel_spi *as)
+{
+       int i;
+       struct spi_master *master = platform_get_drvdata(as->pdev);
+
+       if (!as->native_cs_free)
+               return; /* already initialized */
+
+       if (!master->cs_gpiods)
+               return; /* No CS GPIO */
+
+       /*
+        * On the first version of the controller (AT91RM9200), CS0
+        * can't be used associated with GPIO
+        */
+       if (atmel_spi_is_v2(as))
+               i = 0;
+       else
+               i = 1;
+
+       for (; i < 4; i++)
+               if (master->cs_gpiods[i])
+                       as->native_cs_free |= BIT(i);
+
+       if (as->native_cs_free)
+               as->native_cs_for_gpio = ffs(as->native_cs_free);
+}
+
 static int atmel_spi_setup(struct spi_device *spi)
 {
        struct atmel_spi        *as;
        struct atmel_spi_device *asd;
        u32                     csr;
        unsigned int            bits = spi->bits_per_word;
+       int chip_select;
+       int                     word_delay_csr;
 
        as = spi_master_get_devdata(spi->master);
 
        /* see notes above re chipselect */
-       if (!atmel_spi_is_v2(as)
-                       && spi->chip_select == 0
-                       && (spi->mode & SPI_CS_HIGH)) {
-               dev_dbg(&spi->dev, "setup: can't be active-high\n");
+       if (!spi->cs_gpiod && (spi->mode & SPI_CS_HIGH)) {
+               dev_warn(&spi->dev, "setup: non GPIO CS can't be active-high\n");
                return -EINVAL;
        }
 
+       /* Setup() is called during spi_register_controller(aka
+        * spi_register_master) but after all membmers of the cs_gpiod
+        * array have been filled, so we can looked for which native
+        * CS will be free for using with GPIO
+        */
+       initialize_native_cs_for_gpio(as);
+
+       if (spi->cs_gpiod && as->native_cs_free) {
+               dev_err(&spi->dev,
+                       "No native CS available to support this GPIO CS\n");
+               return -EBUSY;
+       }
+
+       if (spi->cs_gpiod)
+               chip_select = as->native_cs_for_gpio;
+       else
+               chip_select = spi->chip_select;
+
        csr = SPI_BF(BITS, bits - 8);
        if (spi->mode & SPI_CPOL)
                csr |= SPI_BIT(CPOL);
        if (!(spi->mode & SPI_CPHA))
                csr |= SPI_BIT(NCPHA);
-       if (!as->use_cs_gpios)
-               csr |= SPI_BIT(CSAAT);
 
-       /* DLYBS is mostly irrelevant since we manage chipselect using GPIOs.
-        */
+       if (!spi->cs_gpiod)
+               csr |= SPI_BIT(CSAAT);
        csr |= SPI_BF(DLYBS, 0);
 
+       word_delay_csr = atmel_word_delay_csr(spi, as);
+       if (word_delay_csr < 0)
+               return word_delay_csr;
+
        /* DLYBCT adds delays between words.  This is useful for slow devices
         * that need a bit of time to setup the next transfer.
         */
-       csr |= SPI_BF(DLYBCT,
-                       (as->spi_clk / 1000000 * spi->word_delay_usecs) >> 5);
+       csr |= SPI_BF(DLYBCT, word_delay_csr);
 
        asd = spi->controller_state;
        if (!asd) {
@@ -1213,21 +1269,6 @@ static int atmel_spi_setup(struct spi_device *spi)
                if (!asd)
                        return -ENOMEM;
 
-               /*
-                * If use_cs_gpios is true this means that we have "cs-gpios"
-                * defined in the device tree node so we should have
-                * gotten the GPIO lines from the device tree inside the
-                * SPI core. Warn if this is not the case but continue since
-                * CS GPIOs are after all optional.
-                */
-               if (as->use_cs_gpios) {
-                       if (!spi->cs_gpiod) {
-                               dev_err(&spi->dev,
-                                       "host claims to use CS GPIOs but no CS found in DT by the SPI core\n");
-                       }
-                       asd->npcs_pin = spi->cs_gpiod;
-               }
-
                spi->controller_state = asd;
        }
 
@@ -1238,7 +1279,7 @@ static int atmel_spi_setup(struct spi_device *spi)
                bits, spi->mode, spi->chip_select, csr);
 
        if (!atmel_spi_is_v2(as))
-               spi_writel(as, CSR0 + 4 * spi->chip_select, csr);
+               spi_writel(as, CSR0 + 4 * chip_select, csr);
 
        return 0;
 }
@@ -1367,8 +1408,7 @@ static int atmel_spi_one_transfer(struct spi_master *master,
                && as->use_pdc)
                atmel_spi_dma_unmap_xfer(master, xfer);
 
-       if (xfer->delay_usecs)
-               udelay(xfer->delay_usecs);
+       spi_transfer_delay_exec(xfer);
 
        if (xfer->cs_change) {
                if (list_is_last(&xfer->transfer_list,
@@ -1523,7 +1563,7 @@ static int atmel_spi_probe(struct platform_device *pdev)
        master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 16);
        master->dev.of_node = pdev->dev.of_node;
        master->bus_num = pdev->id;
-       master->num_chipselect = master->dev.of_node ? 0 : 4;
+       master->num_chipselect = 4;
        master->setup = atmel_spi_setup;
        master->flags = (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX);
        master->transfer_one_message = atmel_spi_transfer_one_message;
@@ -1551,19 +1591,6 @@ static int atmel_spi_probe(struct platform_device *pdev)
 
        atmel_get_caps(as);
 
-       /*
-        * If there are chip selects in the device tree, those will be
-        * discovered by the SPI core when registering the SPI master
-        * and assigned to each SPI device.
-        */
-       as->use_cs_gpios = true;
-       if (atmel_spi_is_v2(as) &&
-           pdev->dev.of_node &&
-           !of_get_property(pdev->dev.of_node, "cs-gpios", NULL)) {
-               as->use_cs_gpios = false;
-               master->num_chipselect = 4;
-       }
-
        as->use_dma = false;
        as->use_pdc = false;
        if (as->caps.has_dma_support) {
@@ -1771,20 +1798,18 @@ static const struct dev_pm_ops atmel_spi_pm_ops = {
 #define ATMEL_SPI_PM_OPS       NULL
 #endif
 
-#if defined(CONFIG_OF)
 static const struct of_device_id atmel_spi_dt_ids[] = {
        { .compatible = "atmel,at91rm9200-spi" },
        { /* sentinel */ }
 };
 
 MODULE_DEVICE_TABLE(of, atmel_spi_dt_ids);
-#endif
 
 static struct platform_driver atmel_spi_driver = {
        .driver         = {
                .name   = "atmel_spi",
                .pm     = ATMEL_SPI_PM_OPS,
-               .of_match_table = of_match_ptr(atmel_spi_dt_ids),
+               .of_match_table = atmel_spi_dt_ids,
        },
        .probe          = atmel_spi_probe,
        .remove         = atmel_spi_remove,
index 74842f6..eb9b78a 100644 (file)
@@ -163,10 +163,21 @@ static void spi_engine_gen_xfer(struct spi_engine_program *p, bool dry,
 }
 
 static void spi_engine_gen_sleep(struct spi_engine_program *p, bool dry,
-       struct spi_engine *spi_engine, unsigned int clk_div, unsigned int delay)
+       struct spi_engine *spi_engine, unsigned int clk_div,
+       struct spi_transfer *xfer)
 {
        unsigned int spi_clk = clk_get_rate(spi_engine->ref_clk);
        unsigned int t;
+       int delay;
+
+       if (xfer->delay_usecs) {
+               delay = xfer->delay_usecs;
+       } else {
+               delay = spi_delay_to_ns(&xfer->delay, xfer);
+               if (delay < 0)
+                       return;
+               delay /= 1000;
+       }
 
        if (delay == 0)
                return;
@@ -218,8 +229,7 @@ static int spi_engine_compile_message(struct spi_engine *spi_engine,
                        spi_engine_gen_cs(p, dry, spi, true);
 
                spi_engine_gen_xfer(p, dry, xfer);
-               spi_engine_gen_sleep(p, dry, spi_engine, clk_div,
-                       xfer->delay_usecs);
+               spi_engine_gen_sleep(p, dry, spi_engine, clk_div, xfer);
 
                cs_change = xfer->cs_change;
                if (list_is_last(&xfer->transfer_list, &msg->transfers))
index 7a35318..85bad70 100644 (file)
@@ -803,7 +803,8 @@ static int bcm_qspi_bspi_exec_mem_op(struct spi_device *spi,
                        return -EIO;
 
        from = op->addr.val;
-       bcm_qspi_chip_select(qspi, spi->chip_select);
+       if (!spi->cs_gpiod)
+               bcm_qspi_chip_select(qspi, spi->chip_select);
        bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 0);
 
        /*
@@ -882,7 +883,8 @@ static int bcm_qspi_transfer_one(struct spi_master *master,
        int slots;
        unsigned long timeo = msecs_to_jiffies(100);
 
-       bcm_qspi_chip_select(qspi, spi->chip_select);
+       if (!spi->cs_gpiod)
+               bcm_qspi_chip_select(qspi, spi->chip_select);
        qspi->trans_pos.trans = trans;
        qspi->trans_pos.byte = 0;
 
@@ -1234,6 +1236,7 @@ int bcm_qspi_probe(struct platform_device *pdev,
        master->cleanup = bcm_qspi_cleanup;
        master->dev.of_node = dev->of_node;
        master->num_chipselect = NUM_CHIPSELECT;
+       master->use_gpio_descriptors = true;
 
        qspi->big_endian = of_device_is_big_endian(dev->of_node);
 
index c6836a9..7327309 100644 (file)
@@ -291,8 +291,7 @@ static int bcm63xx_hsspi_transfer_one(struct spi_master *master,
 
                msg->actual_length += t->len;
 
-               if (t->delay_usecs)
-                       udelay(t->delay_usecs);
+               spi_transfer_delay_exec(t);
 
                if (t->cs_change)
                        bcm63xx_hsspi_set_cs(bs, spi->chip_select, false);
index fdd7eaa..0f1b10a 100644 (file)
@@ -368,7 +368,7 @@ static int bcm63xx_spi_transfer_one(struct spi_master *master,
                }
 
                /* CS will be deasserted directly after transfer */
-               if (t->delay_usecs) {
+               if (t->delay_usecs || t->delay.value) {
                        dev_err(&spi->dev, "unable to keep CS asserted after transfer\n");
                        status = -EINVAL;
                        goto exit;
index 5aaf215..6854c3c 100644 (file)
@@ -119,8 +119,7 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,
                        *rx_buf++ = (u8)v;
                }
 
-       if (xfer->delay_usecs)
-               udelay(xfer->delay_usecs);
+       spi_transfer_delay_exec(xfer);
 
        return xfer->len;
 }
index db89647..384a3ab 100644 (file)
@@ -228,6 +228,7 @@ static const struct of_device_id dw_spi_mmio_of_match[] = {
        { .compatible = "mscc,ocelot-spi", .data = dw_spi_mscc_ocelot_init},
        { .compatible = "mscc,jaguar2-spi", .data = dw_spi_mscc_jaguar2_init},
        { .compatible = "amazon,alpine-dw-apb-ssi", .data = dw_spi_alpine_init},
+       { .compatible = "renesas,rzn1-spi", },
        { /* end of table */}
 };
 MODULE_DEVICE_TABLE(of, dw_spi_mmio_of_match);
index 1406449..12c131b 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/pm_runtime.h>
 #include <linux/slab.h>
 #include <linux/spi/spi.h>
 #include <linux/module.h>
@@ -35,7 +36,7 @@ static struct spi_pci_desc spi_pci_mid_desc_2 = {
 };
 
 static struct spi_pci_desc spi_pci_ehl_desc = {
-       .num_cs = 1,
+       .num_cs = 2,
        .bus_num = -1,
        .max_freq = 100000000,
 };
@@ -57,13 +58,18 @@ static int spi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        /* Get basic io resource and map it */
        dws->paddr = pci_resource_start(pdev, pci_bar);
+       pci_set_master(pdev);
 
        ret = pcim_iomap_regions(pdev, 1 << pci_bar, pci_name(pdev));
        if (ret)
                return ret;
 
+       ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
+       if (ret < 0)
+               return ret;
+
        dws->regs = pcim_iomap_table(pdev)[pci_bar];
-       dws->irq = pdev->irq;
+       dws->irq = pci_irq_vector(pdev, 0);
 
        /*
         * Specific handling for platforms, like dma setup,
@@ -80,12 +86,15 @@ static int spi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                                return ret;
                }
        } else {
+               pci_free_irq_vectors(pdev);
                return -ENODEV;
        }
 
        ret = dw_spi_add_host(&pdev->dev, dws);
-       if (ret)
+       if (ret) {
+               pci_free_irq_vectors(pdev);
                return ret;
+       }
 
        /* PCI hook and SPI hook use the same drv data */
        pci_set_drvdata(pdev, dws);
@@ -93,6 +102,11 @@ static int spi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        dev_info(&pdev->dev, "found PCI SPI controller(ID: %04x:%04x)\n",
                pdev->vendor, pdev->device);
 
+       pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
+       pm_runtime_use_autosuspend(&pdev->dev);
+       pm_runtime_put_autosuspend(&pdev->dev);
+       pm_runtime_allow(&pdev->dev);
+
        return 0;
 }
 
@@ -100,7 +114,11 @@ static void spi_pci_remove(struct pci_dev *pdev)
 {
        struct dw_spi *dws = pci_get_drvdata(pdev);
 
+       pm_runtime_forbid(&pdev->dev);
+       pm_runtime_get_noresume(&pdev->dev);
+
        dw_spi_remove_host(dws);
+       pci_free_irq_vectors(pdev);
 }
 
 #ifdef CONFIG_PM_SLEEP
index 076652d..a92aa5c 100644 (file)
@@ -494,6 +494,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
        master->dev.of_node = dev->of_node;
        master->dev.fwnode = dev->fwnode;
        master->flags = SPI_MASTER_GPIO_SS;
+       master->auto_runtime_pm = true;
 
        if (dws->set_cs)
                master->set_cs = dws->set_cs;
index c9c1588..38c7de1 100644 (file)
@@ -4,7 +4,6 @@
 
 #include <linux/io.h>
 #include <linux/scatterlist.h>
-#include <linux/gpio.h>
 
 /* Register offsets */
 #define DW_SPI_CTRL0                   0x00
index 00f46c8..d3336a6 100644 (file)
@@ -377,7 +377,7 @@ static int falcon_sflash_xfer_one(struct spi_master *master,
 
                m->actual_length += t->len;
 
-               WARN_ON(t->delay_usecs || t->cs_change);
+               WARN_ON(t->delay_usecs || t->delay.value || t->cs_change);
                spi_flags = 0;
        }
 
index 7bb018e..442cff7 100644 (file)
@@ -129,6 +129,7 @@ enum dspi_trans_mode {
 struct fsl_dspi_devtype_data {
        enum dspi_trans_mode    trans_mode;
        u8                      max_clock_factor;
+       bool                    ptp_sts_supported;
        bool                    xspi_mode;
 };
 
@@ -140,12 +141,14 @@ static const struct fsl_dspi_devtype_data vf610_data = {
 static const struct fsl_dspi_devtype_data ls1021a_v1_data = {
        .trans_mode             = DSPI_TCFQ_MODE,
        .max_clock_factor       = 8,
+       .ptp_sts_supported      = true,
        .xspi_mode              = true,
 };
 
 static const struct fsl_dspi_devtype_data ls2085a_data = {
        .trans_mode             = DSPI_TCFQ_MODE,
        .max_clock_factor       = 8,
+       .ptp_sts_supported      = true,
 };
 
 static const struct fsl_dspi_devtype_data coldfire_data = {
@@ -654,6 +657,9 @@ static int dspi_rxtx(struct fsl_dspi *dspi)
        u16 spi_tcnt;
        u32 spi_tcr;
 
+       spi_take_timestamp_post(dspi->ctlr, dspi->cur_transfer,
+                               dspi->tx - dspi->bytes_per_word, !dspi->irq);
+
        /* Get transfer counter (in number of SPI transfers). It was
         * reset to 0 when transfer(s) were started.
         */
@@ -672,6 +678,9 @@ static int dspi_rxtx(struct fsl_dspi *dspi)
                /* Success! */
                return 0;
 
+       spi_take_timestamp_pre(dspi->ctlr, dspi->cur_transfer,
+                              dspi->tx, !dspi->irq);
+
        if (trans_mode == DSPI_EOQ_MODE)
                dspi_eoq_write(dspi);
        else if (trans_mode == DSPI_TCFQ_MODE)
@@ -779,6 +788,9 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr,
                                     SPI_FRAME_EBITS(transfer->bits_per_word) |
                                     SPI_CTARE_DTCP(1));
 
+               spi_take_timestamp_pre(dspi->ctlr, dspi->cur_transfer,
+                                      dspi->tx, !dspi->irq);
+
                trans_mode = dspi->devtype_data->trans_mode;
                switch (trans_mode) {
                case DSPI_EOQ_MODE:
@@ -815,8 +827,7 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr,
                        dev_err(&dspi->pdev->dev,
                                "Waiting for transfer to complete failed!\n");
 
-               if (transfer->delay_usecs)
-                       udelay(transfer->delay_usecs);
+               spi_transfer_delay_exec(transfer);
        }
 
 out:
@@ -1006,6 +1017,25 @@ static void dspi_init(struct fsl_dspi *dspi)
                             SPI_CTARE_FMSZE(0) | SPI_CTARE_DTCP(1));
 }
 
+static int dspi_slave_abort(struct spi_master *master)
+{
+       struct fsl_dspi *dspi = spi_master_get_devdata(master);
+
+       /*
+        * Terminate all pending DMA transactions for the SPI working
+        * in SLAVE mode.
+        */
+       dmaengine_terminate_sync(dspi->dma->chan_rx);
+       dmaengine_terminate_sync(dspi->dma->chan_tx);
+
+       /* Clear the internal DSPI RX and TX FIFO buffers */
+       regmap_update_bits(dspi->regmap, SPI_MCR,
+                          SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF,
+                          SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF);
+
+       return 0;
+}
+
 static int dspi_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
@@ -1030,6 +1060,7 @@ static int dspi_probe(struct platform_device *pdev)
        ctlr->dev.of_node = pdev->dev.of_node;
 
        ctlr->cleanup = dspi_cleanup;
+       ctlr->slave_abort = dspi_slave_abort;
        ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
 
        pdata = dev_get_platdata(&pdev->dev);
@@ -1135,6 +1166,7 @@ static int dspi_probe(struct platform_device *pdev)
        init_waitqueue_head(&dspi->waitq);
 
 poll_mode:
+
        if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) {
                ret = dspi_request_dma(dspi, res->start);
                if (ret < 0) {
@@ -1146,6 +1178,8 @@ poll_mode:
        ctlr->max_speed_hz =
                clk_get_rate(dspi->clk) / dspi->devtype_data->max_clock_factor;
 
+       ctlr->ptp_sts_supported = dspi->devtype_data->ptp_sts_supported;
+
        platform_set_drvdata(pdev, ctlr);
 
        ret = spi_register_controller(ctlr);
index f203267..e605812 100644 (file)
@@ -427,8 +427,7 @@ static int fsl_espi_trans(struct spi_message *m, struct spi_transfer *trans)
 
        ret = fsl_espi_bufs(spi, trans);
 
-       if (trans->delay_usecs)
-               udelay(trans->delay_usecs);
+       spi_transfer_delay_exec(trans);
 
        return ret;
 }
@@ -437,6 +436,7 @@ static int fsl_espi_do_one_msg(struct spi_master *master,
                               struct spi_message *m)
 {
        unsigned int delay_usecs = 0, rx_nbits = 0;
+       unsigned int delay_nsecs = 0, delay_nsecs1 = 0;
        struct spi_transfer *t, trans = {};
        int ret;
 
@@ -445,8 +445,16 @@ static int fsl_espi_do_one_msg(struct spi_master *master,
                goto out;
 
        list_for_each_entry(t, &m->transfers, transfer_list) {
-               if (t->delay_usecs > delay_usecs)
-                       delay_usecs = t->delay_usecs;
+               if (t->delay_usecs) {
+                       if (t->delay_usecs > delay_usecs) {
+                               delay_usecs = t->delay_usecs;
+                               delay_nsecs = delay_usecs * 1000;
+                       }
+               } else {
+                       delay_nsecs1 = spi_delay_to_ns(&t->delay, t);
+                       if (delay_nsecs1 > delay_nsecs)
+                               delay_nsecs = delay_nsecs1;
+               }
                if (t->rx_nbits > rx_nbits)
                        rx_nbits = t->rx_nbits;
        }
@@ -457,7 +465,8 @@ static int fsl_espi_do_one_msg(struct spi_master *master,
        trans.len = m->frame_length;
        trans.speed_hz = t->speed_hz;
        trans.bits_per_word = t->bits_per_word;
-       trans.delay_usecs = delay_usecs;
+       trans.delay.value = delay_nsecs;
+       trans.delay.unit = SPI_DELAY_UNIT_NSECS;
        trans.rx_nbits = rx_nbits;
 
        if (trans.len)
index 3528ed5..2cc0ddb 100644 (file)
@@ -675,7 +675,7 @@ static int fsl_lpspi_dma_init(struct device *dev,
        int ret;
 
        /* Prepare for TX DMA: */
-       controller->dma_tx = dma_request_slave_channel_reason(dev, "tx");
+       controller->dma_tx = dma_request_chan(dev, "tx");
        if (IS_ERR(controller->dma_tx)) {
                ret = PTR_ERR(controller->dma_tx);
                dev_dbg(dev, "can't get the TX DMA channel, error %d!\n", ret);
@@ -684,7 +684,7 @@ static int fsl_lpspi_dma_init(struct device *dev,
        }
 
        /* Prepare for RX DMA: */
-       controller->dma_rx = dma_request_slave_channel_reason(dev, "rx");
+       controller->dma_rx = dma_request_chan(dev, "rx");
        if (IS_ERR(controller->dma_rx)) {
                ret = PTR_ERR(controller->dma_rx);
                dev_dbg(dev, "can't get the RX DMA channel, error %d\n", ret);
@@ -779,7 +779,7 @@ static irqreturn_t fsl_lpspi_isr(int irq, void *dev_id)
 
        if (temp_SR & SR_FCF && (temp_IER & IER_FCIE)) {
                writel(SR_FCF, fsl_lpspi->base + IMX7ULP_SR);
-                       complete(&fsl_lpspi->xfer_done);
+               complete(&fsl_lpspi->xfer_done);
                return IRQ_HANDLED;
        }
 
index 63c9f7e..79b1558 100644 (file)
 #define QUADSPI_FLSHCR_TCSH_MASK       GENMASK(11, 8)
 #define QUADSPI_FLSHCR_TDH_MASK                GENMASK(17, 16)
 
+#define QUADSPI_BUF0CR                  0x10
+#define QUADSPI_BUF1CR                  0x14
+#define QUADSPI_BUF2CR                  0x18
+#define QUADSPI_BUFXCR_INVALID_MSTRID   0xe
+
 #define QUADSPI_BUF3CR                 0x1c
 #define QUADSPI_BUF3CR_ALLMST_MASK     BIT(31)
 #define QUADSPI_BUF3CR_ADATSZ(x)       ((x) << 8)
 struct fsl_qspi_devtype_data {
        unsigned int rxfifo;
        unsigned int txfifo;
+       int invalid_mstrid;
        unsigned int ahb_buf_size;
        unsigned int quirks;
        bool little_endian;
@@ -203,6 +209,7 @@ struct fsl_qspi_devtype_data {
 static const struct fsl_qspi_devtype_data vybrid_data = {
        .rxfifo = SZ_128,
        .txfifo = SZ_64,
+       .invalid_mstrid = QUADSPI_BUFXCR_INVALID_MSTRID,
        .ahb_buf_size = SZ_1K,
        .quirks = QUADSPI_QUIRK_SWAP_ENDIAN,
        .little_endian = true,
@@ -211,6 +218,7 @@ static const struct fsl_qspi_devtype_data vybrid_data = {
 static const struct fsl_qspi_devtype_data imx6sx_data = {
        .rxfifo = SZ_128,
        .txfifo = SZ_512,
+       .invalid_mstrid = QUADSPI_BUFXCR_INVALID_MSTRID,
        .ahb_buf_size = SZ_1K,
        .quirks = QUADSPI_QUIRK_4X_INT_CLK | QUADSPI_QUIRK_TKT245618,
        .little_endian = true,
@@ -219,6 +227,7 @@ static const struct fsl_qspi_devtype_data imx6sx_data = {
 static const struct fsl_qspi_devtype_data imx7d_data = {
        .rxfifo = SZ_128,
        .txfifo = SZ_512,
+       .invalid_mstrid = QUADSPI_BUFXCR_INVALID_MSTRID,
        .ahb_buf_size = SZ_1K,
        .quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK |
                  QUADSPI_QUIRK_USE_TDH_SETTING,
@@ -228,6 +237,7 @@ static const struct fsl_qspi_devtype_data imx7d_data = {
 static const struct fsl_qspi_devtype_data imx6ul_data = {
        .rxfifo = SZ_128,
        .txfifo = SZ_512,
+       .invalid_mstrid = QUADSPI_BUFXCR_INVALID_MSTRID,
        .ahb_buf_size = SZ_1K,
        .quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK |
                  QUADSPI_QUIRK_USE_TDH_SETTING,
@@ -237,6 +247,7 @@ static const struct fsl_qspi_devtype_data imx6ul_data = {
 static const struct fsl_qspi_devtype_data ls1021a_data = {
        .rxfifo = SZ_128,
        .txfifo = SZ_64,
+       .invalid_mstrid = QUADSPI_BUFXCR_INVALID_MSTRID,
        .ahb_buf_size = SZ_1K,
        .quirks = 0,
        .little_endian = false,
@@ -246,6 +257,7 @@ static const struct fsl_qspi_devtype_data ls2080a_data = {
        .rxfifo = SZ_128,
        .txfifo = SZ_64,
        .ahb_buf_size = SZ_1K,
+       .invalid_mstrid = 0x0,
        .quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_BASE_INTERNAL,
        .little_endian = true,
 };
@@ -633,6 +645,7 @@ static int fsl_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
        void __iomem *base = q->iobase;
        u32 addr_offset = 0;
        int err = 0;
+       int invalid_mstrid = q->devtype_data->invalid_mstrid;
 
        mutex_lock(&q->lock);
 
@@ -656,6 +669,10 @@ static int fsl_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
        qspi_writel(q, QUADSPI_SPTRCLR_BFPTRC | QUADSPI_SPTRCLR_IPPTRC,
                    base + QUADSPI_SPTRCLR);
 
+       qspi_writel(q, invalid_mstrid, base + QUADSPI_BUF0CR);
+       qspi_writel(q, invalid_mstrid, base + QUADSPI_BUF1CR);
+       qspi_writel(q, invalid_mstrid, base + QUADSPI_BUF2CR);
+
        fsl_qspi_prepare_lut(q, op);
 
        /*
index 4b80ace..114801a 100644 (file)
@@ -416,8 +416,7 @@ static int fsl_spi_do_one_msg(struct spi_master *master,
                }
                m->actual_length += t->len;
 
-               if (t->delay_usecs)
-                       udelay(t->delay_usecs);
+               spi_transfer_delay_exec(t);
 
                if (cs_change) {
                        ndelay(nsecs);
index f9c5bbb..7ceb0ba 100644 (file)
@@ -362,9 +362,6 @@ static int spi_gpio_probe(struct platform_device *pdev)
        struct spi_gpio                 *spi_gpio;
        struct device                   *dev = &pdev->dev;
        struct spi_bitbang              *bb;
-       const struct of_device_id       *of_id;
-
-       of_id = of_match_device(spi_gpio_dt_ids, &pdev->dev);
 
        master = spi_alloc_master(dev, sizeof(*spi_gpio));
        if (!master)
@@ -376,7 +373,7 @@ static int spi_gpio_probe(struct platform_device *pdev)
                return status;
        }
 
-       if (of_id)
+       if (pdev->dev.of_node)
                status = spi_gpio_probe_dt(pdev, master);
        else
                status = spi_gpio_probe_pdata(pdev, master);
index 439b01e..f4a8f47 100644 (file)
@@ -673,6 +673,8 @@ static int img_spfi_probe(struct platform_device *pdev)
                        dma_release_channel(spfi->tx_ch);
                if (spfi->rx_ch)
                        dma_release_channel(spfi->rx_ch);
+               spfi->tx_ch = NULL;
+               spfi->rx_ch = NULL;
                dev_warn(spfi->dev, "Failed to get DMA channels, falling back to PIO mode\n");
        } else {
                master->dma_tx = spfi->tx_ch;
index 09c9a1e..49f0099 100644 (file)
@@ -1272,7 +1272,7 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx,
        spi_imx->wml = spi_imx->devtype_data->fifo_size / 2;
 
        /* Prepare for TX DMA: */
-       master->dma_tx = dma_request_slave_channel_reason(dev, "tx");
+       master->dma_tx = dma_request_chan(dev, "tx");
        if (IS_ERR(master->dma_tx)) {
                ret = PTR_ERR(master->dma_tx);
                dev_dbg(dev, "can't get the TX DMA channel, error %d!\n", ret);
@@ -1281,7 +1281,7 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx,
        }
 
        /* Prepare for RX : */
-       master->dma_rx = dma_request_slave_channel_reason(dev, "rx");
+       master->dma_rx = dma_request_chan(dev, "rx");
        if (IS_ERR(master->dma_rx)) {
                ret = PTR_ERR(master->dma_rx);
                dev_dbg(dev, "can't get the RX DMA channel, error %d\n", ret);
index 9dfe8b0..1fd7ee5 100644 (file)
@@ -797,7 +797,6 @@ static int lantiq_ssc_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct spi_master *master;
-       struct resource *res;
        struct lantiq_ssc_spi *spi;
        const struct lantiq_ssc_hwcfg *hwcfg;
        const struct of_device_id *match;
@@ -812,12 +811,6 @@ static int lantiq_ssc_probe(struct platform_device *pdev)
        }
        hwcfg = match->data;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(dev, "failed to get resources\n");
-               return -ENXIO;
-       }
-
        rx_irq = platform_get_irq_byname(pdev, LTQ_SPI_RX_IRQ_NAME);
        if (rx_irq < 0)
                return -ENXIO;
@@ -839,8 +832,7 @@ static int lantiq_ssc_probe(struct platform_device *pdev)
        spi->dev = dev;
        spi->hwcfg = hwcfg;
        platform_set_drvdata(pdev, spi);
-
-       spi->regbase = devm_ioremap_resource(dev, res);
+       spi->regbase = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(spi->regbase)) {
                err = PTR_ERR(spi->regbase);
                goto err_master_put;
index 6f18d49..b6d79cd 100644 (file)
@@ -298,12 +298,18 @@ static struct spi_test spi_tests[] = {
                        {
                                .tx_buf = TX(0),
                                .rx_buf = RX(0),
-                               .delay_usecs = 1000,
+                               .delay = {
+                                       .value = 1000,
+                                       .unit = SPI_DELAY_UNIT_USECS,
+                               },
                        },
                        {
                                .tx_buf = TX(0),
                                .rx_buf = RX(0),
-                               .delay_usecs = 1000,
+                               .delay = {
+                                       .value = 1000,
+                                       .unit = SPI_DELAY_UNIT_USECS,
+                               },
                        },
                },
        },
@@ -537,7 +543,7 @@ static int spi_test_check_elapsed_time(struct spi_device *spi,
                unsigned long long nbits = (unsigned long long)BITS_PER_BYTE *
                                           xfer->len;
 
-               delay_usecs += xfer->delay_usecs;
+               delay_usecs += xfer->delay.value;
                if (!xfer->speed_hz)
                        continue;
                estimated_time += div_u64(nbits * NSEC_PER_SEC, xfer->speed_hz);
index 9f0fa9f..e5a46f0 100644 (file)
@@ -286,7 +286,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
        if (!spi_mem_internal_supports_op(mem, op))
                return -ENOTSUPP;
 
-       if (ctlr->mem_ops) {
+       if (ctlr->mem_ops && !mem->spi->cs_gpiod) {
                ret = spi_mem_access_start(mem);
                if (ret)
                        return ret;
index a337b84..ea1b079 100644 (file)
@@ -311,8 +311,7 @@ static int mpc512x_psc_spi_msg_xfer(struct spi_master *master,
                        break;
                m->actual_length += t->len;
 
-               if (t->delay_usecs)
-                       udelay(t->delay_usecs);
+               spi_transfer_delay_exec(t);
 
                if (cs_change)
                        mpc512x_psc_spi_deactivate_cs(spi);
index c7e478b..17935e7 100644 (file)
@@ -234,8 +234,7 @@ static void mpc52xx_psc_spi_work(struct work_struct *work)
                                break;
                        m->actual_length += t->len;
 
-                       if (t->delay_usecs)
-                               udelay(t->delay_usecs);
+                       spi_transfer_delay_exec(t);
 
                        if (cs_change)
                                mpc52xx_psc_spi_deactivate_cs(spi);
index 6888a4d..6783e12 100644 (file)
@@ -139,7 +139,6 @@ static const struct mtk_spi_compatible mt8183_compat = {
  * supplies it.
  */
 static const struct mtk_chip_config mtk_default_chip_info = {
-       .cs_pol = 0,
        .sample_sel = 0,
 };
 
@@ -230,10 +229,12 @@ static int mtk_spi_prepare_message(struct spi_master *master,
 #endif
 
        if (mdata->dev_comp->enhance_timing) {
-               if (chip_config->cs_pol)
+               /* set CS polarity */
+               if (spi->mode & SPI_CS_HIGH)
                        reg_val |= SPI_CMD_CS_POL;
                else
                        reg_val &= ~SPI_CMD_CS_POL;
+
                if (chip_config->sample_sel)
                        reg_val |= SPI_CMD_SAMPLE_SEL;
                else
@@ -264,6 +265,9 @@ static void mtk_spi_set_cs(struct spi_device *spi, bool enable)
        u32 reg_val;
        struct mtk_spi *mdata = spi_master_get_devdata(spi->master);
 
+       if (spi->mode & SPI_CS_HIGH)
+               enable = !enable;
+
        reg_val = readl(mdata->base + SPI_CMD_REG);
        if (!enable) {
                reg_val |= SPI_CMD_PAUSE_EN;
@@ -619,7 +623,6 @@ static int mtk_spi_probe(struct platform_device *pdev)
        struct spi_master *master;
        struct mtk_spi *mdata;
        const struct of_device_id *of_id;
-       struct resource *res;
        int i, irq, ret, addr_bits;
 
        master = spi_alloc_master(&pdev->dev, sizeof(*mdata));
@@ -647,6 +650,10 @@ static int mtk_spi_probe(struct platform_device *pdev)
 
        mdata = spi_master_get_devdata(master);
        mdata->dev_comp = of_id->data;
+
+       if (mdata->dev_comp->enhance_timing)
+               master->mode_bits |= SPI_CS_HIGH;
+
        if (mdata->dev_comp->must_tx)
                master->flags = SPI_MASTER_MUST_TX;
 
@@ -682,15 +689,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
        }
 
        platform_set_drvdata(pdev, master);
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               ret = -ENODEV;
-               dev_err(&pdev->dev, "failed to determine base address\n");
-               goto err_put_master;
-       }
-
-       mdata->base = devm_ioremap_resource(&pdev->dev, res);
+       mdata->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(mdata->base)) {
                ret = PTR_ERR(mdata->base);
                goto err_put_master;
index a736fdf..69491f3 100644 (file)
@@ -346,7 +346,7 @@ static bool mxic_spi_mem_supports_op(struct spi_mem *mem,
        if (op->addr.nbytes > 7)
                return false;
 
-       return true;
+       return spi_mem_default_supports_op(mem, op);
 }
 
 static int mxic_spi_mem_exec_op(struct spi_mem *mem,
index b191d57..fe62473 100644 (file)
@@ -293,7 +293,6 @@ static void npcm_pspi_reset_hw(struct npcm_pspi *priv)
 static irqreturn_t npcm_pspi_handler(int irq, void *dev_id)
 {
        struct npcm_pspi *priv = dev_id;
-       u16 val;
        u8 stat;
 
        stat = ioread8(priv->base + NPCM_PSPI_STAT);
@@ -303,7 +302,7 @@ static irqreturn_t npcm_pspi_handler(int irq, void *dev_id)
 
        if (priv->tx_buf) {
                if (stat & NPCM_PSPI_STAT_RBF) {
-                       val = ioread8(NPCM_PSPI_DATA + priv->base);
+                       ioread8(NPCM_PSPI_DATA + priv->base);
                        if (priv->tx_bytes == 0) {
                                npcm_pspi_disable(priv);
                                complete(&priv->xfer_done);
index 501b923..c36bb1b 100644 (file)
@@ -1027,7 +1027,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
 
        ctlr->dev.of_node = np;
 
-       ret = spi_register_controller(ctlr);
+       ret = devm_spi_register_controller(&pdev->dev, ctlr);
        if (ret)
                goto err_destroy_mutex;
 
index b955ca8..5c704ba 100644 (file)
@@ -128,7 +128,7 @@ static void spi100k_write_data(struct spi_master *master, int len, int data)
 
 static int spi100k_read_data(struct spi_master *master, int len)
 {
-       int dataH, dataL;
+       int dataL;
        struct omap1_spi100k *spi100k = spi_master_get_devdata(master);
 
        /* Always do at least 16 bits */
@@ -146,7 +146,7 @@ static int spi100k_read_data(struct spi_master *master, int len)
        udelay(1000);
 
        dataL = readw(spi100k->base + SPI_RX_LSB);
-       dataH = readw(spi100k->base + SPI_RX_MSB);
+       readw(spi100k->base + SPI_RX_MSB);
        spi100k_disable_clock(master);
 
        return dataL;
@@ -321,8 +321,7 @@ static int omap1_spi100k_transfer_one_message(struct spi_master *master,
                        }
                }
 
-               if (t->delay_usecs)
-                       udelay(t->delay_usecs);
+               spi_transfer_delay_exec(t);
 
                /* ignore the "leave it on after last xfer" hint */
 
index 848e03e..7e2292c 100644 (file)
@@ -397,30 +397,26 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi,
 {
        struct omap2_mcspi      *mcspi;
        struct omap2_mcspi_dma  *mcspi_dma;
+       struct dma_async_tx_descriptor *tx;
 
        mcspi = spi_master_get_devdata(spi->master);
        mcspi_dma = &mcspi->dma_channels[spi->chip_select];
 
-       if (mcspi_dma->dma_tx) {
-               struct dma_async_tx_descriptor *tx;
+       dmaengine_slave_config(mcspi_dma->dma_tx, &cfg);
 
-               dmaengine_slave_config(mcspi_dma->dma_tx, &cfg);
-
-               tx = dmaengine_prep_slave_sg(mcspi_dma->dma_tx, xfer->tx_sg.sgl,
-                                            xfer->tx_sg.nents,
-                                            DMA_MEM_TO_DEV,
-                                            DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-               if (tx) {
-                       tx->callback = omap2_mcspi_tx_callback;
-                       tx->callback_param = spi;
-                       dmaengine_submit(tx);
-               } else {
-                       /* FIXME: fall back to PIO? */
-               }
+       tx = dmaengine_prep_slave_sg(mcspi_dma->dma_tx, xfer->tx_sg.sgl,
+                                    xfer->tx_sg.nents,
+                                    DMA_MEM_TO_DEV,
+                                    DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+       if (tx) {
+               tx->callback = omap2_mcspi_tx_callback;
+               tx->callback_param = spi;
+               dmaengine_submit(tx);
+       } else {
+               /* FIXME: fall back to PIO? */
        }
        dma_async_issue_pending(mcspi_dma->dma_tx);
        omap2_mcspi_set_dma_req(spi, 0, 1);
-
 }
 
 static unsigned
@@ -439,6 +435,7 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
        int                     word_len, element_count;
        struct omap2_mcspi_cs   *cs = spi->controller_state;
        void __iomem            *chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0;
+       struct dma_async_tx_descriptor *tx;
 
        mcspi = spi_master_get_devdata(spi->master);
        mcspi_dma = &mcspi->dma_channels[spi->chip_select];
@@ -462,55 +459,47 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
        else /* word_len <= 32 */
                element_count = count >> 2;
 
-       if (mcspi_dma->dma_rx) {
-               struct dma_async_tx_descriptor *tx;
 
-               dmaengine_slave_config(mcspi_dma->dma_rx, &cfg);
+       dmaengine_slave_config(mcspi_dma->dma_rx, &cfg);
 
+       /*
+        *  Reduce DMA transfer length by one more if McSPI is
+        *  configured in turbo mode.
+        */
+       if ((l & OMAP2_MCSPI_CHCONF_TURBO) && mcspi->fifo_depth == 0)
+               transfer_reduction += es;
+
+       if (transfer_reduction) {
+               /* Split sgl into two. The second sgl won't be used. */
+               sizes[0] = count - transfer_reduction;
+               sizes[1] = transfer_reduction;
+               nb_sizes = 2;
+       } else {
                /*
-                *  Reduce DMA transfer length by one more if McSPI is
-                *  configured in turbo mode.
+                * Don't bother splitting the sgl. This essentially
+                * clones the original sgl.
                 */
-               if ((l & OMAP2_MCSPI_CHCONF_TURBO) && mcspi->fifo_depth == 0)
-                       transfer_reduction += es;
-
-               if (transfer_reduction) {
-                       /* Split sgl into two. The second sgl won't be used. */
-                       sizes[0] = count - transfer_reduction;
-                       sizes[1] = transfer_reduction;
-                       nb_sizes = 2;
-               } else {
-                       /*
-                        * Don't bother splitting the sgl. This essentially
-                        * clones the original sgl.
-                        */
-                       sizes[0] = count;
-                       nb_sizes = 1;
-               }
+               sizes[0] = count;
+               nb_sizes = 1;
+       }
 
-               ret = sg_split(xfer->rx_sg.sgl, xfer->rx_sg.nents,
-                              0, nb_sizes,
-                              sizes,
-                              sg_out, out_mapped_nents,
-                              GFP_KERNEL);
+       ret = sg_split(xfer->rx_sg.sgl, xfer->rx_sg.nents, 0, nb_sizes,
+                      sizes, sg_out, out_mapped_nents, GFP_KERNEL);
 
-               if (ret < 0) {
-                       dev_err(&spi->dev, "sg_split failed\n");
-                       return 0;
-               }
+       if (ret < 0) {
+               dev_err(&spi->dev, "sg_split failed\n");
+               return 0;
+       }
 
-               tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx,
-                                            sg_out[0],
-                                            out_mapped_nents[0],
-                                            DMA_DEV_TO_MEM,
-                                            DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-               if (tx) {
-                       tx->callback = omap2_mcspi_rx_callback;
-                       tx->callback_param = spi;
-                       dmaengine_submit(tx);
-               } else {
-                               /* FIXME: fall back to PIO? */
-               }
+       tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, sg_out[0],
+                                    out_mapped_nents[0], DMA_DEV_TO_MEM,
+                                    DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+       if (tx) {
+               tx->callback = omap2_mcspi_rx_callback;
+               tx->callback_param = spi;
+               dmaengine_submit(tx);
+       } else {
+               /* FIXME: fall back to PIO? */
        }
 
        dma_async_issue_pending(mcspi_dma->dma_rx);
index 81c991c..c7266ef 100644 (file)
@@ -467,8 +467,7 @@ orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
                        if (orion_spi_write_read_8bit(spi, &tx, &rx) < 0)
                                goto out;
                        count--;
-                       if (xfer->word_delay_usecs)
-                               udelay(xfer->word_delay_usecs);
+                       spi_delay_exec(&xfer->word_delay, xfer);
                } while (count);
        } else if (word_len == 16) {
                const u16 *tx = xfer->tx_buf;
@@ -478,8 +477,7 @@ orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
                        if (orion_spi_write_read_16bit(spi, &tx, &rx) < 0)
                                goto out;
                        count -= 2;
-                       if (xfer->word_delay_usecs)
-                               udelay(xfer->word_delay_usecs);
+                       spi_delay_exec(&xfer->word_delay, xfer);
                } while (count);
        }
 
index 69f517e..156961b 100644 (file)
@@ -606,25 +606,30 @@ static void pic32_spi_cleanup(struct spi_device *spi)
        gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH));
 }
 
-static void pic32_spi_dma_prep(struct pic32_spi *pic32s, struct device *dev)
+static int pic32_spi_dma_prep(struct pic32_spi *pic32s, struct device *dev)
 {
        struct spi_master *master = pic32s->master;
-       dma_cap_mask_t mask;
+       int ret = 0;
 
-       dma_cap_zero(mask);
-       dma_cap_set(DMA_SLAVE, mask);
+       master->dma_rx = dma_request_chan(dev, "spi-rx");
+       if (IS_ERR(master->dma_rx)) {
+               if (PTR_ERR(master->dma_rx) == -EPROBE_DEFER)
+                       ret = -EPROBE_DEFER;
+               else
+                       dev_warn(dev, "RX channel not found.\n");
 
-       master->dma_rx = dma_request_slave_channel_compat(mask, NULL, NULL,
-                                                         dev, "spi-rx");
-       if (!master->dma_rx) {
-               dev_warn(dev, "RX channel not found.\n");
+               master->dma_rx = NULL;
                goto out_err;
        }
 
-       master->dma_tx = dma_request_slave_channel_compat(mask, NULL, NULL,
-                                                         dev, "spi-tx");
-       if (!master->dma_tx) {
-               dev_warn(dev, "TX channel not found.\n");
+       master->dma_tx = dma_request_chan(dev, "spi-tx");
+       if (IS_ERR(master->dma_tx)) {
+               if (PTR_ERR(master->dma_tx) == -EPROBE_DEFER)
+                       ret = -EPROBE_DEFER;
+               else
+                       dev_warn(dev, "TX channel not found.\n");
+
+               master->dma_tx = NULL;
                goto out_err;
        }
 
@@ -634,14 +639,20 @@ static void pic32_spi_dma_prep(struct pic32_spi *pic32s, struct device *dev)
        /* DMA chnls allocated and prepared */
        set_bit(PIC32F_DMA_PREP, &pic32s->flags);
 
-       return;
+       return 0;
 
 out_err:
-       if (master->dma_rx)
+       if (master->dma_rx) {
                dma_release_channel(master->dma_rx);
+               master->dma_rx = NULL;
+       }
 
-       if (master->dma_tx)
+       if (master->dma_tx) {
                dma_release_channel(master->dma_tx);
+               master->dma_tx = NULL;
+       }
+
+       return ret;
 }
 
 static void pic32_spi_dma_unprep(struct pic32_spi *pic32s)
@@ -776,7 +787,10 @@ static int pic32_spi_probe(struct platform_device *pdev)
        master->unprepare_transfer_hardware     = pic32_spi_unprepare_hardware;
 
        /* optional DMA support */
-       pic32_spi_dma_prep(pic32s, &pdev->dev);
+       ret = pic32_spi_dma_prep(pic32s, &pdev->dev);
+       if (ret)
+               goto err_bailout;
+
        if (test_bit(PIC32F_DMA_PREP, &pic32s->flags))
                master->can_dma = pic32_spi_can_dma;
 
index 7fedea6..66028eb 100644 (file)
@@ -485,12 +485,11 @@ static void giveback(struct pl022 *pl022)
                                        struct spi_transfer, transfer_list);
 
        /* Delay if requested before any change in chip select */
-       if (last_transfer->delay_usecs)
-               /*
-                * FIXME: This runs in interrupt context.
-                * Is this really smart?
-                */
-               udelay(last_transfer->delay_usecs);
+       /*
+        * FIXME: This runs in interrupt context.
+        * Is this really smart?
+        */
+       spi_transfer_delay_exec(last_transfer);
 
        if (!last_transfer->cs_change) {
                struct spi_message *next_msg;
@@ -1159,7 +1158,7 @@ static int pl022_dma_autoprobe(struct pl022 *pl022)
        int err;
 
        /* automatically configure DMA channels from platform, normally using DT */
-       chan = dma_request_slave_channel_reason(dev, "rx");
+       chan = dma_request_chan(dev, "rx");
        if (IS_ERR(chan)) {
                err = PTR_ERR(chan);
                goto err_no_rxchan;
@@ -1167,7 +1166,7 @@ static int pl022_dma_autoprobe(struct pl022 *pl022)
 
        pl022->dma_rx_channel = chan;
 
-       chan = dma_request_slave_channel_reason(dev, "tx");
+       chan = dma_request_chan(dev, "tx");
        if (IS_ERR(chan)) {
                err = PTR_ERR(chan);
                goto err_no_txchan;
@@ -1401,12 +1400,11 @@ static void pump_transfers(unsigned long data)
                previous = list_entry(transfer->transfer_list.prev,
                                        struct spi_transfer,
                                        transfer_list);
-               if (previous->delay_usecs)
-                       /*
-                        * FIXME: This runs in interrupt context.
-                        * Is this really smart?
-                        */
-                       udelay(previous->delay_usecs);
+               /*
+                * FIXME: This runs in interrupt context.
+                * Is this really smart?
+                */
+               spi_transfer_delay_exec(previous);
 
                /* Reselect chip select only if cs_change was requested */
                if (previous->cs_change)
@@ -1520,8 +1518,7 @@ static void do_polling_transfer(struct pl022 *pl022)
                        previous =
                            list_entry(transfer->transfer_list.prev,
                                       struct spi_transfer, transfer_list);
-                       if (previous->delay_usecs)
-                               udelay(previous->delay_usecs);
+                       spi_transfer_delay_exec(previous);
                        if (previous->cs_change)
                                pl022_cs_control(pl022, SSP_CHIP_SELECT);
                } else {
index 1e00912..16b6b2a 100644 (file)
@@ -4,27 +4,29 @@
  * Copyright (C) 2013, Intel Corporation
  */
 
+#include <linux/acpi.h>
 #include <linux/bitops.h>
-#include <linux/init.h>
-#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
 #include <linux/device.h>
-#include <linux/ioport.h>
-#include <linux/errno.h>
 #include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/ioport.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/property.h>
+#include <linux/slab.h>
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/spi/spi.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/gpio/consumer.h>
-#include <linux/slab.h>
-#include <linux/clk.h>
-#include <linux/pm_runtime.h>
-#include <linux/acpi.h>
-#include <linux/of_device.h>
 
 #include "spi-pxa2xx.h"
 
@@ -1480,11 +1482,13 @@ MODULE_DEVICE_TABLE(of, pxa2xx_spi_of_match);
 
 #ifdef CONFIG_ACPI
 
-static int pxa2xx_spi_get_port_id(struct acpi_device *adev)
+static int pxa2xx_spi_get_port_id(struct device *dev)
 {
+       struct acpi_device *adev;
        unsigned int devid;
        int port_id = -1;
 
+       adev = ACPI_COMPANION(dev);
        if (adev && adev->pnp.unique_id &&
            !kstrtouint(adev->pnp.unique_id, 0, &devid))
                port_id = devid;
@@ -1493,7 +1497,7 @@ static int pxa2xx_spi_get_port_id(struct acpi_device *adev)
 
 #else /* !CONFIG_ACPI */
 
-static int pxa2xx_spi_get_port_id(struct acpi_device *adev)
+static int pxa2xx_spi_get_port_id(struct device *dev)
 {
        return -1;
 }
@@ -1514,34 +1518,22 @@ static struct pxa2xx_spi_controller *
 pxa2xx_spi_init_pdata(struct platform_device *pdev)
 {
        struct pxa2xx_spi_controller *pdata;
-       struct acpi_device *adev;
        struct ssp_device *ssp;
        struct resource *res;
-       const struct acpi_device_id *adev_id = NULL;
+       struct device *parent = pdev->dev.parent;
+       struct pci_dev *pcidev = dev_is_pci(parent) ? to_pci_dev(parent) : NULL;
        const struct pci_device_id *pcidev_id = NULL;
-       const struct of_device_id *of_id = NULL;
        enum pxa_ssp_type type;
+       const void *match;
 
-       adev = ACPI_COMPANION(&pdev->dev);
-
-       if (pdev->dev.of_node)
-               of_id = of_match_device(pdev->dev.driver->of_match_table,
-                                       &pdev->dev);
-       else if (dev_is_pci(pdev->dev.parent))
-               pcidev_id = pci_match_id(pxa2xx_spi_pci_compound_match,
-                                        to_pci_dev(pdev->dev.parent));
-       else if (adev)
-               adev_id = acpi_match_device(pdev->dev.driver->acpi_match_table,
-                                           &pdev->dev);
-       else
-               return NULL;
+       if (pcidev)
+               pcidev_id = pci_match_id(pxa2xx_spi_pci_compound_match, pcidev);
 
-       if (adev_id)
-               type = (enum pxa_ssp_type)adev_id->driver_data;
+       match = device_get_match_data(&pdev->dev);
+       if (match)
+               type = (enum pxa_ssp_type)match;
        else if (pcidev_id)
                type = (enum pxa_ssp_type)pcidev_id->driver_data;
-       else if (of_id)
-               type = (enum pxa_ssp_type)of_id->data;
        else
                return NULL;
 
@@ -1560,19 +1552,25 @@ pxa2xx_spi_init_pdata(struct platform_device *pdev)
 
 #ifdef CONFIG_PCI
        if (pcidev_id) {
-               pdata->tx_param = pdev->dev.parent;
-               pdata->rx_param = pdev->dev.parent;
+               pdata->tx_param = parent;
+               pdata->rx_param = parent;
                pdata->dma_filter = pxa2xx_spi_idma_filter;
        }
 #endif
 
        ssp->clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(ssp->clk))
+               return NULL;
+
        ssp->irq = platform_get_irq(pdev, 0);
+       if (ssp->irq < 0)
+               return NULL;
+
        ssp->type = type;
-       ssp->pdev = pdev;
-       ssp->port_id = pxa2xx_spi_get_port_id(adev);
+       ssp->dev = &pdev->dev;
+       ssp->port_id = pxa2xx_spi_get_port_id(&pdev->dev);
 
-       pdata->is_slave = of_property_read_bool(pdev->dev.of_node, "spi-slave");
+       pdata->is_slave = device_property_read_bool(&pdev->dev, "spi-slave");
        pdata->num_chipselect = 1;
        pdata->enable_dma = true;
        pdata->dma_burst_size = 1;
index 2f559e5..dd3434a 100644 (file)
@@ -932,11 +932,11 @@ static int spi_qup_init_dma(struct spi_master *master, resource_size_t base)
        int ret;
 
        /* allocate dma resources, if available */
-       master->dma_rx = dma_request_slave_channel_reason(dev, "rx");
+       master->dma_rx = dma_request_chan(dev, "rx");
        if (IS_ERR(master->dma_rx))
                return PTR_ERR(master->dma_rx);
 
-       master->dma_tx = dma_request_slave_channel_reason(dev, "tx");
+       master->dma_tx = dma_request_chan(dev, "tx");
        if (IS_ERR(master->dma_tx)) {
                ret = PTR_ERR(master->dma_tx);
                goto err_tx;
index 7b7151e..cf67ea6 100644 (file)
@@ -1154,15 +1154,13 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 
        if (!is_polling(sdd)) {
                /* Acquire DMA channels */
-               sdd->rx_dma.ch = dma_request_slave_channel_reason(&pdev->dev,
-                                                                 "rx");
+               sdd->rx_dma.ch = dma_request_chan(&pdev->dev, "rx");
                if (IS_ERR(sdd->rx_dma.ch)) {
                        dev_err(&pdev->dev, "Failed to get RX DMA channel\n");
                        ret = PTR_ERR(sdd->rx_dma.ch);
                        goto err_disable_io_clk;
                }
-               sdd->tx_dma.ch = dma_request_slave_channel_reason(&pdev->dev,
-                                                                 "tx");
+               sdd->tx_dma.ch = dma_request_chan(&pdev->dev, "tx");
                if (IS_ERR(sdd->tx_dma.ch)) {
                        dev_err(&pdev->dev, "Failed to get TX DMA channel\n");
                        ret = PTR_ERR(sdd->tx_dma.ch);
index 11acddc..5497eeb 100644 (file)
@@ -211,8 +211,7 @@ static int sc18is602_transfer_one(struct spi_master *master,
                }
                status = 0;
 
-               if (t->delay_usecs)
-                       udelay(t->delay_usecs);
+               spi_transfer_delay_exec(t);
        }
        m->status = status;
        spi_finalize_current_message(master);
index 7f73f91..a62034e 100644 (file)
@@ -190,8 +190,7 @@ static int hspi_transfer_one_message(struct spi_controller *ctlr,
 
                msg->actual_length += t->len;
 
-               if (t->delay_usecs)
-                       udelay(t->delay_usecs);
+               spi_transfer_delay_exec(t);
 
                if (cs_change) {
                        ndelay(nsecs);
index 61bc43b..44edaa3 100644 (file)
@@ -368,7 +368,6 @@ static int mtk_spi_slave_probe(struct platform_device *pdev)
 {
        struct spi_controller *ctlr;
        struct mtk_spi_slave *mdata;
-       struct resource *res;
        int irq, ret;
 
        ctlr = spi_alloc_slave(&pdev->dev, sizeof(*mdata));
@@ -392,17 +391,8 @@ static int mtk_spi_slave_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, ctlr);
 
        init_completion(&mdata->xfer_done);
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               ret = -ENODEV;
-               dev_err(&pdev->dev, "failed to determine base address\n");
-               goto err_put_ctlr;
-       }
-
        mdata->dev = &pdev->dev;
-
-       mdata->base = devm_ioremap_resource(&pdev->dev, res);
+       mdata->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(mdata->base)) {
                ret = PTR_ERR(mdata->base);
                goto err_put_ctlr;
index 9a05128..87dadb6 100644 (file)
@@ -77,6 +77,7 @@
 
 /* Bits definitions for register REG_WDG_CTRL */
 #define BIT_WDG_RUN                    BIT(1)
+#define BIT_WDG_NEW                    BIT(2)
 #define BIT_WDG_RST                    BIT(3)
 
 /* Registers definitions for PMIC */
@@ -383,6 +384,10 @@ static int sprd_adi_restart_handler(struct notifier_block *this,
        /* Unlock the watchdog */
        sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_LOCK, WDG_UNLOCK_KEY);
 
+       sprd_adi_read(sadi, sadi->slave_pbase + REG_WDG_CTRL, &val);
+       val |= BIT_WDG_NEW;
+       sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_CTRL, val);
+
        /* Load the watchdog timeout value, 50ms is always enough. */
        sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_LOAD_LOW,
                       WDG_LOAD_VAL & WDG_LOAD_MASK);
@@ -393,6 +398,9 @@ static int sprd_adi_restart_handler(struct notifier_block *this,
        val |= BIT_WDG_RUN | BIT_WDG_RST;
        sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_CTRL, val);
 
+       /* Lock the watchdog */
+       sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_LOCK, ~WDG_UNLOCK_KEY);
+
        mdelay(1000);
 
        dev_emerg(sadi->dev, "Unable to restart system\n");
index 8c9021b..2ee1feb 100644 (file)
@@ -669,11 +669,15 @@ static void sprd_spi_set_speed(struct sprd_spi *ss, u32 speed_hz)
        writel_relaxed(clk_div, ss->base + SPRD_SPI_CLKD);
 }
 
-static void sprd_spi_init_hw(struct sprd_spi *ss, struct spi_transfer *t)
+static int sprd_spi_init_hw(struct sprd_spi *ss, struct spi_transfer *t)
 {
+       struct spi_delay *d = &t->word_delay;
        u16 word_delay, interval;
        u32 val;
 
+       if (d->unit != SPI_DELAY_UNIT_SCK)
+               return -EINVAL;
+
        val = readl_relaxed(ss->base + SPRD_SPI_CTL7);
        val &= ~(SPRD_SPI_SCK_REV | SPRD_SPI_NG_TX | SPRD_SPI_NG_RX);
        /* Set default chip selection, clock phase and clock polarity */
@@ -686,7 +690,7 @@ static void sprd_spi_init_hw(struct sprd_spi *ss, struct spi_transfer *t)
         * formula as below per datasheet:
         * interval time (source clock cycles) = interval * 4 + 10.
         */
-       word_delay = clamp_t(u16, t->word_delay, SPRD_SPI_MIN_DELAY_CYCLE,
+       word_delay = clamp_t(u16, d->value, SPRD_SPI_MIN_DELAY_CYCLE,
                             SPRD_SPI_MAX_DELAY_CYCLE);
        interval = DIV_ROUND_UP(word_delay - 10, 4);
        ss->word_delay = interval * 4 + 10;
@@ -711,6 +715,8 @@ static void sprd_spi_init_hw(struct sprd_spi *ss, struct spi_transfer *t)
                val &= ~SPRD_SPI_DATA_LINE2_EN;
 
        writel_relaxed(val, ss->base + SPRD_SPI_CTL7);
+
+       return 0;
 }
 
 static int sprd_spi_setup_transfer(struct spi_device *sdev,
@@ -719,13 +725,16 @@ static int sprd_spi_setup_transfer(struct spi_device *sdev,
        struct sprd_spi *ss = spi_controller_get_devdata(sdev->controller);
        u8 bits_per_word = t->bits_per_word;
        u32 val, mode = 0;
+       int ret;
 
        ss->len = t->len;
        ss->tx_buf = t->tx_buf;
        ss->rx_buf = t->rx_buf;
 
        ss->hw_mode = sdev->mode;
-       sprd_spi_init_hw(ss, t);
+       ret = sprd_spi_init_hw(ss, t);
+       if (ret)
+               return ret;
 
        /* Set tansfer speed and valid bits */
        sprd_spi_set_speed(ss, t->speed_hz);
index 0c24c49..77d26d6 100644 (file)
@@ -381,6 +381,7 @@ static int spi_st_probe(struct platform_device *pdev)
        return 0;
 
 clk_disable:
+       pm_runtime_disable(&pdev->dev);
        clk_disable_unprepare(spi_st->clk);
 put_master:
        spi_master_put(master);
@@ -392,6 +393,8 @@ static int spi_st_remove(struct platform_device *pdev)
        struct spi_master *master = platform_get_drvdata(pdev);
        struct spi_st *spi_st = spi_master_get_devdata(master);
 
+       pm_runtime_disable(&pdev->dev);
+
        clk_disable_unprepare(spi_st->clk);
 
        pinctrl_pm_select_sleep_state(&pdev->dev);
index 39374c2..fc40ab1 100644 (file)
@@ -666,8 +666,7 @@ static int tegra_spi_init_dma_param(struct tegra_spi_data *tspi,
        dma_addr_t dma_phys;
        int ret;
 
-       dma_chan = dma_request_slave_channel_reason(tspi->dev,
-                                       dma_to_memory ? "rx" : "tx");
+       dma_chan = dma_request_chan(tspi->dev, dma_to_memory ? "rx" : "tx");
        if (IS_ERR(dma_chan)) {
                ret = PTR_ERR(dma_chan);
                if (ret != -EPROBE_DEFER)
@@ -723,15 +722,31 @@ static void tegra_spi_deinit_dma_param(struct tegra_spi_data *tspi,
        dma_release_channel(dma_chan);
 }
 
-static void tegra_spi_set_hw_cs_timing(struct spi_device *spi, u8 setup_dly,
-                                      u8 hold_dly, u8 inactive_dly)
+static int tegra_spi_set_hw_cs_timing(struct spi_device *spi,
+                                     struct spi_delay *setup,
+                                     struct spi_delay *hold,
+                                     struct spi_delay *inactive)
 {
        struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master);
+       u8 setup_dly, hold_dly, inactive_dly;
        u32 setup_hold;
        u32 spi_cs_timing;
        u32 inactive_cycles;
        u8 cs_state;
 
+       if ((setup && setup->unit != SPI_DELAY_UNIT_SCK) ||
+           (hold && hold->unit != SPI_DELAY_UNIT_SCK) ||
+           (inactive && inactive->unit != SPI_DELAY_UNIT_SCK)) {
+               dev_err(&spi->dev,
+                       "Invalid delay unit %d, should be SPI_DELAY_UNIT_SCK\n",
+                       SPI_DELAY_UNIT_SCK);
+               return -EINVAL;
+       }
+
+       setup_dly = setup ? setup->value : 0;
+       hold_dly = hold ? hold->value : 0;
+       inactive_dly = inactive ? inactive->value : 0;
+
        setup_dly = min_t(u8, setup_dly, MAX_SETUP_HOLD_CYCLES);
        hold_dly = min_t(u8, hold_dly, MAX_SETUP_HOLD_CYCLES);
        if (setup_dly && hold_dly) {
@@ -758,6 +773,8 @@ static void tegra_spi_set_hw_cs_timing(struct spi_device *spi, u8 setup_dly,
                tspi->spi_cs_timing2 = spi_cs_timing;
                tegra_spi_writel(tspi, spi_cs_timing, SPI_CS_TIMING2);
        }
+
+       return 0;
 }
 
 static u32 tegra_spi_setup_transfer_one(struct spi_device *spi,
@@ -984,17 +1001,6 @@ static int tegra_spi_setup(struct spi_device *spi)
        return 0;
 }
 
-static void tegra_spi_transfer_delay(int delay)
-{
-       if (!delay)
-               return;
-
-       if (delay >= 1000)
-               mdelay(delay / 1000);
-
-       udelay(delay % 1000);
-}
-
 static void tegra_spi_transfer_end(struct spi_device *spi)
 {
        struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master);
@@ -1098,7 +1104,7 @@ static int tegra_spi_transfer_one_message(struct spi_master *master,
 complete_xfer:
                if (ret < 0 || skip) {
                        tegra_spi_transfer_end(spi);
-                       tegra_spi_transfer_delay(xfer->delay_usecs);
+                       spi_transfer_delay_exec(xfer);
                        goto exit;
                } else if (list_is_last(&xfer->transfer_list,
                                        &msg->transfers)) {
@@ -1106,11 +1112,11 @@ complete_xfer:
                                tspi->cs_control = spi;
                        else {
                                tegra_spi_transfer_end(spi);
-                               tegra_spi_transfer_delay(xfer->delay_usecs);
+                               spi_transfer_delay_exec(xfer);
                        }
                } else if (xfer->cs_change) {
                        tegra_spi_transfer_end(spi);
-                       tegra_spi_transfer_delay(xfer->delay_usecs);
+                       spi_transfer_delay_exec(xfer);
                }
 
        }
index a841a72..5144293 100644 (file)
@@ -341,10 +341,11 @@ static int tegra_sflash_transfer_one_message(struct spi_master *master,
                        goto exit;
                }
                msg->actual_length += xfer->len;
-               if (xfer->cs_change && xfer->delay_usecs) {
+               if (xfer->cs_change &&
+                   (xfer->delay_usecs || xfer->delay.value)) {
                        tegra_sflash_writel(tsd, tsd->def_command_reg,
                                        SPI_COMMAND);
-                       udelay(xfer->delay_usecs);
+                       spi_transfer_delay_exec(xfer);
                }
        }
        ret = 0;
index 111fffc..7f4d932 100644 (file)
@@ -599,8 +599,7 @@ static int tegra_slink_init_dma_param(struct tegra_slink_data *tspi,
        int ret;
        struct dma_slave_config dma_sconfig;
 
-       dma_chan = dma_request_slave_channel_reason(tspi->dev,
-                                               dma_to_memory ? "rx" : "tx");
+       dma_chan = dma_request_chan(tspi->dev, dma_to_memory ? "rx" : "tx");
        if (IS_ERR(dma_chan)) {
                ret = PTR_ERR(dma_chan);
                if (ret != -EPROBE_DEFER)
@@ -1073,7 +1072,7 @@ static int tegra_slink_probe(struct platform_device *pdev)
        ret = clk_enable(tspi->clk);
        if (ret < 0) {
                dev_err(&pdev->dev, "Clock enable failed %d\n", ret);
-               goto exit_free_master;
+               goto exit_clk_unprepare;
        }
 
        spi_irq = platform_get_irq(pdev, 0);
@@ -1146,6 +1145,8 @@ exit_free_irq:
        free_irq(spi_irq, tspi);
 exit_clk_disable:
        clk_disable(tspi->clk);
+exit_clk_unprepare:
+       clk_unprepare(tspi->clk);
 exit_free_master:
        spi_master_put(master);
        return ret;
@@ -1159,6 +1160,7 @@ static int tegra_slink_remove(struct platform_device *pdev)
        free_irq(tspi->irq, tspi);
 
        clk_disable(tspi->clk);
+       clk_unprepare(tspi->clk);
 
        if (tspi->tx_dma_chan)
                tegra_slink_deinit_dma_param(tspi, false);
index f88cbb9..223353f 100644 (file)
@@ -1229,12 +1229,7 @@ static void pch_spi_process_messages(struct work_struct *pwork)
                        "%s:data->current_msg->actual_length=%d\n",
                        __func__, data->current_msg->actual_length);
 
-               /* check for delay */
-               if (data->cur_trans->delay_usecs) {
-                       dev_dbg(&data->master->dev, "%s:delay in usec=%d\n",
-                               __func__, data->cur_trans->delay_usecs);
-                       udelay(data->cur_trans->delay_usecs);
-               }
+               spi_transfer_delay_exec(data->cur_trans);
 
                spin_lock(&data->lock);
 
index 51759d3..3606232 100644 (file)
@@ -26,7 +26,8 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/module.h>
-#include <linux/gpio.h>
+#include <linux/gpio/machine.h>
+#include <linux/gpio/consumer.h>
 
 
 #define SPI_FIFO_SIZE 4
@@ -79,7 +80,7 @@ struct txx9spi {
        void __iomem *membase;
        int baseclk;
        struct clk *clk;
-       int last_chipselect;
+       struct gpio_desc *last_chipselect;
        int last_chipselect_val;
 };
 
@@ -95,20 +96,22 @@ static void txx9spi_wr(struct txx9spi *c, u32 val, int reg)
 static void txx9spi_cs_func(struct spi_device *spi, struct txx9spi *c,
                int on, unsigned int cs_delay)
 {
-       int val = (spi->mode & SPI_CS_HIGH) ? on : !on;
-
+       /*
+        * The GPIO descriptor will track polarity inversion inside
+        * gpiolib.
+        */
        if (on) {
                /* deselect the chip with cs_change hint in last transfer */
-               if (c->last_chipselect >= 0)
-                       gpio_set_value(c->last_chipselect,
+               if (c->last_chipselect)
+                       gpiod_set_value(c->last_chipselect,
                                        !c->last_chipselect_val);
-               c->last_chipselect = spi->chip_select;
-               c->last_chipselect_val = val;
+               c->last_chipselect = spi->cs_gpiod;
+               c->last_chipselect_val = on;
        } else {
-               c->last_chipselect = -1;
+               c->last_chipselect = NULL;
                ndelay(cs_delay);       /* CS Hold Time */
        }
-       gpio_set_value(spi->chip_select, val);
+       gpiod_set_value(spi->cs_gpiod, on);
        ndelay(cs_delay);       /* CS Setup Time / CS Recovery Time */
 }
 
@@ -119,12 +122,6 @@ static int txx9spi_setup(struct spi_device *spi)
        if (!spi->max_speed_hz)
                return -EINVAL;
 
-       if (gpio_direction_output(spi->chip_select,
-                       !(spi->mode & SPI_CS_HIGH))) {
-               dev_err(&spi->dev, "Cannot setup GPIO for chipselect.\n");
-               return -EINVAL;
-       }
-
        /* deselect chip */
        spin_lock(&c->lock);
        txx9spi_cs_func(spi, c, 0, (NSEC_PER_SEC / 2) / spi->max_speed_hz);
@@ -248,8 +245,7 @@ static void txx9spi_work_one(struct txx9spi *c, struct spi_message *m)
                        len -= count * wsize;
                }
                m->actual_length += t->len;
-               if (t->delay_usecs)
-                       udelay(t->delay_usecs);
+               spi_transfer_delay_exec(t);
 
                if (!cs_change)
                        continue;
@@ -320,6 +316,47 @@ static int txx9spi_transfer(struct spi_device *spi, struct spi_message *m)
        return 0;
 }
 
+/*
+ * Chip select uses GPIO only, further the driver is using the chip select
+ * numer (from the device tree "reg" property, and this can only come from
+ * device tree since this i MIPS and there is no way to pass platform data) as
+ * the GPIO number. As the platform has only one GPIO controller (the txx9 GPIO
+ * chip) it is thus using the chip select number as an offset into that chip.
+ * This chip has a maximum of 16 GPIOs 0..15 and this is what all platforms
+ * register.
+ *
+ * We modernized this behaviour by explicitly converting that offset to an
+ * offset on the GPIO chip using a GPIO descriptor machine table of the same
+ * size as the txx9 GPIO chip with a 1-to-1 mapping of chip select to GPIO
+ * offset.
+ *
+ * This is admittedly a hack, but it is countering the hack of using "reg" to
+ * contain a GPIO offset when it should be using "cs-gpios" as the SPI bindings
+ * state.
+ */
+static struct gpiod_lookup_table txx9spi_cs_gpio_table = {
+       .dev_id = "spi0",
+       .table = {
+               GPIO_LOOKUP_IDX("TXx9", 0, "cs", 0, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("TXx9", 1, "cs", 1, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("TXx9", 2, "cs", 2, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("TXx9", 3, "cs", 3, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("TXx9", 4, "cs", 4, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("TXx9", 5, "cs", 5, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("TXx9", 6, "cs", 6, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("TXx9", 7, "cs", 7, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("TXx9", 8, "cs", 8, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("TXx9", 9, "cs", 9, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("TXx9", 10, "cs", 10, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("TXx9", 11, "cs", 11, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("TXx9", 12, "cs", 12, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("TXx9", 13, "cs", 13, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("TXx9", 14, "cs", 14, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("TXx9", 15, "cs", 15, GPIO_ACTIVE_LOW),
+               { },
+       },
+};
+
 static int txx9spi_probe(struct platform_device *dev)
 {
        struct spi_master *master;
@@ -373,12 +410,14 @@ static int txx9spi_probe(struct platform_device *dev)
        if (ret)
                goto exit;
 
-       c->last_chipselect = -1;
+       c->last_chipselect = NULL;
 
        dev_info(&dev->dev, "at %#llx, irq %d, %dMHz\n",
                 (unsigned long long)res->start, irq,
                 (c->baseclk + 500000) / 1000000);
 
+       gpiod_add_lookup_table(&txx9spi_cs_gpio_table);
+
        /* the spi->mode bits understood by this driver: */
        master->mode_bits = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA;
 
@@ -387,6 +426,7 @@ static int txx9spi_probe(struct platform_device *dev)
        master->transfer = txx9spi_transfer;
        master->num_chipselect = (u16)UINT_MAX; /* any GPIO numbers */
        master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
+       master->use_gpio_descriptors = true;
 
        ret = devm_spi_register_master(&dev->dev, master);
        if (ret)
index a3496c4..1d9b3f0 100644 (file)
@@ -188,8 +188,7 @@ static int spi_xcomm_transfer_one(struct spi_master *master,
                }
                status = 0;
 
-               if (t->delay_usecs)
-                       udelay(t->delay_usecs);
+               spi_transfer_delay_exec(t);
 
                is_first = false;
        }
index d5f9d5f..8dd2bb9 100644 (file)
@@ -391,7 +391,7 @@ static int xilinx_spi_probe(struct platform_device *pdev)
        struct xilinx_spi *xspi;
        struct xspi_platform_data *pdata;
        struct resource *res;
-       int ret, num_cs = 0, bits_per_word = 8;
+       int ret, num_cs = 0, bits_per_word;
        struct spi_master *master;
        u32 tmp;
        u8 i;
@@ -403,6 +403,11 @@ static int xilinx_spi_probe(struct platform_device *pdev)
        } else {
                of_property_read_u32(pdev->dev.of_node, "xlnx,num-ss-bits",
                                          &num_cs);
+               ret = of_property_read_u32(pdev->dev.of_node,
+                                          "xlnx,num-transfer-bits",
+                                          &bits_per_word);
+               if (ret)
+                       bits_per_word = 8;
        }
 
        if (!num_cs) {
index 86516eb..fc2b5eb 100644 (file)
@@ -80,7 +80,6 @@ static void xtfpga_spi_chipselect(struct spi_device *spi, int is_on)
 static int xtfpga_spi_probe(struct platform_device *pdev)
 {
        struct xtfpga_spi *xspi;
-       struct resource *mem;
        int ret;
        struct spi_master *master;
 
@@ -97,14 +96,7 @@ static int xtfpga_spi_probe(struct platform_device *pdev)
        xspi->bitbang.master = master;
        xspi->bitbang.chipselect = xtfpga_spi_chipselect;
        xspi->bitbang.txrx_word[SPI_MODE_0] = xtfpga_spi_txrx_word;
-
-       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!mem) {
-               dev_err(&pdev->dev, "No memory resource\n");
-               ret = -ENODEV;
-               goto err;
-       }
-       xspi->regs = devm_ioremap_resource(&pdev->dev, mem);
+       xspi->regs = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(xspi->regs)) {
                ret = PTR_ERR(xspi->regs);
                goto err;
index 5cf6993..1764115 100644 (file)
@@ -7,7 +7,6 @@
 
 #include <linux/clk.h>
 #include <linux/delay.h>
-#include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/module.h>
@@ -51,7 +50,6 @@
 #define ZYNQ_QSPI_CONFIG_BDRATE_MASK   GENMASK(5, 3) /* Baud Rate Mask */
 #define ZYNQ_QSPI_CONFIG_CPHA_MASK     BIT(2) /* Clock Phase Control */
 #define ZYNQ_QSPI_CONFIG_CPOL_MASK     BIT(1) /* Clock Polarity Control */
-#define ZYNQ_QSPI_CONFIG_SSCTRL_MASK   BIT(10) /* Slave Select Mask */
 #define ZYNQ_QSPI_CONFIG_FWIDTH_MASK   GENMASK(7, 6) /* FIFO width */
 #define ZYNQ_QSPI_CONFIG_MSTREN_MASK   BIT(0) /* Master Mode */
 
@@ -61,9 +59,9 @@
  * These are the values used in the calculation of baud rate divisor and
  * setting the slave select.
  */
-#define ZYNQ_QSPI_BAUD_DIV_MAX         GENMASK(2, 0) /* Baud rate maximum */
-#define ZYNQ_QSPI_BAUD_DIV_SHIFT       3 /* Baud rate divisor shift in CR */
-#define ZYNQ_QSPI_SS_SHIFT             10 /* Slave Select field shift in CR */
+#define ZYNQ_QSPI_CONFIG_BAUD_DIV_MAX  GENMASK(2, 0) /* Baud rate maximum */
+#define ZYNQ_QSPI_CONFIG_BAUD_DIV_SHIFT        3 /* Baud rate divisor shift */
+#define ZYNQ_QSPI_CONFIG_PCS           BIT(10) /* Peripheral Chip Select */
 
 /*
  * QSPI Interrupt Registers bit Masks
@@ -99,9 +97,9 @@
  * It is named Linear Configuration but it controls other modes when not in
  * linear mode also.
  */
-#define ZYNQ_QSPI_LCFG_TWO_MEM_MASK    BIT(30) /* LQSPI Two memories Mask */
-#define ZYNQ_QSPI_LCFG_SEP_BUS_MASK    BIT(29) /* LQSPI Separate bus Mask */
-#define ZYNQ_QSPI_LCFG_U_PAGE_MASK     BIT(28) /* LQSPI Upper Page Mask */
+#define ZYNQ_QSPI_LCFG_TWO_MEM         BIT(30) /* LQSPI Two memories */
+#define ZYNQ_QSPI_LCFG_SEP_BUS         BIT(29) /* LQSPI Separate bus */
+#define ZYNQ_QSPI_LCFG_U_PAGE          BIT(28) /* LQSPI Upper Page */
 
 #define ZYNQ_QSPI_LCFG_DUMMY_SHIFT     8
 
  */
 #define ZYNQ_QSPI_MODEBITS                     (SPI_CPOL | SPI_CPHA)
 
-/* Default number of chip selects */
-#define ZYNQ_QSPI_DEFAULT_NUM_CS       1
+/* Maximum number of chip selects */
+#define ZYNQ_QSPI_MAX_NUM_CS           2
 
 /**
  * struct zynq_qspi - Defines qspi driver instance
@@ -161,6 +159,7 @@ static inline void zynq_qspi_write(struct zynq_qspi *xqspi, u32 offset,
 /**
  * zynq_qspi_init_hw - Initialize the hardware
  * @xqspi:     Pointer to the zynq_qspi structure
+ * @num_cs:    Number of connected CS (to enable dual memories if needed)
  *
  * The default settings of the QSPI controller's configurable parameters on
  * reset are
@@ -178,7 +177,7 @@ static inline void zynq_qspi_write(struct zynq_qspi *xqspi, u32 offset,
  *     - Set the little endian mode of TX FIFO and
  *     - Enable the QSPI controller
  */
-static void zynq_qspi_init_hw(struct zynq_qspi *xqspi)
+static void zynq_qspi_init_hw(struct zynq_qspi *xqspi, unsigned int num_cs)
 {
        u32 config_reg;
 
@@ -186,7 +185,12 @@ static void zynq_qspi_init_hw(struct zynq_qspi *xqspi)
        zynq_qspi_write(xqspi, ZYNQ_QSPI_IDIS_OFFSET, ZYNQ_QSPI_IXR_ALL_MASK);
 
        /* Disable linear mode as the boot loader may have used it */
-       zynq_qspi_write(xqspi, ZYNQ_QSPI_LINEAR_CFG_OFFSET, 0);
+       config_reg = 0;
+       /* At the same time, enable dual mode if more than 1 CS is available */
+       if (num_cs > 1)
+               config_reg |= ZYNQ_QSPI_LCFG_TWO_MEM;
+
+       zynq_qspi_write(xqspi, ZYNQ_QSPI_LINEAR_CFG_OFFSET, config_reg);
 
        /* Clear the RX FIFO */
        while (zynq_qspi_read(xqspi, ZYNQ_QSPI_STATUS_OFFSET) &
@@ -284,21 +288,28 @@ static void zynq_qspi_txfifo_op(struct zynq_qspi *xqspi, unsigned int size)
  */
 static void zynq_qspi_chipselect(struct spi_device *spi, bool assert)
 {
-       struct spi_controller *ctrl = spi->master;
-       struct zynq_qspi *xqspi = spi_controller_get_devdata(ctrl);
+       struct spi_controller *ctlr = spi->master;
+       struct zynq_qspi *xqspi = spi_controller_get_devdata(ctlr);
        u32 config_reg;
 
-       config_reg = zynq_qspi_read(xqspi, ZYNQ_QSPI_CONFIG_OFFSET);
-       if (assert) {
-               /* Select the slave */
-               config_reg &= ~ZYNQ_QSPI_CONFIG_SSCTRL_MASK;
-               config_reg |= (((~(BIT(spi->chip_select))) <<
-                               ZYNQ_QSPI_SS_SHIFT) &
-                               ZYNQ_QSPI_CONFIG_SSCTRL_MASK);
-       } else {
-               config_reg |= ZYNQ_QSPI_CONFIG_SSCTRL_MASK;
+       /* Select the lower (CS0) or upper (CS1) memory */
+       if (ctlr->num_chipselect > 1) {
+               config_reg = zynq_qspi_read(xqspi, ZYNQ_QSPI_LINEAR_CFG_OFFSET);
+               if (!spi->chip_select)
+                       config_reg &= ~ZYNQ_QSPI_LCFG_U_PAGE;
+               else
+                       config_reg |= ZYNQ_QSPI_LCFG_U_PAGE;
+
+               zynq_qspi_write(xqspi, ZYNQ_QSPI_LINEAR_CFG_OFFSET, config_reg);
        }
 
+       /* Ground the line to assert the CS */
+       config_reg = zynq_qspi_read(xqspi, ZYNQ_QSPI_CONFIG_OFFSET);
+       if (assert)
+               config_reg &= ~ZYNQ_QSPI_CONFIG_PCS;
+       else
+               config_reg |= ZYNQ_QSPI_CONFIG_PCS;
+
        zynq_qspi_write(xqspi, ZYNQ_QSPI_CONFIG_OFFSET, config_reg);
 }
 
@@ -332,7 +343,7 @@ static int zynq_qspi_config_op(struct zynq_qspi *xqspi, struct spi_device *spi)
         *      ----------------
         *      111 - divide by 256
         */
-       while ((baud_rate_val < ZYNQ_QSPI_BAUD_DIV_MAX)  &&
+       while ((baud_rate_val < ZYNQ_QSPI_CONFIG_BAUD_DIV_MAX)  &&
               (clk_get_rate(xqspi->refclk) / (2 << baud_rate_val)) >
                spi->max_speed_hz)
                baud_rate_val++;
@@ -348,7 +359,7 @@ static int zynq_qspi_config_op(struct zynq_qspi *xqspi, struct spi_device *spi)
                config_reg |= ZYNQ_QSPI_CONFIG_CPOL_MASK;
 
        config_reg &= ~ZYNQ_QSPI_CONFIG_BDRATE_MASK;
-       config_reg |= (baud_rate_val << ZYNQ_QSPI_BAUD_DIV_SHIFT);
+       config_reg |= (baud_rate_val << ZYNQ_QSPI_CONFIG_BAUD_DIV_SHIFT);
        zynq_qspi_write(xqspi, ZYNQ_QSPI_CONFIG_OFFSET, config_reg);
 
        return 0;
@@ -365,10 +376,10 @@ static int zynq_qspi_config_op(struct zynq_qspi *xqspi, struct spi_device *spi)
  */
 static int zynq_qspi_setup_op(struct spi_device *spi)
 {
-       struct spi_controller *ctrl = spi->master;
-       struct zynq_qspi *qspi = spi_controller_get_devdata(ctrl);
+       struct spi_controller *ctlr = spi->master;
+       struct zynq_qspi *qspi = spi_controller_get_devdata(ctlr);
 
-       if (ctrl->busy)
+       if (ctlr->busy)
                return -EBUSY;
 
        clk_enable(qspi->refclk);
@@ -663,9 +674,6 @@ static int zynq_qspi_probe(struct platform_device *pdev)
                goto clk_dis_pclk;
        }
 
-       /* QSPI controller initializations */
-       zynq_qspi_init_hw(xqspi);
-
        xqspi->irq = platform_get_irq(pdev, 0);
        if (xqspi->irq <= 0) {
                ret = -ENXIO;
@@ -681,10 +689,14 @@ static int zynq_qspi_probe(struct platform_device *pdev)
 
        ret = of_property_read_u32(np, "num-cs",
                                   &num_cs);
-       if (ret < 0)
-               ctlr->num_chipselect = ZYNQ_QSPI_DEFAULT_NUM_CS;
-       else
+       if (ret < 0) {
+               ctlr->num_chipselect = 1;
+       } else if (num_cs > ZYNQ_QSPI_MAX_NUM_CS) {
+               dev_err(&pdev->dev, "only 2 chip selects are available\n");
+               goto remove_master;
+       } else {
                ctlr->num_chipselect = num_cs;
+       }
 
        ctlr->mode_bits =  SPI_RX_DUAL | SPI_RX_QUAD |
                            SPI_TX_DUAL | SPI_TX_QUAD;
@@ -692,6 +704,10 @@ static int zynq_qspi_probe(struct platform_device *pdev)
        ctlr->setup = zynq_qspi_setup_op;
        ctlr->max_speed_hz = clk_get_rate(xqspi->refclk) / 2;
        ctlr->dev.of_node = np;
+
+       /* QSPI controller initializations */
+       zynq_qspi_init_hw(xqspi, ctlr->num_chipselect);
+
        ret = devm_spi_register_controller(&pdev->dev, ctlr);
        if (ret) {
                dev_err(&pdev->dev, "spi_register_master failed\n");
index 26b91ee..5e4c453 100644 (file)
@@ -92,7 +92,7 @@ static ssize_t driver_override_store(struct device *dev,
        if (len) {
                spi->driver_override = driver_override;
        } else {
-               /* Emptry string, disable driver override */
+               /* Empty string, disable driver override */
                spi->driver_override = NULL;
                kfree(driver_override);
        }
@@ -469,7 +469,7 @@ static LIST_HEAD(board_list);
 static LIST_HEAD(spi_controller_list);
 
 /*
- * Used to protect add/del opertion for board_info list and
+ * Used to protect add/del operation for board_info list and
  * spi_controller list, and their matching process
  * also used to protect object of type struct idr
  */
@@ -775,6 +775,15 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n)
 
 static void spi_set_cs(struct spi_device *spi, bool enable)
 {
+       bool enable1 = enable;
+
+       if (!spi->controller->set_cs_timing) {
+               if (enable1)
+                       spi_delay_exec(&spi->controller->cs_setup, NULL);
+               else
+                       spi_delay_exec(&spi->controller->cs_hold, NULL);
+       }
+
        if (spi->mode & SPI_CS_HIGH)
                enable = !enable;
 
@@ -800,6 +809,11 @@ static void spi_set_cs(struct spi_device *spi, bool enable)
        } else if (spi->controller->set_cs) {
                spi->controller->set_cs(spi, !enable);
        }
+
+       if (!spi->controller->set_cs_timing) {
+               if (!enable1)
+                       spi_delay_exec(&spi->controller->cs_inactive, NULL);
+       }
 }
 
 #ifdef CONFIG_HAS_DMA
@@ -1106,42 +1120,79 @@ static void _spi_transfer_delay_ns(u32 ns)
        }
 }
 
-static void _spi_transfer_cs_change_delay(struct spi_message *msg,
-                                         struct spi_transfer *xfer)
+int spi_delay_to_ns(struct spi_delay *_delay, struct spi_transfer *xfer)
 {
-       u32 delay = xfer->cs_change_delay;
-       u32 unit = xfer->cs_change_delay_unit;
+       u32 delay = _delay->value;
+       u32 unit = _delay->unit;
        u32 hz;
 
-       /* return early on "fast" mode - for everything but USECS */
-       if (!delay && unit != SPI_DELAY_UNIT_USECS)
-               return;
+       if (!delay)
+               return 0;
 
        switch (unit) {
        case SPI_DELAY_UNIT_USECS:
-               /* for compatibility use default of 10us */
-               if (!delay)
-                       delay = 10000;
-               else
-                       delay *= 1000;
+               delay *= 1000;
                break;
        case SPI_DELAY_UNIT_NSECS: /* nothing to do here */
                break;
        case SPI_DELAY_UNIT_SCK:
+               /* clock cycles need to be obtained from spi_transfer */
+               if (!xfer)
+                       return -EINVAL;
                /* if there is no effective speed know, then approximate
                 * by underestimating with half the requested hz
                 */
                hz = xfer->effective_speed_hz ?: xfer->speed_hz / 2;
+               if (!hz)
+                       return -EINVAL;
                delay *= DIV_ROUND_UP(1000000000, hz);
                break;
        default:
+               return -EINVAL;
+       }
+
+       return delay;
+}
+EXPORT_SYMBOL_GPL(spi_delay_to_ns);
+
+int spi_delay_exec(struct spi_delay *_delay, struct spi_transfer *xfer)
+{
+       int delay;
+
+       if (!_delay)
+               return -EINVAL;
+
+       delay = spi_delay_to_ns(_delay, xfer);
+       if (delay < 0)
+               return delay;
+
+       _spi_transfer_delay_ns(delay);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(spi_delay_exec);
+
+static void _spi_transfer_cs_change_delay(struct spi_message *msg,
+                                         struct spi_transfer *xfer)
+{
+       u32 delay = xfer->cs_change_delay.value;
+       u32 unit = xfer->cs_change_delay.unit;
+       int ret;
+
+       /* return early on "fast" mode - for everything but USECS */
+       if (!delay) {
+               if (unit == SPI_DELAY_UNIT_USECS)
+                       _spi_transfer_delay_ns(10000);
+               return;
+       }
+
+       ret = spi_delay_exec(&xfer->cs_change_delay, xfer);
+       if (ret) {
                dev_err_once(&msg->spi->dev,
                             "Use of unsupported delay unit %i, using default of 10us\n",
-                            xfer->cs_change_delay_unit);
-               delay = 10000;
+                            unit);
+               _spi_transfer_delay_ns(10000);
        }
-       /* now sleep for the requested amount of time */
-       _spi_transfer_delay_ns(delay);
 }
 
 /*
@@ -1171,6 +1222,11 @@ static int spi_transfer_one_message(struct spi_controller *ctlr,
                spi_statistics_add_transfer_stats(statm, xfer, ctlr);
                spi_statistics_add_transfer_stats(stats, xfer, ctlr);
 
+               if (!ctlr->ptp_sts_supported) {
+                       xfer->ptp_sts_word_pre = 0;
+                       ptp_read_system_prets(xfer->ptp_sts);
+               }
+
                if (xfer->tx_buf || xfer->rx_buf) {
                        reinit_completion(&ctlr->xfer_completion);
 
@@ -1197,13 +1253,17 @@ static int spi_transfer_one_message(struct spi_controller *ctlr,
                                        xfer->len);
                }
 
+               if (!ctlr->ptp_sts_supported) {
+                       ptp_read_system_postts(xfer->ptp_sts);
+                       xfer->ptp_sts_word_post = xfer->len;
+               }
+
                trace_spi_transfer_stop(msg, xfer);
 
                if (msg->status != -EINPROGRESS)
                        goto out;
 
-               if (xfer->delay_usecs)
-                       _spi_transfer_delay_ns(xfer->delay_usecs * 1000);
+               spi_transfer_delay_exec(xfer);
 
                if (xfer->cs_change) {
                        if (list_is_last(&xfer->transfer_list,
@@ -1265,6 +1325,7 @@ EXPORT_SYMBOL_GPL(spi_finalize_current_transfer);
  */
 static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread)
 {
+       struct spi_transfer *xfer;
        struct spi_message *msg;
        bool was_busy = false;
        unsigned long flags;
@@ -1391,6 +1452,13 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread)
                goto out;
        }
 
+       if (!ctlr->ptp_sts_supported && !ctlr->transfer_one) {
+               list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+                       xfer->ptp_sts_word_pre = 0;
+                       ptp_read_system_prets(xfer->ptp_sts);
+               }
+       }
+
        ret = ctlr->transfer_one_message(ctlr, msg);
        if (ret) {
                dev_err(&ctlr->dev,
@@ -1418,6 +1486,99 @@ static void spi_pump_messages(struct kthread_work *work)
        __spi_pump_messages(ctlr, true);
 }
 
+/**
+ * spi_take_timestamp_pre - helper for drivers to collect the beginning of the
+ *                         TX timestamp for the requested byte from the SPI
+ *                         transfer. The frequency with which this function
+ *                         must be called (once per word, once for the whole
+ *                         transfer, once per batch of words etc) is arbitrary
+ *                         as long as the @tx buffer offset is greater than or
+ *                         equal to the requested byte at the time of the
+ *                         call. The timestamp is only taken once, at the
+ *                         first such call. It is assumed that the driver
+ *                         advances its @tx buffer pointer monotonically.
+ * @ctlr: Pointer to the spi_controller structure of the driver
+ * @xfer: Pointer to the transfer being timestamped
+ * @tx: Pointer to the current word within the xfer->tx_buf that the driver is
+ *     preparing to transmit right now.
+ * @irqs_off: If true, will disable IRQs and preemption for the duration of the
+ *           transfer, for less jitter in time measurement. Only compatible
+ *           with PIO drivers. If true, must follow up with
+ *           spi_take_timestamp_post or otherwise system will crash.
+ *           WARNING: for fully predictable results, the CPU frequency must
+ *           also be under control (governor).
+ */
+void spi_take_timestamp_pre(struct spi_controller *ctlr,
+                           struct spi_transfer *xfer,
+                           const void *tx, bool irqs_off)
+{
+       u8 bytes_per_word = DIV_ROUND_UP(xfer->bits_per_word, 8);
+
+       if (!xfer->ptp_sts)
+               return;
+
+       if (xfer->timestamped_pre)
+               return;
+
+       if (tx < (xfer->tx_buf + xfer->ptp_sts_word_pre * bytes_per_word))
+               return;
+
+       /* Capture the resolution of the timestamp */
+       xfer->ptp_sts_word_pre = (tx - xfer->tx_buf) / bytes_per_word;
+
+       xfer->timestamped_pre = true;
+
+       if (irqs_off) {
+               local_irq_save(ctlr->irq_flags);
+               preempt_disable();
+       }
+
+       ptp_read_system_prets(xfer->ptp_sts);
+}
+EXPORT_SYMBOL_GPL(spi_take_timestamp_pre);
+
+/**
+ * spi_take_timestamp_post - helper for drivers to collect the end of the
+ *                          TX timestamp for the requested byte from the SPI
+ *                          transfer. Can be called with an arbitrary
+ *                          frequency: only the first call where @tx exceeds
+ *                          or is equal to the requested word will be
+ *                          timestamped.
+ * @ctlr: Pointer to the spi_controller structure of the driver
+ * @xfer: Pointer to the transfer being timestamped
+ * @tx: Pointer to the current word within the xfer->tx_buf that the driver has
+ *     just transmitted.
+ * @irqs_off: If true, will re-enable IRQs and preemption for the local CPU.
+ */
+void spi_take_timestamp_post(struct spi_controller *ctlr,
+                            struct spi_transfer *xfer,
+                            const void *tx, bool irqs_off)
+{
+       u8 bytes_per_word = DIV_ROUND_UP(xfer->bits_per_word, 8);
+
+       if (!xfer->ptp_sts)
+               return;
+
+       if (xfer->timestamped_post)
+               return;
+
+       if (tx < (xfer->tx_buf + xfer->ptp_sts_word_post * bytes_per_word))
+               return;
+
+       ptp_read_system_postts(xfer->ptp_sts);
+
+       if (irqs_off) {
+               local_irq_restore(ctlr->irq_flags);
+               preempt_enable();
+       }
+
+       /* Capture the resolution of the timestamp */
+       xfer->ptp_sts_word_post = (tx - xfer->tx_buf) / bytes_per_word;
+
+       xfer->timestamped_post = true;
+}
+EXPORT_SYMBOL_GPL(spi_take_timestamp_post);
+
 /**
  * spi_set_thread_rt - set the controller to pump at realtime priority
  * @ctlr: controller to boost priority of
@@ -1503,6 +1664,7 @@ EXPORT_SYMBOL_GPL(spi_get_next_queued_message);
  */
 void spi_finalize_current_message(struct spi_controller *ctlr)
 {
+       struct spi_transfer *xfer;
        struct spi_message *mesg;
        unsigned long flags;
        int ret;
@@ -1511,6 +1673,13 @@ void spi_finalize_current_message(struct spi_controller *ctlr)
        mesg = ctlr->cur_msg;
        spin_unlock_irqrestore(&ctlr->queue_lock, flags);
 
+       if (!ctlr->ptp_sts_supported && !ctlr->transfer_one) {
+               list_for_each_entry(xfer, &mesg->transfers, transfer_list) {
+                       ptp_read_system_postts(xfer->ptp_sts);
+                       xfer->ptp_sts_word_post = xfer->len;
+               }
+       }
+
        spi_unmap_msg(ctlr, mesg);
 
        if (ctlr->cur_msg_prepared && ctlr->unprepare_message) {
@@ -2872,10 +3041,11 @@ struct spi_replaced_transfers *spi_replace_transfers(
                /* add to list */
                list_add(&xfer->transfer_list, rxfer->replaced_after);
 
-               /* clear cs_change and delay_usecs for all but the last */
+               /* clear cs_change and delay for all but the last */
                if (i) {
                        xfer->cs_change = false;
                        xfer->delay_usecs = 0;
+                       xfer->delay.value = 0;
                }
        }
 
@@ -3092,7 +3262,29 @@ int spi_setup(struct spi_device *spi)
        if (spi->controller->setup)
                status = spi->controller->setup(spi);
 
-       spi_set_cs(spi, false);
+       if (spi->controller->auto_runtime_pm && spi->controller->set_cs) {
+               status = pm_runtime_get_sync(spi->controller->dev.parent);
+               if (status < 0) {
+                       pm_runtime_put_noidle(spi->controller->dev.parent);
+                       dev_err(&spi->controller->dev, "Failed to power device: %d\n",
+                               status);
+                       return status;
+               }
+
+               /*
+                * We do not want to return positive value from pm_runtime_get,
+                * there are many instances of devices calling spi_setup() and
+                * checking for a non-zero return value instead of a negative
+                * return value.
+                */
+               status = 0;
+
+               spi_set_cs(spi, false);
+               pm_runtime_mark_last_busy(spi->controller->dev.parent);
+               pm_runtime_put_autosuspend(spi->controller->dev.parent);
+       } else {
+               spi_set_cs(spi, false);
+       }
 
        if (spi->rt && !spi->controller->rt) {
                spi->controller->rt = true;
@@ -3115,18 +3307,71 @@ EXPORT_SYMBOL_GPL(spi_setup);
 /**
  * spi_set_cs_timing - configure CS setup, hold, and inactive delays
  * @spi: the device that requires specific CS timing configuration
- * @setup: CS setup time in terms of clock count
- * @hold: CS hold time in terms of clock count
- * @inactive_dly: CS inactive delay between transfers in terms of clock count
+ * @setup: CS setup time specified via @spi_delay
+ * @hold: CS hold time specified via @spi_delay
+ * @inactive: CS inactive delay between transfers specified via @spi_delay
+ *
+ * Return: zero on success, else a negative error code.
  */
-void spi_set_cs_timing(struct spi_device *spi, u8 setup, u8 hold,
-                      u8 inactive_dly)
+int spi_set_cs_timing(struct spi_device *spi, struct spi_delay *setup,
+                     struct spi_delay *hold, struct spi_delay *inactive)
 {
+       size_t len;
+
        if (spi->controller->set_cs_timing)
-               spi->controller->set_cs_timing(spi, setup, hold, inactive_dly);
+               return spi->controller->set_cs_timing(spi, setup, hold,
+                                                     inactive);
+
+       if ((setup && setup->unit == SPI_DELAY_UNIT_SCK) ||
+           (hold && hold->unit == SPI_DELAY_UNIT_SCK) ||
+           (inactive && inactive->unit == SPI_DELAY_UNIT_SCK)) {
+               dev_err(&spi->dev,
+                       "Clock-cycle delays for CS not supported in SW mode\n");
+               return -ENOTSUPP;
+       }
+
+       len = sizeof(struct spi_delay);
+
+       /* copy delays to controller */
+       if (setup)
+               memcpy(&spi->controller->cs_setup, setup, len);
+       else
+               memset(&spi->controller->cs_setup, 0, len);
+
+       if (hold)
+               memcpy(&spi->controller->cs_hold, hold, len);
+       else
+               memset(&spi->controller->cs_hold, 0, len);
+
+       if (inactive)
+               memcpy(&spi->controller->cs_inactive, inactive, len);
+       else
+               memset(&spi->controller->cs_inactive, 0, len);
+
+       return 0;
 }
 EXPORT_SYMBOL_GPL(spi_set_cs_timing);
 
+static int _spi_xfer_word_delay_update(struct spi_transfer *xfer,
+                                      struct spi_device *spi)
+{
+       int delay1, delay2;
+
+       delay1 = spi_delay_to_ns(&xfer->word_delay, xfer);
+       if (delay1 < 0)
+               return delay1;
+
+       delay2 = spi_delay_to_ns(&spi->word_delay, xfer);
+       if (delay2 < 0)
+               return delay2;
+
+       if (delay1 < delay2)
+               memcpy(&xfer->word_delay, &spi->word_delay,
+                      sizeof(xfer->word_delay));
+
+       return 0;
+}
+
 static int __spi_validate(struct spi_device *spi, struct spi_message *message)
 {
        struct spi_controller *ctlr = spi->controller;
@@ -3262,8 +3507,8 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
                                return -EINVAL;
                }
 
-               if (xfer->word_delay_usecs < spi->word_delay_usecs)
-                       xfer->word_delay_usecs = spi->word_delay_usecs;
+               if (_spi_xfer_word_delay_update(xfer, spi))
+                       return -EINVAL;
        }
 
        message->status = -EINPROGRESS;
@@ -3274,6 +3519,7 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
 static int __spi_async(struct spi_device *spi, struct spi_message *message)
 {
        struct spi_controller *ctlr = spi->controller;
+       struct spi_transfer *xfer;
 
        /*
         * Some controllers do not support doing regular SPI transfers. Return
@@ -3289,6 +3535,13 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)
 
        trace_spi_message_submit(message);
 
+       if (!ctlr->ptp_sts_supported) {
+               list_for_each_entry(xfer, &message->transfers, transfer_list) {
+                       xfer->ptp_sts_word_pre = 0;
+                       ptp_read_system_prets(xfer->ptp_sts);
+               }
+       }
+
        return ctlr->transfer(spi, message);
 }
 
index 3ea9d8a..1e217e3 100644 (file)
@@ -265,9 +265,11 @@ static int spidev_message(struct spidev_data *spidev,
                k_tmp->tx_nbits = u_tmp->tx_nbits;
                k_tmp->rx_nbits = u_tmp->rx_nbits;
                k_tmp->bits_per_word = u_tmp->bits_per_word;
-               k_tmp->delay_usecs = u_tmp->delay_usecs;
+               k_tmp->delay.value = u_tmp->delay_usecs;
+               k_tmp->delay.unit = SPI_DELAY_UNIT_USECS;
                k_tmp->speed_hz = u_tmp->speed_hz;
-               k_tmp->word_delay_usecs = u_tmp->word_delay_usecs;
+               k_tmp->word_delay.value = u_tmp->word_delay_usecs;
+               k_tmp->word_delay.unit = SPI_DELAY_UNIT_USECS;
                if (!k_tmp->speed_hz)
                        k_tmp->speed_hz = spidev->speed_hz;
 #ifdef VERBOSE
index f0e6d64..65fd5ff 100644 (file)
@@ -11,7 +11,6 @@
 
 /* Board specific platform_data */
 struct mtk_chip_config {
-       u32 cs_pol;
        u32 sample_sel;
 };
 #endif
index a5d1837..6facf27 100644 (file)
@@ -206,7 +206,7 @@ enum pxa_ssp_type {
 };
 
 struct ssp_device {
-       struct platform_device *pdev;
+       struct device   *dev;
        struct list_head        node;
 
        struct clk      *clk;
index af4f265..98fe866 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/completion.h>
 #include <linux/scatterlist.h>
 #include <linux/gpio/consumer.h>
+#include <linux/ptp_clock_kernel.h>
 
 struct dma_chan;
 struct property_entry;
@@ -89,6 +90,22 @@ void spi_statistics_add_transfer_stats(struct spi_statistics *stats,
 #define SPI_STATISTICS_INCREMENT_FIELD(stats, field)   \
        SPI_STATISTICS_ADD_TO_FIELD(stats, field, 1)
 
+/**
+ * struct spi_delay - SPI delay information
+ * @value: Value for the delay
+ * @unit: Unit for the delay
+ */
+struct spi_delay {
+#define SPI_DELAY_UNIT_USECS   0
+#define SPI_DELAY_UNIT_NSECS   1
+#define SPI_DELAY_UNIT_SCK     2
+       u16     value;
+       u8      unit;
+};
+
+extern int spi_delay_to_ns(struct spi_delay *_delay, struct spi_transfer *xfer);
+extern int spi_delay_exec(struct spi_delay *_delay, struct spi_transfer *xfer);
+
 /**
  * struct spi_device - Controller side proxy for an SPI slave device
  * @dev: Driver model representation of the device.
@@ -123,7 +140,7 @@ void spi_statistics_add_transfer_stats(struct spi_statistics *stats,
  *     the spi_master.
  * @cs_gpiod: gpio descriptor of the chipselect line (optional, NULL when
  *     not using a GPIO line)
- * @word_delay_usecs: microsecond delay to be inserted between consecutive
+ * @word_delay: delay to be inserted between consecutive
  *     words of a transfer
  *
  * @statistics: statistics for the spi_device
@@ -173,7 +190,7 @@ struct spi_device {
        const char              *driver_override;
        int                     cs_gpio;        /* LEGACY: chip select gpio */
        struct gpio_desc        *cs_gpiod;      /* chip select gpio desc */
-       uint8_t                 word_delay_usecs; /* inter-word delay */
+       struct spi_delay        word_delay; /* inter-word delay */
 
        /* the statistics */
        struct spi_statistics   statistics;
@@ -390,6 +407,11 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
  *          controller has native support for memory like operations.
  * @unprepare_message: undo any work done by prepare_message().
  * @slave_abort: abort the ongoing transfer request on an SPI slave controller
+ * @cs_setup: delay to be introduced by the controller after CS is asserted
+ * @cs_hold: delay to be introduced by the controller before CS is deasserted
+ * @cs_inactive: delay to be introduced by the controller after CS is
+ *     deasserted. If @cs_change_delay is used from @spi_transfer, then the
+ *     two delays will be added up.
  * @cs_gpios: LEGACY: array of GPIO descs to use as chip select lines; one per
  *     CS number. Any individual value may be -ENOENT for CS lines that
  *     are not GPIOs (driven by the SPI controller itself). Use the cs_gpiods
@@ -409,6 +431,12 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
  * @fw_translate_cs: If the boot firmware uses different numbering scheme
  *     what Linux expects, this optional hook can be used to translate
  *     between the two.
+ * @ptp_sts_supported: If the driver sets this to true, it must provide a
+ *     time snapshot in @spi_transfer->ptp_sts as close as possible to the
+ *     moment in time when @spi_transfer->ptp_sts_word_pre and
+ *     @spi_transfer->ptp_sts_word_post were transmitted.
+ *     If the driver does not set this, the SPI core takes the snapshot as
+ *     close to the driver hand-over as possible.
  *
  * Each SPI controller can communicate with one or more @spi_device
  * children.  These make a small bus, sharing MOSI, MISO and SCK signals
@@ -502,8 +530,8 @@ struct spi_controller {
         * to configure specific CS timing through spi_set_cs_timing() after
         * spi_setup().
         */
-       void (*set_cs_timing)(struct spi_device *spi, u8 setup_clk_cycles,
-                             u8 hold_clk_cycles, u8 inactive_clk_cycles);
+       int (*set_cs_timing)(struct spi_device *spi, struct spi_delay *setup,
+                            struct spi_delay *hold, struct spi_delay *inactive);
 
        /* bidirectional bulk transfers
         *
@@ -587,6 +615,11 @@ struct spi_controller {
        /* Optimized handlers for SPI memory-like operations. */
        const struct spi_controller_mem_ops *mem_ops;
 
+       /* CS delays */
+       struct spi_delay        cs_setup;
+       struct spi_delay        cs_hold;
+       struct spi_delay        cs_inactive;
+
        /* gpio chip select */
        int                     *cs_gpios;
        struct gpio_desc        **cs_gpiods;
@@ -604,6 +637,15 @@ struct spi_controller {
        void                    *dummy_tx;
 
        int (*fw_translate_cs)(struct spi_controller *ctlr, unsigned cs);
+
+       /*
+        * Driver sets this field to indicate it is able to snapshot SPI
+        * transfers (needed e.g. for reading the time of POSIX clocks)
+        */
+       bool                    ptp_sts_supported;
+
+       /* Interrupt enable state during PTP system timestamping */
+       unsigned long           irq_flags;
 };
 
 static inline void *spi_controller_get_devdata(struct spi_controller *ctlr)
@@ -644,6 +686,14 @@ extern struct spi_message *spi_get_next_queued_message(struct spi_controller *ct
 extern void spi_finalize_current_message(struct spi_controller *ctlr);
 extern void spi_finalize_current_transfer(struct spi_controller *ctlr);
 
+/* Helper calls for driver to timestamp transfer */
+void spi_take_timestamp_pre(struct spi_controller *ctlr,
+                           struct spi_transfer *xfer,
+                           const void *tx, bool irqs_off);
+void spi_take_timestamp_post(struct spi_controller *ctlr,
+                            struct spi_transfer *xfer,
+                            const void *tx, bool irqs_off);
+
 /* the spi driver core manages memory for the spi_controller classdev */
 extern struct spi_controller *__spi_alloc_controller(struct device *host,
                                                unsigned int size, bool slave);
@@ -739,13 +789,13 @@ extern void spi_res_release(struct spi_controller *ctlr,
  * @cs_change: affects chipselect after this transfer completes
  * @cs_change_delay: delay between cs deassert and assert when
  *      @cs_change is set and @spi_transfer is not the last in @spi_message
- * @cs_change_delay_unit: unit of cs_change_delay
+ * @delay: delay to be introduced after this transfer before
+ *     (optionally) changing the chipselect status, then starting
+ *     the next transfer or completing this @spi_message.
  * @delay_usecs: microseconds to delay after this transfer before
  *     (optionally) changing the chipselect status, then starting
  *     the next transfer or completing this @spi_message.
- * @word_delay_usecs: microseconds to inter word delay after each word size
- *     (set by bits_per_word) transmission.
- * @word_delay: clock cycles to inter word delay after each word size
+ * @word_delay: inter word delay to be introduced after each word size
  *     (set by bits_per_word) transmission.
  * @effective_speed_hz: the effective SCK-speed that was used to
  *      transfer this transfer. Set to 0 if the spi bus driver does
@@ -753,6 +803,35 @@ extern void spi_res_release(struct spi_controller *ctlr,
  * @transfer_list: transfers are sequenced through @spi_message.transfers
  * @tx_sg: Scatterlist for transmit, currently not for client use
  * @rx_sg: Scatterlist for receive, currently not for client use
+ * @ptp_sts_word_pre: The word (subject to bits_per_word semantics) offset
+ *     within @tx_buf for which the SPI device is requesting that the time
+ *     snapshot for this transfer begins. Upon completing the SPI transfer,
+ *     this value may have changed compared to what was requested, depending
+ *     on the available snapshotting resolution (DMA transfer,
+ *     @ptp_sts_supported is false, etc).
+ * @ptp_sts_word_post: See @ptp_sts_word_post. The two can be equal (meaning
+ *     that a single byte should be snapshotted).
+ *     If the core takes care of the timestamp (if @ptp_sts_supported is false
+ *     for this controller), it will set @ptp_sts_word_pre to 0, and
+ *     @ptp_sts_word_post to the length of the transfer. This is done
+ *     purposefully (instead of setting to spi_transfer->len - 1) to denote
+ *     that a transfer-level snapshot taken from within the driver may still
+ *     be of higher quality.
+ * @ptp_sts: Pointer to a memory location held by the SPI slave device where a
+ *     PTP system timestamp structure may lie. If drivers use PIO or their
+ *     hardware has some sort of assist for retrieving exact transfer timing,
+ *     they can (and should) assert @ptp_sts_supported and populate this
+ *     structure using the ptp_read_system_*ts helper functions.
+ *     The timestamp must represent the time at which the SPI slave device has
+ *     processed the word, i.e. the "pre" timestamp should be taken before
+ *     transmitting the "pre" word, and the "post" timestamp after receiving
+ *     transmit confirmation from the controller for the "post" word.
+ * @timestamped_pre: Set by the SPI controller driver to denote it has acted
+ *     upon the @ptp_sts request. Not set when the SPI core has taken care of
+ *     the task. SPI device drivers are free to print a warning if this comes
+ *     back unset and they need the better resolution.
+ * @timestamped_post: See above. The reason why both exist is that these
+ *     booleans are also used to keep state in the core SPI logic.
  *
  * SPI transfers always write the same number of bytes as they read.
  * Protocol drivers should always provide @rx_buf and/or @tx_buf.
@@ -830,18 +909,22 @@ struct spi_transfer {
 #define        SPI_NBITS_DUAL          0x02 /* 2bits transfer */
 #define        SPI_NBITS_QUAD          0x04 /* 4bits transfer */
        u8              bits_per_word;
-       u8              word_delay_usecs;
        u16             delay_usecs;
-       u16             cs_change_delay;
-       u8              cs_change_delay_unit;
-#define SPI_DELAY_UNIT_USECS   0
-#define SPI_DELAY_UNIT_NSECS   1
-#define SPI_DELAY_UNIT_SCK     2
+       struct spi_delay        delay;
+       struct spi_delay        cs_change_delay;
+       struct spi_delay        word_delay;
        u32             speed_hz;
-       u16             word_delay;
 
        u32             effective_speed_hz;
 
+       unsigned int    ptp_sts_word_pre;
+       unsigned int    ptp_sts_word_post;
+
+       struct ptp_system_timestamp *ptp_sts;
+
+       bool            timestamped_pre;
+       bool            timestamped_post;
+
        struct list_head transfer_list;
 };
 
@@ -935,6 +1018,20 @@ spi_transfer_del(struct spi_transfer *t)
        list_del(&t->transfer_list);
 }
 
+static inline int
+spi_transfer_delay_exec(struct spi_transfer *t)
+{
+       struct spi_delay d;
+
+       if (t->delay_usecs) {
+               d.value = t->delay_usecs;
+               d.unit = SPI_DELAY_UNIT_USECS;
+               return spi_delay_exec(&d, NULL);
+       }
+
+       return spi_delay_exec(&t->delay, t);
+}
+
 /**
  * spi_message_init_with_transfers - Initialize spi_message and append transfers
  * @m: spi_message to be initialized
@@ -982,7 +1079,10 @@ static inline void spi_message_free(struct spi_message *m)
        kfree(m);
 }
 
-extern void spi_set_cs_timing(struct spi_device *spi, u8 setup, u8 hold, u8 inactive_dly);
+extern int spi_set_cs_timing(struct spi_device *spi,
+                            struct spi_delay *setup,
+                            struct spi_delay *hold,
+                            struct spi_delay *inactive);
 
 extern int spi_setup(struct spi_device *spi);
 extern int spi_async(struct spi_device *spi, struct spi_message *message);
index e3e5425..e701637 100644 (file)
@@ -177,7 +177,7 @@ static int mmp_sspa_set_dai_fmt(struct snd_soc_dai *cpu_dai,
        /* we can only change the settings if the port is not in use */
        if ((mmp_sspa_read_reg(sspa, SSPA_TXSP) & SSPA_SP_S_EN) ||
            (mmp_sspa_read_reg(sspa, SSPA_RXSP) & SSPA_SP_S_EN)) {
-               dev_err(&sspa->pdev->dev,
+               dev_err(sspa->dev,
                        "can't change hardware dai format: stream is in use\n");
                return -EINVAL;
        }
index 5fdd1a2..6c52014 100644 (file)
@@ -52,11 +52,11 @@ struct ssp_priv {
 
 static void dump_registers(struct ssp_device *ssp)
 {
-       dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n",
+       dev_dbg(ssp->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n",
                 pxa_ssp_read_reg(ssp, SSCR0), pxa_ssp_read_reg(ssp, SSCR1),
                 pxa_ssp_read_reg(ssp, SSTO));
 
-       dev_dbg(&ssp->pdev->dev, "SSPSP 0x%08x SSSR 0x%08x SSACD 0x%08x\n",
+       dev_dbg(ssp->dev, "SSPSP 0x%08x SSSR 0x%08x SSACD 0x%08x\n",
                 pxa_ssp_read_reg(ssp, SSPSP), pxa_ssp_read_reg(ssp, SSSR),
                 pxa_ssp_read_reg(ssp, SSACD));
 }
@@ -223,7 +223,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
                clk_id = PXA_SSP_CLK_EXT;
        }
 
-       dev_dbg(&ssp->pdev->dev,
+       dev_dbg(ssp->dev,
                "pxa_ssp_set_dai_sysclk id: %d, clk_id %d, freq %u\n",
                cpu_dai->id, clk_id, freq);
 
@@ -316,7 +316,7 @@ static int pxa_ssp_set_pll(struct ssp_priv *priv, unsigned int freq)
 
                        ssacd |= (0x6 << 4);
 
-                       dev_dbg(&ssp->pdev->dev,
+                       dev_dbg(ssp->dev,
                                "Using SSACDD %x to supply %uHz\n",
                                val, freq);
                        break;
@@ -687,7 +687,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
         * - complain loudly and fail if they've not been set up yet.
         */
        if ((sscr0 & SSCR0_MOD) && !ttsa) {
-               dev_err(&ssp->pdev->dev, "No TDM timeslot configured\n");
+               dev_err(ssp->dev, "No TDM timeslot configured\n");
                return -EINVAL;
        }