Commit 69609a91 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull spi updates from Mark Brown:
 "The biggest single thing in the diffstat here is a massive overhaul of
  the PXA2xx driver from Andy Shevchenko (the IP is still in use on
  modern Intel systems), though we also have quite a lot of core work as
  well:

   - Better support for mixing native and GPIO chip selects also from
     Andy.

   - Support for devices with multiple chip selects from Sebastian
     Reichel.

   - Helper for polling status registers in spi-mem from Patrice
     Chotard.

   - Support for Renesas RZ/N1 and Rockchip RV1126"

* tag 'spi-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (86 commits)
  spi: core: add dma_map_dev for dma device
  spi: convert Xilinx Zynq UltraScale+ MPSoC GQSPI bindings to YAML
  spi: Fix self assignment issue with ancillary->mode
  spi: spi-sh-msiof: : use proper DMAENGINE API for termination
  spi: spi-rspi: : use proper DMAENGINE API for termination
  spi: spi-rockchip: add description for rv1126
  spi: rockchip: Support SPI_CS_HIGH
  spi: rockchip: Support cs-gpio
  spi: rockchip: Wait for STB status in slave mode tx_xfer
  spi: rockchip: Set rx_fifo interrupt waterline base on transfer item
  spi: rockchip: add compatible string for rv1126
  spi: spi-sun6i: Fix chipselect/clock bug
  spi: dt-bindings: support devices with multiple chipselects
  spi: add ancillary device support
  spi: xilinx: convert to yaml
  spi: convert Cadence SPI bindings to YAML
  spi: stm32-qspi: Remove unused qspi field of struct stm32_qspi_flash
  spi: add of_device_uevent_modalias support
  spi: meson-spicc: fix memory leak in meson_spicc_probe
  spi: meson-spicc: fix a wrong goto jump for avoiding memory leak.
  ...
parents c10383b3 1bee1ecf
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"
...@@ -67,6 +67,12 @@ properties: ...@@ -67,6 +67,12 @@ properties:
const: baikal,bt1-sys-ssi const: baikal,bt1-sys-ssi
- description: Canaan Kendryte K210 SoS SPI Controller - description: Canaan Kendryte K210 SoS SPI Controller
const: canaan,k210-spi const: canaan,k210-spi
- description: Renesas RZ/N1 SPI Controller
items:
- enum:
- renesas,r9a06g032-spi # RZ/N1D
- renesas,r9a06g033-spi # RZ/N1S
- const: renesas,rzn1-spi # RZ/N1
reg: reg:
minItems: 1 minItems: 1
......
Cadence SPI controller Device Tree Bindings
-------------------------------------------
Required properties:
- compatible : Should be "cdns,spi-r1p6" or "xlnx,zynq-spi-r1p6".
- reg : Physical base address and size of SPI registers map.
- interrupts : Property with a value describing the interrupt
number.
- clock-names : List of input clock names - "ref_clk", "pclk"
(See clock bindings for details).
- clocks : Clock phandles (see clock bindings for details).
Optional properties:
- num-cs : Number of chip selects used.
If a decoder is used, this will be the number of
chip selects after the decoder.
- is-decoded-cs : Flag to indicate whether decoder is used or not.
Example:
spi@e0007000 {
compatible = "xlnx,zynq-spi-r1p6";
clock-names = "ref_clk", "pclk";
clocks = <&clkc 26>, <&clkc 35>;
interrupt-parent = <&intc>;
interrupts = <0 49 4>;
num-cs = <4>;
is-decoded-cs = <0>;
reg = <0xe0007000 0x1000>;
} ;
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/spi/spi-cadence.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Cadence SPI controller Device Tree Bindings
maintainers:
- Michal Simek <michal.simek@xilinx.com>
allOf:
- $ref: "spi-controller.yaml#"
properties:
compatible:
enum:
- cdns,spi-r1p6
- xlnx,zynq-spi-r1p6
reg:
maxItems: 1
interrupts:
maxItems: 1
clock-names:
items:
- const: ref_clk
- const: pclk
clocks:
maxItems: 2
num-cs:
description: |
Number of chip selects used. If a decoder is used,
this will be the number of chip selects after the
decoder.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 1
maximum: 4
default: 4
is-decoded-cs:
description: |
Flag to indicate whether decoder is used or not.
$ref: /schemas/types.yaml#/definitions/uint32
enum: [ 0, 1 ]
default: 0
unevaluatedProperties: false
examples:
- |
spi@e0007000 {
compatible = "xlnx,zynq-spi-r1p6";
clock-names = "ref_clk", "pclk";
clocks = <&clkc 26>, <&clkc 35>;
interrupt-parent = <&intc>;
interrupts = <0 49 4>;
num-cs = <4>;
is-decoded-cs = <0>;
reg = <0xe0007000 0x1000>;
};
...
...@@ -114,8 +114,11 @@ patternProperties: ...@@ -114,8 +114,11 @@ patternProperties:
Compatible of the SPI device. Compatible of the SPI device.
reg: reg:
minimum: 0 minItems: 1
maximum: 256 maxItems: 256
items:
minimum: 0
maximum: 256
description: description:
Chip select used by the device. Chip select used by the device.
......
...@@ -33,6 +33,7 @@ properties: ...@@ -33,6 +33,7 @@ properties:
- rockchip,rk3328-spi - rockchip,rk3328-spi
- rockchip,rk3368-spi - rockchip,rk3368-spi
- rockchip,rk3399-spi - rockchip,rk3399-spi
- rockchip,rv1126-spi
- const: rockchip,rk3066-spi - const: rockchip,rk3066-spi
reg: reg:
......
Xilinx SPI controller Device Tree Bindings
-------------------------------------------------
Required properties:
- compatible : Should be "xlnx,xps-spi-2.00.a", "xlnx,xps-spi-2.00.b" or "xlnx,axi-quad-spi-1.00.a"
- reg : Physical base address and size of SPI registers map.
- interrupts : Property with a value describing the interrupt
number.
Optional properties:
- 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 {
compatible = "xlnx,xps-spi-2.00.a";
interrupt-parent = <&intc>;
interrupts = <0 31 1>;
reg = <0x41e00000 0x10000>;
xlnx,num-ss-bits = <0x1>;
xlnx,num-transfer-bits = <32>;
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/spi/spi-xilinx.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Xilinx SPI controller Device Tree Bindings
maintainers:
- Michal Simek <michal.simek@xilinx.com>
allOf:
- $ref: "spi-controller.yaml#"
properties:
compatible:
enum:
- xlnx,xps-spi-2.00.a
- xlnx,xps-spi-2.00.b
- xlnx,axi-quad-spi-1.00.a
reg:
maxItems: 1
interrupts:
maxItems: 1
xlnx,num-ss-bits:
description: Number of chip selects used.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 1
maximum: 32
xlnx,num-transfer-bits:
description: Number of bits per transfer. This will be 8 if not specified.
$ref: /schemas/types.yaml#/definitions/uint32
enum: [8, 16, 32]
default: 8
required:
- compatible
- reg
- interrupts
unevaluatedProperties: false
examples:
- |
spi0: spi@41e00000 {
compatible = "xlnx,xps-spi-2.00.a";
interrupt-parent = <&intc>;
interrupts = <0 31 1>;
reg = <0x41e00000 0x10000>;
xlnx,num-ss-bits = <0x1>;
xlnx,num-transfer-bits = <32>;
};
...
Xilinx Zynq UltraScale+ MPSoC GQSPI controller Device Tree Bindings
-------------------------------------------------------------------
Required properties:
- compatible : Should be "xlnx,zynqmp-qspi-1.0".
- reg : Physical base address and size of GQSPI registers map.
- interrupts : Property with a value describing the interrupt
number.
- clock-names : List of input clock names - "ref_clk", "pclk"
(See clock bindings for details).
- clocks : Clock phandles (see clock bindings for details).
Optional properties:
- num-cs : Number of chip selects used.
Example:
qspi: spi@ff0f0000 {
compatible = "xlnx,zynqmp-qspi-1.0";
clock-names = "ref_clk", "pclk";
clocks = <&misc_clk &misc_clk>;
interrupts = <0 15 4>;
interrupt-parent = <&gic>;
num-cs = <1>;
reg = <0x0 0xff0f0000 0x1000>,<0x0 0xc0000000 0x8000000>;
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/spi/spi-zynqmp-qspi.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Xilinx Zynq UltraScale+ MPSoC GQSPI controller Device Tree Bindings
maintainers:
- Michal Simek <michal.simek@xilinx.com>
allOf:
- $ref: "spi-controller.yaml#"
properties:
compatible:
const: xlnx,zynqmp-qspi-1.0
reg:
maxItems: 2
interrupts:
maxItems: 1
clock-names:
items:
- const: ref_clk
- const: pclk
clocks:
maxItems: 2
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/xlnx-zynqmp-clk.h>
soc {
#address-cells = <2>;
#size-cells = <2>;
qspi: spi@ff0f0000 {
compatible = "xlnx,zynqmp-qspi-1.0";
clocks = <&zynqmp_clk QSPI_REF>, <&zynqmp_clk LPD_LSBUS>;
clock-names = "ref_clk", "pclk";
interrupts = <0 15 4>;
interrupt-parent = <&gic>;
reg = <0x0 0xff0f0000 0x0 0x1000>,
<0x0 0xc0000000 0x0 0x8000000>;
};
};
...@@ -2,43 +2,47 @@ ...@@ -2,43 +2,47 @@
PXA2xx SPI on SSP driver HOWTO PXA2xx SPI on SSP driver HOWTO
============================== ==============================
This a mini howto on the pxa2xx_spi driver. The driver turns a PXA2xx This a mini HOWTO on the pxa2xx_spi driver. The driver turns a PXA2xx
synchronous serial port into a SPI master controller synchronous serial port into an SPI master controller
(see Documentation/spi/spi-summary.rst). The driver has the following features (see Documentation/spi/spi-summary.rst). The driver has the following features
- Support for any PXA2xx SSP - Support for any PXA2xx and compatible SSP.
- SSP PIO and SSP DMA data transfers. - SSP PIO and SSP DMA data transfers.
- External and Internal (SSPFRM) chip selects. - External and Internal (SSPFRM) chip selects.
- Per slave device (chip) configuration. - Per slave device (chip) configuration.
- Full suspend, freeze, resume support. - Full suspend, freeze, resume support.
The driver is built around a "spi_message" fifo serviced by workqueue and a The driver is built around a &struct spi_message FIFO serviced by kernel
tasklet. The workqueue, "pump_messages", drives message fifo and the tasklet thread. The kernel thread, spi_pump_messages(), drives message FIFO and
(pump_transfer) is responsible for queuing SPI transactions and setting up and is responsible for queuing SPI transactions and setting up and launching
launching the dma/interrupt driven transfers. the DMA or interrupt driven transfers.
Declaring PXA2xx Master Controllers Declaring PXA2xx Master Controllers
----------------------------------- -----------------------------------
Typically a SPI master is defined in the arch/.../mach-*/board-*.c as a Typically, for a legacy platform, an SPI master is defined in the
"platform device". The master configuration is passed to the driver via a table arch/.../mach-*/board-*.c as a "platform device". The master configuration
found in include/linux/spi/pxa2xx_spi.h:: is passed to the driver via a table found in include/linux/spi/pxa2xx_spi.h::
struct pxa2xx_spi_controller { struct pxa2xx_spi_controller {
u16 num_chipselect; u16 num_chipselect;
u8 enable_dma; u8 enable_dma;
...
}; };
The "pxa2xx_spi_controller.num_chipselect" field is used to determine the number of The "pxa2xx_spi_controller.num_chipselect" field is used to determine the number of
slave device (chips) attached to this SPI master. slave device (chips) attached to this SPI master.
The "pxa2xx_spi_controller.enable_dma" field informs the driver that SSP DMA should The "pxa2xx_spi_controller.enable_dma" field informs the driver that SSP DMA should
be used. This caused the driver to acquire two DMA channels: rx_channel and be used. This caused the driver to acquire two DMA channels: Rx channel and
tx_channel. The rx_channel has a higher DMA service priority the tx_channel. Tx channel. The Rx channel has a higher DMA service priority than the Tx channel.
See the "PXA2xx Developer Manual" section "DMA Controller". See the "PXA2xx Developer Manual" section "DMA Controller".
For the new platforms the description of the controller and peripheral devices
comes from Device Tree or ACPI.
NSSP MASTER SAMPLE NSSP MASTER SAMPLE
------------------ ------------------
Below is a sample configuration using the PXA255 NSSP:: Below is a sample configuration using the PXA255 NSSP for a legacy platform::
static struct resource pxa_spi_nssp_resources[] = { static struct resource pxa_spi_nssp_resources[] = {
[0] = { [0] = {
...@@ -79,9 +83,10 @@ Below is a sample configuration using the PXA255 NSSP:: ...@@ -79,9 +83,10 @@ Below is a sample configuration using the PXA255 NSSP::
Declaring Slave Devices Declaring Slave Devices
----------------------- -----------------------
Typically each SPI slave (chip) is defined in the arch/.../mach-*/board-*.c Typically, for a legacy platform, each SPI slave (chip) is defined in the
using the "spi_board_info" structure found in "linux/spi/spi.h". See arch/.../mach-*/board-*.c using the "spi_board_info" structure found in
"Documentation/spi/spi-summary.rst" for additional information. "linux/spi/spi.h". See "Documentation/spi/spi-summary.rst" for additional
information.
Each slave device attached to the PXA must provide slave specific configuration Each slave device attached to the PXA must provide slave specific configuration
information via the structure "pxa2xx_spi_chip" found in information via the structure "pxa2xx_spi_chip" found in
...@@ -101,9 +106,9 @@ device. All fields are optional. ...@@ -101,9 +106,9 @@ device. All fields are optional.
}; };
The "pxa2xx_spi_chip.tx_threshold" and "pxa2xx_spi_chip.rx_threshold" fields are The "pxa2xx_spi_chip.tx_threshold" and "pxa2xx_spi_chip.rx_threshold" fields are
used to configure the SSP hardware fifo. These fields are critical to the used to configure the SSP hardware FIFO. These fields are critical to the
performance of pxa2xx_spi driver and misconfiguration will result in rx performance of pxa2xx_spi driver and misconfiguration will result in rx
fifo overruns (especially in PIO mode transfers). Good default values are:: FIFO overruns (especially in PIO mode transfers). Good default values are::
.tx_threshold = 8, .tx_threshold = 8,
.rx_threshold = 8, .rx_threshold = 8,
...@@ -118,7 +123,7 @@ use a value of 8. The driver will determine a reasonable default if ...@@ -118,7 +123,7 @@ use a value of 8. The driver will determine a reasonable default if
dma_burst_size == 0. dma_burst_size == 0.
The "pxa2xx_spi_chip.timeout" fields is used to efficiently handle The "pxa2xx_spi_chip.timeout" fields is used to efficiently handle
trailing bytes in the SSP receiver fifo. The correct value for this field is trailing bytes in the SSP receiver FIFO. The correct value for this field is
dependent on the SPI bus speed ("spi_board_info.max_speed_hz") and the specific dependent on the SPI bus speed ("spi_board_info.max_speed_hz") and the specific
slave device. Please note that the PXA2xx SSP 1 does not support trailing byte slave device. Please note that the PXA2xx SSP 1 does not support trailing byte
timeouts and must busy-wait any trailing bytes. timeouts and must busy-wait any trailing bytes.
...@@ -131,19 +136,19 @@ testing. ...@@ -131,19 +136,19 @@ testing.
The "pxa2xx_spi_chip.cs_control" field is used to point to a board specific The "pxa2xx_spi_chip.cs_control" field is used to point to a board specific
function for asserting/deasserting a slave device chip select. If the field is function for asserting/deasserting a slave device chip select. If the field is
NULL, the pxa2xx_spi master controller driver assumes that the SSP port is NULL, the pxa2xx_spi master controller driver assumes that the SSP port is
configured to use SSPFRM instead. configured to use GPIO or SSPFRM instead.
NOTE: the SPI driver cannot control the chip select if SSPFRM is used, so the NOTE: the SPI driver cannot control the chip select if SSPFRM is used, so the
chipselect is dropped after each spi_transfer. Most devices need chip select chipselect is dropped after each spi_transfer. Most devices need chip select
asserted around the complete message. Use SSPFRM as a GPIO (through cs_control) asserted around the complete message. Use SSPFRM as a GPIO (through a descriptor)
to accommodate these chips. to accommodate these chips.
NSSP SLAVE SAMPLE NSSP SLAVE SAMPLE
----------------- -----------------
The pxa2xx_spi_chip structure is passed to the pxa2xx_spi driver in the For a legacy platform or in some other cases, the pxa2xx_spi_chip structure
"spi_board_info.controller_data" field. Below is a sample configuration using is passed to the pxa2xx_spi driver in the "spi_board_info.controller_data"
the PXA255 NSSP. field. Below is a sample configuration using the PXA255 NSSP.
:: ::
...@@ -212,7 +217,9 @@ DMA and PIO I/O Support ...@@ -212,7 +217,9 @@ DMA and PIO I/O Support
----------------------- -----------------------
The pxa2xx_spi driver supports both DMA and interrupt driven PIO message The pxa2xx_spi driver supports both DMA and interrupt driven PIO message
transfers. The driver defaults to PIO mode and DMA transfers must be enabled transfers. The driver defaults to PIO mode and DMA transfers must be enabled
by setting the "enable_dma" flag in the "pxa2xx_spi_controller" structure. The DMA by setting the "enable_dma" flag in the "pxa2xx_spi_controller" structure.
For the newer platforms, that are known to support DMA, the driver will enable
it automatically and try it first with a possible fallback to PIO. The DMA
mode supports both coherent and stream based DMA mappings. mode supports both coherent and stream based DMA mappings.
The following logic is used to determine the type of I/O to be used on The following logic is used to determine the type of I/O to be used on
...@@ -236,5 +243,4 @@ a per "spi_transfer" basis:: ...@@ -236,5 +243,4 @@ a per "spi_transfer" basis::
THANKS TO THANKS TO
--------- ---------
David Brownell and others for mentoring the development of this driver. David Brownell and others for mentoring the development of this driver.
...@@ -473,20 +473,26 @@ static int spinand_erase_op(struct spinand_device *spinand, ...@@ -473,20 +473,26 @@ static int spinand_erase_op(struct spinand_device *spinand,
return spi_mem_exec_op(spinand->spimem, &op); return spi_mem_exec_op(spinand->spimem, &op);
} }
static int spinand_wait(struct spinand_device *spinand, u8 *s) static int spinand_wait(struct spinand_device *spinand,
unsigned long initial_delay_us,
unsigned long poll_delay_us,
u8 *s)
{ {
unsigned long timeo = jiffies + msecs_to_jiffies(400); struct spi_mem_op op = SPINAND_GET_FEATURE_OP(REG_STATUS,
spinand->scratchbuf);
u8 status; u8 status;
int ret; int ret;
do { ret = spi_mem_poll_status(spinand->spimem, &op, STATUS_BUSY, 0,
ret = spinand_read_status(spinand, &status); initial_delay_us,
if (ret) poll_delay_us,
return ret; SPINAND_WAITRDY_TIMEOUT_MS);
if (ret)
return ret;
if (!(status & STATUS_BUSY)) status = *spinand->scratchbuf;
goto out; if (!(status & STATUS_BUSY))
} while (time_before(jiffies, timeo)); goto out;
/* /*
* Extra read, just in case the STATUS_READY bit has changed * Extra read, just in case the STATUS_READY bit has changed
...@@ -526,7 +532,10 @@ static int spinand_reset_op(struct spinand_device *spinand) ...@@ -526,7 +532,10 @@ static int spinand_reset_op(struct spinand_device *spinand)
if (ret) if (ret)
return ret; return ret;
return spinand_wait(spinand, NULL); return spinand_wait(spinand,
SPINAND_RESET_INITIAL_DELAY_US,
SPINAND_RESET_POLL_DELAY_US,
NULL);
} }
static int spinand_lock_block(struct spinand_device *spinand, u8 lock) static int spinand_lock_block(struct spinand_device *spinand, u8 lock)
...@@ -549,7 +558,10 @@ static int spinand_read_page(struct spinand_device *spinand, ...@@ -549,7 +558,10 @@ static int spinand_read_page(struct spinand_device *spinand,
if (ret) if (ret)
return ret; return ret;
ret = spinand_wait(spinand, &status); ret = spinand_wait(spinand,
SPINAND_READ_INITIAL_DELAY_US,
SPINAND_READ_POLL_DELAY_US,
&status);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -585,7 +597,10 @@ static int spinand_write_page(struct spinand_device *spinand, ...@@ -585,7 +597,10 @@ static int spinand_write_page(struct spinand_device *spinand,
if (ret) if (ret)
return ret; return ret;
ret = spinand_wait(spinand, &status); ret = spinand_wait(spinand,
SPINAND_WRITE_INITIAL_DELAY_US,
SPINAND_WRITE_POLL_DELAY_US,
&status);
if (!ret && (status & STATUS_PROG_FAILED)) if (!ret && (status & STATUS_PROG_FAILED))
return -EIO; return -EIO;
...@@ -768,7 +783,11 @@ static int spinand_erase(struct nand_device *nand, const struct nand_pos *pos) ...@@ -768,7 +783,11 @@ static int spinand_erase(struct nand_device *nand, const struct nand_pos *pos)
if (ret) if (ret)
return ret; return ret;
ret = spinand_wait(spinand, &status); ret = spinand_wait(spinand,
SPINAND_ERASE_INITIAL_DELAY_US,
SPINAND_ERASE_POLL_DELAY_US,
&status);
if (!ret && (status & STATUS_ERASE_FAILED)) if (!ret && (status & STATUS_ERASE_FAILED))
ret = -EIO; ret = -EIO;
......
...@@ -806,6 +806,7 @@ config SPI_STM32_QSPI ...@@ -806,6 +806,7 @@ config SPI_STM32_QSPI
tristate "STMicroelectronics STM32 QUAD SPI controller" tristate "STMicroelectronics STM32 QUAD SPI controller"
depends on ARCH_STM32 || COMPILE_TEST depends on ARCH_STM32 || COMPILE_TEST
depends on OF depends on OF
depends on SPI_MEM
help help
This enables support for the Quad SPI controller in master mode. This enables support for the Quad SPI controller in master mode.
This driver does not support generic SPI. The implementation only This driver does not support generic SPI. The implementation only
......
...@@ -148,10 +148,8 @@ static int dfl_spi_altera_probe(struct dfl_device *dfl_dev) ...@@ -148,10 +148,8 @@ static int dfl_spi_altera_probe(struct dfl_device *dfl_dev)
base = devm_ioremap_resource(dev, &dfl_dev->mmio_res); base = devm_ioremap_resource(dev, &dfl_dev->mmio_res);
if (IS_ERR(base)) { if (IS_ERR(base))
dev_err(dev, "%s get mem resource fail!\n", __func__);
return PTR_ERR(base); return PTR_ERR(base);
}
config_spi_master(base, master); config_spi_master(base, master);
dev_dbg(dev, "%s cs %u bpm 0x%x mode 0x%x\n", __func__, dev_dbg(dev, "%s cs %u bpm 0x%x mode 0x%x\n", __func__,
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/platform_data/spi-ath79.h>
#define DRV_NAME "ath79-spi" #define DRV_NAME "ath79-spi"
...@@ -138,7 +137,6 @@ static int ath79_spi_probe(struct platform_device *pdev) ...@@ -138,7 +137,6 @@ static int ath79_spi_probe(struct platform_device *pdev)
{ {
struct spi_master *master; struct spi_master *master;
struct ath79_spi *sp; struct ath79_spi *sp;
struct ath79_spi_platform_data *pdata;
unsigned long rate; unsigned long rate;
int ret; int ret;
...@@ -152,15 +150,10 @@ static int ath79_spi_probe(struct platform_device *pdev) ...@@ -152,15 +150,10 @@ static int ath79_spi_probe(struct platform_device *pdev)
master->dev.of_node = pdev->dev.of_node; master->dev.of_node = pdev->dev.of_node;
platform_set_drvdata(pdev, sp); platform_set_drvdata(pdev, sp);
pdata = dev_get_platdata(&pdev->dev);
master->use_gpio_descriptors = true; master->use_gpio_descriptors = true;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
master->flags = SPI_MASTER_GPIO_SS; master->flags = SPI_MASTER_GPIO_SS;
if (pdata) { master->num_chipselect = 3;
master->bus_num = pdata->bus_num;
master->num_chipselect = pdata->num_chipselect;
}
sp->bitbang.master = master; sp->bitbang.master = master;
sp->bitbang.chipselect = ath79_spi_chipselect; sp->bitbang.chipselect = ath79_spi_chipselect;
......
...@@ -700,7 +700,6 @@ static void atmel_spi_next_xfer_pio(struct spi_master *master, ...@@ -700,7 +700,6 @@ static void atmel_spi_next_xfer_pio(struct spi_master *master,
static int atmel_spi_next_xfer_dma_submit(struct spi_master *master, static int atmel_spi_next_xfer_dma_submit(struct spi_master *master,
struct spi_transfer *xfer, struct spi_transfer *xfer,
u32 *plen) u32 *plen)
__must_hold(&as->lock)
{ {
struct atmel_spi *as = spi_master_get_devdata(master); struct atmel_spi *as = spi_master_get_devdata(master);
struct dma_chan *rxchan = master->dma_rx; struct dma_chan *rxchan = master->dma_rx;
...@@ -716,8 +715,6 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master, ...@@ -716,8 +715,6 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master,
if (!rxchan || !txchan) if (!rxchan || !txchan)
return -ENODEV; return -ENODEV;
/* release lock for DMA operations */
atmel_spi_unlock(as);
*plen = xfer->len; *plen = xfer->len;
...@@ -786,15 +783,12 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master, ...@@ -786,15 +783,12 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master,
rxchan->device->device_issue_pending(rxchan); rxchan->device->device_issue_pending(rxchan);
txchan->device->device_issue_pending(txchan); txchan->device->device_issue_pending(txchan);
/* take back lock */
atmel_spi_lock(as);
return 0; return 0;
err_dma: err_dma:
spi_writel(as, IDR, SPI_BIT(OVRES)); spi_writel(as, IDR, SPI_BIT(OVRES));
atmel_spi_stop_dma(master); atmel_spi_stop_dma(master);
err_exit: err_exit:
atmel_spi_lock(as);
return -ENOMEM; return -ENOMEM;
} }
...@@ -863,7 +857,6 @@ static int atmel_spi_set_xfer_speed(struct atmel_spi *as, ...@@ -863,7 +857,6 @@ static int atmel_spi_set_xfer_speed(struct atmel_spi *as,
* lock is held, spi irq is blocked * lock is held, spi irq is blocked
*/ */
static void atmel_spi_pdc_next_xfer(struct spi_master *master, static void atmel_spi_pdc_next_xfer(struct spi_master *master,
struct spi_message *msg,
struct spi_transfer *xfer) struct spi_transfer *xfer)
{ {
struct atmel_spi *as = spi_master_get_devdata(master); struct atmel_spi *as = spi_master_get_devdata(master);
...@@ -879,12 +872,12 @@ static void atmel_spi_pdc_next_xfer(struct spi_master *master, ...@@ -879,12 +872,12 @@ static void atmel_spi_pdc_next_xfer(struct spi_master *master,
spi_writel(as, RPR, rx_dma); spi_writel(as, RPR, rx_dma);
spi_writel(as, TPR, tx_dma); spi_writel(as, TPR, tx_dma);
if (msg->spi->bits_per_word > 8) if (xfer->bits_per_word > 8)
len >>= 1; len >>= 1;
spi_writel(as, RCR, len); spi_writel(as, RCR, len);
spi_writel(as, TCR, len); spi_writel(as, TCR, len);
dev_dbg(&msg->spi->dev, dev_dbg(&master->dev,
" start xfer %p: len %u tx %p/%08llx rx %p/%08llx\n", " start xfer %p: len %u tx %p/%08llx rx %p/%08llx\n",
xfer, xfer->len, xfer->tx_buf, xfer, xfer->len, xfer->tx_buf,
(unsigned long long)xfer->tx_dma, xfer->rx_buf, (unsigned long long)xfer->tx_dma, xfer->rx_buf,
...@@ -898,12 +891,12 @@ static void atmel_spi_pdc_next_xfer(struct spi_master *master, ...@@ -898,12 +891,12 @@ static void atmel_spi_pdc_next_xfer(struct spi_master *master,
spi_writel(as, RNPR, rx_dma); spi_writel(as, RNPR, rx_dma);
spi_writel(as, TNPR, tx_dma); spi_writel(as, TNPR, tx_dma);
if (msg->spi->bits_per_word > 8) if (xfer->bits_per_word > 8)
len >>= 1; len >>= 1;
spi_writel(as, RNCR, len); spi_writel(as, RNCR, len);
spi_writel(as, TNCR, len); spi_writel(as, TNCR, len);
dev_dbg(&msg->spi->dev, dev_dbg(&master->dev,
" next xfer %p: len %u tx %p/%08llx rx %p/%08llx\n", " next xfer %p: len %u tx %p/%08llx rx %p/%08llx\n",
xfer, xfer->len, xfer->tx_buf, xfer, xfer->len, xfer->tx_buf,
(unsigned long long)xfer->tx_dma, xfer->rx_buf, (unsigned long long)xfer->tx_dma, xfer->rx_buf,
...@@ -1054,8 +1047,6 @@ atmel_spi_pump_pio_data(struct atmel_spi *as, struct spi_transfer *xfer) ...@@ -1054,8 +1047,6 @@ atmel_spi_pump_pio_data(struct atmel_spi *as, struct spi_transfer *xfer)
/* Interrupt /* Interrupt
* *
* No need for locking in this Interrupt handler: done_status is the
* only information modified.
*/ */
static irqreturn_t static irqreturn_t
atmel_spi_pio_interrupt(int irq, void *dev_id) atmel_spi_pio_interrupt(int irq, void *dev_id)
...@@ -1273,12 +1264,28 @@ static int atmel_spi_setup(struct spi_device *spi) ...@@ -1273,12 +1264,28 @@ static int atmel_spi_setup(struct spi_device *spi)
return 0; return 0;
} }
static void atmel_spi_set_cs(struct spi_device *spi, bool enable)
{
struct atmel_spi *as = spi_master_get_devdata(spi->master);
/* the core doesn't really pass us enable/disable, but CS HIGH vs CS LOW
* since we already have routines for activate/deactivate translate
* high/low to active/inactive
*/
enable = (!!(spi->mode & SPI_CS_HIGH) == enable);
if (enable) {
cs_activate(as, spi);
} else {
cs_deactivate(as, spi);
}
}
static int atmel_spi_one_transfer(struct spi_master *master, static int atmel_spi_one_transfer(struct spi_master *master,
struct spi_message *msg, struct spi_device *spi,
struct spi_transfer *xfer) struct spi_transfer *xfer)
{ {
struct atmel_spi *as; struct atmel_spi *as;
struct spi_device *spi = msg->spi;
u8 bits; u8 bits;
u32 len; u32 len;
struct atmel_spi_device *asd; struct atmel_spi_device *asd;
...@@ -1288,11 +1295,6 @@ static int atmel_spi_one_transfer(struct spi_master *master, ...@@ -1288,11 +1295,6 @@ static int atmel_spi_one_transfer(struct spi_master *master,
as = spi_master_get_devdata(master); as = spi_master_get_devdata(master);
if (!(xfer->tx_buf || xfer->rx_buf) && xfer->len) {
dev_dbg(&spi->dev, "missing rx or tx buf\n");
return -EINVAL;
}
asd = spi->controller_state; asd = spi->controller_state;
bits = (asd->csr >> 4) & 0xf; bits = (asd->csr >> 4) & 0xf;
if (bits != xfer->bits_per_word - 8) { if (bits != xfer->bits_per_word - 8) {
...@@ -1305,13 +1307,13 @@ static int atmel_spi_one_transfer(struct spi_master *master, ...@@ -1305,13 +1307,13 @@ static int atmel_spi_one_transfer(struct spi_master *master,
* DMA map early, for performance (empties dcache ASAP) and * DMA map early, for performance (empties dcache ASAP) and
* better fault reporting. * better fault reporting.
*/ */
if ((!msg->is_dma_mapped) if ((!master->cur_msg_mapped)
&& as->use_pdc) { && as->use_pdc) {
if (atmel_spi_dma_map_xfer(as, xfer) < 0) if (atmel_spi_dma_map_xfer(as, xfer) < 0)
return -ENOMEM; return -ENOMEM;
} }
atmel_spi_set_xfer_speed(as, msg->spi, xfer); atmel_spi_set_xfer_speed(as, spi, xfer);
as->done_status = 0; as->done_status = 0;
as->current_transfer = xfer; as->current_transfer = xfer;
...@@ -1320,7 +1322,9 @@ static int atmel_spi_one_transfer(struct spi_master *master, ...@@ -1320,7 +1322,9 @@ static int atmel_spi_one_transfer(struct spi_master *master,
reinit_completion(&as->xfer_completion); reinit_completion(&as->xfer_completion);
if (as->use_pdc) { if (as->use_pdc) {
atmel_spi_pdc_next_xfer(master, msg, xfer); atmel_spi_lock(as);
atmel_spi_pdc_next_xfer(master, xfer);
atmel_spi_unlock(as);
} else if (atmel_spi_use_dma(as, xfer)) { } else if (atmel_spi_use_dma(as, xfer)) {
len = as->current_remaining_bytes; len = as->current_remaining_bytes;
ret = atmel_spi_next_xfer_dma_submit(master, ret = atmel_spi_next_xfer_dma_submit(master,
...@@ -1328,21 +1332,21 @@ static int atmel_spi_one_transfer(struct spi_master *master, ...@@ -1328,21 +1332,21 @@ static int atmel_spi_one_transfer(struct spi_master *master,
if (ret) { if (ret) {
dev_err(&spi->dev, dev_err(&spi->dev,
"unable to use DMA, fallback to PIO\n"); "unable to use DMA, fallback to PIO\n");
atmel_spi_next_xfer_pio(master, xfer); as->done_status = ret;
break;
} else { } else {
as->current_remaining_bytes -= len; as->current_remaining_bytes -= len;
if (as->current_remaining_bytes < 0) if (as->current_remaining_bytes < 0)
as->current_remaining_bytes = 0; as->current_remaining_bytes = 0;
} }
} else { } else {
atmel_spi_lock(as);
atmel_spi_next_xfer_pio(master, xfer); atmel_spi_next_xfer_pio(master, xfer);
atmel_spi_unlock(as);
} }
/* interrupts are disabled, so free the lock for schedule */
atmel_spi_unlock(as);
dma_timeout = wait_for_completion_timeout(&as->xfer_completion, dma_timeout = wait_for_completion_timeout(&as->xfer_completion,
SPI_DMA_TIMEOUT); SPI_DMA_TIMEOUT);
atmel_spi_lock(as);
if (WARN_ON(dma_timeout == 0)) { if (WARN_ON(dma_timeout == 0)) {
dev_err(&spi->dev, "spi transfer timeout\n"); dev_err(&spi->dev, "spi transfer timeout\n");
as->done_status = -EIO; as->done_status = -EIO;
...@@ -1381,90 +1385,16 @@ static int atmel_spi_one_transfer(struct spi_master *master, ...@@ -1381,90 +1385,16 @@ static int atmel_spi_one_transfer(struct spi_master *master,
} else if (atmel_spi_use_dma(as, xfer)) { } else if (atmel_spi_use_dma(as, xfer)) {
atmel_spi_stop_dma(master); atmel_spi_stop_dma(master);
} }
if (!msg->is_dma_mapped
&& as->use_pdc)
atmel_spi_dma_unmap_xfer(master, xfer);
return 0;
} else {
/* only update length if no error */
msg->actual_length += xfer->len;
} }
if (!msg->is_dma_mapped if (!master->cur_msg_mapped
&& as->use_pdc) && as->use_pdc)
atmel_spi_dma_unmap_xfer(master, xfer); atmel_spi_dma_unmap_xfer(master, xfer);
spi_transfer_delay_exec(xfer);
if (xfer->cs_change) {
if (list_is_last(&xfer->transfer_list,
&msg->transfers)) {
as->keep_cs = true;
} else {
cs_deactivate(as, msg->spi);
udelay(10);
cs_activate(as, msg->spi);
}
}
return 0;
}
static int atmel_spi_transfer_one_message(struct spi_master *master,
struct spi_message *msg)
{
struct atmel_spi *as;
struct spi_transfer *xfer;
struct spi_device *spi = msg->spi;
int ret = 0;
as = spi_master_get_devdata(master);
dev_dbg(&spi->dev, "new message %p submitted for %s\n",
msg, dev_name(&spi->dev));
atmel_spi_lock(as);
cs_activate(as, spi);
as->keep_cs = false;
msg->status = 0;
msg->actual_length = 0;
list_for_each_entry(xfer, &msg->transfers, transfer_list) {
trace_spi_transfer_start(msg, xfer);
ret = atmel_spi_one_transfer(master, msg, xfer);
if (ret)
goto msg_done;
trace_spi_transfer_stop(msg, xfer);
}
if (as->use_pdc) if (as->use_pdc)
atmel_spi_disable_pdc_transfer(as); atmel_spi_disable_pdc_transfer(as);
list_for_each_entry(xfer, &msg->transfers, transfer_list) { return as->done_status;
dev_dbg(&spi->dev,
" xfer %p: len %u tx %p/%pad rx %p/%pad\n",
xfer, xfer->len,
xfer->tx_buf, &xfer->tx_dma,
xfer->rx_buf, &xfer->rx_dma);
}
msg_done:
if (!as->keep_cs)
cs_deactivate(as, msg->spi);
atmel_spi_unlock(as);
msg->status = as->done_status;
spi_finalize_current_message(spi->master);
return ret;
} }
static void atmel_spi_cleanup(struct spi_device *spi) static void atmel_spi_cleanup(struct spi_device *spi)
...@@ -1554,7 +1484,8 @@ static int atmel_spi_probe(struct platform_device *pdev) ...@@ -1554,7 +1484,8 @@ static int atmel_spi_probe(struct platform_device *pdev)
master->num_chipselect = 4; master->num_chipselect = 4;
master->setup = atmel_spi_setup; master->setup = atmel_spi_setup;
master->flags = (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX); master->flags = (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX);
master->transfer_one_message = atmel_spi_transfer_one_message; master->transfer_one = atmel_spi_one_transfer;
master->set_cs = atmel_spi_set_cs;
master->cleanup = atmel_spi_cleanup; master->cleanup = atmel_spi_cleanup;
master->auto_runtime_pm = true; master->auto_runtime_pm = true;
master->max_dma_len = SPI_MAX_DMA_XFER; master->max_dma_len = SPI_MAX_DMA_XFER;
......
This diff is collapsed.
...@@ -384,7 +384,7 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master, ...@@ -384,7 +384,7 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master,
bs->pending = 0; bs->pending = 0;
/* Calculate the estimated time in us the transfer runs. Note that /* Calculate the estimated time in us the transfer runs. Note that
* there are are 2 idle clocks cycles after each chunk getting * there are 2 idle clocks cycles after each chunk getting
* transferred - in our case the chunk size is 3 bytes, so we * transferred - in our case the chunk size is 3 bytes, so we
* approximate this by 9 cycles/byte. This is used to find the number * approximate this by 9 cycles/byte. This is used to find the number
* of Hz per byte per polling limit. E.g., we can transfer 1 byte in * of Hz per byte per polling limit. E.g., we can transfer 1 byte in
......
...@@ -56,7 +56,7 @@ struct dw_spi_mscc { ...@@ -56,7 +56,7 @@ struct dw_spi_mscc {
/* /*
* The Designware SPI controller (referred to as master in the documentation) * The Designware SPI controller (referred to as master in the documentation)
* automatically deasserts chip select when the tx fifo is empty. The chip * automatically deasserts chip select when the tx fifo is empty. The chip
* selects then needs to be either driven as GPIOs or, for the first 4 using the * selects then needs to be either driven as GPIOs or, for the first 4 using
* the SPI boot controller registers. the final chip select is an OR gate * the SPI boot controller registers. the final chip select is an OR gate
* between the Designware SPI controller and the SPI boot controller. * between the Designware SPI controller and the SPI boot controller.
*/ */
......
...@@ -639,8 +639,8 @@ static irqreturn_t geni_spi_isr(int irq, void *data) ...@@ -639,8 +639,8 @@ static irqreturn_t geni_spi_isr(int irq, void *data)
complete(&mas->abort_done); complete(&mas->abort_done);
/* /*
* It's safe or a good idea to Ack all of our our interrupts at the * It's safe or a good idea to Ack all of our interrupts at the end
* end of the function. Specifically: * of the function. Specifically:
* - M_CMD_DONE_EN / M_RX_FIFO_LAST_EN: Edge triggered interrupts and * - M_CMD_DONE_EN / M_RX_FIFO_LAST_EN: Edge triggered interrupts and
* clearing Acks. Clearing at the end relies on nobody else having * clearing Acks. Clearing at the end relies on nobody else having
* started a new transfer yet or else we could be clearing _their_ * started a new transfer yet or else we could be clearing _their_
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/bitfield.h> #include <linux/bitfield.h>
#include <linux/debugfs.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
...@@ -126,6 +127,7 @@ struct hisi_spi { ...@@ -126,6 +127,7 @@ struct hisi_spi {
void __iomem *regs; void __iomem *regs;
int irq; int irq;
u32 fifo_len; /* depth of the FIFO buffer */ u32 fifo_len; /* depth of the FIFO buffer */
u16 bus_num;
/* Current message transfer state info */ /* Current message transfer state info */
const void *tx; const void *tx;
...@@ -133,8 +135,49 @@ struct hisi_spi { ...@@ -133,8 +135,49 @@ struct hisi_spi {
void *rx; void *rx;
unsigned int rx_len; unsigned int rx_len;
u8 n_bytes; /* current is a 1/2/4 bytes op */ u8 n_bytes; /* current is a 1/2/4 bytes op */
struct dentry *debugfs;
struct debugfs_regset32 regset;
};
#define HISI_SPI_DBGFS_REG(_name, _off) \
{ \
.name = _name, \
.offset = _off, \
}
static const struct debugfs_reg32 hisi_spi_regs[] = {
HISI_SPI_DBGFS_REG("CSCR", HISI_SPI_CSCR),
HISI_SPI_DBGFS_REG("CR", HISI_SPI_CR),
HISI_SPI_DBGFS_REG("ENR", HISI_SPI_ENR),
HISI_SPI_DBGFS_REG("FIFOC", HISI_SPI_FIFOC),
HISI_SPI_DBGFS_REG("IMR", HISI_SPI_IMR),
HISI_SPI_DBGFS_REG("DIN", HISI_SPI_DIN),
HISI_SPI_DBGFS_REG("DOUT", HISI_SPI_DOUT),
HISI_SPI_DBGFS_REG("SR", HISI_SPI_SR),
HISI_SPI_DBGFS_REG("RISR", HISI_SPI_RISR),
HISI_SPI_DBGFS_REG("ISR", HISI_SPI_ISR),
HISI_SPI_DBGFS_REG("ICR", HISI_SPI_ICR),
HISI_SPI_DBGFS_REG("VERSION", HISI_SPI_VERSION),
}; };
static int hisi_spi_debugfs_init(struct hisi_spi *hs)
{
char name[32];
snprintf(name, 32, "hisi_spi%d", hs->bus_num);
hs->debugfs = debugfs_create_dir(name, NULL);
if (!hs->debugfs)
return -ENOMEM;
hs->regset.regs = hisi_spi_regs;
hs->regset.nregs = ARRAY_SIZE(hisi_spi_regs);
hs->regset.base = hs->regs;
debugfs_create_regset32("registers", 0400, hs->debugfs, &hs->regset);
return 0;
}
static u32 hisi_spi_busy(struct hisi_spi *hs) static u32 hisi_spi_busy(struct hisi_spi *hs)
{ {
return readl(hs->regs + HISI_SPI_SR) & SR_BUSY; return readl(hs->regs + HISI_SPI_SR) & SR_BUSY;
...@@ -424,6 +467,7 @@ static int hisi_spi_probe(struct platform_device *pdev) ...@@ -424,6 +467,7 @@ static int hisi_spi_probe(struct platform_device *pdev)
hs = spi_controller_get_devdata(master); hs = spi_controller_get_devdata(master);
hs->dev = dev; hs->dev = dev;
hs->irq = irq; hs->irq = irq;
hs->bus_num = pdev->id;
hs->regs = devm_platform_ioremap_resource(pdev, 0); hs->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(hs->regs)) if (IS_ERR(hs->regs))
...@@ -446,7 +490,7 @@ static int hisi_spi_probe(struct platform_device *pdev) ...@@ -446,7 +490,7 @@ static int hisi_spi_probe(struct platform_device *pdev)
master->use_gpio_descriptors = true; master->use_gpio_descriptors = true;
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
master->bus_num = pdev->id; master->bus_num = hs->bus_num;
master->setup = hisi_spi_setup; master->setup = hisi_spi_setup;
master->cleanup = hisi_spi_cleanup; master->cleanup = hisi_spi_cleanup;
master->transfer_one = hisi_spi_transfer_one; master->transfer_one = hisi_spi_transfer_one;
...@@ -462,6 +506,9 @@ static int hisi_spi_probe(struct platform_device *pdev) ...@@ -462,6 +506,9 @@ static int hisi_spi_probe(struct platform_device *pdev)
return ret; return ret;
} }
if (hisi_spi_debugfs_init(hs))
dev_info(dev, "failed to create debugfs dir\n");
ret = spi_register_controller(master); ret = spi_register_controller(master);
if (ret) { if (ret) {
dev_err(dev, "failed to register spi master, ret=%d\n", ret); dev_err(dev, "failed to register spi master, ret=%d\n", ret);
...@@ -478,7 +525,9 @@ static int hisi_spi_probe(struct platform_device *pdev) ...@@ -478,7 +525,9 @@ static int hisi_spi_probe(struct platform_device *pdev)
static int hisi_spi_remove(struct platform_device *pdev) static int hisi_spi_remove(struct platform_device *pdev)
{ {
struct spi_controller *master = platform_get_drvdata(pdev); struct spi_controller *master = platform_get_drvdata(pdev);
struct hisi_spi *hs = spi_controller_get_devdata(master);
debugfs_remove_recursive(hs->debugfs);
spi_unregister_controller(master); spi_unregister_controller(master);
return 0; return 0;
......
...@@ -202,7 +202,7 @@ static void spi_lm70llp_attach(struct parport *p) ...@@ -202,7 +202,7 @@ static void spi_lm70llp_attach(struct parport *p)
* the lm70 driver could verify it, reading the manf ID. * the lm70 driver could verify it, reading the manf ID.
*/ */
master = spi_alloc_master(p->physport->dev, sizeof *pp); master = spi_alloc_master(p->physport->dev, sizeof(*pp));
if (!master) { if (!master) {
status = -ENOMEM; status = -ENOMEM;
goto out_fail; goto out_fail;
......
...@@ -875,7 +875,7 @@ static int spi_test_run_iter(struct spi_device *spi, ...@@ -875,7 +875,7 @@ static int spi_test_run_iter(struct spi_device *spi,
test.transfers[i].len = len; test.transfers[i].len = len;
if (test.transfers[i].tx_buf) if (test.transfers[i].tx_buf)
test.transfers[i].tx_buf += tx_off; test.transfers[i].tx_buf += tx_off;
if (test.transfers[i].tx_buf) if (test.transfers[i].rx_buf)
test.transfers[i].rx_buf += rx_off; test.transfers[i].rx_buf += rx_off;
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
* Author: Boris Brezillon <boris.brezillon@bootlin.com> * Author: Boris Brezillon <boris.brezillon@bootlin.com>
*/ */
#include <linux/dmaengine.h> #include <linux/dmaengine.h>
#include <linux/iopoll.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/spi/spi-mem.h> #include <linux/spi/spi-mem.h>
...@@ -743,6 +744,91 @@ static inline struct spi_mem_driver *to_spi_mem_drv(struct device_driver *drv) ...@@ -743,6 +744,91 @@ static inline struct spi_mem_driver *to_spi_mem_drv(struct device_driver *drv)
return container_of(drv, struct spi_mem_driver, spidrv.driver); return container_of(drv, struct spi_mem_driver, spidrv.driver);
} }
static int spi_mem_read_status(struct spi_mem *mem,
const struct spi_mem_op *op,
u16 *status)
{
const u8 *bytes = (u8 *)op->data.buf.in;
int ret;
ret = spi_mem_exec_op(mem, op);
if (ret)
return ret;
if (op->data.nbytes > 1)
*status = ((u16)bytes[0] << 8) | bytes[1];
else
*status = bytes[0];
return 0;
}
/**
* spi_mem_poll_status() - Poll memory device status
* @mem: SPI memory device
* @op: the memory operation to execute
* @mask: status bitmask to ckeck
* @match: (status & mask) expected value
* @initial_delay_us: delay in us before starting to poll
* @polling_delay_us: time to sleep between reads in us
* @timeout_ms: timeout in milliseconds
*
* This function polls a status register and returns when
* (status & mask) == match or when the timeout has expired.
*
* Return: 0 in case of success, -ETIMEDOUT in case of error,
* -EOPNOTSUPP if not supported.
*/
int spi_mem_poll_status(struct spi_mem *mem,
const struct spi_mem_op *op,
u16 mask, u16 match,
unsigned long initial_delay_us,
unsigned long polling_delay_us,
u16 timeout_ms)
{
struct spi_controller *ctlr = mem->spi->controller;
int ret = -EOPNOTSUPP;
int read_status_ret;
u16 status;
if (op->data.nbytes < 1 || op->data.nbytes > 2 ||
op->data.dir != SPI_MEM_DATA_IN)
return -EINVAL;
if (ctlr->mem_ops && ctlr->mem_ops->poll_status) {
ret = spi_mem_access_start(mem);
if (ret)
return ret;
ret = ctlr->mem_ops->poll_status(mem, op, mask, match,
initial_delay_us, polling_delay_us,
timeout_ms);
spi_mem_access_end(mem);
}
if (ret == -EOPNOTSUPP) {
if (!spi_mem_supports_op(mem, op))
return ret;
if (initial_delay_us < 10)
udelay(initial_delay_us);
else
usleep_range((initial_delay_us >> 2) + 1,
initial_delay_us);
ret = read_poll_timeout(spi_mem_read_status, read_status_ret,
(read_status_ret || ((status) & mask) == match),
polling_delay_us, timeout_ms * 1000, false, mem,
op, &status);
if (read_status_ret)
return read_status_ret;
}
return ret;
}
EXPORT_SYMBOL_GPL(spi_mem_poll_status);
static int spi_mem_probe(struct spi_device *spi) static int spi_mem_probe(struct spi_device *spi)
{ {
struct spi_mem_driver *memdrv = to_spi_mem_drv(spi->dev.driver); struct spi_mem_driver *memdrv = to_spi_mem_drv(spi->dev.driver);
...@@ -810,7 +896,7 @@ int spi_mem_driver_register_with_owner(struct spi_mem_driver *memdrv, ...@@ -810,7 +896,7 @@ int spi_mem_driver_register_with_owner(struct spi_mem_driver *memdrv,
EXPORT_SYMBOL_GPL(spi_mem_driver_register_with_owner); EXPORT_SYMBOL_GPL(spi_mem_driver_register_with_owner);
/** /**
* spi_mem_driver_unregister_with_owner() - Unregister a SPI memory driver * spi_mem_driver_unregister() - Unregister a SPI memory driver
* @memdrv: the SPI memory driver to unregister * @memdrv: the SPI memory driver to unregister
* *
* Unregisters a SPI memory driver. * Unregisters a SPI memory driver.
......
...@@ -725,7 +725,7 @@ static int meson_spicc_probe(struct platform_device *pdev) ...@@ -725,7 +725,7 @@ static int meson_spicc_probe(struct platform_device *pdev)
ret = clk_prepare_enable(spicc->pclk); ret = clk_prepare_enable(spicc->pclk);
if (ret) { if (ret) {
dev_err(&pdev->dev, "pclk clock enable failed\n"); dev_err(&pdev->dev, "pclk clock enable failed\n");
goto out_master; goto out_core_clk;
} }
device_reset_optional(&pdev->dev); device_reset_optional(&pdev->dev);
...@@ -752,7 +752,7 @@ static int meson_spicc_probe(struct platform_device *pdev) ...@@ -752,7 +752,7 @@ static int meson_spicc_probe(struct platform_device *pdev)
ret = meson_spicc_clk_init(spicc); ret = meson_spicc_clk_init(spicc);
if (ret) { if (ret) {
dev_err(&pdev->dev, "clock registration failed\n"); dev_err(&pdev->dev, "clock registration failed\n");
goto out_master; goto out_clk;
} }
ret = devm_spi_register_master(&pdev->dev, master); ret = devm_spi_register_master(&pdev->dev, master);
...@@ -764,9 +764,11 @@ static int meson_spicc_probe(struct platform_device *pdev) ...@@ -764,9 +764,11 @@ static int meson_spicc_probe(struct platform_device *pdev)
return 0; return 0;
out_clk: out_clk:
clk_disable_unprepare(spicc->core);
clk_disable_unprepare(spicc->pclk); clk_disable_unprepare(spicc->pclk);
out_core_clk:
clk_disable_unprepare(spicc->core);
out_master: out_master:
spi_master_put(master); spi_master_put(master);
......
...@@ -369,7 +369,7 @@ static int mpc512x_psc_spi_setup(struct spi_device *spi) ...@@ -369,7 +369,7 @@ static int mpc512x_psc_spi_setup(struct spi_device *spi)
return -EINVAL; return -EINVAL;
if (!cs) { if (!cs) {
cs = kzalloc(sizeof *cs, GFP_KERNEL); cs = kzalloc(sizeof(*cs), GFP_KERNEL);
if (!cs) if (!cs)
return -ENOMEM; return -ENOMEM;
...@@ -491,7 +491,7 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, ...@@ -491,7 +491,7 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
void *tempp; void *tempp;
struct clk *clk; struct clk *clk;
master = spi_alloc_master(dev, sizeof *mps); master = spi_alloc_master(dev, sizeof(*mps));
if (master == NULL) if (master == NULL)
return -ENOMEM; return -ENOMEM;
......
...@@ -265,7 +265,7 @@ static int mpc52xx_psc_spi_setup(struct spi_device *spi) ...@@ -265,7 +265,7 @@ static int mpc52xx_psc_spi_setup(struct spi_device *spi)
return -EINVAL; return -EINVAL;
if (!cs) { if (!cs) {
cs = kzalloc(sizeof *cs, GFP_KERNEL); cs = kzalloc(sizeof(*cs), GFP_KERNEL);
if (!cs) if (!cs)
return -ENOMEM; return -ENOMEM;
spi->controller_state = cs; spi->controller_state = cs;
...@@ -365,7 +365,7 @@ static int mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr, ...@@ -365,7 +365,7 @@ static int mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr,
struct spi_master *master; struct spi_master *master;
int ret; int ret;
master = spi_alloc_master(dev, sizeof *mps); master = spi_alloc_master(dev, sizeof(*mps));
if (master == NULL) if (master == NULL)
return -ENOMEM; return -ENOMEM;
......
...@@ -415,7 +415,7 @@ static int mpc52xx_spi_probe(struct platform_device *op) ...@@ -415,7 +415,7 @@ static int mpc52xx_spi_probe(struct platform_device *op)
} }
dev_dbg(&op->dev, "allocating spi_master struct\n"); dev_dbg(&op->dev, "allocating spi_master struct\n");
master = spi_alloc_master(&op->dev, sizeof *ms); master = spi_alloc_master(&op->dev, sizeof(*ms));
if (!master) { if (!master) {
rc = -ENOMEM; rc = -ENOMEM;
goto err_alloc; goto err_alloc;
......
...@@ -105,7 +105,7 @@ static void npcm_pspi_set_mode(struct spi_device *spi) ...@@ -105,7 +105,7 @@ static void npcm_pspi_set_mode(struct spi_device *spi)
u16 regtemp; u16 regtemp;
u16 mode_val; u16 mode_val;
switch (spi->mode & (SPI_CPOL | SPI_CPHA)) { switch (spi->mode & SPI_MODE_X_MASK) {
case SPI_MODE_0: case SPI_MODE_0:
mode_val = 0; mode_val = 0;
break; break;
......
...@@ -86,7 +86,7 @@ static int tiny_spi_setup(struct spi_device *spi) ...@@ -86,7 +86,7 @@ static int tiny_spi_setup(struct spi_device *spi)
hw->speed_hz = spi->max_speed_hz; hw->speed_hz = spi->max_speed_hz;
hw->baud = tiny_spi_baud(spi, hw->speed_hz); hw->baud = tiny_spi_baud(spi, hw->speed_hz);
} }
hw->mode = spi->mode & (SPI_CPOL | SPI_CPHA); hw->mode = spi->mode & SPI_MODE_X_MASK;
return 0; return 0;
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (C) 2005, 2006 Nokia Corporation * Copyright (C) 2005, 2006 Nokia Corporation
* Author: Samuel Ortiz <samuel.ortiz@nokia.com> and * Author: Samuel Ortiz <samuel.ortiz@nokia.com> and
* Juha Yrj�l� <juha.yrjola@nokia.com> * Juha Yrjola <juha.yrjola@nokia.com>
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -241,7 +241,7 @@ static int omap1_spi100k_setup_transfer(struct spi_device *spi, ...@@ -241,7 +241,7 @@ static int omap1_spi100k_setup_transfer(struct spi_device *spi,
else else
word_len = spi->bits_per_word; word_len = spi->bits_per_word;
if (spi->bits_per_word > 32) if (word_len > 32)
return -EINVAL; return -EINVAL;
cs->word_len = word_len; cs->word_len = word_len;
...@@ -296,7 +296,6 @@ static int omap1_spi100k_transfer_one_message(struct spi_master *master, ...@@ -296,7 +296,6 @@ static int omap1_spi100k_transfer_one_message(struct spi_master *master,
list_for_each_entry(t, &m->transfers, transfer_list) { list_for_each_entry(t, &m->transfers, transfer_list) {
if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) { if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) {
status = -EINVAL;
break; break;
} }
status = omap1_spi100k_setup_transfer(spi, t); status = omap1_spi100k_setup_transfer(spi, t);
...@@ -315,7 +314,6 @@ static int omap1_spi100k_transfer_one_message(struct spi_master *master, ...@@ -315,7 +314,6 @@ static int omap1_spi100k_transfer_one_message(struct spi_master *master,
m->actual_length += count; m->actual_length += count;
if (count != t->len) { if (count != t->len) {
status = -EIO;
break; break;
} }
} }
......
...@@ -330,7 +330,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t) ...@@ -330,7 +330,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
if (spi->mode & SPI_CPOL) if (spi->mode & SPI_CPOL)
flags |= UWIRE_CLK_INVERTED; flags |= UWIRE_CLK_INVERTED;
switch (spi->mode & (SPI_CPOL | SPI_CPHA)) { switch (spi->mode & SPI_MODE_X_MASK) {
case SPI_MODE_0: case SPI_MODE_0:
case SPI_MODE_3: case SPI_MODE_3:
flags |= UWIRE_WRITE_FALLING_EDGE | UWIRE_READ_RISING_EDGE; flags |= UWIRE_WRITE_FALLING_EDGE | UWIRE_READ_RISING_EDGE;
...@@ -460,7 +460,7 @@ static int uwire_probe(struct platform_device *pdev) ...@@ -460,7 +460,7 @@ static int uwire_probe(struct platform_device *pdev)
struct uwire_spi *uwire; struct uwire_spi *uwire;
int status; int status;
master = spi_alloc_master(&pdev->dev, sizeof *uwire); master = spi_alloc_master(&pdev->dev, sizeof(*uwire));
if (!master) if (!master)
return -ENODEV; return -ENODEV;
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* *
* Copyright (C) 2005, 2006 Nokia Corporation * Copyright (C) 2005, 2006 Nokia Corporation
* Author: Samuel Ortiz <samuel.ortiz@nokia.com> and * Author: Samuel Ortiz <samuel.ortiz@nokia.com> and
* Juha Yrj�l� <juha.yrjola@nokia.com> * Juha Yrjola <juha.yrjola@nokia.com>
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -1054,7 +1054,7 @@ static int omap2_mcspi_setup(struct spi_device *spi) ...@@ -1054,7 +1054,7 @@ static int omap2_mcspi_setup(struct spi_device *spi)
struct omap2_mcspi_cs *cs = spi->controller_state; struct omap2_mcspi_cs *cs = spi->controller_state;
if (!cs) { if (!cs) {
cs = kzalloc(sizeof *cs, GFP_KERNEL); cs = kzalloc(sizeof(*cs), GFP_KERNEL);
if (!cs) if (!cs)
return -ENOMEM; return -ENOMEM;
cs->base = mcspi->base + spi->chip_select * 0x14; cs->base = mcspi->base + spi->chip_select * 0x14;
......
...@@ -288,7 +288,7 @@ ...@@ -288,7 +288,7 @@
#define SPI_POLLING_TIMEOUT 1000 #define SPI_POLLING_TIMEOUT 1000
/* /*
* The type of reading going on on this chip * The type of reading going on this chip
*/ */
enum ssp_reading { enum ssp_reading {
READING_NULL, READING_NULL,
...@@ -298,7 +298,7 @@ enum ssp_reading { ...@@ -298,7 +298,7 @@ enum ssp_reading {
}; };
/* /*
* The type of writing going on on this chip * The type of writing going on this chip
*/ */
enum ssp_writing { enum ssp_writing {
WRITING_NULL, WRITING_NULL,
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h> #include <linux/spi/spi_bitbang.h>
#include <asm/io.h> #include <linux/io.h>
#include <asm/dcr.h> #include <asm/dcr.h>
#include <asm/dcr-regs.h> #include <asm/dcr-regs.h>
...@@ -223,7 +223,7 @@ static int spi_ppc4xx_setup(struct spi_device *spi) ...@@ -223,7 +223,7 @@ static int spi_ppc4xx_setup(struct spi_device *spi)
} }
if (cs == NULL) { if (cs == NULL) {
cs = kzalloc(sizeof *cs, GFP_KERNEL); cs = kzalloc(sizeof(*cs), GFP_KERNEL);
if (!cs) if (!cs)
return -ENOMEM; return -ENOMEM;
spi->controller_state = cs; spi->controller_state = cs;
...@@ -235,7 +235,7 @@ static int spi_ppc4xx_setup(struct spi_device *spi) ...@@ -235,7 +235,7 @@ static int spi_ppc4xx_setup(struct spi_device *spi)
*/ */
cs->mode = SPI_PPC4XX_MODE_SPE; cs->mode = SPI_PPC4XX_MODE_SPE;
switch (spi->mode & (SPI_CPHA | SPI_CPOL)) { switch (spi->mode & SPI_MODE_X_MASK) {
case SPI_MODE_0: case SPI_MODE_0:
cs->mode |= SPI_CLK_MODE0; cs->mode |= SPI_CLK_MODE0;
break; break;
...@@ -326,7 +326,7 @@ static void spi_ppc4xx_enable(struct ppc4xx_spi *hw) ...@@ -326,7 +326,7 @@ static void spi_ppc4xx_enable(struct ppc4xx_spi *hw)
{ {
/* /*
* On all 4xx PPC's the SPI bus is shared/multiplexed with * On all 4xx PPC's the SPI bus is shared/multiplexed with
* the 2nd I2C bus. We need to enable the the SPI bus before * the 2nd I2C bus. We need to enable the SPI bus before
* using it. * using it.
*/ */
...@@ -349,7 +349,7 @@ static int spi_ppc4xx_of_probe(struct platform_device *op) ...@@ -349,7 +349,7 @@ static int spi_ppc4xx_of_probe(struct platform_device *op)
int ret; int ret;
const unsigned int *clk; const unsigned int *clk;
master = spi_alloc_master(dev, sizeof *hw); master = spi_alloc_master(dev, sizeof(*hw));
if (master == NULL) if (master == NULL)
return -ENOMEM; return -ENOMEM;
master->dev.of_node = np; master->dev.of_node = np;
......
...@@ -2,18 +2,18 @@ ...@@ -2,18 +2,18 @@
/* /*
* PXA2xx SPI DMA engine support. * PXA2xx SPI DMA engine support.
* *
* Copyright (C) 2013, Intel Corporation * Copyright (C) 2013, 2021 Intel Corporation
* Author: Mika Westerberg <mika.westerberg@linux.intel.com> * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
*/ */
#include <linux/device.h> #include <linux/device.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/dmaengine.h> #include <linux/dmaengine.h>
#include <linux/pxa2xx_ssp.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/sizes.h> #include <linux/sizes.h>
#include <linux/spi/spi.h>
#include <linux/spi/pxa2xx_spi.h> #include <linux/spi/pxa2xx_spi.h>
#include <linux/spi/spi.h>
#include "spi-pxa2xx.h" #include "spi-pxa2xx.h"
...@@ -26,7 +26,7 @@ static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data, ...@@ -26,7 +26,7 @@ static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data,
* It is possible that one CPU is handling ROR interrupt and other * It is possible that one CPU is handling ROR interrupt and other
* just gets DMA completion. Calling pump_transfers() twice for the * just gets DMA completion. Calling pump_transfers() twice for the
* same transfer leads to problems thus we prevent concurrent calls * same transfer leads to problems thus we prevent concurrent calls
* by using ->dma_running. * by using dma_running.
*/ */
if (atomic_dec_and_test(&drv_data->dma_running)) { if (atomic_dec_and_test(&drv_data->dma_running)) {
/* /*
...@@ -34,25 +34,18 @@ static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data, ...@@ -34,25 +34,18 @@ static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data,
* might not know about the error yet. So we re-check the * might not know about the error yet. So we re-check the
* ROR bit here before we clear the status register. * ROR bit here before we clear the status register.
*/ */
if (!error) { if (!error)
u32 status = pxa2xx_spi_read(drv_data, SSSR) error = read_SSSR_bits(drv_data, drv_data->mask_sr) & SSSR_ROR;
& drv_data->mask_sr;
error = status & SSSR_ROR;
}
/* Clear status & disable interrupts */ /* Clear status & disable interrupts */
pxa2xx_spi_write(drv_data, SSCR1, clear_SSCR1_bits(drv_data, drv_data->dma_cr1);
pxa2xx_spi_read(drv_data, SSCR1)
& ~drv_data->dma_cr1);
write_SSSR_CS(drv_data, drv_data->clear_sr); write_SSSR_CS(drv_data, drv_data->clear_sr);
if (!pxa25x_ssp_comp(drv_data)) if (!pxa25x_ssp_comp(drv_data))
pxa2xx_spi_write(drv_data, SSTO, 0); pxa2xx_spi_write(drv_data, SSTO, 0);
if (error) { if (error) {
/* In case we got an error we disable the SSP now */ /* In case we got an error we disable the SSP now */
pxa2xx_spi_write(drv_data, SSCR0, pxa_ssp_disable(drv_data->ssp);
pxa2xx_spi_read(drv_data, SSCR0)
& ~SSCR0_SSE);
msg->status = -EIO; msg->status = -EIO;
} }
...@@ -94,14 +87,14 @@ pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data, ...@@ -94,14 +87,14 @@ pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data,
cfg.direction = dir; cfg.direction = dir;
if (dir == DMA_MEM_TO_DEV) { if (dir == DMA_MEM_TO_DEV) {
cfg.dst_addr = drv_data->ssdr_physical; cfg.dst_addr = drv_data->ssp->phys_base + SSDR;
cfg.dst_addr_width = width; cfg.dst_addr_width = width;
cfg.dst_maxburst = chip->dma_burst_size; cfg.dst_maxburst = chip->dma_burst_size;
sgt = &xfer->tx_sg; sgt = &xfer->tx_sg;
chan = drv_data->controller->dma_tx; chan = drv_data->controller->dma_tx;
} else { } else {
cfg.src_addr = drv_data->ssdr_physical; cfg.src_addr = drv_data->ssp->phys_base + SSDR;
cfg.src_addr_width = width; cfg.src_addr_width = width;
cfg.src_maxburst = chip->dma_burst_size; cfg.src_maxburst = chip->dma_burst_size;
...@@ -111,7 +104,7 @@ pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data, ...@@ -111,7 +104,7 @@ pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data,
ret = dmaengine_slave_config(chan, &cfg); ret = dmaengine_slave_config(chan, &cfg);
if (ret) { if (ret) {
dev_warn(&drv_data->pdev->dev, "DMA slave config failed\n"); dev_warn(drv_data->ssp->dev, "DMA slave config failed\n");
return NULL; return NULL;
} }
...@@ -123,9 +116,9 @@ irqreturn_t pxa2xx_spi_dma_transfer(struct driver_data *drv_data) ...@@ -123,9 +116,9 @@ irqreturn_t pxa2xx_spi_dma_transfer(struct driver_data *drv_data)
{ {
u32 status; u32 status;
status = pxa2xx_spi_read(drv_data, SSSR) & drv_data->mask_sr; status = read_SSSR_bits(drv_data, drv_data->mask_sr);
if (status & SSSR_ROR) { if (status & SSSR_ROR) {
dev_err(&drv_data->pdev->dev, "FIFO overrun\n"); dev_err(drv_data->ssp->dev, "FIFO overrun\n");
dmaengine_terminate_async(drv_data->controller->dma_rx); dmaengine_terminate_async(drv_data->controller->dma_rx);
dmaengine_terminate_async(drv_data->controller->dma_tx); dmaengine_terminate_async(drv_data->controller->dma_tx);
...@@ -145,16 +138,14 @@ int pxa2xx_spi_dma_prepare(struct driver_data *drv_data, ...@@ -145,16 +138,14 @@ int pxa2xx_spi_dma_prepare(struct driver_data *drv_data,
tx_desc = pxa2xx_spi_dma_prepare_one(drv_data, DMA_MEM_TO_DEV, xfer); tx_desc = pxa2xx_spi_dma_prepare_one(drv_data, DMA_MEM_TO_DEV, xfer);
if (!tx_desc) { if (!tx_desc) {
dev_err(&drv_data->pdev->dev, dev_err(drv_data->ssp->dev, "failed to get DMA TX descriptor\n");
"failed to get DMA TX descriptor\n");
err = -EBUSY; err = -EBUSY;
goto err_tx; goto err_tx;
} }
rx_desc = pxa2xx_spi_dma_prepare_one(drv_data, DMA_DEV_TO_MEM, xfer); rx_desc = pxa2xx_spi_dma_prepare_one(drv_data, DMA_DEV_TO_MEM, xfer);
if (!rx_desc) { if (!rx_desc) {
dev_err(&drv_data->pdev->dev, dev_err(drv_data->ssp->dev, "failed to get DMA RX descriptor\n");
"failed to get DMA RX descriptor\n");
err = -EBUSY; err = -EBUSY;
goto err_rx; goto err_rx;
} }
...@@ -191,8 +182,8 @@ void pxa2xx_spi_dma_stop(struct driver_data *drv_data) ...@@ -191,8 +182,8 @@ void pxa2xx_spi_dma_stop(struct driver_data *drv_data)
int pxa2xx_spi_dma_setup(struct driver_data *drv_data) int pxa2xx_spi_dma_setup(struct driver_data *drv_data)
{ {
struct pxa2xx_spi_controller *pdata = drv_data->controller_info; struct pxa2xx_spi_controller *pdata = drv_data->controller_info;
struct device *dev = &drv_data->pdev->dev;
struct spi_controller *controller = drv_data->controller; struct spi_controller *controller = drv_data->controller;
struct device *dev = drv_data->ssp->dev;
dma_cap_mask_t mask; dma_cap_mask_t mask;
dma_cap_zero(mask); dma_cap_zero(mask);
......
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* CE4100's SPI device is more or less the same one as found on PXA * PCI glue driver for SPI PXA2xx compatible controllers.
* CE4100's SPI device is more or less the same one as found on PXA.
* *
* Copyright (C) 2016, Intel Corporation * Copyright (C) 2016, 2021 Intel Corporation
*/ */
#include <linux/clk-provider.h> #include <linux/clk-provider.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/spi/pxa2xx_spi.h> #include <linux/spi/pxa2xx_spi.h>
#include <linux/dmaengine.h> #include <linux/dmaengine.h>
...@@ -178,7 +180,7 @@ static struct pxa_spi_info spi_info_configs[] = { ...@@ -178,7 +180,7 @@ static struct pxa_spi_info spi_info_configs[] = {
.rx_param = &bsw2_rx_param, .rx_param = &bsw2_rx_param,
}, },
[PORT_MRFLD] = { [PORT_MRFLD] = {
.type = PXA27x_SSP, .type = MRFLD_SSP,
.max_clk_rate = 25000000, .max_clk_rate = 25000000,
.setup = mrfld_spi_setup, .setup = mrfld_spi_setup,
}, },
...@@ -239,6 +241,7 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, ...@@ -239,6 +241,7 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev,
spi_pdata.dma_burst_size = c->dma_burst_size ? c->dma_burst_size : 1; spi_pdata.dma_burst_size = c->dma_burst_size ? c->dma_burst_size : 1;
ssp = &spi_pdata.ssp; ssp = &spi_pdata.ssp;
ssp->dev = &dev->dev;
ssp->phys_base = pci_resource_start(dev, 0); ssp->phys_base = pci_resource_start(dev, 0);
ssp->mmio_base = pcim_iomap_table(dev)[0]; ssp->mmio_base = pcim_iomap_table(dev)[0];
ssp->port_id = (c->port_id >= 0) ? c->port_id : dev->devfn; ssp->port_id = (c->port_id >= 0) ? c->port_id : dev->devfn;
...@@ -254,7 +257,7 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, ...@@ -254,7 +257,7 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev,
snprintf(buf, sizeof(buf), "pxa2xx-spi.%d", ssp->port_id); snprintf(buf, sizeof(buf), "pxa2xx-spi.%d", ssp->port_id);
ssp->clk = clk_register_fixed_rate(&dev->dev, buf, NULL, 0, ssp->clk = clk_register_fixed_rate(&dev->dev, buf, NULL, 0,
c->max_clk_rate); c->max_clk_rate);
if (IS_ERR(ssp->clk)) if (IS_ERR(ssp->clk))
return PTR_ERR(ssp->clk); return PTR_ERR(ssp->clk);
memset(&pi, 0, sizeof(pi)); memset(&pi, 0, sizeof(pi));
......
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (C) 2005 Stephen Street / StreetFire Sound Labs * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs
* Copyright (C) 2013, Intel Corporation * Copyright (C) 2013, 2021 Intel Corporation
*/ */
#ifndef SPI_PXA2XX_H #ifndef SPI_PXA2XX_H
#define SPI_PXA2XX_H #define SPI_PXA2XX_H
#include <linux/atomic.h>
#include <linux/dmaengine.h>
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/platform_device.h> #include <linux/io.h>
#include <linux/pxa2xx_ssp.h> #include <linux/types.h>
#include <linux/scatterlist.h>
#include <linux/sizes.h> #include <linux/sizes.h>
#include <linux/spi/spi.h>
#include <linux/spi/pxa2xx_spi.h>
struct driver_data { #include <linux/pxa2xx_ssp.h>
/* Driver model hookup */
struct platform_device *pdev; struct gpio_desc;
struct pxa2xx_spi_controller;
struct spi_controller;
struct spi_device;
struct spi_transfer;
struct driver_data {
/* SSP Info */ /* SSP Info */
struct ssp_device *ssp; struct ssp_device *ssp;
...@@ -33,10 +31,6 @@ struct driver_data { ...@@ -33,10 +31,6 @@ struct driver_data {
/* PXA hookup */ /* PXA hookup */
struct pxa2xx_spi_controller *controller_info; struct pxa2xx_spi_controller *controller_info;
/* SSP register addresses */
void __iomem *ioaddr;
phys_addr_t ssdr_physical;
/* SSP masks*/ /* SSP masks*/
u32 dma_cr1; u32 dma_cr1;
u32 int_cr1; u32 int_cr1;
...@@ -59,9 +53,6 @@ struct driver_data { ...@@ -59,9 +53,6 @@ struct driver_data {
void __iomem *lpss_base; void __iomem *lpss_base;
/* GPIOs for chip selects */
struct gpio_desc **cs_gpiods;
/* Optional slave FIFO ready signal */ /* Optional slave FIFO ready signal */
struct gpio_desc *gpiod_ready; struct gpio_desc *gpiod_ready;
}; };
...@@ -71,37 +62,32 @@ struct chip_data { ...@@ -71,37 +62,32 @@ struct chip_data {
u32 dds_rate; u32 dds_rate;
u32 timeout; u32 timeout;
u8 n_bytes; u8 n_bytes;
u8 enable_dma;
u32 dma_burst_size; u32 dma_burst_size;
u32 threshold;
u32 dma_threshold; u32 dma_threshold;
u32 threshold;
u16 lpss_rx_threshold; u16 lpss_rx_threshold;
u16 lpss_tx_threshold; u16 lpss_tx_threshold;
u8 enable_dma;
union {
struct gpio_desc *gpiod_cs;
unsigned int frm;
};
int gpio_cs_inverted;
int (*write)(struct driver_data *drv_data); int (*write)(struct driver_data *drv_data);
int (*read)(struct driver_data *drv_data); int (*read)(struct driver_data *drv_data);
void (*cs_control)(u32 command); void (*cs_control)(u32 command);
}; };
static inline u32 pxa2xx_spi_read(const struct driver_data *drv_data, static inline u32 pxa2xx_spi_read(const struct driver_data *drv_data, u32 reg)
unsigned reg)
{ {
return __raw_readl(drv_data->ioaddr + reg); return pxa_ssp_read_reg(drv_data->ssp, reg);
} }
static inline void pxa2xx_spi_write(const struct driver_data *drv_data, static inline void pxa2xx_spi_write(const struct driver_data *drv_data, u32 reg, u32 val)
unsigned reg, u32 val)
{ {
__raw_writel(val, drv_data->ioaddr + reg); pxa_ssp_write_reg(drv_data->ssp, reg, val);
} }
#define DMA_ALIGNMENT 8 #define DMA_ALIGNMENT 8
static inline int pxa25x_ssp_comp(struct driver_data *drv_data) static inline int pxa25x_ssp_comp(const struct driver_data *drv_data)
{ {
switch (drv_data->ssp_type) { switch (drv_data->ssp_type) {
case PXA25x_SSP: case PXA25x_SSP:
...@@ -113,11 +99,21 @@ static inline int pxa25x_ssp_comp(struct driver_data *drv_data) ...@@ -113,11 +99,21 @@ static inline int pxa25x_ssp_comp(struct driver_data *drv_data)
} }
} }
static inline void write_SSSR_CS(struct driver_data *drv_data, u32 val) static inline void clear_SSCR1_bits(const struct driver_data *drv_data, u32 bits)
{
pxa2xx_spi_write(drv_data, SSCR1, pxa2xx_spi_read(drv_data, SSCR1) & ~bits);
}
static inline u32 read_SSSR_bits(const struct driver_data *drv_data, u32 bits)
{
return pxa2xx_spi_read(drv_data, SSSR) & bits;
}
static inline void write_SSSR_CS(const struct driver_data *drv_data, u32 val)
{ {
if (drv_data->ssp_type == CE4100_SSP || if (drv_data->ssp_type == CE4100_SSP ||
drv_data->ssp_type == QUARK_X1000_SSP) drv_data->ssp_type == QUARK_X1000_SSP)
val |= pxa2xx_spi_read(drv_data, SSSR) & SSSR_ALT_FRM_MASK; val |= read_SSSR_bits(drv_data, SSSR_ALT_FRM_MASK);
pxa2xx_spi_write(drv_data, SSSR, val); pxa2xx_spi_write(drv_data, SSSR, val);
} }
......
...@@ -107,6 +107,8 @@ ...@@ -107,6 +107,8 @@
#define CR0_OPM_MASTER 0x0 #define CR0_OPM_MASTER 0x0
#define CR0_OPM_SLAVE 0x1 #define CR0_OPM_SLAVE 0x1
#define CR0_SOI_OFFSET 23
#define CR0_MTM_OFFSET 0x21 #define CR0_MTM_OFFSET 0x21
/* Bit fields in SER, 2bit */ /* Bit fields in SER, 2bit */
...@@ -116,13 +118,14 @@ ...@@ -116,13 +118,14 @@
#define BAUDR_SCKDV_MIN 2 #define BAUDR_SCKDV_MIN 2
#define BAUDR_SCKDV_MAX 65534 #define BAUDR_SCKDV_MAX 65534
/* Bit fields in SR, 5bit */ /* Bit fields in SR, 6bit */
#define SR_MASK 0x1f #define SR_MASK 0x3f
#define SR_BUSY (1 << 0) #define SR_BUSY (1 << 0)
#define SR_TF_FULL (1 << 1) #define SR_TF_FULL (1 << 1)
#define SR_TF_EMPTY (1 << 2) #define SR_TF_EMPTY (1 << 2)
#define SR_RF_EMPTY (1 << 3) #define SR_RF_EMPTY (1 << 3)
#define SR_RF_FULL (1 << 4) #define SR_RF_FULL (1 << 4)
#define SR_SLAVE_TX_BUSY (1 << 5)
/* Bit fields in ISR, IMR, ISR, RISR, 5bit */ /* Bit fields in ISR, IMR, ISR, RISR, 5bit */
#define INT_MASK 0x1f #define INT_MASK 0x1f
...@@ -156,7 +159,8 @@ ...@@ -156,7 +159,8 @@
*/ */
#define ROCKCHIP_SPI_MAX_TRANLEN 0xffff #define ROCKCHIP_SPI_MAX_TRANLEN 0xffff
#define ROCKCHIP_SPI_MAX_CS_NUM 2 /* 2 for native cs, 2 for cs-gpio */
#define ROCKCHIP_SPI_MAX_CS_NUM 4
#define ROCKCHIP_SPI_VER2_TYPE1 0x05EC0002 #define ROCKCHIP_SPI_VER2_TYPE1 0x05EC0002
#define ROCKCHIP_SPI_VER2_TYPE2 0x00110002 #define ROCKCHIP_SPI_VER2_TYPE2 0x00110002
...@@ -197,13 +201,19 @@ static inline void spi_enable_chip(struct rockchip_spi *rs, bool enable) ...@@ -197,13 +201,19 @@ static inline void spi_enable_chip(struct rockchip_spi *rs, bool enable)
writel_relaxed((enable ? 1U : 0U), rs->regs + ROCKCHIP_SPI_SSIENR); writel_relaxed((enable ? 1U : 0U), rs->regs + ROCKCHIP_SPI_SSIENR);
} }
static inline void wait_for_idle(struct rockchip_spi *rs) static inline void wait_for_tx_idle(struct rockchip_spi *rs, bool slave_mode)
{ {
unsigned long timeout = jiffies + msecs_to_jiffies(5); unsigned long timeout = jiffies + msecs_to_jiffies(5);
do { do {
if (!(readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY)) if (slave_mode) {
return; if (!(readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_SLAVE_TX_BUSY) &&
!((readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY)))
return;
} else {
if (!(readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY))
return;
}
} while (!time_after(jiffies, timeout)); } while (!time_after(jiffies, timeout));
dev_warn(rs->dev, "spi controller is in busy state!\n"); dev_warn(rs->dev, "spi controller is in busy state!\n");
...@@ -228,7 +238,7 @@ static void rockchip_spi_set_cs(struct spi_device *spi, bool enable) ...@@ -228,7 +238,7 @@ static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
{ {
struct spi_controller *ctlr = spi->controller; struct spi_controller *ctlr = spi->controller;
struct rockchip_spi *rs = spi_controller_get_devdata(ctlr); struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
bool cs_asserted = !enable; bool cs_asserted = spi->mode & SPI_CS_HIGH ? enable : !enable;
/* Return immediately for no-op */ /* Return immediately for no-op */
if (cs_asserted == rs->cs_asserted[spi->chip_select]) if (cs_asserted == rs->cs_asserted[spi->chip_select])
...@@ -238,11 +248,15 @@ static void rockchip_spi_set_cs(struct spi_device *spi, bool enable) ...@@ -238,11 +248,15 @@ static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
/* Keep things powered as long as CS is asserted */ /* Keep things powered as long as CS is asserted */
pm_runtime_get_sync(rs->dev); pm_runtime_get_sync(rs->dev);
ROCKCHIP_SPI_SET_BITS(rs->regs + ROCKCHIP_SPI_SER, if (spi->cs_gpiod)
BIT(spi->chip_select)); ROCKCHIP_SPI_SET_BITS(rs->regs + ROCKCHIP_SPI_SER, 1);
else
ROCKCHIP_SPI_SET_BITS(rs->regs + ROCKCHIP_SPI_SER, BIT(spi->chip_select));
} else { } else {
ROCKCHIP_SPI_CLR_BITS(rs->regs + ROCKCHIP_SPI_SER, if (spi->cs_gpiod)
BIT(spi->chip_select)); ROCKCHIP_SPI_CLR_BITS(rs->regs + ROCKCHIP_SPI_SER, 1);
else
ROCKCHIP_SPI_CLR_BITS(rs->regs + ROCKCHIP_SPI_SER, BIT(spi->chip_select));
/* Drop reference from when we first asserted CS */ /* Drop reference from when we first asserted CS */
pm_runtime_put(rs->dev); pm_runtime_put(rs->dev);
...@@ -383,7 +397,7 @@ static void rockchip_spi_dma_txcb(void *data) ...@@ -383,7 +397,7 @@ static void rockchip_spi_dma_txcb(void *data)
return; return;
/* Wait until the FIFO data completely. */ /* Wait until the FIFO data completely. */
wait_for_idle(rs); wait_for_tx_idle(rs, ctlr->slave);
spi_enable_chip(rs, false); spi_enable_chip(rs, false);
spi_finalize_current_transfer(ctlr); spi_finalize_current_transfer(ctlr);
...@@ -495,6 +509,8 @@ static int rockchip_spi_config(struct rockchip_spi *rs, ...@@ -495,6 +509,8 @@ static int rockchip_spi_config(struct rockchip_spi *rs,
cr0 |= (spi->mode & 0x3U) << CR0_SCPH_OFFSET; cr0 |= (spi->mode & 0x3U) << CR0_SCPH_OFFSET;
if (spi->mode & SPI_LSB_FIRST) if (spi->mode & SPI_LSB_FIRST)
cr0 |= CR0_FBM_LSB << CR0_FBM_OFFSET; cr0 |= CR0_FBM_LSB << CR0_FBM_OFFSET;
if (spi->mode & SPI_CS_HIGH)
cr0 |= BIT(spi->chip_select) << CR0_SOI_OFFSET;
if (xfer->rx_buf && xfer->tx_buf) if (xfer->rx_buf && xfer->tx_buf)
cr0 |= CR0_XFM_TR << CR0_XFM_OFFSET; cr0 |= CR0_XFM_TR << CR0_XFM_OFFSET;
...@@ -540,12 +556,12 @@ static int rockchip_spi_config(struct rockchip_spi *rs, ...@@ -540,12 +556,12 @@ static int rockchip_spi_config(struct rockchip_spi *rs,
* interrupt exactly when the fifo is full doesn't seem to work, * interrupt exactly when the fifo is full doesn't seem to work,
* so we need the strict inequality here * so we need the strict inequality here
*/ */
if (xfer->len < rs->fifo_len) if ((xfer->len / rs->n_bytes) < rs->fifo_len)
writel_relaxed(xfer->len - 1, rs->regs + ROCKCHIP_SPI_RXFTLR); writel_relaxed(xfer->len / rs->n_bytes - 1, rs->regs + ROCKCHIP_SPI_RXFTLR);
else else
writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_RXFTLR); writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_RXFTLR);
writel_relaxed(rs->fifo_len / 2, rs->regs + ROCKCHIP_SPI_DMATDLR); writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_DMATDLR);
writel_relaxed(rockchip_spi_calc_burst_size(xfer->len / rs->n_bytes) - 1, writel_relaxed(rockchip_spi_calc_burst_size(xfer->len / rs->n_bytes) - 1,
rs->regs + ROCKCHIP_SPI_DMARDLR); rs->regs + ROCKCHIP_SPI_DMARDLR);
writel_relaxed(dmacr, rs->regs + ROCKCHIP_SPI_DMACR); writel_relaxed(dmacr, rs->regs + ROCKCHIP_SPI_DMACR);
...@@ -783,6 +799,14 @@ static int rockchip_spi_probe(struct platform_device *pdev) ...@@ -783,6 +799,14 @@ static int rockchip_spi_probe(struct platform_device *pdev)
ctlr->can_dma = rockchip_spi_can_dma; ctlr->can_dma = rockchip_spi_can_dma;
} }
switch (readl_relaxed(rs->regs + ROCKCHIP_SPI_VERSION)) {
case ROCKCHIP_SPI_VER2_TYPE2:
ctlr->mode_bits |= SPI_CS_HIGH;
break;
default:
break;
}
ret = devm_spi_register_controller(&pdev->dev, ctlr); ret = devm_spi_register_controller(&pdev->dev, ctlr);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "Failed to register controller\n"); dev_err(&pdev->dev, "Failed to register controller\n");
...@@ -922,6 +946,7 @@ static const struct of_device_id rockchip_spi_dt_match[] = { ...@@ -922,6 +946,7 @@ static const struct of_device_id rockchip_spi_dt_match[] = {
{ .compatible = "rockchip,rk3368-spi", }, { .compatible = "rockchip,rk3368-spi", },
{ .compatible = "rockchip,rk3399-spi", }, { .compatible = "rockchip,rk3399-spi", },
{ .compatible = "rockchip,rv1108-spi", }, { .compatible = "rockchip,rv1108-spi", },
{ .compatible = "rockchip,rv1126-spi", },
{ }, { },
}; };
MODULE_DEVICE_TABLE(of, rockchip_spi_dt_match); MODULE_DEVICE_TABLE(of, rockchip_spi_dt_match);
......
...@@ -618,9 +618,9 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, ...@@ -618,9 +618,9 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
} }
if (tx) if (tx)
dmaengine_terminate_all(rspi->ctlr->dma_tx); dmaengine_terminate_sync(rspi->ctlr->dma_tx);
if (rx) if (rx)
dmaengine_terminate_all(rspi->ctlr->dma_rx); dmaengine_terminate_sync(rspi->ctlr->dma_rx);
} }
rspi_disable_irq(rspi, irq_mask); rspi_disable_irq(rspi, irq_mask);
...@@ -634,7 +634,7 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, ...@@ -634,7 +634,7 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
no_dma_tx: no_dma_tx:
if (rx) if (rx)
dmaengine_terminate_all(rspi->ctlr->dma_rx); dmaengine_terminate_sync(rspi->ctlr->dma_rx);
no_dma_rx: no_dma_rx:
if (ret == -EAGAIN) { if (ret == -EAGAIN) {
dev_warn_once(&rspi->ctlr->dev, dev_warn_once(&rspi->ctlr->dev,
......
...@@ -853,10 +853,10 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, ...@@ -853,10 +853,10 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
sh_msiof_spi_stop(p, rx); sh_msiof_spi_stop(p, rx);
stop_dma: stop_dma:
if (tx) if (tx)
dmaengine_terminate_all(p->ctlr->dma_tx); dmaengine_terminate_sync(p->ctlr->dma_tx);
no_dma_tx: no_dma_tx:
if (rx) if (rx)
dmaengine_terminate_all(p->ctlr->dma_rx); dmaengine_terminate_sync(p->ctlr->dma_rx);
sh_msiof_write(p, SIIER, 0); sh_msiof_write(p, SIIER, 0);
return ret; return ret;
} }
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#define CR_FTIE BIT(18) #define CR_FTIE BIT(18)
#define CR_SMIE BIT(19) #define CR_SMIE BIT(19)
#define CR_TOIE BIT(20) #define CR_TOIE BIT(20)
#define CR_APMS BIT(22)
#define CR_PRESC_MASK GENMASK(31, 24) #define CR_PRESC_MASK GENMASK(31, 24)
#define QSPI_DCR 0x04 #define QSPI_DCR 0x04
...@@ -53,6 +54,7 @@ ...@@ -53,6 +54,7 @@
#define QSPI_FCR 0x0c #define QSPI_FCR 0x0c
#define FCR_CTEF BIT(0) #define FCR_CTEF BIT(0)
#define FCR_CTCF BIT(1) #define FCR_CTCF BIT(1)
#define FCR_CSMF BIT(3)
#define QSPI_DLR 0x10 #define QSPI_DLR 0x10
...@@ -91,7 +93,6 @@ ...@@ -91,7 +93,6 @@
#define STM32_AUTOSUSPEND_DELAY -1 #define STM32_AUTOSUSPEND_DELAY -1
struct stm32_qspi_flash { struct stm32_qspi_flash {
struct stm32_qspi *qspi;
u32 cs; u32 cs;
u32 presc; u32 presc;
}; };
...@@ -107,6 +108,7 @@ struct stm32_qspi { ...@@ -107,6 +108,7 @@ struct stm32_qspi {
u32 clk_rate; u32 clk_rate;
struct stm32_qspi_flash flash[STM32_QSPI_MAX_NORCHIP]; struct stm32_qspi_flash flash[STM32_QSPI_MAX_NORCHIP];
struct completion data_completion; struct completion data_completion;
struct completion match_completion;
u32 fmode; u32 fmode;
struct dma_chan *dma_chtx; struct dma_chan *dma_chtx;
...@@ -115,6 +117,7 @@ struct stm32_qspi { ...@@ -115,6 +117,7 @@ struct stm32_qspi {
u32 cr_reg; u32 cr_reg;
u32 dcr_reg; u32 dcr_reg;
unsigned long status_timeout;
/* /*
* to protect device configuration, could be different between * to protect device configuration, could be different between
...@@ -128,11 +131,20 @@ static irqreturn_t stm32_qspi_irq(int irq, void *dev_id) ...@@ -128,11 +131,20 @@ static irqreturn_t stm32_qspi_irq(int irq, void *dev_id)
struct stm32_qspi *qspi = (struct stm32_qspi *)dev_id; struct stm32_qspi *qspi = (struct stm32_qspi *)dev_id;
u32 cr, sr; u32 cr, sr;
cr = readl_relaxed(qspi->io_base + QSPI_CR);
sr = readl_relaxed(qspi->io_base + QSPI_SR); sr = readl_relaxed(qspi->io_base + QSPI_SR);
if (cr & CR_SMIE && sr & SR_SMF) {
/* disable irq */
cr &= ~CR_SMIE;
writel_relaxed(cr, qspi->io_base + QSPI_CR);
complete(&qspi->match_completion);
return IRQ_HANDLED;
}
if (sr & (SR_TEF | SR_TCF)) { if (sr & (SR_TEF | SR_TCF)) {
/* disable irq */ /* disable irq */
cr = readl_relaxed(qspi->io_base + QSPI_CR);
cr &= ~CR_TCIE & ~CR_TEIE; cr &= ~CR_TCIE & ~CR_TEIE;
writel_relaxed(cr, qspi->io_base + QSPI_CR); writel_relaxed(cr, qspi->io_base + QSPI_CR);
complete(&qspi->data_completion); complete(&qspi->data_completion);
...@@ -322,6 +334,24 @@ static int stm32_qspi_wait_cmd(struct stm32_qspi *qspi, ...@@ -322,6 +334,24 @@ static int stm32_qspi_wait_cmd(struct stm32_qspi *qspi,
return err; return err;
} }
static int stm32_qspi_wait_poll_status(struct stm32_qspi *qspi,
const struct spi_mem_op *op)
{
u32 cr;
reinit_completion(&qspi->match_completion);
cr = readl_relaxed(qspi->io_base + QSPI_CR);
writel_relaxed(cr | CR_SMIE, qspi->io_base + QSPI_CR);
if (!wait_for_completion_timeout(&qspi->match_completion,
msecs_to_jiffies(qspi->status_timeout)))
return -ETIMEDOUT;
writel_relaxed(FCR_CSMF, qspi->io_base + QSPI_FCR);
return 0;
}
static int stm32_qspi_get_mode(struct stm32_qspi *qspi, u8 buswidth) static int stm32_qspi_get_mode(struct stm32_qspi *qspi, u8 buswidth)
{ {
if (buswidth == 4) if (buswidth == 4)
...@@ -335,7 +365,7 @@ static int stm32_qspi_send(struct spi_mem *mem, const struct spi_mem_op *op) ...@@ -335,7 +365,7 @@ static int stm32_qspi_send(struct spi_mem *mem, const struct spi_mem_op *op)
struct stm32_qspi *qspi = spi_controller_get_devdata(mem->spi->master); struct stm32_qspi *qspi = spi_controller_get_devdata(mem->spi->master);
struct stm32_qspi_flash *flash = &qspi->flash[mem->spi->chip_select]; struct stm32_qspi_flash *flash = &qspi->flash[mem->spi->chip_select];
u32 ccr, cr; u32 ccr, cr;
int timeout, err = 0; int timeout, err = 0, err_poll_status = 0;
dev_dbg(qspi->dev, "cmd:%#x mode:%d.%d.%d.%d addr:%#llx len:%#x\n", dev_dbg(qspi->dev, "cmd:%#x mode:%d.%d.%d.%d addr:%#llx len:%#x\n",
op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth, op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
...@@ -381,6 +411,9 @@ static int stm32_qspi_send(struct spi_mem *mem, const struct spi_mem_op *op) ...@@ -381,6 +411,9 @@ static int stm32_qspi_send(struct spi_mem *mem, const struct spi_mem_op *op)
if (op->addr.nbytes && qspi->fmode != CCR_FMODE_MM) if (op->addr.nbytes && qspi->fmode != CCR_FMODE_MM)
writel_relaxed(op->addr.val, qspi->io_base + QSPI_AR); writel_relaxed(op->addr.val, qspi->io_base + QSPI_AR);
if (qspi->fmode == CCR_FMODE_APM)
err_poll_status = stm32_qspi_wait_poll_status(qspi, op);
err = stm32_qspi_tx(qspi, op); err = stm32_qspi_tx(qspi, op);
/* /*
...@@ -390,7 +423,7 @@ static int stm32_qspi_send(struct spi_mem *mem, const struct spi_mem_op *op) ...@@ -390,7 +423,7 @@ static int stm32_qspi_send(struct spi_mem *mem, const struct spi_mem_op *op)
* byte of device (device size - fifo size). like device size is not * byte of device (device size - fifo size). like device size is not
* knows, the prefetching is always stop. * knows, the prefetching is always stop.
*/ */
if (err || qspi->fmode == CCR_FMODE_MM) if (err || err_poll_status || qspi->fmode == CCR_FMODE_MM)
goto abort; goto abort;
/* wait end of tx in indirect mode */ /* wait end of tx in indirect mode */
...@@ -409,15 +442,49 @@ static int stm32_qspi_send(struct spi_mem *mem, const struct spi_mem_op *op) ...@@ -409,15 +442,49 @@ static int stm32_qspi_send(struct spi_mem *mem, const struct spi_mem_op *op)
cr, !(cr & CR_ABORT), 1, cr, !(cr & CR_ABORT), 1,
STM32_ABT_TIMEOUT_US); STM32_ABT_TIMEOUT_US);
writel_relaxed(FCR_CTCF, qspi->io_base + QSPI_FCR); writel_relaxed(FCR_CTCF | FCR_CSMF, qspi->io_base + QSPI_FCR);
if (err || timeout) if (err || err_poll_status || timeout)
dev_err(qspi->dev, "%s err:%d abort timeout:%d\n", dev_err(qspi->dev, "%s err:%d err_poll_status:%d abort timeout:%d\n",
__func__, err, timeout); __func__, err, err_poll_status, timeout);
return err; return err;
} }
static int stm32_qspi_poll_status(struct spi_mem *mem, const struct spi_mem_op *op,
u16 mask, u16 match,
unsigned long initial_delay_us,
unsigned long polling_rate_us,
unsigned long timeout_ms)
{
struct stm32_qspi *qspi = spi_controller_get_devdata(mem->spi->master);
int ret;
if (!spi_mem_supports_op(mem, op))
return -EOPNOTSUPP;
ret = pm_runtime_get_sync(qspi->dev);
if (ret < 0) {
pm_runtime_put_noidle(qspi->dev);
return ret;
}
mutex_lock(&qspi->lock);
writel_relaxed(mask, qspi->io_base + QSPI_PSMKR);
writel_relaxed(match, qspi->io_base + QSPI_PSMAR);
qspi->fmode = CCR_FMODE_APM;
qspi->status_timeout = timeout_ms;
ret = stm32_qspi_send(mem, op);
mutex_unlock(&qspi->lock);
pm_runtime_mark_last_busy(qspi->dev);
pm_runtime_put_autosuspend(qspi->dev);
return ret;
}
static int stm32_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) static int stm32_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
{ {
struct stm32_qspi *qspi = spi_controller_get_devdata(mem->spi->master); struct stm32_qspi *qspi = spi_controller_get_devdata(mem->spi->master);
...@@ -525,12 +592,11 @@ static int stm32_qspi_setup(struct spi_device *spi) ...@@ -525,12 +592,11 @@ static int stm32_qspi_setup(struct spi_device *spi)
presc = DIV_ROUND_UP(qspi->clk_rate, spi->max_speed_hz) - 1; presc = DIV_ROUND_UP(qspi->clk_rate, spi->max_speed_hz) - 1;
flash = &qspi->flash[spi->chip_select]; flash = &qspi->flash[spi->chip_select];
flash->qspi = qspi;
flash->cs = spi->chip_select; flash->cs = spi->chip_select;
flash->presc = presc; flash->presc = presc;
mutex_lock(&qspi->lock); mutex_lock(&qspi->lock);
qspi->cr_reg = 3 << CR_FTHRES_SHIFT | CR_SSHIFT | CR_EN; qspi->cr_reg = CR_APMS | 3 << CR_FTHRES_SHIFT | CR_SSHIFT | CR_EN;
writel_relaxed(qspi->cr_reg, qspi->io_base + QSPI_CR); writel_relaxed(qspi->cr_reg, qspi->io_base + QSPI_CR);
/* set dcr fsize to max address */ /* set dcr fsize to max address */
...@@ -610,6 +676,7 @@ static const struct spi_controller_mem_ops stm32_qspi_mem_ops = { ...@@ -610,6 +676,7 @@ static const struct spi_controller_mem_ops stm32_qspi_mem_ops = {
.exec_op = stm32_qspi_exec_op, .exec_op = stm32_qspi_exec_op,
.dirmap_create = stm32_qspi_dirmap_create, .dirmap_create = stm32_qspi_dirmap_create,
.dirmap_read = stm32_qspi_dirmap_read, .dirmap_read = stm32_qspi_dirmap_read,
.poll_status = stm32_qspi_poll_status,
}; };
static int stm32_qspi_probe(struct platform_device *pdev) static int stm32_qspi_probe(struct platform_device *pdev)
...@@ -664,6 +731,7 @@ static int stm32_qspi_probe(struct platform_device *pdev) ...@@ -664,6 +731,7 @@ static int stm32_qspi_probe(struct platform_device *pdev)
} }
init_completion(&qspi->data_completion); init_completion(&qspi->data_completion);
init_completion(&qspi->match_completion);
qspi->clk = devm_clk_get(dev, NULL); qspi->clk = devm_clk_get(dev, NULL);
if (IS_ERR(qspi->clk)) { if (IS_ERR(qspi->clk)) {
......
...@@ -379,6 +379,10 @@ static int sun6i_spi_transfer_one(struct spi_master *master, ...@@ -379,6 +379,10 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
} }
sun6i_spi_write(sspi, SUN6I_CLK_CTL_REG, reg); sun6i_spi_write(sspi, SUN6I_CLK_CTL_REG, reg);
/* Finally enable the bus - doing so before might raise SCK to HIGH */
reg = sun6i_spi_read(sspi, SUN6I_GBL_CTL_REG);
reg |= SUN6I_GBL_CTL_BUS_ENABLE;
sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG, reg);
/* Setup the transfer now... */ /* Setup the transfer now... */
if (sspi->tx_buf) if (sspi->tx_buf)
...@@ -504,7 +508,7 @@ static int sun6i_spi_runtime_resume(struct device *dev) ...@@ -504,7 +508,7 @@ static int sun6i_spi_runtime_resume(struct device *dev)
} }
sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG, sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG,
SUN6I_GBL_CTL_BUS_ENABLE | SUN6I_GBL_CTL_MASTER | SUN6I_GBL_CTL_TP); SUN6I_GBL_CTL_MASTER | SUN6I_GBL_CTL_TP);
return 0; return 0;
......
...@@ -1071,8 +1071,7 @@ static int tegra_spi_transfer_one_message(struct spi_master *master, ...@@ -1071,8 +1071,7 @@ static int tegra_spi_transfer_one_message(struct spi_master *master,
ret = wait_for_completion_timeout(&tspi->xfer_completion, ret = wait_for_completion_timeout(&tspi->xfer_completion,
SPI_DMA_TIMEOUT); SPI_DMA_TIMEOUT);
if (WARN_ON(ret == 0)) { if (WARN_ON(ret == 0)) {
dev_err(tspi->dev, dev_err(tspi->dev, "spi transfer timeout\n");
"spi transfer timeout, err %d\n", ret);
if (tspi->is_curr_dma_xfer && if (tspi->is_curr_dma_xfer &&
(tspi->cur_direction & DATA_DIR_TX)) (tspi->cur_direction & DATA_DIR_TX))
dmaengine_terminate_all(tspi->tx_dma_chan); dmaengine_terminate_all(tspi->tx_dma_chan);
......
...@@ -1028,7 +1028,7 @@ static int tegra_qspi_transfer_one_message(struct spi_master *master, struct spi ...@@ -1028,7 +1028,7 @@ static int tegra_qspi_transfer_one_message(struct spi_master *master, struct spi
ret = wait_for_completion_timeout(&tqspi->xfer_completion, ret = wait_for_completion_timeout(&tqspi->xfer_completion,
QSPI_DMA_TIMEOUT); QSPI_DMA_TIMEOUT);
if (WARN_ON(ret == 0)) { if (WARN_ON(ret == 0)) {
dev_err(tqspi->dev, "transfer timeout: %d\n", ret); dev_err(tqspi->dev, "transfer timeout\n");
if (tqspi->is_curr_dma_xfer && (tqspi->cur_direction & DATA_DIR_TX)) if (tqspi->is_curr_dma_xfer && (tqspi->cur_direction & DATA_DIR_TX))
dmaengine_terminate_all(tqspi->tx_dma_chan); dmaengine_terminate_all(tqspi->tx_dma_chan);
if (tqspi->is_curr_dma_xfer && (tqspi->cur_direction & DATA_DIR_RX)) if (tqspi->is_curr_dma_xfer && (tqspi->cur_direction & DATA_DIR_RX))
......
...@@ -580,8 +580,10 @@ static void pch_spi_set_tx(struct pch_spi_data *data, int *bpw) ...@@ -580,8 +580,10 @@ static void pch_spi_set_tx(struct pch_spi_data *data, int *bpw)
data->pkt_tx_buff = kzalloc(size, GFP_KERNEL); data->pkt_tx_buff = kzalloc(size, GFP_KERNEL);
if (data->pkt_tx_buff != NULL) { if (data->pkt_tx_buff != NULL) {
data->pkt_rx_buff = kzalloc(size, GFP_KERNEL); data->pkt_rx_buff = kzalloc(size, GFP_KERNEL);
if (!data->pkt_rx_buff) if (!data->pkt_rx_buff) {
kfree(data->pkt_tx_buff); kfree(data->pkt_tx_buff);
data->pkt_tx_buff = NULL;
}
} }
if (!data->pkt_rx_buff) { if (!data->pkt_rx_buff) {
......
...@@ -142,7 +142,7 @@ static void uniphier_spi_set_mode(struct spi_device *spi) ...@@ -142,7 +142,7 @@ static void uniphier_spi_set_mode(struct spi_device *spi)
* FSTRT start frame timing * FSTRT start frame timing
* 0: rising edge of clock, 1: falling edge of clock * 0: rising edge of clock, 1: falling edge of clock
*/ */
switch (spi->mode & (SPI_CPOL | SPI_CPHA)) { switch (spi->mode & SPI_MODE_X_MASK) {
case SPI_MODE_0: case SPI_MODE_0:
/* CKPHS=1, CKINIT=0, CKDLY=1, FSTRT=0 */ /* CKPHS=1, CKINIT=0, CKDLY=1, FSTRT=0 */
val1 = SSI_CKS_CKPHS | SSI_CKS_CKDLY; val1 = SSI_CKS_CKPHS | SSI_CKS_CKDLY;
......
This diff is collapsed.
...@@ -59,7 +59,7 @@ static DECLARE_BITMAP(minors, N_SPI_MINORS); ...@@ -59,7 +59,7 @@ static DECLARE_BITMAP(minors, N_SPI_MINORS);
* *
* REVISIT should changing those flags be privileged? * REVISIT should changing those flags be privileged?
*/ */
#define SPI_MODE_MASK (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH \ #define SPI_MODE_MASK (SPI_MODE_X_MASK | SPI_CS_HIGH \
| SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP \ | SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP \
| SPI_NO_CS | SPI_READY | SPI_TX_DUAL \ | SPI_NO_CS | SPI_READY | SPI_TX_DUAL \
| SPI_TX_QUAD | SPI_TX_OCTAL | SPI_RX_DUAL \ | SPI_TX_QUAD | SPI_TX_OCTAL | SPI_RX_DUAL \
......
...@@ -170,6 +170,28 @@ struct spinand_op; ...@@ -170,6 +170,28 @@ struct spinand_op;
struct spinand_device; struct spinand_device;
#define SPINAND_MAX_ID_LEN 4 #define SPINAND_MAX_ID_LEN 4
/*
* For erase, write and read operation, we got the following timings :
* tBERS (erase) 1ms to 4ms
* tPROG 300us to 400us
* tREAD 25us to 100us
* In order to minimize latency, the min value is divided by 4 for the
* initial delay, and dividing by 20 for the poll delay.
* For reset, 5us/10us/500us if the device is respectively
* reading/programming/erasing when the RESET occurs. Since we always
* issue a RESET when the device is IDLE, 5us is selected for both initial
* and poll delay.
*/
#define SPINAND_READ_INITIAL_DELAY_US 6
#define SPINAND_READ_POLL_DELAY_US 5
#define SPINAND_RESET_INITIAL_DELAY_US 5
#define SPINAND_RESET_POLL_DELAY_US 5
#define SPINAND_WRITE_INITIAL_DELAY_US 75
#define SPINAND_WRITE_POLL_DELAY_US 15
#define SPINAND_ERASE_INITIAL_DELAY_US 250
#define SPINAND_ERASE_POLL_DELAY_US 50
#define SPINAND_WAITRDY_TIMEOUT_MS 400
/** /**
* struct spinand_id - SPI NAND id structure * struct spinand_id - SPI NAND id structure
......
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Platform data definition for Atheros AR71XX/AR724X/AR913X SPI controller
*
* Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
*/
#ifndef _ATH79_SPI_PLATFORM_H
#define _ATH79_SPI_PLATFORM_H
struct ath79_spi_platform_data {
unsigned bus_num;
unsigned num_chipselect;
};
#endif /* _ATH79_SPI_PLATFORM_H */
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (C) 2003 Russell King, All Rights Reserved. * Copyright (C) 2003 Russell King, All Rights Reserved.
* *
* This driver supports the following PXA CPU/SSP ports:- * This driver supports the following PXA CPU/SSP ports:-
* *
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
* PXA3xx SSP1, SSP2, SSP3, SSP4 * PXA3xx SSP1, SSP2, SSP3, SSP4
*/ */
#ifndef __LINUX_SSP_H #ifndef __LINUX_PXA2XX_SSP_H
#define __LINUX_SSP_H #define __LINUX_PXA2XX_SSP_H
#include <linux/bits.h> #include <linux/bits.h>
#include <linux/compiler_types.h> #include <linux/compiler_types.h>
...@@ -38,7 +38,6 @@ struct device_node; ...@@ -38,7 +38,6 @@ struct device_node;
#define SSDR (0x10) /* SSP Data Write/Data Read Register */ #define SSDR (0x10) /* SSP Data Write/Data Read Register */
#define SSTO (0x28) /* SSP Time Out Register */ #define SSTO (0x28) /* SSP Time Out Register */
#define DDS_RATE (0x28) /* SSP DDS Clock Rate Register (Intel Quark) */
#define SSPSP (0x2C) /* SSP Programmable Serial Protocol */ #define SSPSP (0x2C) /* SSP Programmable Serial Protocol */
#define SSTSA (0x30) /* SSP Tx Timeslot Active */ #define SSTSA (0x30) /* SSP Tx Timeslot Active */
#define SSRSA (0x34) /* SSP Rx Timeslot Active */ #define SSRSA (0x34) /* SSP Rx Timeslot Active */
...@@ -60,7 +59,7 @@ struct device_node; ...@@ -60,7 +59,7 @@ struct device_node;
/* PXA27x, PXA3xx */ /* PXA27x, PXA3xx */
#define SSCR0_EDSS BIT(20) /* Extended data size select */ #define SSCR0_EDSS BIT(20) /* Extended data size select */
#define SSCR0_NCS BIT(21) /* Network clock select */ #define SSCR0_NCS BIT(21) /* Network clock select */
#define SSCR0_RIM BIT(22) /* Receive FIFO overrrun interrupt mask */ #define SSCR0_RIM BIT(22) /* Receive FIFO overrun interrupt mask */
#define SSCR0_TUM BIT(23) /* Transmit FIFO underrun interrupt mask */ #define SSCR0_TUM BIT(23) /* Transmit FIFO underrun interrupt mask */
#define SSCR0_FRDC GENMASK(26, 24) /* Frame rate divider control (mask) */ #define SSCR0_FRDC GENMASK(26, 24) /* Frame rate divider control (mask) */
#define SSCR0_SlotsPerFrm(x) (((x) - 1) << 24) /* Time slots per frame [1..8] */ #define SSCR0_SlotsPerFrm(x) (((x) - 1) << 24) /* Time slots per frame [1..8] */
...@@ -105,6 +104,9 @@ struct device_node; ...@@ -105,6 +104,9 @@ struct device_node;
#define CE4100_SSCR1_RFT GENMASK(11, 10) /* Receive FIFO Threshold (mask) */ #define CE4100_SSCR1_RFT GENMASK(11, 10) /* Receive FIFO Threshold (mask) */
#define CE4100_SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..4] */ #define CE4100_SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..4] */
/* Intel Quark X1000 */
#define DDS_RATE 0x28 /* SSP DDS Clock Rate Register */
/* QUARK_X1000 SSCR0 bit definition */ /* QUARK_X1000 SSCR0 bit definition */
#define QUARK_X1000_SSCR0_DSS GENMASK(4, 0) /* Data Size Select (mask) */ #define QUARK_X1000_SSCR0_DSS GENMASK(4, 0) /* Data Size Select (mask) */
#define QUARK_X1000_SSCR0_DataSize(x) ((x) - 1) /* Data Size Select [4..32] */ #define QUARK_X1000_SSCR0_DataSize(x) ((x) - 1) /* Data Size Select [4..32] */
...@@ -124,7 +126,7 @@ struct device_node; ...@@ -124,7 +126,7 @@ struct device_node;
#define QUARK_X1000_SSCR1_EFWR BIT(16) /* Enable FIFO Write/Read */ #define QUARK_X1000_SSCR1_EFWR BIT(16) /* Enable FIFO Write/Read */
#define QUARK_X1000_SSCR1_STRF BIT(17) /* Select FIFO or EFWR */ #define QUARK_X1000_SSCR1_STRF BIT(17) /* Select FIFO or EFWR */
/* extra bits in PXA255, PXA26x and PXA27x SSP ports */ /* Extra bits in PXA255, PXA26x and PXA27x SSP ports */
#define SSCR0_TISSP (1 << 4) /* TI Sync Serial Protocol */ #define SSCR0_TISSP (1 << 4) /* TI Sync Serial Protocol */
#define SSCR0_PSP (3 << 4) /* PSP - Programmable Serial Protocol */ #define SSCR0_PSP (3 << 4) /* PSP - Programmable Serial Protocol */
...@@ -181,6 +183,21 @@ struct device_node; ...@@ -181,6 +183,21 @@ struct device_node;
#define SSACD_ACPS(x) ((x) << 4) /* Audio clock PLL select */ #define SSACD_ACPS(x) ((x) << 4) /* Audio clock PLL select */
#define SSACD_SCDX8 BIT(7) /* SYSCLK division ratio select */ #define SSACD_SCDX8 BIT(7) /* SYSCLK division ratio select */
/* Intel Merrifield SSP */
#define SFIFOL 0x68 /* FIFO level */
#define SFIFOTT 0x6c /* FIFO trigger threshold */
#define RX_THRESH_MRFLD_DFLT 16
#define TX_THRESH_MRFLD_DFLT 16
#define SFIFOL_TFL_MASK GENMASK(15, 0) /* Transmit FIFO Level mask */
#define SFIFOL_RFL_MASK GENMASK(31, 16) /* Receive FIFO Level mask */
#define SFIFOTT_TFT GENMASK(15, 0) /* Transmit FIFO Threshold (mask) */
#define SFIFOTT_TxThresh(x) (((x) - 1) << 0) /* TX FIFO trigger threshold / level */
#define SFIFOTT_RFT GENMASK(31, 16) /* Receive FIFO Threshold (mask) */
#define SFIFOTT_RxThresh(x) (((x) - 1) << 16) /* RX FIFO trigger threshold / level */
/* LPSS SSP */ /* LPSS SSP */
#define SSITF 0x44 /* TX FIFO trigger level */ #define SSITF 0x44 /* TX FIFO trigger level */
#define SSITF_TxHiThresh(x) (((x) - 1) << 0) #define SSITF_TxHiThresh(x) (((x) - 1) << 0)
...@@ -203,8 +220,10 @@ enum pxa_ssp_type { ...@@ -203,8 +220,10 @@ enum pxa_ssp_type {
MMP2_SSP, MMP2_SSP,
PXA910_SSP, PXA910_SSP,
CE4100_SSP, CE4100_SSP,
MRFLD_SSP,
QUARK_X1000_SSP, QUARK_X1000_SSP,
LPSS_LPT_SSP, /* Keep LPSS types sorted with lpss_platforms[] */ /* Keep LPSS types sorted with lpss_platforms[] */
LPSS_LPT_SSP,
LPSS_BYT_SSP, LPSS_BYT_SSP,
LPSS_BSW_SSP, LPSS_BSW_SSP,
LPSS_SPT_SSP, LPSS_SPT_SSP,
...@@ -252,6 +271,22 @@ static inline u32 pxa_ssp_read_reg(struct ssp_device *dev, u32 reg) ...@@ -252,6 +271,22 @@ static inline u32 pxa_ssp_read_reg(struct ssp_device *dev, u32 reg)
return __raw_readl(dev->mmio_base + reg); return __raw_readl(dev->mmio_base + reg);
} }
static inline void pxa_ssp_enable(struct ssp_device *ssp)
{
u32 sscr0;
sscr0 = pxa_ssp_read_reg(ssp, SSCR0) | SSCR0_SSE;
pxa_ssp_write_reg(ssp, SSCR0, sscr0);
}
static inline void pxa_ssp_disable(struct ssp_device *ssp)
{
u32 sscr0;
sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & ~SSCR0_SSE;
pxa_ssp_write_reg(ssp, SSCR0, sscr0);
}
#if IS_ENABLED(CONFIG_PXA_SSP) #if IS_ENABLED(CONFIG_PXA_SSP)
struct ssp_device *pxa_ssp_request(int port, const char *label); struct ssp_device *pxa_ssp_request(int port, const char *label);
void pxa_ssp_free(struct ssp_device *); void pxa_ssp_free(struct ssp_device *);
...@@ -270,4 +305,4 @@ static inline struct ssp_device *pxa_ssp_request_of(const struct device_node *n, ...@@ -270,4 +305,4 @@ static inline struct ssp_device *pxa_ssp_request_of(const struct device_node *n,
static inline void pxa_ssp_free(struct ssp_device *ssp) {} static inline void pxa_ssp_free(struct ssp_device *ssp) {}
#endif #endif
#endif #endif /* __LINUX_PXA2XX_SSP_H */
...@@ -2,8 +2,10 @@ ...@@ -2,8 +2,10 @@
/* /*
* Copyright (C) 2005 Stephen Street / StreetFire Sound Labs * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs
*/ */
#ifndef __linux_pxa2xx_spi_h #ifndef __LINUX_SPI_PXA2XX_SPI_H
#define __linux_pxa2xx_spi_h #define __LINUX_SPI_PXA2XX_SPI_H
#include <linux/types.h>
#include <linux/pxa2xx_ssp.h> #include <linux/pxa2xx_ssp.h>
...@@ -12,7 +14,10 @@ ...@@ -12,7 +14,10 @@
struct dma_chan; struct dma_chan;
/* device.platform_data for SSP controller devices */ /*
* The platform data for SSP controller devices
* (resides in device.platform_data).
*/
struct pxa2xx_spi_controller { struct pxa2xx_spi_controller {
u16 num_chipselect; u16 num_chipselect;
u8 enable_dma; u8 enable_dma;
...@@ -28,8 +33,11 @@ struct pxa2xx_spi_controller { ...@@ -28,8 +33,11 @@ struct pxa2xx_spi_controller {
struct ssp_device ssp; struct ssp_device ssp;
}; };
/* spi_board_info.controller_data for SPI slave devices, /*
* copied to spi_device.platform_data ... mostly for dma tuning * The controller specific data for SPI slave devices
* (resides in spi_board_info.controller_data),
* copied to spi_device.platform_data ... mostly for
* DMA tuning.
*/ */
struct pxa2xx_spi_chip { struct pxa2xx_spi_chip {
u8 tx_threshold; u8 tx_threshold;
...@@ -49,4 +57,5 @@ struct pxa2xx_spi_chip { ...@@ -49,4 +57,5 @@ struct pxa2xx_spi_chip {
extern void pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_controller *info); extern void pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_controller *info);
#endif #endif
#endif
#endif /* __LINUX_SPI_PXA2XX_SPI_H */
...@@ -250,6 +250,9 @@ static inline void *spi_mem_get_drvdata(struct spi_mem *mem) ...@@ -250,6 +250,9 @@ static inline void *spi_mem_get_drvdata(struct spi_mem *mem)
* the currently mapped area), and the caller of * the currently mapped area), and the caller of
* spi_mem_dirmap_write() is responsible for calling it again in * spi_mem_dirmap_write() is responsible for calling it again in
* this case. * this case.
* @poll_status: poll memory device status until (status & mask) == match or
* when the timeout has expired. It fills the data buffer with
* the last status value.
* *
* This interface should be implemented by SPI controllers providing an * This interface should be implemented by SPI controllers providing an
* high-level interface to execute SPI memory operation, which is usually the * high-level interface to execute SPI memory operation, which is usually the
...@@ -274,6 +277,12 @@ struct spi_controller_mem_ops { ...@@ -274,6 +277,12 @@ struct spi_controller_mem_ops {
u64 offs, size_t len, void *buf); u64 offs, size_t len, void *buf);
ssize_t (*dirmap_write)(struct spi_mem_dirmap_desc *desc, ssize_t (*dirmap_write)(struct spi_mem_dirmap_desc *desc,
u64 offs, size_t len, const void *buf); u64 offs, size_t len, const void *buf);
int (*poll_status)(struct spi_mem *mem,
const struct spi_mem_op *op,
u16 mask, u16 match,
unsigned long initial_delay_us,
unsigned long polling_rate_us,
unsigned long timeout_ms);
}; };
/** /**
...@@ -369,6 +378,13 @@ devm_spi_mem_dirmap_create(struct device *dev, struct spi_mem *mem, ...@@ -369,6 +378,13 @@ devm_spi_mem_dirmap_create(struct device *dev, struct spi_mem *mem,
void devm_spi_mem_dirmap_destroy(struct device *dev, void devm_spi_mem_dirmap_destroy(struct device *dev,
struct spi_mem_dirmap_desc *desc); struct spi_mem_dirmap_desc *desc);
int spi_mem_poll_status(struct spi_mem *mem,
const struct spi_mem_op *op,
u16 mask, u16 match,
unsigned long initial_delay_us,
unsigned long polling_delay_us,
u16 timeout_ms);
int spi_mem_driver_register_with_owner(struct spi_mem_driver *drv, int spi_mem_driver_register_with_owner(struct spi_mem_driver *drv,
struct module *owner); struct module *owner);
......
...@@ -299,6 +299,8 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) ...@@ -299,6 +299,8 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
driver_unregister(&sdrv->driver); driver_unregister(&sdrv->driver);
} }
extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 chip_select);
/* use a define to avoid include chaining to get THIS_MODULE */ /* use a define to avoid include chaining to get THIS_MODULE */
#define spi_register_driver(driver) \ #define spi_register_driver(driver) \
__spi_register_driver(THIS_MODULE, driver) __spi_register_driver(THIS_MODULE, driver)
...@@ -586,6 +588,7 @@ struct spi_controller { ...@@ -586,6 +588,7 @@ struct spi_controller {
bool (*can_dma)(struct spi_controller *ctlr, bool (*can_dma)(struct spi_controller *ctlr,
struct spi_device *spi, struct spi_device *spi,
struct spi_transfer *xfer); struct spi_transfer *xfer);
struct device *dma_map_dev;
/* /*
* These hooks are for drivers that want to use the generic * These hooks are for drivers that want to use the generic
...@@ -1108,11 +1111,6 @@ static inline void spi_message_free(struct spi_message *m) ...@@ -1108,11 +1111,6 @@ static inline void spi_message_free(struct spi_message *m)
kfree(m); kfree(m);
} }
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_setup(struct spi_device *spi);
extern int spi_async(struct spi_device *spi, struct spi_message *message); extern int spi_async(struct spi_device *spi, struct spi_message *message);
extern int spi_async_locked(struct spi_device *spi, extern int spi_async_locked(struct spi_device *spi,
......
...@@ -42,6 +42,63 @@ DEFINE_EVENT(spi_controller, spi_controller_busy, ...@@ -42,6 +42,63 @@ DEFINE_EVENT(spi_controller, spi_controller_busy,
); );
TRACE_EVENT(spi_setup,
TP_PROTO(struct spi_device *spi, int status),
TP_ARGS(spi, status),
TP_STRUCT__entry(
__field(int, bus_num)
__field(int, chip_select)
__field(unsigned long, mode)
__field(unsigned int, bits_per_word)
__field(unsigned int, max_speed_hz)
__field(int, status)
),
TP_fast_assign(
__entry->bus_num = spi->controller->bus_num;
__entry->chip_select = spi->chip_select;
__entry->mode = spi->mode;
__entry->bits_per_word = spi->bits_per_word;
__entry->max_speed_hz = spi->max_speed_hz;
__entry->status = status;
),
TP_printk("spi%d.%d setup mode %lu, %s%s%s%s%u bits/w, %u Hz max --> %d",
__entry->bus_num, __entry->chip_select,
(__entry->mode & SPI_MODE_X_MASK),
(__entry->mode & SPI_CS_HIGH) ? "cs_high, " : "",
(__entry->mode & SPI_LSB_FIRST) ? "lsb, " : "",
(__entry->mode & SPI_3WIRE) ? "3wire, " : "",
(__entry->mode & SPI_LOOP) ? "loopback, " : "",
__entry->bits_per_word, __entry->max_speed_hz,
__entry->status)
);
TRACE_EVENT(spi_set_cs,
TP_PROTO(struct spi_device *spi, bool enable),
TP_ARGS(spi, enable),
TP_STRUCT__entry(
__field(int, bus_num)
__field(int, chip_select)
__field(unsigned long, mode)
__field(bool, enable)
),
TP_fast_assign(
__entry->bus_num = spi->controller->bus_num;
__entry->chip_select = spi->chip_select;
__entry->mode = spi->mode;
__entry->enable = enable;
),
TP_printk("spi%d.%d %s%s",
__entry->bus_num, __entry->chip_select,
__entry->enable ? "activate" : "deactivate",
(__entry->mode & SPI_CS_HIGH) ? ", cs_high" : "")
);
DECLARE_EVENT_CLASS(spi_message, DECLARE_EVENT_CLASS(spi_message,
TP_PROTO(struct spi_message *msg), TP_PROTO(struct spi_message *msg),
......
...@@ -61,22 +61,6 @@ static void dump_registers(struct ssp_device *ssp) ...@@ -61,22 +61,6 @@ static void dump_registers(struct ssp_device *ssp)
pxa_ssp_read_reg(ssp, SSACD)); pxa_ssp_read_reg(ssp, SSACD));
} }
static void pxa_ssp_enable(struct ssp_device *ssp)
{
uint32_t sscr0;
sscr0 = __raw_readl(ssp->mmio_base + SSCR0) | SSCR0_SSE;
__raw_writel(sscr0, ssp->mmio_base + SSCR0);
}
static void pxa_ssp_disable(struct ssp_device *ssp)
{
uint32_t sscr0;
sscr0 = __raw_readl(ssp->mmio_base + SSCR0) & ~SSCR0_SSE;
__raw_writel(sscr0, ssp->mmio_base + SSCR0);
}
static void pxa_ssp_set_dma_params(struct ssp_device *ssp, int width4, static void pxa_ssp_set_dma_params(struct ssp_device *ssp, int width4,
int out, struct snd_dmaengine_dai_dma_data *dma) int out, struct snd_dmaengine_dai_dma_data *dma)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment