Commit 13e574b4 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'spi-v6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi

Pull spi updates from Mark Brown:
 "This has been a fairly quiet release for SPI, though it is likely that
  the next release will have some big changes as there's some
  preparatory work for multiple chip select support gone in - the rest
  of the code is on the list but will need to be rebased onto -rc1.
  Otherwise there's a couple of new tunables for chip select timings,
  some new devices and smaller device specific updates and fixes.

   - Support for configuring the hold and minimum inactive times for
     chip selects.

   - Beginnings of support for supporting devices which have multiple
     chip selects on a single device.

   - Support for newer Broadcom HSSPI and Intel controllers, Silicon
     Labs EM3581 and SI3210"

* tag 'spi-v6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (67 commits)
  spi: dt-bindings: qcom,spi-qcom-qspi: document OPP and power-domains
  spi: spidev: drop the incorrect notice from Kconfig
  spi: bcm63xx-hsspi: fix error code in probe
  spi: bcmbca-hsspi: Fix error code in probe() function
  spi: synquacer: Fix timeout handling in synquacer_spi_transfer_one()
  spi: intel: Check number of chip selects after reading the descriptor
  spi: xilinx: add force_irq for QSPI mode
  spi: spi-st-ssc: convert to DT schema
  spi: Reorder fields in 'struct spi_transfer'
  spi: cadence-quadspi: use STIG mode for small reads
  spi: cadence-quadspi: setup ADDR Bits in cmd reads
  spi: cadence-quadspi: Add flag for direct mode writes
  spi: cadence-quadspi: Reset CMD_CTRL Reg on cmd r/w completion
  MAINTAINERS: Remove file reference for Broadcom Broadband SoC HS SPI driver entry
  spi: bcm63xx-hsspi: bcmbca-hsspi: fix _be16 type usage
  MAINTAINERS: Add entry for Broadcom Broadband SoC HS SPI drivers
  spi: bcmbca-hsspi: Add driver for newer HSSPI controller
  spi: bcm63xx-hsspi: Disable spi mem dual io read op support
  spi: spi-mem: Allow controller supporting mem_ops without exec_op
  spi: bcm63xx-hsspi: Add prepend mode support
  ...
parents 0175ec3a de82c25d
......@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Allwinner A10 SPI Controller
allOf:
- $ref: "spi-controller.yaml"
- $ref: spi-controller.yaml
maintainers:
- Chen-Yu Tsai <wens@csie.org>
......
......@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Allwinner A31 SPI Controller
allOf:
- $ref: "spi-controller.yaml"
- $ref: spi-controller.yaml
maintainers:
- Chen-Yu Tsai <wens@csie.org>
......
......@@ -2,8 +2,8 @@
# Copyright 2019 BayLibre, SAS
%YAML 1.2
---
$id: "http://devicetree.org/schemas/spi/amlogic,meson-gx-spicc.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
$id: http://devicetree.org/schemas/spi/amlogic,meson-gx-spicc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Amlogic Meson SPI Communication Controller
......@@ -41,7 +41,7 @@ properties:
maxItems: 2
allOf:
- $ref: "spi-controller.yaml#"
- $ref: spi-controller.yaml#
- if:
properties:
compatible:
......
......@@ -2,8 +2,8 @@
# Copyright 2019 BayLibre, SAS
%YAML 1.2
---
$id: "http://devicetree.org/schemas/spi/amlogic,meson6-spifc.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
$id: http://devicetree.org/schemas/spi/amlogic,meson6-spifc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Amlogic Meson SPI Flash Controller
......@@ -11,7 +11,7 @@ maintainers:
- Neil Armstrong <neil.armstrong@linaro.org>
allOf:
- $ref: "spi-controller.yaml#"
- $ref: spi-controller.yaml#
description: |
The Meson SPIFC is a controller optimized for communication with SPI
......
......@@ -15,7 +15,7 @@ description: |
SPI) of the AST2400, AST2500 and AST2600 SOCs.
allOf:
- $ref: "spi-controller.yaml#"
- $ref: spi-controller.yaml#
properties:
compatible:
......
# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/spi/brcm,bcm63xx-hsspi.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Broadcom Broadband SoC High Speed SPI controller
maintainers:
- William Zhang <william.zhang@broadcom.com>
- Kursad Oney <kursad.oney@broadcom.com>
- Jonas Gorski <jonas.gorski@gmail.com>
description: |
Broadcom Broadband SoC supports High Speed SPI master controller since the
early MIPS based chips such as BCM6328 and BCM63268. This initial rev 1.0
controller was carried over to recent ARM based chips, such as BCM63138,
BCM4908 and BCM6858. The old MIPS based chip should continue to use the
brcm,bcm6328-hsspi compatible string. The recent ARM based chip is required to
use the brcm,bcmbca-hsspi-v1.0 as part of its compatible string list as
defined below to match the specific chip along with ip revision info.
This rev 1.0 controller has a limitation that can not keep the chip select line
active between the SPI transfers within the same SPI message. This can
terminate the transaction to some SPI devices prematurely. The issue can be
worked around by either the controller's prepend mode or using the dummy chip
select workaround. Driver automatically picks the suitable mode based on
transfer type so it is transparent to the user.
The newer SoCs such as BCM6756, BCM4912 and BCM6855 include an updated SPI
controller rev 1.1 that add the capability to allow the driver to control chip
select explicitly. This solves the issue in the old controller.
properties:
compatible:
oneOf:
- const: brcm,bcm6328-hsspi
- items:
- enum:
- brcm,bcm47622-hsspi
- brcm,bcm4908-hsspi
- brcm,bcm63138-hsspi
- brcm,bcm63146-hsspi
- brcm,bcm63148-hsspi
- brcm,bcm63158-hsspi
- brcm,bcm63178-hsspi
- brcm,bcm6846-hsspi
- brcm,bcm6856-hsspi
- brcm,bcm6858-hsspi
- brcm,bcm6878-hsspi
- const: brcm,bcmbca-hsspi-v1.0
- items:
- enum:
- brcm,bcm4912-hsspi
- brcm,bcm6756-hsspi
- brcm,bcm6813-hsspi
- brcm,bcm6855-hsspi
- const: brcm,bcmbca-hsspi-v1.1
reg:
items:
- description: main registers
- description: miscellaneous control registers
minItems: 1
reg-names:
items:
- const: hsspi
- const: spim-ctrl
minItems: 1
clocks:
items:
- description: SPI master reference clock
- description: SPI master pll clock
clock-names:
items:
- const: hsspi
- const: pll
interrupts:
maxItems: 1
required:
- compatible
- reg
- clocks
- clock-names
- interrupts
allOf:
- $ref: spi-controller.yaml#
- if:
properties:
compatible:
contains:
enum:
- brcm,bcm6328-hsspi
- brcm,bcmbca-hsspi-v1.0
then:
properties:
reg:
maxItems: 1
reg-names:
maxItems: 1
else:
properties:
reg:
minItems: 2
maxItems: 2
reg-names:
minItems: 2
maxItems: 2
required:
- reg-names
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
spi@ff801000 {
compatible = "brcm,bcm6756-hsspi", "brcm,bcmbca-hsspi-v1.1";
reg = <0xff801000 0x1000>,
<0xff802610 0x4>;
reg-names = "hsspi", "spim-ctrl";
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&hsspi>, <&hsspi_pll>;
clock-names = "hsspi", "pll";
num-cs = <8>;
#address-cells = <1>;
#size-cells = <0>;
};
......@@ -47,7 +47,7 @@ properties:
cdns,fifo-depth:
description:
Size of the data FIFO in words.
$ref: "/schemas/types.yaml#/definitions/uint32"
$ref: /schemas/types.yaml#/definitions/uint32
enum: [ 128, 256 ]
default: 128
......
......@@ -2,8 +2,8 @@
# Copyright 2020-21 Cadence
%YAML 1.2
---
$id: "http://devicetree.org/schemas/spi/cdns,xspi.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
$id: http://devicetree.org/schemas/spi/cdns,xspi.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Cadence XSPI Controller
......@@ -16,7 +16,7 @@ description: |
read/write access to slaves such as SPI-NOR flash.
allOf:
- $ref: "spi-controller.yaml#"
- $ref: spi-controller.yaml#
properties:
compatible:
......
......@@ -10,7 +10,7 @@ maintainers:
- Han Xu <han.xu@nxp.com>
allOf:
- $ref: "spi-controller.yaml#"
- $ref: spi-controller.yaml#
properties:
compatible:
......
......@@ -10,7 +10,7 @@ maintainers:
- Shawn Guo <shawnguo@kernel.org>
allOf:
- $ref: "/schemas/spi/spi-controller.yaml#"
- $ref: /schemas/spi/spi-controller.yaml#
properties:
compatible:
......
......@@ -10,7 +10,7 @@ maintainers:
- Leilk Liu <leilk.liu@mediatek.com>
allOf:
- $ref: "/schemas/spi/spi-controller.yaml#"
- $ref: /schemas/spi/spi-controller.yaml#
properties:
compatible:
......
......@@ -18,14 +18,12 @@ description: |
using the accompanying ECC engine. There should be only one spi
slave device following generic spi bindings.
allOf:
- $ref: /schemas/spi/spi-controller.yaml#
properties:
compatible:
enum:
- mediatek,mt7622-snand
- mediatek,mt7629-snand
- mediatek,mt7986-snand
reg:
items:
......@@ -36,19 +34,20 @@ properties:
- description: NFI interrupt
clocks:
items:
- description: clock used for the controller
- description: clock used for the SPI bus
minItems: 2
maxItems: 3
clock-names:
items:
- const: nfi_clk
- const: pad_clk
minItems: 2
maxItems: 3
nand-ecc-engine:
description: device-tree node of the accompanying ECC engine.
$ref: /schemas/types.yaml#/definitions/phandle
mediatek,rx-latch-latency-ns:
description: Data read latch latency, unit is nanoseconds.
required:
- compatible
- reg
......@@ -57,6 +56,43 @@ required:
- clock-names
- nand-ecc-engine
allOf:
- $ref: /schemas/spi/spi-controller.yaml#
- if:
properties:
compatible:
enum:
- mediatek,mt7622-snand
- mediatek,mt7629-snand
then:
properties:
clocks:
items:
- description: clock used for the controller
- description: clock used for the SPI bus
clock-names:
items:
- const: nfi_clk
- const: pad_clk
- if:
properties:
compatible:
enum:
- mediatek,mt7986-snand
then:
properties:
clocks:
items:
- description: clock used for the controller
- description: clock used for the SPI bus
- description: clock used for the AHB bus
clock-names:
items:
- const: nfi_clk
- const: pad_clk
- const: nfi_hclk
unevaluatedProperties: false
examples:
......
......@@ -10,7 +10,7 @@ maintainers:
- Leilk Liu <leilk.liu@mediatek.com>
allOf:
- $ref: "/schemas/spi/spi-controller.yaml#"
- $ref: /schemas/spi/spi-controller.yaml#
properties:
compatible:
......
......@@ -11,7 +11,7 @@ maintainers:
- Bert Vermeulen <bert@biot.com>
allOf:
- $ref: "spi-controller.yaml#"
- $ref: spi-controller.yaml#
properties:
compatible:
......
......@@ -10,7 +10,7 @@ maintainers:
- Miquel Raynal <miquel.raynal@bootlin.com>
allOf:
- $ref: "spi-controller.yaml#"
- $ref: spi-controller.yaml#
properties:
compatible:
......
......@@ -10,7 +10,7 @@ maintainers:
- Marek Vasut <marex@denx.de>
allOf:
- $ref: "/schemas/spi/spi-controller.yaml#"
- $ref: /schemas/spi/spi-controller.yaml#
properties:
compatible:
......
......@@ -11,7 +11,7 @@ maintainers:
- Jonathan Hunter <jonathanh@nvidia.com>
allOf:
- $ref: "spi-controller.yaml#"
- $ref: spi-controller.yaml#
properties:
compatible:
......
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: "http://devicetree.org/schemas/spi/qcom,spi-qcom-qspi.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
$id: http://devicetree.org/schemas/spi/qcom,spi-qcom-qspi.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Quad Serial Peripheral Interface (QSPI)
......@@ -53,6 +52,11 @@ properties:
- const: qspi-config
- const: qspi-memory
operating-points-v2: true
power-domains:
maxItems: 1
required:
- compatible
- reg
......@@ -88,7 +92,6 @@ examples:
spi-tx-bus-width = <2>;
spi-rx-bus-width = <2>;
};
};
};
...
......@@ -11,7 +11,7 @@ maintainers:
- Birger Koblitz <mail@birger-koblitz.de>
allOf:
- $ref: "spi-controller.yaml#"
- $ref: spi-controller.yaml#
properties:
compatible:
......
......@@ -10,7 +10,7 @@ maintainers:
- Mark Brown <broonie@kernel.org>
allOf:
- $ref: "spi-controller.yaml#"
- $ref: spi-controller.yaml#
- if:
properties:
compatible:
......
Binding for Broadcom BCM6328 High Speed SPI controller
Required properties:
- compatible: must contain of "brcm,bcm6328-hsspi".
- reg: Base address and size of the controllers memory area.
- interrupts: Interrupt for the SPI block.
- clocks: phandles of the SPI clock and the PLL clock.
- clock-names: must be "hsspi", "pll".
- #address-cells: <1>, as required by generic SPI binding.
- #size-cells: <0>, also as required by generic SPI binding.
Optional properties:
- num-cs: some controllers have less than 8 cs signals. Defaults to 8
if absent.
Child nodes as per the generic SPI binding.
Example:
spi@10001000 {
compatible = "brcm,bcm6328-hsspi";
reg = <0x10001000 0x600>;
interrupts = <29>;
clocks = <&clkctl 9>, <&hsspi_pll>;
clock-names = "hsspi", "pll";
num-cs = <2>;
#address-cells = <1>;
#size-cells = <0>;
};
......@@ -10,7 +10,7 @@ maintainers:
- Michal Simek <michal.simek@xilinx.com>
allOf:
- $ref: "spi-controller.yaml#"
- $ref: spi-controller.yaml#
properties:
compatible:
......
......@@ -10,7 +10,7 @@ maintainers:
- Anson Huang <Anson.Huang@nxp.com>
allOf:
- $ref: "/schemas/spi/spi-controller.yaml#"
- $ref: /schemas/spi/spi-controller.yaml#
properties:
compatible:
......
......@@ -14,7 +14,7 @@ description:
dedicated GPIO lines.
allOf:
- $ref: "/schemas/spi/spi-controller.yaml#"
- $ref: /schemas/spi/spi-controller.yaml#
properties:
compatible:
......@@ -41,7 +41,7 @@ properties:
num-chipselects:
description: Number of chipselect lines. Should be <0> if a single device
with no chip select is connected.
$ref: "/schemas/types.yaml#/definitions/uint32"
$ref: /schemas/types.yaml#/definitions/uint32
# Deprecated properties
gpio-sck: false
......
......@@ -30,8 +30,8 @@ description: |
+------------+
allOf:
- $ref: "/schemas/spi/spi-controller.yaml#"
- $ref: "/schemas/spi/spi-peripheral-props.yaml#"
- $ref: /schemas/spi/spi-controller.yaml#
- $ref: /schemas/spi/spi-peripheral-props.yaml#
maintainers:
- Chris Packham <chris.packham@alliedtelesis.co.nz>
......
......@@ -11,7 +11,7 @@ maintainers:
- Kuldeep Singh <singh.kuldeep87k@gmail.com>
allOf:
- $ref: "spi-controller.yaml#"
- $ref: spi-controller.yaml#
properties:
compatible:
......
......@@ -49,6 +49,16 @@ properties:
Delay in nanoseconds to be introduced by the controller after CS is
asserted.
spi-cs-hold-delay-ns:
description:
Delay in nanoseconds to be introduced by the controller before CS is
de-asserted.
spi-cs-inactive-delay-ns:
description:
Delay in nanoseconds to be introduced by the controller after CS is
de-asserted.
spi-rx-bus-width:
description:
Bus width to the SPI bus used for read transfers.
......
......@@ -10,7 +10,7 @@ maintainers:
- Linus Walleij <linus.walleij@linaro.org>
allOf:
- $ref: "spi-controller.yaml#"
- $ref: spi-controller.yaml#
# We need a select here so we don't match all nodes with 'arm,primecell'
select:
......@@ -45,7 +45,7 @@ properties:
description: delay in ms following transfer completion before the
runtime power management system suspends the device. A setting of 0
indicates no delay and the device will be suspended immediately.
$ref: "/schemas/types.yaml#/definitions/uint32"
$ref: /schemas/types.yaml#/definitions/uint32
pl022,rt:
description: indicates the controller should run the message pump with realtime
......@@ -81,7 +81,7 @@ patternProperties:
properties:
pl022,interface:
description: SPI interface type
$ref: "/schemas/types.yaml#/definitions/uint32"
$ref: /schemas/types.yaml#/definitions/uint32
enum:
- 0 # SPI
- 1 # Texas Instruments Synchronous Serial Frame Format
......@@ -89,7 +89,7 @@ patternProperties:
pl022,com-mode:
description: Specifies the transfer mode
$ref: "/schemas/types.yaml#/definitions/uint32"
$ref: /schemas/types.yaml#/definitions/uint32
enum:
- 0 # interrupt mode
- 1 # polling mode
......@@ -98,30 +98,30 @@ patternProperties:
pl022,rx-level-trig:
description: Rx FIFO watermark level
$ref: "/schemas/types.yaml#/definitions/uint32"
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 4
pl022,tx-level-trig:
description: Tx FIFO watermark level
$ref: "/schemas/types.yaml#/definitions/uint32"
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 4
pl022,ctrl-len:
description: Microwire interface - Control length
$ref: "/schemas/types.yaml#/definitions/uint32"
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0x03
maximum: 0x1f
pl022,wait-state:
description: Microwire interface - Wait state
$ref: "/schemas/types.yaml#/definitions/uint32"
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1]
pl022,duplex:
description: Microwire interface - Full/Half duplex
$ref: "/schemas/types.yaml#/definitions/uint32"
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1]
required:
......
......@@ -11,7 +11,7 @@ description:
as flash and display controllers using the SPI communication interface.
allOf:
- $ref: "spi-controller.yaml#"
- $ref: spi-controller.yaml#
maintainers:
- Heiko Stuebner <heiko@sntech.de>
......
......@@ -12,7 +12,7 @@ maintainers:
- Palmer Dabbelt <palmer@sifive.com>
allOf:
- $ref: "spi-controller.yaml#"
- $ref: spi-controller.yaml#
properties:
compatible:
......@@ -51,14 +51,14 @@ properties:
sifive,fifo-depth:
description:
Depth of hardware queues; defaults to 8
$ref: "/schemas/types.yaml#/definitions/uint32"
$ref: /schemas/types.yaml#/definitions/uint32
enum: [8]
default: 8
sifive,max-bits-per-word:
description:
Maximum bits per word; defaults to 8
$ref: "/schemas/types.yaml#/definitions/uint32"
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1, 2, 3, 4, 5, 6, 7, 8]
default: 8
......
STMicroelectronics SSC (SPI) Controller
---------------------------------------
Required properties:
- compatible : "st,comms-ssc4-spi"
- reg : Offset and length of the device's register set
- interrupts : The interrupt specifier
- clock-names : Must contain "ssc"
- clocks : Must contain an entry for each name in clock-names
See ../clk/*
- pinctrl-names : Uses "default", can use "sleep" if provided
See ../pinctrl/pinctrl-bindings.txt
Optional properties:
- cs-gpios : List of GPIO chip selects
See ../spi/spi-bus.txt
Child nodes represent devices on the SPI bus
See ../spi/spi-bus.txt
Example:
spi@9840000 {
compatible = "st,comms-ssc4-spi";
reg = <0x9840000 0x110>;
interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk_s_c0_flexgen CLK_EXT2F_A9>;
clock-names = "ssc";
pinctrl-0 = <&pinctrl_spi0_default>;
pinctrl-names = "default";
cs-gpios = <&pio17 5 0>;
#address-cells = <1>;
#size-cells = <0>;
st95hf@0{
compatible = "st,st95hf";
reg = <0>;
spi-max-frequency = <1000000>;
interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
};
};
......@@ -8,7 +8,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Sunplus sp7021 SPI controller
allOf:
- $ref: "spi-controller.yaml"
- $ref: spi-controller.yaml
maintainers:
- Li-hao Kuo <lhjeff911@gmail.com>
......@@ -59,9 +59,9 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
spi@9C002D80 {
spi@9c002d80 {
compatible = "sunplus,sp7021-spi";
reg = <0x9C002D80 0x80>, <0x9C002E00 0x80>;
reg = <0x9c002d80 0x80>, <0x9c002e00 0x80>;
reg-names = "master", "slave";
interrupt-parent = <&intc>;
interrupt-names = "dma_w",
......
......@@ -10,7 +10,7 @@ maintainers:
- Michal Simek <michal.simek@xilinx.com>
allOf:
- $ref: "spi-controller.yaml#"
- $ref: spi-controller.yaml#
properties:
compatible:
......
......@@ -10,7 +10,7 @@ maintainers:
- Michal Simek <michal.simek@xilinx.com>
allOf:
- $ref: "spi-controller.yaml#"
- $ref: spi-controller.yaml#
properties:
compatible:
......
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: "http://devicetree.org/schemas/spi/sprd,spi-adi.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
$id: http://devicetree.org/schemas/spi/sprd,spi-adi.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Spreadtrum ADI controller
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/spi/st,ssc-spi.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: STMicroelectronics SSC SPI Controller
description: |
The STMicroelectronics SSC SPI controller can be found on STi platforms
and it used to communicate with external devices using the
Serial Peripheral Interface.
maintainers:
- Patrice Chotard <patrice.chotard@foss.st.com>
allOf:
- $ref: spi-controller.yaml#
properties:
compatible:
const: st,comms-ssc4-spi
reg:
maxItems: 1
clocks:
maxItems: 1
clock-names:
const: ssc
interrupts:
maxItems: 1
required:
- compatible
- reg
- clocks
- clock-names
- interrupts
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/stih407-clks.h>
spi@9840000 {
compatible = "st,comms-ssc4-spi";
reg = <0x9840000 0x110>;
interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk_s_c0_flexgen CLK_EXT2F_A9>;
clock-names = "ssc";
pinctrl-0 = <&pinctrl_spi0_default>;
pinctrl-names = "default";
#address-cells = <1>;
#size-cells = <0>;
};
...
......@@ -11,7 +11,7 @@ maintainers:
- Patrice Chotard <patrice.chotard@foss.st.com>
allOf:
- $ref: "spi-controller.yaml#"
- $ref: spi-controller.yaml#
properties:
compatible:
......
......@@ -17,7 +17,7 @@ maintainers:
- Fabrice Gasnier <fabrice.gasnier@foss.st.com>
allOf:
- $ref: "spi-controller.yaml#"
- $ref: spi-controller.yaml#
- if:
properties:
compatible:
......@@ -95,7 +95,6 @@ examples:
<&dmamux1 1 40 0x400 0x05>;
dma-names = "rx", "tx";
cs-gpios = <&gpioa 11 0>;
};
...
......@@ -11,7 +11,7 @@ description:
memory devices.
allOf:
- $ref: "spi-controller.yaml#"
- $ref: spi-controller.yaml#
maintainers:
- Michal Simek <michal.simek@xilinx.com>
......
......@@ -65,6 +65,8 @@ properties:
- capella,cm3232
# CM3323: Ambient Light Sensor
- capella,cm3323
# Cisco SPI Petra
- cisco,spi-petra
# High-Precision Digital Thermometer
- dallas,ds1631
# Total-Elapsed-Time Recorder with Alarm
......@@ -169,6 +171,8 @@ properties:
- isil,isl29030
# Intersil ISL68137 Digital Output Configurable PWM Controller
- isil,isl68137
# Linear Technology LTC2488
- lineartechnology,ltc2488
# 5 Bit Programmable, Pulse-Width Modulator
- maxim,ds1050
# 10 kOhm digital potentiometer with I2C interface
......@@ -227,6 +231,8 @@ properties:
- memsic,mxc6655
# Menlo on-board CPLD trivial SPI device
- menlo,m53cpld
# Micron SPI NOR Authenta
- micron,spi-authenta
# Microchip differential I2C ADC, 1 Channel, 18 bit
- microchip,mcp3421
# Microchip differential I2C ADC, 2 Channel, 18 bit
......@@ -305,10 +311,14 @@ properties:
- pulsedlight,lidar-lite-v2
# Renesas ISL29501 time-of-flight sensor
- renesas,isl29501
# Rohm DH2228FV
- rohm,dh2228fv
# S524AD0XF1 (128K/256K-bit Serial EEPROM for Low Power)
- samsung,24ad0xd1
# Samsung Exynos SoC SATA PHY I2C device
- samsung,exynos-sataphy-i2c
# Semtech sx1301 baseband processor
- semtech,sx1301
# Sensirion low power multi-pixel gas sensor with I2C interface
- sensirion,sgpc3
# Sensirion multi-pixel gas sensor with I2C interface
......@@ -323,6 +333,10 @@ properties:
- sensortek,stk8ba50
# SGX Sensortech VZ89X Sensors
- sgx,vz89x
# Silicon Labs EM3581 Zigbee SoC with SPI interface
- silabs,em3581
# Silicon Labs SI3210 Programmable CMOS SLIC/CODEC with SPI interface
- silabs,si3210
# Relative Humidity and Temperature Sensors
- silabs,si7020
# Skyworks SKY81452: Six-Channel White LED Driver with Touch Panel Bias Supply
......
......@@ -141,15 +141,15 @@ field. Below is a sample configuration using the PXA255 NSSP.
::
static struct pxa2xx_spi_chip cs8415a_chip_info = {
.tx_threshold = 8, /* SSP hardward FIFO threshold */
.rx_threshold = 8, /* SSP hardward FIFO threshold */
.tx_threshold = 8, /* SSP hardware FIFO threshold */
.rx_threshold = 8, /* SSP hardware FIFO threshold */
.dma_burst_size = 8, /* Byte wide transfers used so 8 byte bursts */
.timeout = 235, /* See Intel documentation */
};
static struct pxa2xx_spi_chip cs8405a_chip_info = {
.tx_threshold = 8, /* SSP hardward FIFO threshold */
.rx_threshold = 8, /* SSP hardward FIFO threshold */
.tx_threshold = 8, /* SSP hardware FIFO threshold */
.rx_threshold = 8, /* SSP hardware FIFO threshold */
.dma_burst_size = 8, /* Byte wide transfers used so 8 byte bursts */
.timeout = 235, /* See Intel documentation */
};
......@@ -157,7 +157,7 @@ field. Below is a sample configuration using the PXA255 NSSP.
static struct spi_board_info streetracer_spi_board_info[] __initdata = {
{
.modalias = "cs8415a", /* Name of spi_driver for this device */
.max_speed_hz = 3686400, /* Run SSP as fast a possbile */
.max_speed_hz = 3686400, /* Run SSP as fast a possible */
.bus_num = 2, /* Framework bus number */
.chip_select = 0, /* Framework chip select */
.platform_data = NULL; /* No spi_driver specific config */
......@@ -166,7 +166,7 @@ field. Below is a sample configuration using the PXA255 NSSP.
},
{
.modalias = "cs8405a", /* Name of spi_driver for this device */
.max_speed_hz = 3686400, /* Run SSP as fast a possbile */
.max_speed_hz = 3686400, /* Run SSP as fast a possible */
.bus_num = 2, /* Framework bus number */
.chip_select = 1, /* Framework chip select */
.controller_data = &cs8405a_chip_info, /* Master chip config */
......
......@@ -57,7 +57,7 @@ devices might share the same SI/SO pin.
The bitbanger routine in this driver (lm70_txrx) is called back from
the bound "hwmon/lm70" protocol driver through its sysfs hook, using a
spi_write_then_read() call. It performs Mode 0 (SPI/Microwire) bitbanging.
The lm70 driver then inteprets the resulting digital temperature value
The lm70 driver then interprets the resulting digital temperature value
and exports it through sysfs.
A "gotcha": National Semiconductor's LM70 LLP eval board circuit schematic
......
......@@ -105,7 +105,7 @@ find isn't necessarily helpful. The four modes combine two mode bits:
- CPHA indicates the clock phase used to sample data; CPHA=0 says
sample on the leading edge, CPHA=1 means the trailing edge.
Since the signal needs to stablize before it's sampled, CPHA=0
Since the signal needs to stabilize before it's sampled, CPHA=0
implies that its data is written half a clock before the first
clock edge. The chipselect may have made it become available.
......
......@@ -2788,6 +2788,7 @@ M: Patrice Chotard <patrice.chotard@foss.st.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
W: http://www.stlinux.com
F: Documentation/devicetree/bindings/spi/st,ssc-spi.yaml
F: Documentation/devicetree/bindings/i2c/i2c-st.txt
F: arch/arm/boot/dts/sti*
F: arch/arm/mach-sti/
......@@ -4144,6 +4145,17 @@ L: linux-kernel@vger.kernel.org
S: Maintained
F: drivers/phy/broadcom/phy-brcm-usb*
BROADCOM Broadband SoC High Speed SPI Controller DRIVER
M: William Zhang <william.zhang@broadcom.com>
M: Kursad Oney <kursad.oney@broadcom.com>
M: Jonas Gorski <jonas.gorski@gmail.com>
R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
L: linux-spi@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/spi/brcm,bcm63xx-hsspi.yaml
F: drivers/spi/spi-bcm63xx-hsspi.c
F: drivers/spi/spi-bcmbca-hsspi.c
BROADCOM ETHERNET PHY DRIVERS
M: Florian Fainelli <f.fainelli@gmail.com>
R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
......
......@@ -199,6 +199,15 @@ config SPI_BCM_QSPI
based platforms. This driver works for both SPI master for SPI NOR
flash device as well as MSPI device.
config SPI_BCMBCA_HSSPI
tristate "Broadcom BCMBCA HS SPI controller driver"
depends on ARCH_BCMBCA || COMPILE_TEST
help
This enables support for the High Speed SPI controller present on
newer Broadcom BCMBCA SoCs. These SoCs include an updated SPI controller
that adds the capability to allow the driver to control chip select
explicitly.
config SPI_BITBANG
tristate "Utilities for Bitbanging SPI masters"
help
......@@ -247,7 +256,7 @@ config SPI_CADENCE_XSPI
Enable support for the Cadence XSPI Flash controller.
Cadence XSPI is a specialized controller for connecting an SPI
Flash over upto 8bit wide bus. Enable this option if you have a
Flash over up to 8-bit wide bus. Enable this option if you have a
device with a Cadence XSPI controller and want to access the
Flash as an MTD device.
......@@ -295,7 +304,6 @@ config SPI_DW_BT1
tristate "Baikal-T1 SPI driver for DW SPI core"
depends on MIPS_BAIKAL_T1 || COMPILE_TEST
select MULTIPLEXER
select MUX_MMIO
help
Baikal-T1 SoC is equipped with three DW APB SSI-based MMIO SPI
controllers. Two of them are pretty much normal: with IRQ, DMA,
......@@ -448,19 +456,19 @@ config SPI_INTEL
tristate
config SPI_INTEL_PCI
tristate "Intel PCH/PCU SPI flash PCI driver (DANGEROUS)"
tristate "Intel PCH/PCU SPI flash PCI driver"
depends on PCI
depends on X86 || COMPILE_TEST
depends on SPI_MEM
select SPI_INTEL
help
This enables PCI support for the Intel PCH/PCU SPI controller in
master mode. This controller is present in modern Intel hardware
and is used to hold BIOS and other persistent settings. Using
this driver it is possible to upgrade BIOS directly from Linux.
Say N here unless you know what you are doing. Overwriting the
SPI flash may render the system unbootable.
master mode. This controller is used to hold BIOS and other
persistent settings. Controllers present in modern Intel hardware
only work in hardware sequencing mode, this means that the
controller exposes a subset of operations that makes it safer to
use. Using this driver it is possible to upgrade BIOS directly
from Linux.
To compile this driver as a module, choose M here: the module
will be called spi-intel-pci.
......@@ -472,10 +480,11 @@ config SPI_INTEL_PLATFORM
select SPI_INTEL
help
This enables platform support for the Intel PCH/PCU SPI
controller in master mode. This controller is present in modern
Intel hardware and is used to hold BIOS and other persistent
settings. Using this driver it is possible to upgrade BIOS
directly from Linux.
controller in master mode that is used to hold BIOS and other
persistent settings. Most of these controllers work in
software sequencing mode, which means that the controller
exposes the low level SPI-NOR opcodes to the software. Using
this driver it is possible to upgrade BIOS directly from Linux.
Say N here unless you know what you are doing. Overwriting the
SPI flash may render the system unbootable.
......@@ -1142,9 +1151,6 @@ config SPI_SPIDEV
help
This supports user mode SPI protocol drivers.
Note that this application programming interface is EXPERIMENTAL
and hence SUBJECT TO CHANGE WITHOUT NOTICE while it stabilizes.
config SPI_LOOPBACK_TEST
tristate "spi loopback test framework support"
depends on m
......
......@@ -30,6 +30,7 @@ obj-$(CONFIG_SPI_BCM2835) += spi-bcm2835.o
obj-$(CONFIG_SPI_BCM2835AUX) += spi-bcm2835aux.o
obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o
obj-$(CONFIG_SPI_BCM63XX_HSSPI) += spi-bcm63xx-hsspi.o
obj-$(CONFIG_SPI_BCMBCA_HSSPI) += spi-bcmbca-hsspi.o
obj-$(CONFIG_SPI_BCM_QSPI) += spi-iproc-qspi.o spi-brcmstb-qspi.o spi-bcm-qspi.o
obj-$(CONFIG_SPI_BITBANG) += spi-bitbang.o
obj-$(CONFIG_SPI_BUTTERFLY) += spi-butterfly.o
......
......@@ -406,7 +406,7 @@ static int atmel_qspi_set_cfg(struct atmel_qspi *aq,
static int atmel_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
{
struct atmel_qspi *aq = spi_controller_get_devdata(mem->spi->master);
struct atmel_qspi *aq = spi_controller_get_devdata(mem->spi->controller);
u32 sr, offset;
int err;
......@@ -476,7 +476,7 @@ static const struct spi_controller_mem_ops atmel_qspi_mem_ops = {
static int atmel_qspi_setup(struct spi_device *spi)
{
struct spi_controller *ctrl = spi->master;
struct spi_controller *ctrl = spi->controller;
struct atmel_qspi *aq = spi_controller_get_devdata(ctrl);
unsigned long src_rate;
u32 scbr;
......@@ -512,7 +512,7 @@ static int atmel_qspi_setup(struct spi_device *spi)
static int atmel_qspi_set_cs_timing(struct spi_device *spi)
{
struct spi_controller *ctrl = spi->master;
struct spi_controller *ctrl = spi->controller;
struct atmel_qspi *aq = spi_controller_get_devdata(ctrl);
unsigned long clk_rate;
u32 cs_setup;
......@@ -582,7 +582,7 @@ static int atmel_qspi_probe(struct platform_device *pdev)
struct resource *res;
int irq, err = 0;
ctrl = devm_spi_alloc_master(&pdev->dev, sizeof(*aq));
ctrl = devm_spi_alloc_host(&pdev->dev, sizeof(*aq));
if (!ctrl)
return -ENOMEM;
......
......@@ -24,7 +24,7 @@
#define ALTERA_SPI_TXDATA 4
#define ALTERA_SPI_STATUS 8
#define ALTERA_SPI_CONTROL 12
#define ALTERA_SPI_SLAVE_SEL 20
#define ALTERA_SPI_TARGET_SEL 20
#define ALTERA_SPI_STATUS_ROE_MSK 0x8
#define ALTERA_SPI_STATUS_TOE_MSK 0x10
......@@ -67,7 +67,7 @@ static int altr_spi_readl(struct altera_spi *hw, unsigned int reg,
static inline struct altera_spi *altera_spi_to_hw(struct spi_device *sdev)
{
return spi_master_get_devdata(sdev->master);
return spi_controller_get_devdata(sdev->controller);
}
static void altera_spi_set_cs(struct spi_device *spi, bool is_high)
......@@ -77,9 +77,9 @@ static void altera_spi_set_cs(struct spi_device *spi, bool is_high)
if (is_high) {
hw->imr &= ~ALTERA_SPI_CONTROL_SSO_MSK;
altr_spi_writel(hw, ALTERA_SPI_CONTROL, hw->imr);
altr_spi_writel(hw, ALTERA_SPI_SLAVE_SEL, 0);
altr_spi_writel(hw, ALTERA_SPI_TARGET_SEL, 0);
} else {
altr_spi_writel(hw, ALTERA_SPI_SLAVE_SEL,
altr_spi_writel(hw, ALTERA_SPI_TARGET_SEL,
BIT(spi->chip_select));
hw->imr |= ALTERA_SPI_CONTROL_SSO_MSK;
altr_spi_writel(hw, ALTERA_SPI_CONTROL, hw->imr);
......@@ -139,10 +139,10 @@ static void altera_spi_rx_word(struct altera_spi *hw)
hw->count++;
}
static int altera_spi_txrx(struct spi_master *master,
static int altera_spi_txrx(struct spi_controller *host,
struct spi_device *spi, struct spi_transfer *t)
{
struct altera_spi *hw = spi_master_get_devdata(master);
struct altera_spi *hw = spi_controller_get_devdata(host);
u32 val;
hw->tx = t->tx_buf;
......@@ -175,15 +175,15 @@ static int altera_spi_txrx(struct spi_master *master,
altera_spi_rx_word(hw);
}
spi_finalize_current_transfer(master);
spi_finalize_current_transfer(host);
return 0;
}
irqreturn_t altera_spi_irq(int irq, void *dev)
{
struct spi_master *master = dev;
struct altera_spi *hw = spi_master_get_devdata(master);
struct spi_controller *host = dev;
struct altera_spi *hw = spi_controller_get_devdata(host);
altera_spi_rx_word(hw);
......@@ -194,20 +194,20 @@ irqreturn_t altera_spi_irq(int irq, void *dev)
hw->imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK;
altr_spi_writel(hw, ALTERA_SPI_CONTROL, hw->imr);
spi_finalize_current_transfer(master);
spi_finalize_current_transfer(host);
}
return IRQ_HANDLED;
}
EXPORT_SYMBOL_GPL(altera_spi_irq);
void altera_spi_init_master(struct spi_master *master)
void altera_spi_init_host(struct spi_controller *host)
{
struct altera_spi *hw = spi_master_get_devdata(master);
struct altera_spi *hw = spi_controller_get_devdata(host);
u32 val;
master->transfer_one = altera_spi_txrx;
master->set_cs = altera_spi_set_cs;
host->transfer_one = altera_spi_txrx;
host->set_cs = altera_spi_set_cs;
/* program defaults into the registers */
hw->imr = 0; /* disable spi interrupts */
......@@ -217,6 +217,6 @@ void altera_spi_init_master(struct spi_master *master)
if (val & ALTERA_SPI_STATUS_RRDY_MSK)
altr_spi_readl(hw, ALTERA_SPI_RXDATA, &val); /* flush rxdata */
}
EXPORT_SYMBOL_GPL(altera_spi_init_master);
EXPORT_SYMBOL_GPL(altera_spi_init_host);
MODULE_LICENSE("GPL");
......@@ -104,20 +104,20 @@ static const struct regmap_config indirect_regbus_cfg = {
.reg_read = indirect_bus_reg_read,
};
static void config_spi_master(void __iomem *base, struct spi_master *master)
static void config_spi_host(void __iomem *base, struct spi_controller *host)
{
u64 v;
v = readq(base + SPI_CORE_PARAMETER);
master->mode_bits = SPI_CS_HIGH;
host->mode_bits = SPI_CS_HIGH;
if (FIELD_GET(CLK_POLARITY, v))
master->mode_bits |= SPI_CPOL;
host->mode_bits |= SPI_CPOL;
if (FIELD_GET(CLK_PHASE, v))
master->mode_bits |= SPI_CPHA;
host->mode_bits |= SPI_CPHA;
master->num_chipselect = FIELD_GET(NUM_CHIPSELECT, v);
master->bits_per_word_mask =
host->num_chipselect = FIELD_GET(NUM_CHIPSELECT, v);
host->bits_per_word_mask =
SPI_BPW_RANGE_MASK(1, FIELD_GET(DATA_WIDTH, v));
}
......@@ -125,18 +125,18 @@ static int dfl_spi_altera_probe(struct dfl_device *dfl_dev)
{
struct spi_board_info board_info = { 0 };
struct device *dev = &dfl_dev->dev;
struct spi_master *master;
struct spi_controller *host;
struct altera_spi *hw;
void __iomem *base;
int err;
master = devm_spi_alloc_master(dev, sizeof(struct altera_spi));
if (!master)
host = devm_spi_alloc_host(dev, sizeof(struct altera_spi));
if (!host)
return -ENOMEM;
master->bus_num = -1;
host->bus_num = -1;
hw = spi_master_get_devdata(master);
hw = spi_controller_get_devdata(host);
hw->dev = dev;
......@@ -145,10 +145,10 @@ static int dfl_spi_altera_probe(struct dfl_device *dfl_dev)
if (IS_ERR(base))
return PTR_ERR(base);
config_spi_master(base, master);
config_spi_host(base, host);
dev_dbg(dev, "%s cs %u bpm 0x%x mode 0x%x\n", __func__,
master->num_chipselect, master->bits_per_word_mask,
master->mode_bits);
host->num_chipselect, host->bits_per_word_mask,
host->mode_bits);
hw->regmap = devm_regmap_init(dev, NULL, base, &indirect_regbus_cfg);
if (IS_ERR(hw->regmap))
......@@ -156,11 +156,11 @@ static int dfl_spi_altera_probe(struct dfl_device *dfl_dev)
hw->irq = -EINVAL;
altera_spi_init_master(master);
altera_spi_init_host(host);
err = devm_spi_register_master(dev, master);
err = devm_spi_register_controller(dev, host);
if (err)
return dev_err_probe(dev, err, "%s failed to register spi master\n",
return dev_err_probe(dev, err, "%s failed to register spi host\n",
__func__);
if (dfl_dev->revision == FME_FEATURE_REV_MAX10_SPI_N5010)
......@@ -172,7 +172,7 @@ static int dfl_spi_altera_probe(struct dfl_device *dfl_dev)
board_info.bus_num = 0;
board_info.chip_select = 0;
if (!spi_new_device(master, &board_info)) {
if (!spi_new_device(host, &board_info)) {
dev_err(dev, "%s failed to create SPI device: %s\n",
__func__, board_info.modalias);
}
......
......@@ -39,16 +39,16 @@ static int altera_spi_probe(struct platform_device *pdev)
struct altera_spi_platform_data *pdata = dev_get_platdata(&pdev->dev);
enum altera_spi_type type = ALTERA_SPI_TYPE_UNKNOWN;
struct altera_spi *hw;
struct spi_master *master;
struct spi_controller *host;
int err = -ENODEV;
u16 i;
master = spi_alloc_master(&pdev->dev, sizeof(struct altera_spi));
if (!master)
host = spi_alloc_host(&pdev->dev, sizeof(struct altera_spi));
if (!host)
return err;
/* setup the master state. */
master->bus_num = -1;
/* setup the host state. */
host->bus_num = -1;
if (pdata) {
if (pdata->num_chipselect > ALTERA_SPI_MAX_CS) {
......@@ -59,18 +59,18 @@ static int altera_spi_probe(struct platform_device *pdev)
goto exit;
}
master->num_chipselect = pdata->num_chipselect;
master->mode_bits = pdata->mode_bits;
master->bits_per_word_mask = pdata->bits_per_word_mask;
host->num_chipselect = pdata->num_chipselect;
host->mode_bits = pdata->mode_bits;
host->bits_per_word_mask = pdata->bits_per_word_mask;
} else {
master->num_chipselect = 16;
master->mode_bits = SPI_CS_HIGH;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 16);
host->num_chipselect = 16;
host->mode_bits = SPI_CS_HIGH;
host->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 16);
}
master->dev.of_node = pdev->dev.of_node;
host->dev.of_node = pdev->dev.of_node;
hw = spi_master_get_devdata(master);
hw = spi_controller_get_devdata(host);
hw->dev = &pdev->dev;
if (platid)
......@@ -107,24 +107,24 @@ static int altera_spi_probe(struct platform_device *pdev)
}
}
altera_spi_init_master(master);
altera_spi_init_host(host);
/* irq is optional */
hw->irq = platform_get_irq(pdev, 0);
if (hw->irq >= 0) {
err = devm_request_irq(&pdev->dev, hw->irq, altera_spi_irq, 0,
pdev->name, master);
pdev->name, host);
if (err)
goto exit;
}
err = devm_spi_register_master(&pdev->dev, master);
err = devm_spi_register_controller(&pdev->dev, host);
if (err)
goto exit;
if (pdata) {
for (i = 0; i < pdata->num_devices; i++) {
if (!spi_new_device(master, pdata->devices + i))
if (!spi_new_device(host, pdata->devices + i))
dev_warn(&pdev->dev,
"unable to create SPI device: %s\n",
pdata->devices[i].modalias);
......@@ -135,7 +135,7 @@ static int altera_spi_probe(struct platform_device *pdev)
return 0;
exit:
spi_master_put(master);
spi_controller_put(host);
return err;
}
......
......@@ -61,7 +61,7 @@ static inline int ar934x_spi_clk_div(struct ar934x_spi *sp, unsigned int freq)
static int ar934x_spi_setup(struct spi_device *spi)
{
struct ar934x_spi *sp = spi_controller_get_devdata(spi->master);
struct ar934x_spi *sp = spi_controller_get_devdata(spi->controller);
if ((spi->max_speed_hz == 0) ||
(spi->max_speed_hz > (sp->clk_freq / 2))) {
......@@ -74,10 +74,10 @@ static int ar934x_spi_setup(struct spi_device *spi)
return 0;
}
static int ar934x_spi_transfer_one_message(struct spi_controller *master,
static int ar934x_spi_transfer_one_message(struct spi_controller *ctlr,
struct spi_message *m)
{
struct ar934x_spi *sp = spi_controller_get_devdata(master);
struct ar934x_spi *sp = spi_controller_get_devdata(ctlr);
struct spi_transfer *t = NULL;
struct spi_device *spi = m->spi;
unsigned long trx_done, trx_cur;
......@@ -150,7 +150,7 @@ static int ar934x_spi_transfer_one_message(struct spi_controller *master,
msg_done:
m->status = stat;
spi_finalize_current_message(master);
spi_finalize_current_message(ctlr);
return 0;
}
......@@ -183,7 +183,7 @@ static int ar934x_spi_probe(struct platform_device *pdev)
if (ret)
return ret;
ctlr = devm_spi_alloc_master(&pdev->dev, sizeof(*sp));
ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(*sp));
if (!ctlr) {
dev_info(&pdev->dev, "failed to allocate spi controller\n");
ret = -ENOMEM;
......
......@@ -100,7 +100,7 @@
#define A3700_SPI_CLK_CAPT_EDGE BIT(7)
struct a3700_spi {
struct spi_master *master;
struct spi_controller *host;
void __iomem *base;
struct clk *clk;
unsigned int irq;
......@@ -174,7 +174,7 @@ static int a3700_spi_pin_mode_set(struct a3700_spi *a3700_spi,
val |= A3700_SPI_ADDR_PIN;
break;
default:
dev_err(&a3700_spi->master->dev, "wrong pin mode %u", pin_mode);
dev_err(&a3700_spi->host->dev, "wrong pin mode %u", pin_mode);
return -EINVAL;
}
......@@ -278,7 +278,7 @@ static int a3700_spi_fifo_flush(struct a3700_spi *a3700_spi)
static void a3700_spi_init(struct a3700_spi *a3700_spi)
{
struct spi_master *master = a3700_spi->master;
struct spi_controller *host = a3700_spi->host;
u32 val;
int i;
......@@ -295,14 +295,14 @@ static void a3700_spi_init(struct a3700_spi *a3700_spi)
/* Disable AUTO_CS and deactivate all chip-selects */
a3700_spi_auto_cs_unset(a3700_spi);
for (i = 0; i < master->num_chipselect; i++)
for (i = 0; i < host->num_chipselect; i++)
a3700_spi_deactivate_cs(a3700_spi, i);
/* Enable FIFO mode */
a3700_spi_fifo_mode_set(a3700_spi, true);
/* Set SPI mode */
a3700_spi_mode_set(a3700_spi, master->mode_bits);
a3700_spi_mode_set(a3700_spi, host->mode_bits);
/* Reset counters */
spireg_write(a3700_spi, A3700_SPI_IF_HDR_CNT_REG, 0);
......@@ -315,11 +315,11 @@ static void a3700_spi_init(struct a3700_spi *a3700_spi)
static irqreturn_t a3700_spi_interrupt(int irq, void *dev_id)
{
struct spi_master *master = dev_id;
struct spi_controller *host = dev_id;
struct a3700_spi *a3700_spi;
u32 cause;
a3700_spi = spi_master_get_devdata(master);
a3700_spi = spi_controller_get_devdata(host);
/* Get interrupt causes */
cause = spireg_read(a3700_spi, A3700_SPI_INT_STAT_REG);
......@@ -344,7 +344,7 @@ static bool a3700_spi_wait_completion(struct spi_device *spi)
unsigned int ctrl_reg;
unsigned long timeout_jiffies;
a3700_spi = spi_master_get_devdata(spi->master);
a3700_spi = spi_controller_get_devdata(spi->controller);
/* SPI interrupt is edge-triggered, which means an interrupt will
* be generated only when detecting a specific status bit changed
......@@ -393,7 +393,7 @@ static bool a3700_spi_transfer_wait(struct spi_device *spi,
{
struct a3700_spi *a3700_spi;
a3700_spi = spi_master_get_devdata(spi->master);
a3700_spi = spi_controller_get_devdata(spi->controller);
a3700_spi->wait_mask = bit_mask;
return a3700_spi_wait_completion(spi);
......@@ -417,7 +417,7 @@ static void a3700_spi_transfer_setup(struct spi_device *spi,
{
struct a3700_spi *a3700_spi;
a3700_spi = spi_master_get_devdata(spi->master);
a3700_spi = spi_controller_get_devdata(spi->controller);
a3700_spi_clock_set(a3700_spi, xfer->speed_hz);
......@@ -434,7 +434,7 @@ static void a3700_spi_transfer_setup(struct spi_device *spi,
static void a3700_spi_set_cs(struct spi_device *spi, bool enable)
{
struct a3700_spi *a3700_spi = spi_master_get_devdata(spi->master);
struct a3700_spi *a3700_spi = spi_controller_get_devdata(spi->controller);
if (!enable)
a3700_spi_activate_cs(a3700_spi, spi->chip_select);
......@@ -565,10 +565,10 @@ static void a3700_spi_transfer_abort_fifo(struct a3700_spi *a3700_spi)
spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
}
static int a3700_spi_prepare_message(struct spi_master *master,
static int a3700_spi_prepare_message(struct spi_controller *host,
struct spi_message *message)
{
struct a3700_spi *a3700_spi = spi_master_get_devdata(master);
struct a3700_spi *a3700_spi = spi_controller_get_devdata(host);
struct spi_device *spi = message->spi;
int ret;
......@@ -588,11 +588,11 @@ static int a3700_spi_prepare_message(struct spi_master *master,
return 0;
}
static int a3700_spi_transfer_one_fifo(struct spi_master *master,
static int a3700_spi_transfer_one_fifo(struct spi_controller *host,
struct spi_device *spi,
struct spi_transfer *xfer)
{
struct a3700_spi *a3700_spi = spi_master_get_devdata(master);
struct a3700_spi *a3700_spi = spi_controller_get_devdata(host);
int ret = 0, timeout = A3700_SPI_TIMEOUT;
unsigned int nbits = 0, byte_len;
u32 val;
......@@ -732,16 +732,16 @@ static int a3700_spi_transfer_one_fifo(struct spi_master *master,
error:
a3700_spi_transfer_abort_fifo(a3700_spi);
out:
spi_finalize_current_transfer(master);
spi_finalize_current_transfer(host);
return ret;
}
static int a3700_spi_transfer_one_full_duplex(struct spi_master *master,
static int a3700_spi_transfer_one_full_duplex(struct spi_controller *host,
struct spi_device *spi,
struct spi_transfer *xfer)
{
struct a3700_spi *a3700_spi = spi_master_get_devdata(master);
struct a3700_spi *a3700_spi = spi_controller_get_devdata(host);
u32 val;
/* Disable FIFO mode */
......@@ -777,27 +777,27 @@ static int a3700_spi_transfer_one_full_duplex(struct spi_master *master,
}
spi_finalize_current_transfer(master);
spi_finalize_current_transfer(host);
return 0;
}
static int a3700_spi_transfer_one(struct spi_master *master,
static int a3700_spi_transfer_one(struct spi_controller *host,
struct spi_device *spi,
struct spi_transfer *xfer)
{
a3700_spi_transfer_setup(spi, xfer);
if (xfer->tx_buf && xfer->rx_buf)
return a3700_spi_transfer_one_full_duplex(master, spi, xfer);
return a3700_spi_transfer_one_full_duplex(host, spi, xfer);
return a3700_spi_transfer_one_fifo(master, spi, xfer);
return a3700_spi_transfer_one_fifo(host, spi, xfer);
}
static int a3700_spi_unprepare_message(struct spi_master *master,
static int a3700_spi_unprepare_message(struct spi_controller *host,
struct spi_message *message)
{
struct a3700_spi *a3700_spi = spi_master_get_devdata(master);
struct a3700_spi *a3700_spi = spi_controller_get_devdata(host);
clk_disable(a3700_spi->clk);
......@@ -815,14 +815,14 @@ static int a3700_spi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *of_node = dev->of_node;
struct spi_master *master;
struct spi_controller *host;
struct a3700_spi *spi;
u32 num_cs = 0;
int irq, ret = 0;
master = spi_alloc_master(dev, sizeof(*spi));
if (!master) {
dev_err(dev, "master allocation failed\n");
host = spi_alloc_host(dev, sizeof(*spi));
if (!host) {
dev_err(dev, "host allocation failed\n");
ret = -ENOMEM;
goto out;
}
......@@ -833,23 +833,23 @@ static int a3700_spi_probe(struct platform_device *pdev)
goto error;
}
master->bus_num = pdev->id;
master->dev.of_node = of_node;
master->mode_bits = SPI_MODE_3;
master->num_chipselect = num_cs;
master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(32);
master->prepare_message = a3700_spi_prepare_message;
master->transfer_one = a3700_spi_transfer_one;
master->unprepare_message = a3700_spi_unprepare_message;
master->set_cs = a3700_spi_set_cs;
master->mode_bits |= (SPI_RX_DUAL | SPI_TX_DUAL |
host->bus_num = pdev->id;
host->dev.of_node = of_node;
host->mode_bits = SPI_MODE_3;
host->num_chipselect = num_cs;
host->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(32);
host->prepare_message = a3700_spi_prepare_message;
host->transfer_one = a3700_spi_transfer_one;
host->unprepare_message = a3700_spi_unprepare_message;
host->set_cs = a3700_spi_set_cs;
host->mode_bits |= (SPI_RX_DUAL | SPI_TX_DUAL |
SPI_RX_QUAD | SPI_TX_QUAD);
platform_set_drvdata(pdev, master);
platform_set_drvdata(pdev, host);
spi = spi_master_get_devdata(master);
spi = spi_controller_get_devdata(host);
spi->master = master;
spi->host = host;
spi->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(spi->base)) {
......@@ -878,23 +878,23 @@ static int a3700_spi_probe(struct platform_device *pdev)
goto error;
}
master->max_speed_hz = min_t(unsigned long, A3700_SPI_MAX_SPEED_HZ,
host->max_speed_hz = min_t(unsigned long, A3700_SPI_MAX_SPEED_HZ,
clk_get_rate(spi->clk));
master->min_speed_hz = DIV_ROUND_UP(clk_get_rate(spi->clk),
host->min_speed_hz = DIV_ROUND_UP(clk_get_rate(spi->clk),
A3700_SPI_MAX_PRESCALE);
a3700_spi_init(spi);
ret = devm_request_irq(dev, spi->irq, a3700_spi_interrupt, 0,
dev_name(dev), master);
dev_name(dev), host);
if (ret) {
dev_err(dev, "could not request IRQ: %d\n", ret);
goto error_clk;
}
ret = devm_spi_register_master(dev, master);
ret = devm_spi_register_controller(dev, host);
if (ret) {
dev_err(dev, "Failed to register master\n");
dev_err(dev, "Failed to register host\n");
goto error_clk;
}
......@@ -903,15 +903,15 @@ static int a3700_spi_probe(struct platform_device *pdev)
error_clk:
clk_unprepare(spi->clk);
error:
spi_master_put(master);
spi_controller_put(host);
out:
return ret;
}
static int a3700_spi_remove(struct platform_device *pdev)
{
struct spi_master *master = platform_get_drvdata(pdev);
struct a3700_spi *spi = spi_master_get_devdata(master);
struct spi_controller *host = platform_get_drvdata(pdev);
struct a3700_spi *spi = spi_controller_get_devdata(host);
clk_unprepare(spi->clk);
......
......@@ -38,7 +38,7 @@
#define US_CR_TXEN BIT(6)
#define US_CR_TXDIS BIT(7)
#define US_MR_SPI_MASTER 0x0E
#define US_MR_SPI_HOST 0x0E
#define US_MR_CHRL GENMASK(7, 6)
#define US_MR_CPHA BIT(8)
#define US_MR_CPOL BIT(16)
......@@ -61,7 +61,7 @@
#define US_OVRE_RXRDY_IRQS (US_IR_OVRE | US_IR_RXRDY)
#define US_INIT \
(US_MR_SPI_MASTER | US_MR_CHRL | US_MR_CLKO | US_MR_WRDBT)
(US_MR_SPI_HOST | US_MR_CHRL | US_MR_CLKO | US_MR_WRDBT)
#define US_DMA_MIN_BYTES 16
#define US_DMA_TIMEOUT (msecs_to_jiffies(1000))
......@@ -104,7 +104,7 @@ struct at91_usart_spi {
static void dma_callback(void *data)
{
struct spi_controller *ctlr = data;
struct at91_usart_spi *aus = spi_master_get_devdata(ctlr);
struct at91_usart_spi *aus = spi_controller_get_devdata(ctlr);
at91_usart_spi_writel(aus, IER, US_IR_RXRDY);
aus->current_rx_remaining_bytes = 0;
......@@ -115,7 +115,7 @@ static bool at91_usart_spi_can_dma(struct spi_controller *ctrl,
struct spi_device *spi,
struct spi_transfer *xfer)
{
struct at91_usart_spi *aus = spi_master_get_devdata(ctrl);
struct at91_usart_spi *aus = spi_controller_get_devdata(ctrl);
return aus->use_dma && xfer->len >= US_DMA_MIN_BYTES;
}
......@@ -216,7 +216,7 @@ static void at91_usart_spi_stop_dma(struct spi_controller *ctlr)
static int at91_usart_spi_dma_transfer(struct spi_controller *ctlr,
struct spi_transfer *xfer)
{
struct at91_usart_spi *aus = spi_master_get_devdata(ctlr);
struct at91_usart_spi *aus = spi_controller_get_devdata(ctlr);
struct dma_chan *rxchan = ctlr->dma_rx;
struct dma_chan *txchan = ctlr->dma_tx;
struct dma_async_tx_descriptor *rxdesc;
......@@ -334,7 +334,7 @@ at91_usart_spi_set_xfer_speed(struct at91_usart_spi *aus,
static irqreturn_t at91_usart_spi_interrupt(int irq, void *dev_id)
{
struct spi_controller *controller = dev_id;
struct at91_usart_spi *aus = spi_master_get_devdata(controller);
struct at91_usart_spi *aus = spi_controller_get_devdata(controller);
spin_lock(&aus->lock);
at91_usart_spi_read_status(aus);
......@@ -359,7 +359,7 @@ static irqreturn_t at91_usart_spi_interrupt(int irq, void *dev_id)
static int at91_usart_spi_setup(struct spi_device *spi)
{
struct at91_usart_spi *aus = spi_master_get_devdata(spi->controller);
struct at91_usart_spi *aus = spi_controller_get_devdata(spi->controller);
u32 *ausd = spi->controller_state;
unsigned int mr = at91_usart_spi_readl(aus, MR);
......@@ -399,7 +399,7 @@ static int at91_usart_spi_transfer_one(struct spi_controller *ctlr,
struct spi_device *spi,
struct spi_transfer *xfer)
{
struct at91_usart_spi *aus = spi_master_get_devdata(ctlr);
struct at91_usart_spi *aus = spi_controller_get_devdata(ctlr);
unsigned long dma_timeout = 0;
int ret = 0;
......@@ -444,7 +444,7 @@ static int at91_usart_spi_transfer_one(struct spi_controller *ctlr,
static int at91_usart_spi_prepare_message(struct spi_controller *ctlr,
struct spi_message *message)
{
struct at91_usart_spi *aus = spi_master_get_devdata(ctlr);
struct at91_usart_spi *aus = spi_controller_get_devdata(ctlr);
struct spi_device *spi = message->spi;
u32 *ausd = spi->controller_state;
......@@ -458,7 +458,7 @@ static int at91_usart_spi_prepare_message(struct spi_controller *ctlr,
static int at91_usart_spi_unprepare_message(struct spi_controller *ctlr,
struct spi_message *message)
{
struct at91_usart_spi *aus = spi_master_get_devdata(ctlr);
struct at91_usart_spi *aus = spi_controller_get_devdata(ctlr);
at91_usart_spi_writel(aus, CR, US_RESET | US_DISABLE);
at91_usart_spi_writel(aus, IDR, US_OVRE_RXRDY_IRQS);
......@@ -515,7 +515,7 @@ static int at91_usart_spi_probe(struct platform_device *pdev)
return PTR_ERR(clk);
ret = -ENOMEM;
controller = spi_alloc_master(&pdev->dev, sizeof(*aus));
controller = spi_alloc_host(&pdev->dev, sizeof(*aus));
if (!controller)
goto at91_usart_spi_probe_fail;
......@@ -539,7 +539,7 @@ static int at91_usart_spi_probe(struct platform_device *pdev)
US_MAX_CLK_DIV);
platform_set_drvdata(pdev, controller);
aus = spi_master_get_devdata(controller);
aus = spi_controller_get_devdata(controller);
aus->dev = &pdev->dev;
aus->regs = devm_ioremap_resource(&pdev->dev, regs);
......@@ -574,9 +574,9 @@ static int at91_usart_spi_probe(struct platform_device *pdev)
spin_lock_init(&aus->lock);
init_completion(&aus->xfer_completion);
ret = devm_spi_register_master(&pdev->dev, controller);
ret = devm_spi_register_controller(&pdev->dev, controller);
if (ret)
goto at91_usart_fail_register_master;
goto at91_usart_fail_register_controller;
dev_info(&pdev->dev,
"AT91 USART SPI Controller version 0x%x at %pa (irq %d)\n",
......@@ -585,19 +585,19 @@ static int at91_usart_spi_probe(struct platform_device *pdev)
return 0;
at91_usart_fail_register_master:
at91_usart_fail_register_controller:
at91_usart_spi_release_dma(controller);
at91_usart_fail_dma:
clk_disable_unprepare(clk);
at91_usart_spi_probe_fail:
spi_master_put(controller);
spi_controller_put(controller);
return ret;
}
__maybe_unused static int at91_usart_spi_runtime_suspend(struct device *dev)
{
struct spi_controller *ctlr = dev_get_drvdata(dev);
struct at91_usart_spi *aus = spi_master_get_devdata(ctlr);
struct at91_usart_spi *aus = spi_controller_get_devdata(ctlr);
clk_disable_unprepare(aus->clk);
pinctrl_pm_select_sleep_state(dev);
......@@ -608,7 +608,7 @@ __maybe_unused static int at91_usart_spi_runtime_suspend(struct device *dev)
__maybe_unused static int at91_usart_spi_runtime_resume(struct device *dev)
{
struct spi_controller *ctrl = dev_get_drvdata(dev);
struct at91_usart_spi *aus = spi_master_get_devdata(ctrl);
struct at91_usart_spi *aus = spi_controller_get_devdata(ctrl);
pinctrl_pm_select_default_state(dev);
......@@ -633,7 +633,7 @@ __maybe_unused static int at91_usart_spi_suspend(struct device *dev)
__maybe_unused static int at91_usart_spi_resume(struct device *dev)
{
struct spi_controller *ctrl = dev_get_drvdata(dev);
struct at91_usart_spi *aus = spi_master_get_devdata(ctrl);
struct at91_usart_spi *aus = spi_controller_get_devdata(ctrl);
int ret;
if (!pm_runtime_suspended(dev)) {
......@@ -650,7 +650,7 @@ __maybe_unused static int at91_usart_spi_resume(struct device *dev)
static int at91_usart_spi_remove(struct platform_device *pdev)
{
struct spi_controller *ctlr = platform_get_drvdata(pdev);
struct at91_usart_spi *aus = spi_master_get_devdata(ctlr);
struct at91_usart_spi *aus = spi_controller_get_devdata(ctlr);
at91_usart_spi_release_dma(ctlr);
clk_disable_unprepare(aus->clk);
......
......@@ -58,7 +58,7 @@ static inline void ath79_spi_wr(struct ath79_spi *sp, unsigned int reg, u32 val)
static inline struct ath79_spi *ath79_spidev_to_sp(struct spi_device *spi)
{
return spi_master_get_devdata(spi->master);
return spi_controller_get_devdata(spi->controller);
}
static inline void ath79_spi_delay(struct ath79_spi *sp, unsigned int nsecs)
......@@ -120,7 +120,7 @@ static u32 ath79_spi_txrx_mode0(struct spi_device *spi, unsigned int nsecs,
else
out = ioc & ~AR71XX_SPI_IOC_DO;
/* setup MSB (to slave) on trailing edge */
/* setup MSB (to target) on trailing edge */
ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out);
ath79_spi_delay(sp, nsecs);
ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out | AR71XX_SPI_IOC_CLK);
......@@ -168,28 +168,28 @@ static const struct spi_controller_mem_ops ath79_mem_ops = {
static int ath79_spi_probe(struct platform_device *pdev)
{
struct spi_master *master;
struct spi_controller *host;
struct ath79_spi *sp;
unsigned long rate;
int ret;
master = spi_alloc_master(&pdev->dev, sizeof(*sp));
if (master == NULL) {
dev_err(&pdev->dev, "failed to allocate spi master\n");
host = spi_alloc_host(&pdev->dev, sizeof(*sp));
if (host == NULL) {
dev_err(&pdev->dev, "failed to allocate spi host\n");
return -ENOMEM;
}
sp = spi_master_get_devdata(master);
master->dev.of_node = pdev->dev.of_node;
sp = spi_controller_get_devdata(host);
host->dev.of_node = pdev->dev.of_node;
platform_set_drvdata(pdev, sp);
master->use_gpio_descriptors = true;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
master->flags = SPI_MASTER_GPIO_SS;
master->num_chipselect = 3;
master->mem_ops = &ath79_mem_ops;
host->use_gpio_descriptors = true;
host->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
host->flags = SPI_MASTER_GPIO_SS;
host->num_chipselect = 3;
host->mem_ops = &ath79_mem_ops;
sp->bitbang.master = master;
sp->bitbang.master = host;
sp->bitbang.chipselect = ath79_spi_chipselect;
sp->bitbang.txrx_word[SPI_MODE_0] = ath79_spi_txrx_mode0;
sp->bitbang.flags = SPI_CS_HIGH;
......@@ -197,18 +197,18 @@ static int ath79_spi_probe(struct platform_device *pdev)
sp->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(sp->base)) {
ret = PTR_ERR(sp->base);
goto err_put_master;
goto err_put_host;
}
sp->clk = devm_clk_get(&pdev->dev, "ahb");
if (IS_ERR(sp->clk)) {
ret = PTR_ERR(sp->clk);
goto err_put_master;
goto err_put_host;
}
ret = clk_prepare_enable(sp->clk);
if (ret)
goto err_put_master;
goto err_put_host;
rate = DIV_ROUND_UP(clk_get_rate(sp->clk), MHZ);
if (!rate) {
......@@ -231,8 +231,8 @@ static int ath79_spi_probe(struct platform_device *pdev)
ath79_spi_disable(sp);
err_clk_disable:
clk_disable_unprepare(sp->clk);
err_put_master:
spi_master_put(sp->bitbang.master);
err_put_host:
spi_controller_put(host);
return ret;
}
......@@ -244,7 +244,7 @@ static int ath79_spi_remove(struct platform_device *pdev)
spi_bitbang_stop(&sp->bitbang);
ath79_spi_disable(sp);
clk_disable_unprepare(sp->clk);
spi_master_put(sp->bitbang.master);
spi_controller_put(sp->bitbang.master);
return 0;
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -84,6 +84,7 @@ struct cqspi_st {
u32 trigger_address;
u32 wr_delay;
bool use_direct_mode;
bool use_direct_mode_wr;
struct cqspi_flash_pdata f_pdata[CQSPI_MAX_CHIPSELECT];
bool use_dma_read;
u32 pd_dev_id;
......@@ -531,6 +532,17 @@ static int cqspi_command_read(struct cqspi_flash_pdata *f_pdata,
/* 0 means 1 byte. */
reg |= (((n_rx - 1) & CQSPI_REG_CMDCTRL_RD_BYTES_MASK)
<< CQSPI_REG_CMDCTRL_RD_BYTES_LSB);
/* setup ADDR BIT field */
if (op->addr.nbytes) {
reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB);
reg |= ((op->addr.nbytes - 1) &
CQSPI_REG_CMDCTRL_ADD_BYTES_MASK)
<< CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;
writel(op->addr.val, reg_base + CQSPI_REG_CMDADDRESS);
}
status = cqspi_exec_flash_cmd(cqspi, reg);
if (status)
return status;
......@@ -549,6 +561,9 @@ static int cqspi_command_read(struct cqspi_flash_pdata *f_pdata,
memcpy(rxbuf, &reg, read_len);
}
/* Reset CMD_CTRL Reg once command read completes */
writel(0, reg_base + CQSPI_REG_CMDCTRL);
return 0;
}
......@@ -613,7 +628,12 @@ static int cqspi_command_write(struct cqspi_flash_pdata *f_pdata,
}
}
return cqspi_exec_flash_cmd(cqspi, reg);
ret = cqspi_exec_flash_cmd(cqspi, reg);
/* Reset CMD_CTRL Reg once command write completes */
writel(0, reg_base + CQSPI_REG_CMDCTRL);
return ret;
}
static int cqspi_read_setup(struct cqspi_flash_pdata *f_pdata,
......@@ -937,6 +957,12 @@ static int cqspi_write_setup(struct cqspi_flash_pdata *f_pdata,
reg = readl(reg_base + CQSPI_REG_WR_COMPLETION_CTRL);
reg |= CQSPI_REG_WR_DISABLE_AUTO_POLL;
writel(reg, reg_base + CQSPI_REG_WR_COMPLETION_CTRL);
/*
* DAC mode require auto polling as flash needs to be polled
* for write completion in case of bubble in SPI transaction
* due to slow CPU/DMA master.
*/
cqspi->use_direct_mode_wr = false;
}
reg = readl(reg_base + CQSPI_REG_SIZE);
......@@ -1222,7 +1248,7 @@ static ssize_t cqspi_write(struct cqspi_flash_pdata *f_pdata,
* data.
*/
if (!op->cmd.dtr && cqspi->use_direct_mode &&
((to + len) <= cqspi->ahb_size)) {
cqspi->use_direct_mode_wr && ((to + len) <= cqspi->ahb_size)) {
memcpy_toio(cqspi->ahb_base + to, buf, len);
return cqspi_wait_idle(cqspi);
}
......@@ -1333,7 +1359,13 @@ static int cqspi_mem_process(struct spi_mem *mem, const struct spi_mem_op *op)
cqspi_configure(f_pdata, mem->spi->max_speed_hz);
if (op->data.dir == SPI_MEM_DATA_IN && op->data.buf.in) {
if (!op->addr.nbytes)
/*
* Performing reads in DAC mode forces to read minimum 4 bytes
* which is unsupported on some flash devices during register
* reads, prefer STIG mode for such small reads.
*/
if (!op->addr.nbytes ||
op->data.nbytes <= CQSPI_STIG_DATA_LEN_MAX)
return cqspi_command_read(f_pdata, op);
return cqspi_read(f_pdata, op);
......@@ -1692,8 +1724,10 @@ static int cqspi_probe(struct platform_device *pdev)
cqspi->master_ref_clk_hz);
if (ddata->hwcaps_mask & CQSPI_SUPPORTS_OCTAL)
master->mode_bits |= SPI_RX_OCTAL | SPI_TX_OCTAL;
if (!(ddata->quirks & CQSPI_DISABLE_DAC_MODE))
if (!(ddata->quirks & CQSPI_DISABLE_DAC_MODE)) {
cqspi->use_direct_mode = true;
cqspi->use_direct_mode_wr = true;
}
if (ddata->quirks & CQSPI_SUPPORT_EXTERNAL_DMA)
cqspi->use_dma_read = true;
if (ddata->quirks & CQSPI_NO_SUPPORT_WR_COMPLETION)
......
......@@ -87,6 +87,8 @@ struct spi_geni_master {
struct completion cs_done;
struct completion cancel_done;
struct completion abort_done;
struct completion tx_reset_done;
struct completion rx_reset_done;
unsigned int oversampling;
spinlock_t lock;
int irq;
......@@ -95,6 +97,8 @@ struct spi_geni_master {
struct dma_chan *tx;
struct dma_chan *rx;
int cur_xfer_mode;
dma_addr_t tx_se_dma;
dma_addr_t rx_se_dma;
};
static int get_spi_clk_cfg(unsigned int speed_hz,
......@@ -129,23 +133,27 @@ static int get_spi_clk_cfg(unsigned int speed_hz,
return ret;
}
static void handle_fifo_timeout(struct spi_master *spi,
static void handle_se_timeout(struct spi_master *spi,
struct spi_message *msg)
{
struct spi_geni_master *mas = spi_master_get_devdata(spi);
unsigned long time_left;
struct geni_se *se = &mas->se;
const struct spi_transfer *xfer;
spin_lock_irq(&mas->lock);
reinit_completion(&mas->cancel_done);
if (mas->cur_xfer_mode == GENI_SE_FIFO)
writel(0, se->base + SE_GENI_TX_WATERMARK_REG);
xfer = mas->cur_xfer;
mas->cur_xfer = NULL;
geni_se_cancel_m_cmd(se);
spin_unlock_irq(&mas->lock);
time_left = wait_for_completion_timeout(&mas->cancel_done, HZ);
if (time_left)
return;
goto unmap_if_dma;
spin_lock_irq(&mas->lock);
reinit_completion(&mas->abort_done);
......@@ -162,6 +170,39 @@ static void handle_fifo_timeout(struct spi_master *spi,
*/
mas->abort_failed = true;
}
unmap_if_dma:
if (mas->cur_xfer_mode == GENI_SE_DMA) {
if (xfer) {
if (xfer->tx_buf && mas->tx_se_dma) {
spin_lock_irq(&mas->lock);
reinit_completion(&mas->tx_reset_done);
writel(1, se->base + SE_DMA_TX_FSM_RST);
spin_unlock_irq(&mas->lock);
time_left = wait_for_completion_timeout(&mas->tx_reset_done, HZ);
if (!time_left)
dev_err(mas->dev, "DMA TX RESET failed\n");
geni_se_tx_dma_unprep(se, mas->tx_se_dma, xfer->len);
}
if (xfer->rx_buf && mas->rx_se_dma) {
spin_lock_irq(&mas->lock);
reinit_completion(&mas->rx_reset_done);
writel(1, se->base + SE_DMA_RX_FSM_RST);
spin_unlock_irq(&mas->lock);
time_left = wait_for_completion_timeout(&mas->rx_reset_done, HZ);
if (!time_left)
dev_err(mas->dev, "DMA RX RESET failed\n");
geni_se_rx_dma_unprep(se, mas->rx_se_dma, xfer->len);
}
} else {
/*
* This can happen if a timeout happened and we had to wait
* for lock in this function because isr was holding the lock
* and handling transfer completion at that time.
*/
dev_warn(mas->dev, "Cancel/Abort on completed SPI transfer\n");
}
}
}
static void handle_gpi_timeout(struct spi_master *spi, struct spi_message *msg)
......@@ -178,7 +219,8 @@ static void spi_geni_handle_err(struct spi_master *spi, struct spi_message *msg)
switch (mas->cur_xfer_mode) {
case GENI_SE_FIFO:
handle_fifo_timeout(spi, msg);
case GENI_SE_DMA:
handle_se_timeout(spi, msg);
break;
case GENI_GPI_DMA:
handle_gpi_timeout(spi, msg);
......@@ -250,6 +292,8 @@ static void spi_geni_set_cs(struct spi_device *slv, bool set_flag)
}
mas->cs_flag = set_flag;
/* set xfer_mode to FIFO to complete cs_done in isr */
mas->cur_xfer_mode = GENI_SE_FIFO;
reinit_completion(&mas->cs_done);
if (set_flag)
geni_se_setup_m_cmd(se, SPI_CS_ASSERT, 0);
......@@ -260,7 +304,7 @@ static void spi_geni_set_cs(struct spi_device *slv, bool set_flag)
time_left = wait_for_completion_timeout(&mas->cs_done, HZ);
if (!time_left) {
dev_warn(mas->dev, "Timeout setting chip select\n");
handle_fifo_timeout(spi, NULL);
handle_se_timeout(spi, NULL);
}
exit:
......@@ -482,8 +526,12 @@ static bool geni_can_dma(struct spi_controller *ctlr,
{
struct spi_geni_master *mas = spi_master_get_devdata(slv->master);
/* check if dma is supported */
return mas->cur_xfer_mode != GENI_SE_FIFO;
/*
* Return true if transfer needs to be mapped prior to
* calling transfer_one which is the case only for GPI_DMA.
* For SE_DMA mode, map/unmap is done in geni_se_*x_dma_prep.
*/
return mas->cur_xfer_mode == GENI_GPI_DMA;
}
static int spi_geni_prepare_message(struct spi_master *spi,
......@@ -494,6 +542,7 @@ static int spi_geni_prepare_message(struct spi_master *spi,
switch (mas->cur_xfer_mode) {
case GENI_SE_FIFO:
case GENI_SE_DMA:
if (spi_geni_is_abort_still_pending(mas))
return -EBUSY;
ret = setup_fifo_params(spi_msg->spi, spi);
......@@ -597,7 +646,7 @@ static int spi_geni_init(struct spi_geni_master *mas)
break;
}
/*
* in case of failure to get dma channel, we can still do the
* in case of failure to get gpi dma channel, we can still do the
* FIFO mode, so fallthrough
*/
dev_warn(mas->dev, "FIFO mode disabled, but couldn't get DMA, fall back to FIFO mode\n");
......@@ -716,12 +765,12 @@ static void geni_spi_handle_rx(struct spi_geni_master *mas)
mas->rx_rem_bytes -= rx_bytes;
}
static void setup_fifo_xfer(struct spi_transfer *xfer,
static int setup_se_xfer(struct spi_transfer *xfer,
struct spi_geni_master *mas,
u16 mode, struct spi_master *spi)
{
u32 m_cmd = 0;
u32 len;
u32 len, fifo_size;
struct geni_se *se = &mas->se;
int ret;
......@@ -748,7 +797,7 @@ static void setup_fifo_xfer(struct spi_transfer *xfer,
/* Speed and bits per word can be overridden per transfer */
ret = geni_spi_set_clock_and_bw(mas, xfer->speed_hz);
if (ret)
return;
return ret;
mas->tx_rem_bytes = 0;
mas->rx_rem_bytes = 0;
......@@ -772,17 +821,50 @@ static void setup_fifo_xfer(struct spi_transfer *xfer,
mas->rx_rem_bytes = xfer->len;
}
/* Select transfer mode based on transfer length */
fifo_size = mas->tx_fifo_depth * mas->fifo_width_bits / mas->cur_bits_per_word;
mas->cur_xfer_mode = (len <= fifo_size) ? GENI_SE_FIFO : GENI_SE_DMA;
geni_se_select_mode(se, mas->cur_xfer_mode);
/*
* Lock around right before we start the transfer since our
* interrupt could come in at any time now.
*/
spin_lock_irq(&mas->lock);
geni_se_setup_m_cmd(se, m_cmd, FRAGMENTATION);
if (mas->cur_xfer_mode == GENI_SE_DMA) {
if (m_cmd & SPI_RX_ONLY) {
ret = geni_se_rx_dma_prep(se, xfer->rx_buf,
xfer->len, &mas->rx_se_dma);
if (ret) {
dev_err(mas->dev, "Failed to setup Rx dma %d\n", ret);
mas->rx_se_dma = 0;
goto unlock_and_return;
}
}
if (m_cmd & SPI_TX_ONLY) {
ret = geni_se_tx_dma_prep(se, (void *)xfer->tx_buf,
xfer->len, &mas->tx_se_dma);
if (ret) {
dev_err(mas->dev, "Failed to setup Tx dma %d\n", ret);
mas->tx_se_dma = 0;
if (m_cmd & SPI_RX_ONLY) {
/* Unmap rx buffer if duplex transfer */
geni_se_rx_dma_unprep(se, mas->rx_se_dma, xfer->len);
mas->rx_se_dma = 0;
}
goto unlock_and_return;
}
}
} else if (m_cmd & SPI_TX_ONLY) {
if (geni_spi_handle_tx(mas))
writel(mas->tx_wm, se->base + SE_GENI_TX_WATERMARK_REG);
}
unlock_and_return:
spin_unlock_irq(&mas->lock);
return ret;
}
static int spi_geni_transfer_one(struct spi_master *spi,
......@@ -790,6 +872,7 @@ static int spi_geni_transfer_one(struct spi_master *spi,
struct spi_transfer *xfer)
{
struct spi_geni_master *mas = spi_master_get_devdata(spi);
int ret;
if (spi_geni_is_abort_still_pending(mas))
return -EBUSY;
......@@ -798,9 +881,12 @@ static int spi_geni_transfer_one(struct spi_master *spi,
if (!xfer->len)
return 0;
if (mas->cur_xfer_mode == GENI_SE_FIFO) {
setup_fifo_xfer(xfer, mas, slv->mode, spi);
return 1;
if (mas->cur_xfer_mode == GENI_SE_FIFO || mas->cur_xfer_mode == GENI_SE_DMA) {
ret = setup_se_xfer(xfer, mas, slv->mode, spi);
/* SPI framework expects +ve ret code to wait for transfer complete */
if (!ret)
ret = 1;
return ret;
}
return setup_gsi_xfer(xfer, mas, slv, spi);
}
......@@ -823,6 +909,7 @@ static irqreturn_t geni_spi_isr(int irq, void *data)
spin_lock(&mas->lock);
if (mas->cur_xfer_mode == GENI_SE_FIFO) {
if ((m_irq & M_RX_FIFO_WATERMARK_EN) || (m_irq & M_RX_FIFO_LAST_EN))
geni_spi_handle_rx(mas);
......@@ -858,6 +945,36 @@ static irqreturn_t geni_spi_isr(int irq, void *data)
complete(&mas->cs_done);
}
}
} else if (mas->cur_xfer_mode == GENI_SE_DMA) {
const struct spi_transfer *xfer = mas->cur_xfer;
u32 dma_tx_status = readl_relaxed(se->base + SE_DMA_TX_IRQ_STAT);
u32 dma_rx_status = readl_relaxed(se->base + SE_DMA_RX_IRQ_STAT);
if (dma_tx_status)
writel(dma_tx_status, se->base + SE_DMA_TX_IRQ_CLR);
if (dma_rx_status)
writel(dma_rx_status, se->base + SE_DMA_RX_IRQ_CLR);
if (dma_tx_status & TX_DMA_DONE)
mas->tx_rem_bytes = 0;
if (dma_rx_status & RX_DMA_DONE)
mas->rx_rem_bytes = 0;
if (dma_tx_status & TX_RESET_DONE)
complete(&mas->tx_reset_done);
if (dma_rx_status & RX_RESET_DONE)
complete(&mas->rx_reset_done);
if (!mas->tx_rem_bytes && !mas->rx_rem_bytes && xfer) {
if (xfer->tx_buf && mas->tx_se_dma) {
geni_se_tx_dma_unprep(se, mas->tx_se_dma, xfer->len);
mas->tx_se_dma = 0;
}
if (xfer->rx_buf && mas->rx_se_dma) {
geni_se_rx_dma_unprep(se, mas->rx_se_dma, xfer->len);
mas->rx_se_dma = 0;
}
spi_finalize_current_transfer(spi);
mas->cur_xfer = NULL;
}
}
if (m_irq & M_CMD_CANCEL_EN)
complete(&mas->cancel_done);
......@@ -949,6 +1066,8 @@ static int spi_geni_probe(struct platform_device *pdev)
init_completion(&mas->cs_done);
init_completion(&mas->cancel_done);
init_completion(&mas->abort_done);
init_completion(&mas->tx_reset_done);
init_completion(&mas->rx_reset_done);
spin_lock_init(&mas->lock);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_autosuspend_delay(&pdev->dev, 250);
......
......@@ -60,12 +60,12 @@ static int intel_spi_pci_probe(struct pci_dev *pdev,
}
static const struct pci_device_id intel_spi_pci_ids[] = {
{ PCI_VDEVICE(INTEL, 0x02a4), (unsigned long)&bxt_info },
{ PCI_VDEVICE(INTEL, 0x06a4), (unsigned long)&bxt_info },
{ PCI_VDEVICE(INTEL, 0x02a4), (unsigned long)&cnl_info },
{ PCI_VDEVICE(INTEL, 0x06a4), (unsigned long)&cnl_info },
{ PCI_VDEVICE(INTEL, 0x18e0), (unsigned long)&bxt_info },
{ PCI_VDEVICE(INTEL, 0x19e0), (unsigned long)&bxt_info },
{ PCI_VDEVICE(INTEL, 0x1bca), (unsigned long)&bxt_info },
{ PCI_VDEVICE(INTEL, 0x34a4), (unsigned long)&bxt_info },
{ PCI_VDEVICE(INTEL, 0x34a4), (unsigned long)&cnl_info },
{ PCI_VDEVICE(INTEL, 0x38a4), (unsigned long)&bxt_info },
{ PCI_VDEVICE(INTEL, 0x43a4), (unsigned long)&cnl_info },
{ PCI_VDEVICE(INTEL, 0x4b24), (unsigned long)&bxt_info },
......@@ -75,11 +75,14 @@ static const struct pci_device_id intel_spi_pci_ids[] = {
{ PCI_VDEVICE(INTEL, 0x7a24), (unsigned long)&cnl_info },
{ PCI_VDEVICE(INTEL, 0x7aa4), (unsigned long)&cnl_info },
{ PCI_VDEVICE(INTEL, 0x7e23), (unsigned long)&cnl_info },
{ PCI_VDEVICE(INTEL, 0xa0a4), (unsigned long)&bxt_info },
{ PCI_VDEVICE(INTEL, 0x9d24), (unsigned long)&cnl_info },
{ PCI_VDEVICE(INTEL, 0x9da4), (unsigned long)&cnl_info },
{ PCI_VDEVICE(INTEL, 0xa0a4), (unsigned long)&cnl_info },
{ PCI_VDEVICE(INTEL, 0xa1a4), (unsigned long)&bxt_info },
{ PCI_VDEVICE(INTEL, 0xa224), (unsigned long)&bxt_info },
{ PCI_VDEVICE(INTEL, 0xa2a4), (unsigned long)&cnl_info },
{ PCI_VDEVICE(INTEL, 0xa324), (unsigned long)&cnl_info },
{ PCI_VDEVICE(INTEL, 0xa3a4), (unsigned long)&bxt_info },
{ PCI_VDEVICE(INTEL, 0xa3a4), (unsigned long)&cnl_info },
{ },
};
MODULE_DEVICE_TABLE(pci, intel_spi_pci_ids);
......
......@@ -104,7 +104,7 @@
#define BXT_PR 0x84
#define BXT_SSFSTS_CTL 0xa0
#define BXT_FREG_NUM 12
#define BXT_PR_NUM 6
#define BXT_PR_NUM 5
#define CNL_PR 0x84
#define CNL_FREG_NUM 6
......@@ -1368,14 +1368,14 @@ static int intel_spi_populate_chip(struct intel_spi *ispi)
if (!spi_new_device(ispi->master, &chip))
return -ENODEV;
/* Add the second chip if present */
if (ispi->master->num_chipselect < 2)
return 0;
ret = intel_spi_read_desc(ispi);
if (ret)
return ret;
/* Add the second chip if present */
if (ispi->master->num_chipselect < 2)
return 0;
chip.platform_data = NULL;
chip.chip_select = 1;
......
......@@ -71,6 +71,11 @@ module_param(check_ranges, int, 0644);
MODULE_PARM_DESC(check_ranges,
"checks rx_buffer pattern are valid");
static unsigned int delay_ms = 100;
module_param(delay_ms, uint, 0644);
MODULE_PARM_DESC(delay_ms,
"delay between tests, in milliseconds (default: 100)");
/* the actual tests to execute */
static struct spi_test spi_tests[] = {
{
......@@ -1098,7 +1103,8 @@ int spi_test_run_tests(struct spi_device *spi,
* detect the individual tests when using a logic analyzer
* we also add scheduling to avoid potential spi_timeouts...
*/
mdelay(100);
if (delay_ms)
mdelay(delay_ms);
schedule();
}
......
......@@ -325,7 +325,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 && !mem->spi->cs_gpiod) {
if (ctlr->mem_ops && ctlr->mem_ops->exec_op && !mem->spi->cs_gpiod) {
ret = spi_mem_access_start(mem);
if (ret)
return ret;
......
......@@ -195,6 +195,8 @@
#define DATA_READ_MODE_X4 2
#define DATA_READ_MODE_DUAL 5
#define DATA_READ_MODE_QUAD 6
#define DATA_READ_LATCH_LAT GENMASK(9, 8)
#define DATA_READ_LATCH_LAT_S 8
#define PG_LOAD_CUSTOM_EN BIT(7)
#define DATARD_CUSTOM_EN BIT(6)
#define CS_DESELECT_CYC_S 0
......@@ -205,6 +207,9 @@
#define SNF_DLY_CTL3 0x548
#define SFCK_SAM_DLY_S 0
#define SFCK_SAM_DLY GENMASK(5, 0)
#define SFCK_SAM_DLY_TOTAL 9
#define SFCK_SAM_DLY_RANGE 47
#define SNF_STA_CTL1 0x550
#define CUS_PG_DONE BIT(28)
......@@ -297,6 +302,7 @@ struct mtk_snand {
struct device *dev;
struct clk *nfi_clk;
struct clk *pad_clk;
struct clk *nfi_hclk;
void __iomem *nfi_base;
int irq;
struct completion op_done;
......@@ -1339,7 +1345,16 @@ static int mtk_snand_enable_clk(struct mtk_snand *ms)
dev_err(ms->dev, "unable to enable pad clk\n");
goto err1;
}
ret = clk_prepare_enable(ms->nfi_hclk);
if (ret) {
dev_err(ms->dev, "unable to enable nfi hclk\n");
goto err2;
}
return 0;
err2:
clk_disable_unprepare(ms->pad_clk);
err1:
clk_disable_unprepare(ms->nfi_clk);
return ret;
......@@ -1347,6 +1362,7 @@ static int mtk_snand_enable_clk(struct mtk_snand *ms)
static void mtk_snand_disable_clk(struct mtk_snand *ms)
{
clk_disable_unprepare(ms->nfi_hclk);
clk_disable_unprepare(ms->pad_clk);
clk_disable_unprepare(ms->nfi_clk);
}
......@@ -1357,6 +1373,8 @@ static int mtk_snand_probe(struct platform_device *pdev)
const struct of_device_id *dev_id;
struct spi_controller *ctlr;
struct mtk_snand *ms;
unsigned long spi_freq;
u32 val = 0;
int ret;
dev_id = of_match_node(mtk_snand_ids, np);
......@@ -1401,6 +1419,13 @@ static int mtk_snand_probe(struct platform_device *pdev)
goto release_ecc;
}
ms->nfi_hclk = devm_clk_get_optional(&pdev->dev, "nfi_hclk");
if (IS_ERR(ms->nfi_hclk)) {
ret = PTR_ERR(ms->nfi_hclk);
dev_err(&pdev->dev, "unable to get nfi_hclk, err = %d\n", ret);
goto release_ecc;
}
ret = mtk_snand_enable_clk(ms);
if (ret)
goto release_ecc;
......@@ -1428,10 +1453,22 @@ static int mtk_snand_probe(struct platform_device *pdev)
// switch to SNFI mode
nfi_write32(ms, SNF_CFG, SPI_MODE);
ret = of_property_read_u32(np, "rx-sample-delay-ns", &val);
if (!ret)
nfi_rmw32(ms, SNF_DLY_CTL3, SFCK_SAM_DLY,
val * SFCK_SAM_DLY_RANGE / SFCK_SAM_DLY_TOTAL);
ret = of_property_read_u32(np, "mediatek,rx-latch-latency-ns", &val);
if (!ret) {
spi_freq = clk_get_rate(ms->pad_clk);
val = DIV_ROUND_CLOSEST(val, NSEC_PER_SEC / spi_freq);
nfi_rmw32(ms, SNF_MISC_CTL, DATA_READ_LATCH_LAT,
val << DATA_READ_LATCH_LAT_S);
}
// setup an initial page format for ops matching page_cache_op template
// before ECC is called.
ret = mtk_snand_setup_pagefmt(ms, ms->caps->sector_size,
ms->caps->spare_sizes[0]);
ret = mtk_snand_setup_pagefmt(ms, SZ_2K, SZ_64);
if (ret) {
dev_err(ms->dev, "failed to set initial page format\n");
goto disable_clk;
......
......@@ -2091,7 +2091,6 @@ pl022_platform_data_dt_get(struct device *dev)
return NULL;
pd->bus_id = -1;
pd->enable_dma = 1;
of_property_read_u32(np, "pl022,autosuspend-delay",
&pd->autosuspend_delay);
pd->rt = of_property_read_bool(np, "pl022,rt");
......
......@@ -472,10 +472,9 @@ static int synquacer_spi_transfer_one(struct spi_master *master,
read_fifo(sspi);
}
if (status < 0) {
dev_err(sspi->dev, "failed to transfer. status: 0x%x\n",
status);
return status;
if (status == 0) {
dev_err(sspi->dev, "failed to transfer. Timeout.\n");
return -ETIMEDOUT;
}
return 0;
......
......@@ -83,7 +83,7 @@ struct xilinx_spi {
void __iomem *regs; /* virt. address of the control registers */
int irq;
bool force_irq; /* force irq to setup master inhibit */
u8 *rx_ptr; /* pointer in the Tx buffer */
const u8 *tx_ptr; /* pointer in the Rx buffer */
u8 bytes_per_word;
......@@ -248,7 +248,8 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
xspi->rx_ptr = t->rx_buf;
remaining_words = t->len / xspi->bytes_per_word;
if (xspi->irq >= 0 && remaining_words > xspi->buffer_size) {
if (xspi->irq >= 0 &&
(xspi->force_irq || remaining_words > xspi->buffer_size)) {
u32 isr;
use_irq = true;
/* Inhibit irq to avoid spurious irqs on tx_empty*/
......@@ -393,6 +394,7 @@ static int xilinx_spi_probe(struct platform_device *pdev)
struct resource *res;
int ret, num_cs = 0, bits_per_word;
struct spi_master *master;
bool force_irq = false;
u32 tmp;
u8 i;
......@@ -400,6 +402,7 @@ static int xilinx_spi_probe(struct platform_device *pdev)
if (pdata) {
num_cs = pdata->num_chipselect;
bits_per_word = pdata->bits_per_word;
force_irq = pdata->force_irq;
} else {
of_property_read_u32(pdev->dev.of_node, "xlnx,num-ss-bits",
&num_cs);
......@@ -477,6 +480,8 @@ static int xilinx_spi_probe(struct platform_device *pdev)
dev_name(&pdev->dev), xspi);
if (ret)
return ret;
xspi->force_irq = force_irq;
}
/* SPI controller initializations */
......
......@@ -604,7 +604,7 @@ static void spi_dev_set_name(struct spi_device *spi)
}
dev_set_name(&spi->dev, "%s.%u", dev_name(&spi->controller->dev),
spi->chip_select);
spi_get_chipselect(spi, 0));
}
static int spi_dev_check(struct device *dev, void *data)
......@@ -613,7 +613,7 @@ static int spi_dev_check(struct device *dev, void *data)
struct spi_device *new_spi = data;
if (spi->controller == new_spi->controller &&
spi->chip_select == new_spi->chip_select)
spi_get_chipselect(spi, 0) == spi_get_chipselect(new_spi, 0))
return -EBUSY;
return 0;
}
......@@ -638,7 +638,7 @@ static int __spi_add_device(struct spi_device *spi)
status = bus_for_each_dev(&spi_bus_type, NULL, spi, spi_dev_check);
if (status) {
dev_err(dev, "chipselect %d already in use\n",
spi->chip_select);
spi_get_chipselect(spi, 0));
return status;
}
......@@ -649,7 +649,7 @@ static int __spi_add_device(struct spi_device *spi)
}
if (ctlr->cs_gpiods)
spi->cs_gpiod = ctlr->cs_gpiods[spi->chip_select];
spi_set_csgpiod(spi, 0, ctlr->cs_gpiods[spi_get_chipselect(spi, 0)]);
/*
* Drivers may modify this initial i/o setup, but will
......@@ -692,8 +692,8 @@ int spi_add_device(struct spi_device *spi)
int status;
/* Chipselects are numbered 0..max; validate. */
if (spi->chip_select >= ctlr->num_chipselect) {
dev_err(dev, "cs%d >= max %d\n", spi->chip_select,
if (spi_get_chipselect(spi, 0) >= ctlr->num_chipselect) {
dev_err(dev, "cs%d >= max %d\n", spi_get_chipselect(spi, 0),
ctlr->num_chipselect);
return -EINVAL;
}
......@@ -714,8 +714,8 @@ static int spi_add_device_locked(struct spi_device *spi)
struct device *dev = ctlr->dev.parent;
/* Chipselects are numbered 0..max; validate. */
if (spi->chip_select >= ctlr->num_chipselect) {
dev_err(dev, "cs%d >= max %d\n", spi->chip_select,
if (spi_get_chipselect(spi, 0) >= ctlr->num_chipselect) {
dev_err(dev, "cs%d >= max %d\n", spi_get_chipselect(spi, 0),
ctlr->num_chipselect);
return -EINVAL;
}
......@@ -761,7 +761,7 @@ struct spi_device *spi_new_device(struct spi_controller *ctlr,
WARN_ON(strlen(chip->modalias) >= sizeof(proxy->modalias));
proxy->chip_select = chip->chip_select;
spi_set_chipselect(proxy, 0, chip->chip_select);
proxy->max_speed_hz = chip->max_speed_hz;
proxy->mode = chip->mode;
proxy->irq = chip->irq;
......@@ -970,24 +970,23 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
* Avoid calling into the driver (or doing delays) if the chip select
* isn't actually changing from the last time this was called.
*/
if (!force && ((enable && spi->controller->last_cs == spi->chip_select) ||
(!enable && spi->controller->last_cs != spi->chip_select)) &&
if (!force && ((enable && spi->controller->last_cs == spi_get_chipselect(spi, 0)) ||
(!enable && spi->controller->last_cs != spi_get_chipselect(spi, 0))) &&
(spi->controller->last_cs_mode_high == (spi->mode & SPI_CS_HIGH)))
return;
trace_spi_set_cs(spi, activate);
spi->controller->last_cs = enable ? spi->chip_select : -1;
spi->controller->last_cs = enable ? spi_get_chipselect(spi, 0) : -1;
spi->controller->last_cs_mode_high = spi->mode & SPI_CS_HIGH;
if ((spi->cs_gpiod || !spi->controller->set_cs_timing) && !activate) {
if ((spi_get_csgpiod(spi, 0) || !spi->controller->set_cs_timing) && !activate)
spi_delay_exec(&spi->cs_hold, NULL);
}
if (spi->mode & SPI_CS_HIGH)
enable = !enable;
if (spi->cs_gpiod) {
if (spi_get_csgpiod(spi, 0)) {
if (!(spi->mode & SPI_NO_CS)) {
/*
* Historically ACPI has no means of the GPIO polarity and
......@@ -1000,10 +999,10 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
* into account.
*/
if (has_acpi_companion(&spi->dev))
gpiod_set_value_cansleep(spi->cs_gpiod, !enable);
gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), !enable);
else
/* Polarity handled by GPIO library */
gpiod_set_value_cansleep(spi->cs_gpiod, activate);
gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), activate);
}
/* Some SPI masters need both GPIO CS & slave_select */
if ((spi->controller->flags & SPI_MASTER_GPIO_SS) &&
......@@ -1013,7 +1012,7 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
spi->controller->set_cs(spi, !enable);
}
if (spi->cs_gpiod || !spi->controller->set_cs_timing) {
if (spi_get_csgpiod(spi, 0) || !spi->controller->set_cs_timing) {
if (activate)
spi_delay_exec(&spi->cs_setup, NULL);
else
......@@ -1484,6 +1483,13 @@ static void _spi_transfer_cs_change_delay(struct spi_message *msg,
}
}
void spi_transfer_cs_change_delay_exec(struct spi_message *msg,
struct spi_transfer *xfer)
{
_spi_transfer_cs_change_delay(msg, xfer);
}
EXPORT_SYMBOL_GPL(spi_transfer_cs_change_delay_exec);
/*
* spi_transfer_one_message - Default implementation of transfer_one_message()
*
......@@ -1921,7 +1927,7 @@ void spi_take_timestamp_post(struct spi_controller *ctlr,
/* Capture the resolution of the timestamp */
xfer->ptp_sts_word_post = progress;
xfer->timestamped = true;
xfer->timestamped = 1;
}
EXPORT_SYMBOL_GPL(spi_take_timestamp_post);
......@@ -2319,7 +2325,7 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
nc, rc);
return rc;
}
spi->chip_select = value;
spi_set_chipselect(spi, 0, value);
/* Device speed */
if (!of_property_read_u32(nc, "spi-max-frequency", &value))
......@@ -2327,6 +2333,8 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
/* Device CS delays */
of_spi_parse_dt_cs_delay(nc, &spi->cs_setup, "spi-cs-setup-delay-ns");
of_spi_parse_dt_cs_delay(nc, &spi->cs_hold, "spi-cs-hold-delay-ns");
of_spi_parse_dt_cs_delay(nc, &spi->cs_inactive, "spi-cs-inactive-delay-ns");
return 0;
}
......@@ -2436,7 +2444,7 @@ struct spi_device *spi_new_ancillary_device(struct spi_device *spi,
strscpy(ancillary->modalias, "dummy", sizeof(ancillary->modalias));
/* Use provided chip-select for ancillary device */
ancillary->chip_select = chip_select;
spi_set_chipselect(ancillary, 0, chip_select);
/* Take over SPI mode/speed from SPI main device */
ancillary->max_speed_hz = spi->max_speed_hz;
......@@ -2683,7 +2691,7 @@ struct spi_device *acpi_spi_device_alloc(struct spi_controller *ctlr,
spi->mode |= lookup.mode;
spi->irq = lookup.irq;
spi->bits_per_word = lookup.bits_per_word;
spi->chip_select = lookup.chip_select;
spi_set_chipselect(spi, 0, lookup.chip_select);
return spi;
}
......@@ -3064,16 +3072,15 @@ static int spi_controller_check_ops(struct spi_controller *ctlr)
* The controller may implement only the high-level SPI-memory like
* operations if it does not support regular SPI transfers, and this is
* valid use case.
* If ->mem_ops is NULL, we request that at least one of the
* ->transfer_xxx() method be implemented.
* If ->mem_ops or ->mem_ops->exec_op is NULL, we request that at least
* one of the ->transfer_xxx() method be implemented.
*/
if (ctlr->mem_ops) {
if (!ctlr->mem_ops->exec_op)
return -EINVAL;
} else if (!ctlr->transfer && !ctlr->transfer_one &&
if (!ctlr->mem_ops || (ctlr->mem_ops && !ctlr->mem_ops->exec_op)) {
if (!ctlr->transfer && !ctlr->transfer_one &&
!ctlr->transfer_one_message) {
return -EINVAL;
}
}
return 0;
}
......@@ -3645,7 +3652,7 @@ static int spi_set_cs_timing(struct spi_device *spi)
struct device *parent = spi->controller->dev.parent;
int status = 0;
if (spi->controller->set_cs_timing && !spi->cs_gpiod) {
if (spi->controller->set_cs_timing && !spi_get_csgpiod(spi, 0)) {
if (spi->controller->auto_runtime_pm) {
status = pm_runtime_get_sync(parent);
if (status < 0) {
......@@ -3850,7 +3857,7 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
* cs_change is set for each transfer.
*/
if ((spi->mode & SPI_CS_WORD) && (!(ctlr->mode_bits & SPI_CS_WORD) ||
spi->cs_gpiod)) {
spi_get_csgpiod(spi, 0))) {
size_t maxsize;
int ret;
......
......@@ -116,7 +116,6 @@ spidev_sync(struct spidev_data *spidev, struct spi_message *message)
status = spidev_sync_unlocked(spi, message);
mutex_unlock(&spidev->spi_lock);
return status;
}
......@@ -712,6 +711,8 @@ static const struct spi_device_id spidev_spi_ids[] = {
{ .name = "m53cpld" },
{ .name = "spi-petra" },
{ .name = "spi-authenta" },
{ .name = "em3581" },
{ .name = "si3210" },
{},
};
MODULE_DEVICE_TABLE(spi, spidev_spi_ids);
......@@ -730,14 +731,16 @@ static int spidev_of_check(struct device *dev)
}
static const struct of_device_id spidev_dt_ids[] = {
{ .compatible = "rohm,dh2228fv", .data = &spidev_of_check },
{ .compatible = "cisco,spi-petra", .data = &spidev_of_check },
{ .compatible = "dh,dhcom-board", .data = &spidev_of_check },
{ .compatible = "lineartechnology,ltc2488", .data = &spidev_of_check },
{ .compatible = "semtech,sx1301", .data = &spidev_of_check },
{ .compatible = "lwn,bk4", .data = &spidev_of_check },
{ .compatible = "dh,dhcom-board", .data = &spidev_of_check },
{ .compatible = "menlo,m53cpld", .data = &spidev_of_check },
{ .compatible = "cisco,spi-petra", .data = &spidev_of_check },
{ .compatible = "micron,spi-authenta", .data = &spidev_of_check },
{ .compatible = "rohm,dh2228fv", .data = &spidev_of_check },
{ .compatible = "semtech,sx1301", .data = &spidev_of_check },
{ .compatible = "silabs,em3581", .data = &spidev_of_check },
{ .compatible = "silabs,si3210", .data = &spidev_of_check },
{},
};
MODULE_DEVICE_TABLE(of, spidev_dt_ids);
......
......@@ -14,7 +14,7 @@
/**
* struct altera_spi_platform_data - Platform data of the Altera SPI driver
* @mode_bits: Mode bits of SPI master.
* @mode_bits: Mode bits of SPI host.
* @num_chipselect: Number of chipselects.
* @bits_per_word_mask: bitmask of supported bits_per_word for transfers.
* @num_devices: Number of devices that shall be added when the driver
......@@ -46,5 +46,5 @@ struct altera_spi {
};
extern irqreturn_t altera_spi_irq(int irq, void *dev);
extern void altera_spi_init_master(struct spi_master *master);
extern void altera_spi_init_host(struct spi_controller *host);
#endif /* __LINUX_SPI_ALTERA_H */
......@@ -26,6 +26,7 @@ struct spi_controller;
struct spi_transfer;
struct spi_controller_mem_ops;
struct spi_controller_mem_caps;
struct spi_message;
/*
* INTERFACES between SPI master-side drivers and SPI slave protocol handlers,
......@@ -119,6 +120,8 @@ struct spi_delay {
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);
extern void spi_transfer_cs_change_delay_exec(struct spi_message *msg,
struct spi_transfer *xfer);
/**
* struct spi_device - Controller side proxy for an SPI slave device
......@@ -263,7 +266,25 @@ static inline void *spi_get_drvdata(struct spi_device *spi)
return dev_get_drvdata(&spi->dev);
}
struct spi_message;
static inline u8 spi_get_chipselect(struct spi_device *spi, u8 idx)
{
return spi->chip_select;
}
static inline void spi_set_chipselect(struct spi_device *spi, u8 idx, u8 chipselect)
{
spi->chip_select = chipselect;
}
static inline struct gpio_desc *spi_get_csgpiod(struct spi_device *spi, u8 idx)
{
return spi->cs_gpiod;
}
static inline void spi_set_csgpiod(struct spi_device *spi, u8 idx, struct gpio_desc *csgpiod)
{
spi->cs_gpiod = csgpiod;
}
/**
* struct spi_driver - Host side "protocol" driver
......@@ -1001,6 +1022,9 @@ struct spi_transfer {
void *rx_buf;
unsigned len;
#define SPI_TRANS_FAIL_NO_START BIT(0)
u16 error;
dma_addr_t tx_dma;
dma_addr_t rx_dma;
struct sg_table tx_sg;
......@@ -1011,6 +1035,7 @@ struct spi_transfer {
unsigned cs_change:1;
unsigned tx_nbits:3;
unsigned rx_nbits:3;
unsigned timestamped:1;
#define SPI_NBITS_SINGLE 0x01 /* 1bit transfer */
#define SPI_NBITS_DUAL 0x02 /* 2bits transfer */
#define SPI_NBITS_QUAD 0x04 /* 4bits transfer */
......@@ -1027,12 +1052,7 @@ struct spi_transfer {
struct ptp_system_timestamp *ptp_sts;
bool timestamped;
struct list_head transfer_list;
#define SPI_TRANS_FAIL_NO_START BIT(0)
u16 error;
};
/**
......
......@@ -15,6 +15,7 @@ struct xspi_platform_data {
u8 bits_per_word;
struct spi_board_info *devices;
u8 num_devices;
bool force_irq;
};
#endif /* __LINUX_SPI_XILINX_SPI_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment