1
0
Fork 0

Merge branch 'spi-5.5' into spi-next

alistair/sunxi64-5.5-dsi
Mark Brown 2019-11-22 19:56:35 +00:00
commit ca4196aa10
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
73 changed files with 1416 additions and 713 deletions

View File

@ -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>;
};

View File

@ -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"

View File

@ -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>;
};

View File

@ -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>;
};

View File

@ -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>;
};

View 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

View File

@ -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>;
};

View File

@ -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>;
};
...

View File

@ -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>;
...
};
};

View 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>;
};

View File

@ -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>;
};
};
...

View 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))

View 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,

View 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"

View 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);

View File

@ -222,37 +222,13 @@
| 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,

View 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))

View 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);

View 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);

View 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;

View 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;
}

View 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);

View 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

View 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;

View File

@ -4,7 +4,6 @@
#include <linux/io.h>
#include <linux/scatterlist.h>
#include <linux/gpio.h>
/* Register offsets */
#define DW_SPI_CTRL0 0x00

View 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;
}

View 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);

View 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)

View 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;
}

View File

@ -68,6 +68,11 @@
#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)
@ -195,6 +200,7 @@
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);
/*

View 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);

View 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);

View 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;

View 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);

View 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;

View 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);

View 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;

View 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);

View 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);

View 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;

View 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,

View 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);

View 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;

View 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 */

View 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;
sizes[0] = count;
nb_sizes = 1;
}
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;
}
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);

View 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);
}

View 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;

View 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 {

View 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 (pcidev)
pcidev_id = pci_match_id(pxa2xx_spi_pci_compound_match, pcidev);
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 (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);
ssp->irq = platform_get_irq(pdev, 0);
ssp->type = type;
ssp->pdev = pdev;
ssp->port_id = pxa2xx_spi_get_port_id(adev);
if (IS_ERR(ssp->clk))
return NULL;
pdata->is_slave = of_property_read_bool(pdev->dev.of_node, "spi-slave");
ssp->irq = platform_get_irq(pdev, 0);
if (ssp->irq < 0)
return NULL;
ssp->type = type;
ssp->dev = &pdev->dev;
ssp->port_id = pxa2xx_spi_get_port_id(&pdev->dev);
pdata->is_slave = device_property_read_bool(&pdev->dev, "spi-slave");
pdata->num_chipselect = 1;
pdata->enable_dma = true;
pdata->dma_burst_size = 1;

View 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;

View 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);

View 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);

View 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);

View 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;

View 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");

View 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);

View 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);

View 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);
}
}

View 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;

View 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);

View 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);

View 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)

View 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;
}

View 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) {

View 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;

View 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
@ -116,8 +114,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");

View 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);
}

View 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

View File

@ -11,7 +11,6 @@
/* Board specific platform_data */
struct mtk_chip_config {
u32 cs_pol;
u32 sample_sel;
};
#endif

View 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;

View 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);

View 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;
}

View 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;
}