Commit 2019295c authored by Linus Torvalds's avatar Linus Torvalds

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

Pull spi updates from Mark Brown:
 "This is quite a quiet release for SPI, there's been a bit of cleanup
  to the core from Uwe but nothing functionality wise.

  We have added several new drivers, Cadence XSPI, Ingenic JZ47xx,
  Qualcomm SC7280 and SC7180 and Xilinx Versal OSPI"

* tag 'spi-v5.16' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (41 commits)
  spi: Convert NXP flexspi to json schema
  spi: spi-geni-qcom: Add support for GPI dma
  spi: fsi: Fix contention in the FSI2SPI engine
  spi: spi-rpc-if: Check return value of rpcif_sw_init()
  spi: tegra210-quad: Put device into suspend on driver removal
  spi: tegra20-slink: Put device into suspend on driver removal
  spi: bcm-qspi: Fix missing clk_disable_unprepare() on error in bcm_qspi_probe()
  spi: at91-usart: replacing legacy gpio interface for gpiod
  spi: replace snprintf in show functions with sysfs_emit
  spi: cadence: Add of_node_put() before return
  spi: orion: Add of_node_put() before goto
  spi: cadence-quadspi: fix dma_unmap_single() call
  spi: tegra20: fix build with CONFIG_PM_SLEEP=n
  spi: bcm-qspi: add support for 3-wire mode for half duplex transfer
  spi: bcm-qspi: Add mspi spcr3 32/64-bits xfer mode
  spi: Make several public functions private to spi.c
  spi: Reorder functions to simplify the next commit
  spi: Remove unused function spi_busnum_to_master()
  spi: Move comment about chipselect check to the right place
  spi: fsi: Print status on error
  ...
parents 1260d242 28b5eaf9
...@@ -11,6 +11,14 @@ maintainers: ...@@ -11,6 +11,14 @@ maintainers:
allOf: allOf:
- $ref: spi-controller.yaml# - $ref: spi-controller.yaml#
- if:
properties:
compatible:
contains:
const: xlnx,versal-ospi-1.0
then:
required:
- power-domains
properties: properties:
compatible: compatible:
...@@ -20,6 +28,7 @@ properties: ...@@ -20,6 +28,7 @@ properties:
- ti,k2g-qspi - ti,k2g-qspi
- ti,am654-ospi - ti,am654-ospi
- intel,lgm-qspi - intel,lgm-qspi
- xlnx,versal-ospi-1.0
- const: cdns,qspi-nor - const: cdns,qspi-nor
- const: cdns,qspi-nor - const: cdns,qspi-nor
...@@ -65,6 +74,9 @@ properties: ...@@ -65,6 +74,9 @@ properties:
data rather than the QSPI clock. Make sure that QSPI return clock data rather than the QSPI clock. Make sure that QSPI return clock
is populated on the board before using this property. is populated on the board before using this property.
power-domains:
maxItems: 1
resets: resets:
maxItems: 2 maxItems: 2
......
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
# Copyright 2020-21 Cadence
%YAML 1.2
---
$id: "http://devicetree.org/schemas/spi/cdns,xspi.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
title: Cadence XSPI Controller
maintainers:
- Parshuram Thombare <pthombar@cadence.com>
description: |
The XSPI controller allows SPI protocol communication in
single, dual, quad or octal wire transmission modes for
read/write access to slaves such as SPI-NOR flash.
allOf:
- $ref: "spi-controller.yaml#"
properties:
compatible:
const: cdns,xspi-nor
reg:
items:
- description: address and length of the controller register set
- description: address and length of the Slave DMA data port
- description: address and length of the auxiliary registers
reg-names:
items:
- const: io
- const: sdma
- const: aux
interrupts:
maxItems: 1
required:
- compatible
- reg
- interrupts
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
bus {
#address-cells = <2>;
#size-cells = <2>;
xspi: spi@a0010000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "cdns,xspi-nor";
reg = <0x0 0xa0010000 0x0 0x1040>,
<0x0 0xb0000000 0x0 0x1000>,
<0x0 0xa0020000 0x0 0x100>;
reg-names = "io", "sdma", "aux";
interrupts = <0 90 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&gic>;
flash@0 {
compatible = "jedec,spi-nor";
spi-max-frequency = <75000000>;
reg = <0>;
};
flash@1 {
compatible = "jedec,spi-nor";
spi-max-frequency = <75000000>;
reg = <1>;
};
};
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/spi/ingenic,spi.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Ingenic SoCs SPI controller devicetree bindings
maintainers:
- Artur Rojek <contact@artur-rojek.eu>
- Paul Cercueil <paul@crapouillou.net>
allOf:
- $ref: /schemas/spi/spi-controller.yaml#
properties:
compatible:
oneOf:
- enum:
- ingenic,jz4750-spi
- ingenic,jz4780-spi
- items:
- enum:
- ingenic,jz4760-spi
- ingenic,jz4770-spi
- const: ingenic,jz4750-spi
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
maxItems: 1
dmas:
maxItems: 2
minItems: 2
dma-names:
items:
- const: rx
- const: tx
required:
- compatible
- reg
- interrupts
- clocks
- dmas
- dma-names
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/jz4770-cgu.h>
spi@10043000 {
compatible = "ingenic,jz4770-spi", "ingenic,jz4750-spi";
reg = <0x10043000 0x1c>;
#address-cells = <1>;
#size-cells = <0>;
interrupt-parent = <&intc>;
interrupts = <8>;
clocks = <&cgu JZ4770_CLK_SSI0>;
dmas = <&dmac1 23 0xffffffff>, <&dmac1 22 0xffffffff>;
dma-names = "rx", "tx";
};
...@@ -21,7 +21,11 @@ allOf: ...@@ -21,7 +21,11 @@ allOf:
properties: properties:
compatible: compatible:
items: items:
- const: qcom,sdm845-qspi - enum:
- qcom,sc7180-qspi
- qcom,sc7280-qspi
- qcom,sdm845-qspi
- const: qcom,qspi-v1 - const: qcom,qspi-v1
reg: reg:
......
* NXP Flex Serial Peripheral Interface (FSPI)
Required properties:
- compatible : Should be "nxp,lx2160a-fspi"
"nxp,imx8qxp-fspi"
"nxp,imx8mm-fspi"
"nxp,imx8mp-fspi"
"nxp,imx8dxl-fspi"
- reg : First contains the register location and length,
Second contains the memory mapping address and length
- reg-names : Should contain the resource reg names:
- fspi_base: configuration register address space
- fspi_mmap: memory mapped address space
- interrupts : Should contain the interrupt for the device
Required SPI slave node properties:
- reg : There are two buses (A and B) with two chip selects each.
This encodes to which bus and CS the flash is connected:
- <0>: Bus A, CS 0
- <1>: Bus A, CS 1
- <2>: Bus B, CS 0
- <3>: Bus B, CS 1
Example showing the usage of two SPI NOR slave devices on bus A:
fspi0: spi@20c0000 {
compatible = "nxp,lx2160a-fspi";
reg = <0x0 0x20c0000 0x0 0x10000>, <0x0 0x20000000 0x0 0x10000000>;
reg-names = "fspi_base", "fspi_mmap";
interrupts = <0 25 0x4>; /* Level high type */
clocks = <&clockgen 4 3>, <&clockgen 4 3>;
clock-names = "fspi_en", "fspi";
mt35xu512aba0: flash@0 {
reg = <0>;
....
};
mt35xu512aba1: flash@1 {
reg = <1>;
....
};
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/spi/spi-nxp-fspi.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NXP Flex Serial Peripheral Interface (FSPI)
maintainers:
- Kuldeep Singh <kuldeep.singh@nxp.com>
allOf:
- $ref: "spi-controller.yaml#"
properties:
compatible:
enum:
- nxp,imx8dxl-fspi
- nxp,imx8mm-fspi
- nxp,imx8mp-fspi
- nxp,imx8qxp-fspi
- nxp,lx2160a-fspi
reg:
items:
- description: registers address space
- description: memory mapped address space
reg-names:
items:
- const: fspi_base
- const: fspi_mmap
interrupts:
maxItems: 1
clocks:
items:
- description: SPI bus clock
- description: SPI serial clock
clock-names:
items:
- const: fspi_en
- const: fspi
required:
- compatible
- reg
- reg-names
- interrupts
- clocks
- clock-names
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/fsl,qoriq-clockgen.h>
soc {
#address-cells = <2>;
#size-cells = <2>;
spi@20c0000 {
compatible = "nxp,lx2160a-fspi";
reg = <0x0 0x20c0000 0x0 0x100000>,
<0x0 0x20000000 0x0 0x10000000>;
reg-names = "fspi_base", "fspi_mmap";
interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL QORIQ_CLK_PLL_DIV(4)>,
<&clockgen QORIQ_CLK_PLATFORM_PLL QORIQ_CLK_PLL_DIV(4)>;
clock-names = "fspi_en", "fspi";
#address-cells = <1>;
#size-cells = <0>;
flash@0 {
compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
reg = <0>;
spi-rx-bus-width = <8>;
spi-tx-bus-width = <8>;
};
};
};
...@@ -336,14 +336,6 @@ certainly includes SPI devices hooked up through the card connectors! ...@@ -336,14 +336,6 @@ certainly includes SPI devices hooked up through the card connectors!
Non-static Configurations Non-static Configurations
^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
Developer boards often play by different rules than product boards, and one
example is the potential need to hotplug SPI devices and/or controllers.
For those cases you might need to use spi_busnum_to_master() to look
up the spi bus master, and will likely need spi_new_device() to provide the
board info based on the board that was hotplugged. Of course, you'd later
call at least spi_unregister_device() when that board is removed.
When Linux includes support for MMC/SD/SDIO/DataFlash cards through SPI, those When Linux includes support for MMC/SD/SDIO/DataFlash cards through SPI, those
configurations will also be dynamic. Fortunately, such devices all support configurations will also be dynamic. Fortunately, such devices all support
basic device identification probes, so they should hotplug normally. basic device identification probes, so they should hotplug normally.
......
...@@ -13488,7 +13488,7 @@ M: Ashish Kumar <ashish.kumar@nxp.com> ...@@ -13488,7 +13488,7 @@ M: Ashish Kumar <ashish.kumar@nxp.com>
R: Yogesh Gaur <yogeshgaur.83@gmail.com> R: Yogesh Gaur <yogeshgaur.83@gmail.com>
L: linux-spi@vger.kernel.org L: linux-spi@vger.kernel.org
S: Maintained S: Maintained
F: Documentation/devicetree/bindings/spi/spi-nxp-fspi.txt F: Documentation/devicetree/bindings/spi/spi-nxp-fspi.yaml
F: drivers/spi/spi-nxp-fspi.c F: drivers/spi/spi-nxp-fspi.c
NXP FXAS21002C DRIVER NXP FXAS21002C DRIVER
......
...@@ -113,9 +113,12 @@ &cgu { ...@@ -113,9 +113,12 @@ &cgu {
* Use the 32.768 kHz oscillator as the parent of the RTC for a higher * Use the 32.768 kHz oscillator as the parent of the RTC for a higher
* precision. * precision.
*/ */
assigned-clocks = <&cgu JZ4780_CLK_OTGPHY>, <&cgu JZ4780_CLK_RTC>; assigned-clocks = <&cgu JZ4780_CLK_OTGPHY>, <&cgu JZ4780_CLK_RTC>,
assigned-clock-parents = <0>, <&cgu JZ4780_CLK_RTCLK>; <&cgu JZ4780_CLK_SSIPLL>, <&cgu JZ4780_CLK_SSI>;
assigned-clock-rates = <48000000>; assigned-clock-parents = <0>, <&cgu JZ4780_CLK_RTCLK>,
<&cgu JZ4780_CLK_MPLL>,
<&cgu JZ4780_CLK_SSIPLL>;
assigned-clock-rates = <48000000>, <0>, <54000000>;
}; };
&tcu { &tcu {
......
...@@ -255,22 +255,23 @@ gpf: gpio@5 { ...@@ -255,22 +255,23 @@ gpf: gpio@5 {
}; };
}; };
spi_gpio { spi0: spi@10043000 {
compatible = "spi-gpio"; compatible = "ingenic,jz4780-spi";
reg = <0x10043000 0x1c>;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
num-chipselects = <2>;
gpio-miso = <&gpe 14 0>; interrupt-parent = <&intc>;
gpio-sck = <&gpe 15 0>; interrupts = <8>;
gpio-mosi = <&gpe 17 0>;
cs-gpios = <&gpe 16 0>, <&gpe 18 0>;
spidev@0 { clocks = <&cgu JZ4780_CLK_SSI0>;
compatible = "spidev"; clock-names = "spi";
reg = <0>;
spi-max-frequency = <1000000>; dmas = <&dma JZ4780_DMA_SSI0_RX 0xffffffff>,
}; <&dma JZ4780_DMA_SSI0_TX 0xffffffff>;
dma-names = "rx", "tx";
status = "disabled";
}; };
uart0: serial@10030000 { uart0: serial@10030000 {
...@@ -338,6 +339,25 @@ uart4: serial@10034000 { ...@@ -338,6 +339,25 @@ uart4: serial@10034000 {
status = "disabled"; status = "disabled";
}; };
spi1: spi@10044000 {
compatible = "ingenic,jz4780-spi";
reg = <0x10044000 0x1c>;
#address-cells = <1>;
#size-sells = <0>;
interrupt-parent = <&intc>;
interrupts = <7>;
clocks = <&cgu JZ4780_CLK_SSI1>;
clock-names = "spi";
dmas = <&dma JZ4780_DMA_SSI1_RX 0xffffffff>,
<&dma JZ4780_DMA_SSI1_TX 0xffffffff>;
dma-names = "rx", "tx";
status = "disabled";
};
i2c0: i2c@10050000 { i2c0: i2c@10050000 {
compatible = "ingenic,jz4780-i2c", "ingenic,jz4770-i2c"; compatible = "ingenic,jz4780-i2c", "ingenic,jz4770-i2c";
#address-cells = <1>; #address-cells = <1>;
......
...@@ -647,6 +647,23 @@ int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type) ...@@ -647,6 +647,23 @@ int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type)
} }
EXPORT_SYMBOL_GPL(zynqmp_pm_sd_dll_reset); EXPORT_SYMBOL_GPL(zynqmp_pm_sd_dll_reset);
/**
* zynqmp_pm_ospi_mux_select() - OSPI Mux selection
*
* @dev_id: Device Id of the OSPI device.
* @select: OSPI Mux select value.
*
* This function select the OSPI Mux.
*
* Return: Returns status, either success or error+reason
*/
int zynqmp_pm_ospi_mux_select(u32 dev_id, u32 select)
{
return zynqmp_pm_invoke_fn(PM_IOCTL, dev_id, IOCTL_OSPI_MUX_SELECT,
select, 0, NULL);
}
EXPORT_SYMBOL_GPL(zynqmp_pm_ospi_mux_select);
/** /**
* zynqmp_pm_write_ggs() - PM API for writing global general storage (ggs) * zynqmp_pm_write_ggs() - PM API for writing global general storage (ggs)
* @index: GGS register index * @index: GGS register index
......
...@@ -228,6 +228,18 @@ config SPI_CADENCE_QUADSPI ...@@ -228,6 +228,18 @@ config SPI_CADENCE_QUADSPI
device with a Cadence QSPI controller and want to access the device with a Cadence QSPI controller and want to access the
Flash as an MTD device. Flash as an MTD device.
config SPI_CADENCE_XSPI
tristate "Cadence XSPI controller"
depends on (OF || COMPILE_TEST) && HAS_IOMEM
depends on SPI_MEM
help
Enable support for the Cadence XSPI Flash controller.
Cadence XSPI is a specialized controller for connecting an SPI
Flash over upto 8bit wide bus. Enable this option if you have a
device with a Cadence XSPI controller and want to access the
Flash as an MTD device.
config SPI_CLPS711X config SPI_CLPS711X
tristate "CLPS711X host SPI controller" tristate "CLPS711X host SPI controller"
depends on ARCH_CLPS711X || COMPILE_TEST depends on ARCH_CLPS711X || COMPILE_TEST
...@@ -406,6 +418,15 @@ config SPI_IMX ...@@ -406,6 +418,15 @@ config SPI_IMX
help help
This enables support for the Freescale i.MX SPI controllers. This enables support for the Freescale i.MX SPI controllers.
config SPI_INGENIC
tristate "Ingenic JZ47xx SoCs SPI controller"
depends on MACH_INGENIC || COMPILE_TEST
help
This enables support for the Ingenic JZ47xx SoCs SPI controller.
To compile this driver as a module, choose M here: the module
will be called spi-ingenic.
config SPI_JCORE config SPI_JCORE
tristate "J-Core SPI Master" tristate "J-Core SPI Master"
depends on OF && (SUPERH || COMPILE_TEST) depends on OF && (SUPERH || COMPILE_TEST)
...@@ -738,10 +759,11 @@ config SPI_S3C24XX_FIQ ...@@ -738,10 +759,11 @@ config SPI_S3C24XX_FIQ
TX and RX data paths. TX and RX data paths.
config SPI_S3C64XX config SPI_S3C64XX
tristate "Samsung S3C64XX series type SPI" tristate "Samsung S3C64XX/Exynos SoC series type SPI"
depends on (PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST) depends on (PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST)
help help
SPI driver for Samsung S3C64XX and newer SoCs. SPI driver for Samsung S3C64XX, S5Pv210 and Exynos SoCs.
Choose Y/M here only if you build for such Samsung SoC.
config SPI_SC18IS602 config SPI_SC18IS602
tristate "NXP SC18IS602/602B/603 I2C to SPI bridge" tristate "NXP SC18IS602/602B/603 I2C to SPI bridge"
......
...@@ -34,6 +34,7 @@ obj-$(CONFIG_SPI_BITBANG) += spi-bitbang.o ...@@ -34,6 +34,7 @@ obj-$(CONFIG_SPI_BITBANG) += spi-bitbang.o
obj-$(CONFIG_SPI_BUTTERFLY) += spi-butterfly.o obj-$(CONFIG_SPI_BUTTERFLY) += spi-butterfly.o
obj-$(CONFIG_SPI_CADENCE) += spi-cadence.o obj-$(CONFIG_SPI_CADENCE) += spi-cadence.o
obj-$(CONFIG_SPI_CADENCE_QUADSPI) += spi-cadence-quadspi.o obj-$(CONFIG_SPI_CADENCE_QUADSPI) += spi-cadence-quadspi.o
obj-$(CONFIG_SPI_CADENCE_XSPI) += spi-cadence-xspi.o
obj-$(CONFIG_SPI_CLPS711X) += spi-clps711x.o obj-$(CONFIG_SPI_CLPS711X) += spi-clps711x.o
obj-$(CONFIG_SPI_COLDFIRE_QSPI) += spi-coldfire-qspi.o obj-$(CONFIG_SPI_COLDFIRE_QSPI) += spi-coldfire-qspi.o
obj-$(CONFIG_SPI_DAVINCI) += spi-davinci.o obj-$(CONFIG_SPI_DAVINCI) += spi-davinci.o
...@@ -59,6 +60,7 @@ obj-$(CONFIG_SPI_HISI_KUNPENG) += spi-hisi-kunpeng.o ...@@ -59,6 +60,7 @@ obj-$(CONFIG_SPI_HISI_KUNPENG) += spi-hisi-kunpeng.o
obj-$(CONFIG_SPI_HISI_SFC_V3XX) += spi-hisi-sfc-v3xx.o obj-$(CONFIG_SPI_HISI_SFC_V3XX) += spi-hisi-sfc-v3xx.o
obj-$(CONFIG_SPI_IMG_SPFI) += spi-img-spfi.o obj-$(CONFIG_SPI_IMG_SPFI) += spi-img-spfi.o
obj-$(CONFIG_SPI_IMX) += spi-imx.o obj-$(CONFIG_SPI_IMX) += spi-imx.o
obj-$(CONFIG_SPI_INGENIC) += spi-ingenic.o
obj-$(CONFIG_SPI_LANTIQ_SSC) += spi-lantiq-ssc.o obj-$(CONFIG_SPI_LANTIQ_SSC) += spi-lantiq-ssc.o
obj-$(CONFIG_SPI_JCORE) += spi-jcore.o obj-$(CONFIG_SPI_JCORE) += spi-jcore.o
obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o
......
...@@ -310,7 +310,7 @@ static int atmel_qspi_set_cfg(struct atmel_qspi *aq, ...@@ -310,7 +310,7 @@ static int atmel_qspi_set_cfg(struct atmel_qspi *aq,
return mode; return mode;
ifr |= atmel_qspi_modes[mode].config; ifr |= atmel_qspi_modes[mode].config;
if (op->dummy.buswidth && op->dummy.nbytes) if (op->dummy.nbytes)
dummy_cycles = op->dummy.nbytes * 8 / op->dummy.buswidth; dummy_cycles = op->dummy.nbytes * 8 / op->dummy.buswidth;
/* /*
......
...@@ -38,126 +38,102 @@ struct amd_spi { ...@@ -38,126 +38,102 @@ struct amd_spi {
void __iomem *io_remap_addr; void __iomem *io_remap_addr;
unsigned long io_base_addr; unsigned long io_base_addr;
u32 rom_addr; u32 rom_addr;
u8 chip_select;
}; };
static inline u8 amd_spi_readreg8(struct spi_master *master, int idx) static inline u8 amd_spi_readreg8(struct amd_spi *amd_spi, int idx)
{ {
struct amd_spi *amd_spi = spi_master_get_devdata(master);
return ioread8((u8 __iomem *)amd_spi->io_remap_addr + idx); return ioread8((u8 __iomem *)amd_spi->io_remap_addr + idx);
} }
static inline void amd_spi_writereg8(struct spi_master *master, int idx, static inline void amd_spi_writereg8(struct amd_spi *amd_spi, int idx, u8 val)
u8 val)
{ {
struct amd_spi *amd_spi = spi_master_get_devdata(master);
iowrite8(val, ((u8 __iomem *)amd_spi->io_remap_addr + idx)); iowrite8(val, ((u8 __iomem *)amd_spi->io_remap_addr + idx));
} }
static inline void amd_spi_setclear_reg8(struct spi_master *master, int idx, static void amd_spi_setclear_reg8(struct amd_spi *amd_spi, int idx, u8 set, u8 clear)
u8 set, u8 clear)
{ {
u8 tmp = amd_spi_readreg8(master, idx); u8 tmp = amd_spi_readreg8(amd_spi, idx);
tmp = (tmp & ~clear) | set; tmp = (tmp & ~clear) | set;
amd_spi_writereg8(master, idx, tmp); amd_spi_writereg8(amd_spi, idx, tmp);
} }
static inline u32 amd_spi_readreg32(struct spi_master *master, int idx) static inline u32 amd_spi_readreg32(struct amd_spi *amd_spi, int idx)
{ {
struct amd_spi *amd_spi = spi_master_get_devdata(master);
return ioread32((u8 __iomem *)amd_spi->io_remap_addr + idx); return ioread32((u8 __iomem *)amd_spi->io_remap_addr + idx);
} }
static inline void amd_spi_writereg32(struct spi_master *master, int idx, static inline void amd_spi_writereg32(struct amd_spi *amd_spi, int idx, u32 val)
u32 val)
{ {
struct amd_spi *amd_spi = spi_master_get_devdata(master);
iowrite32(val, ((u8 __iomem *)amd_spi->io_remap_addr + idx)); iowrite32(val, ((u8 __iomem *)amd_spi->io_remap_addr + idx));
} }
static inline void amd_spi_setclear_reg32(struct spi_master *master, int idx, static inline void amd_spi_setclear_reg32(struct amd_spi *amd_spi, int idx, u32 set, u32 clear)
u32 set, u32 clear)
{ {
u32 tmp = amd_spi_readreg32(master, idx); u32 tmp = amd_spi_readreg32(amd_spi, idx);
tmp = (tmp & ~clear) | set; tmp = (tmp & ~clear) | set;
amd_spi_writereg32(master, idx, tmp); amd_spi_writereg32(amd_spi, idx, tmp);
} }
static void amd_spi_select_chip(struct spi_master *master) static void amd_spi_select_chip(struct amd_spi *amd_spi, u8 cs)
{ {
struct amd_spi *amd_spi = spi_master_get_devdata(master); amd_spi_setclear_reg8(amd_spi, AMD_SPI_ALT_CS_REG, cs, AMD_SPI_ALT_CS_MASK);
u8 chip_select = amd_spi->chip_select;
amd_spi_setclear_reg8(master, AMD_SPI_ALT_CS_REG, chip_select,
AMD_SPI_ALT_CS_MASK);
} }
static void amd_spi_clear_fifo_ptr(struct spi_master *master) static void amd_spi_clear_fifo_ptr(struct amd_spi *amd_spi)
{ {
amd_spi_setclear_reg32(master, AMD_SPI_CTRL0_REG, AMD_SPI_FIFO_CLEAR, amd_spi_setclear_reg32(amd_spi, AMD_SPI_CTRL0_REG, AMD_SPI_FIFO_CLEAR, AMD_SPI_FIFO_CLEAR);
AMD_SPI_FIFO_CLEAR);
} }
static void amd_spi_set_opcode(struct spi_master *master, u8 cmd_opcode) static void amd_spi_set_opcode(struct amd_spi *amd_spi, u8 cmd_opcode)
{ {
amd_spi_setclear_reg32(master, AMD_SPI_CTRL0_REG, cmd_opcode, amd_spi_setclear_reg32(amd_spi, AMD_SPI_CTRL0_REG, cmd_opcode, AMD_SPI_OPCODE_MASK);
AMD_SPI_OPCODE_MASK);
} }
static inline void amd_spi_set_rx_count(struct spi_master *master, static inline void amd_spi_set_rx_count(struct amd_spi *amd_spi, u8 rx_count)
u8 rx_count)
{ {
amd_spi_setclear_reg8(master, AMD_SPI_RX_COUNT_REG, rx_count, 0xff); amd_spi_setclear_reg8(amd_spi, AMD_SPI_RX_COUNT_REG, rx_count, 0xff);
} }
static inline void amd_spi_set_tx_count(struct spi_master *master, static inline void amd_spi_set_tx_count(struct amd_spi *amd_spi, u8 tx_count)
u8 tx_count)
{ {
amd_spi_setclear_reg8(master, AMD_SPI_TX_COUNT_REG, tx_count, 0xff); amd_spi_setclear_reg8(amd_spi, AMD_SPI_TX_COUNT_REG, tx_count, 0xff);
} }
static inline int amd_spi_busy_wait(struct amd_spi *amd_spi) static int amd_spi_busy_wait(struct amd_spi *amd_spi)
{ {
bool spi_busy;
int timeout = 100000; int timeout = 100000;
/* poll for SPI bus to become idle */ /* poll for SPI bus to become idle */
spi_busy = (ioread32((u8 __iomem *)amd_spi->io_remap_addr + while (amd_spi_readreg32(amd_spi, AMD_SPI_CTRL0_REG) & AMD_SPI_BUSY) {
AMD_SPI_CTRL0_REG) & AMD_SPI_BUSY) == AMD_SPI_BUSY;
while (spi_busy) {
usleep_range(10, 20); usleep_range(10, 20);
if (timeout-- < 0) if (timeout-- < 0)
return -ETIMEDOUT; return -ETIMEDOUT;
spi_busy = (ioread32((u8 __iomem *)amd_spi->io_remap_addr +
AMD_SPI_CTRL0_REG) & AMD_SPI_BUSY) == AMD_SPI_BUSY;
} }
return 0; return 0;
} }
static void amd_spi_execute_opcode(struct spi_master *master) static int amd_spi_execute_opcode(struct amd_spi *amd_spi)
{ {
struct amd_spi *amd_spi = spi_master_get_devdata(master); int ret;
ret = amd_spi_busy_wait(amd_spi);
if (ret)
return ret;
/* Set ExecuteOpCode bit in the CTRL0 register */ /* Set ExecuteOpCode bit in the CTRL0 register */
amd_spi_setclear_reg32(master, AMD_SPI_CTRL0_REG, AMD_SPI_EXEC_CMD, amd_spi_setclear_reg32(amd_spi, AMD_SPI_CTRL0_REG, AMD_SPI_EXEC_CMD, AMD_SPI_EXEC_CMD);
AMD_SPI_EXEC_CMD);
amd_spi_busy_wait(amd_spi); return 0;
} }
static int amd_spi_master_setup(struct spi_device *spi) static int amd_spi_master_setup(struct spi_device *spi)
{ {
struct spi_master *master = spi->master; struct amd_spi *amd_spi = spi_master_get_devdata(spi->master);
amd_spi_clear_fifo_ptr(master); amd_spi_clear_fifo_ptr(amd_spi);
return 0; return 0;
} }
...@@ -185,19 +161,18 @@ static inline int amd_spi_fifo_xfer(struct amd_spi *amd_spi, ...@@ -185,19 +161,18 @@ static inline int amd_spi_fifo_xfer(struct amd_spi *amd_spi,
tx_len = xfer->len - 1; tx_len = xfer->len - 1;
cmd_opcode = *(u8 *)xfer->tx_buf; cmd_opcode = *(u8 *)xfer->tx_buf;
buf++; buf++;
amd_spi_set_opcode(master, cmd_opcode); amd_spi_set_opcode(amd_spi, cmd_opcode);
/* Write data into the FIFO. */ /* Write data into the FIFO. */
for (i = 0; i < tx_len; i++) { for (i = 0; i < tx_len; i++) {
iowrite8(buf[i], iowrite8(buf[i], ((u8 __iomem *)amd_spi->io_remap_addr +
((u8 __iomem *)amd_spi->io_remap_addr +
AMD_SPI_FIFO_BASE + i)); AMD_SPI_FIFO_BASE + i));
} }
amd_spi_set_tx_count(master, tx_len); amd_spi_set_tx_count(amd_spi, tx_len);
amd_spi_clear_fifo_ptr(master); amd_spi_clear_fifo_ptr(amd_spi);
/* Execute command */ /* Execute command */
amd_spi_execute_opcode(master); amd_spi_execute_opcode(amd_spi);
} }
if (m_cmd & AMD_SPI_XFER_RX) { if (m_cmd & AMD_SPI_XFER_RX) {
/* /*
...@@ -206,15 +181,14 @@ static inline int amd_spi_fifo_xfer(struct amd_spi *amd_spi, ...@@ -206,15 +181,14 @@ static inline int amd_spi_fifo_xfer(struct amd_spi *amd_spi,
*/ */
rx_len = xfer->len; rx_len = xfer->len;
buf = (u8 *)xfer->rx_buf; buf = (u8 *)xfer->rx_buf;
amd_spi_set_rx_count(master, rx_len); amd_spi_set_rx_count(amd_spi, rx_len);
amd_spi_clear_fifo_ptr(master); amd_spi_clear_fifo_ptr(amd_spi);
/* Execute command */ /* Execute command */
amd_spi_execute_opcode(master); amd_spi_execute_opcode(amd_spi);
amd_spi_busy_wait(amd_spi);
/* Read data from FIFO to receive buffer */ /* Read data from FIFO to receive buffer */
for (i = 0; i < rx_len; i++) for (i = 0; i < rx_len; i++)
buf[i] = amd_spi_readreg8(master, buf[i] = amd_spi_readreg8(amd_spi, AMD_SPI_FIFO_BASE + tx_len + i);
AMD_SPI_FIFO_BASE +
tx_len + i);
} }
} }
...@@ -233,8 +207,7 @@ static int amd_spi_master_transfer(struct spi_master *master, ...@@ -233,8 +207,7 @@ static int amd_spi_master_transfer(struct spi_master *master,
struct amd_spi *amd_spi = spi_master_get_devdata(master); struct amd_spi *amd_spi = spi_master_get_devdata(master);
struct spi_device *spi = msg->spi; struct spi_device *spi = msg->spi;
amd_spi->chip_select = spi->chip_select; amd_spi_select_chip(amd_spi, spi->chip_select);
amd_spi_select_chip(master);
/* /*
* Extract spi_transfers from the spi message and * Extract spi_transfers from the spi message and
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/of_gpio.h> #include <linux/gpio/consumer.h>
#include <linux/pinctrl/consumer.h> #include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
...@@ -482,29 +482,12 @@ static void at91_usart_spi_init(struct at91_usart_spi *aus) ...@@ -482,29 +482,12 @@ static void at91_usart_spi_init(struct at91_usart_spi *aus)
static int at91_usart_gpio_setup(struct platform_device *pdev) static int at91_usart_gpio_setup(struct platform_device *pdev)
{ {
struct device_node *np = pdev->dev.parent->of_node; struct gpio_descs *cs_gpios;
int i;
int ret;
int nb;
if (!np)
return -EINVAL;
nb = of_gpio_named_count(np, "cs-gpios");
for (i = 0; i < nb; i++) {
int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
if (cs_gpio < 0) cs_gpios = devm_gpiod_get_array_optional(&pdev->dev, "cs", GPIOD_OUT_LOW);
return cs_gpio;
if (gpio_is_valid(cs_gpio)) { if (IS_ERR(cs_gpios))
ret = devm_gpio_request_one(&pdev->dev, cs_gpio, return PTR_ERR(cs_gpios);
GPIOF_DIR_OUT,
dev_name(&pdev->dev));
if (ret)
return ret;
}
}
return 0; return 0;
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -67,9 +67,14 @@ ...@@ -67,9 +67,14 @@
SPI_FSI_STATUS_RDR_OVERRUN) SPI_FSI_STATUS_RDR_OVERRUN)
#define SPI_FSI_PORT_CTRL 0x9 #define SPI_FSI_PORT_CTRL 0x9
struct fsi2spi {
struct fsi_device *fsi; /* FSI2SPI CFAM engine device */
struct mutex lock; /* lock access to the device */
};
struct fsi_spi { struct fsi_spi {
struct device *dev; /* SPI controller device */ struct device *dev; /* SPI controller device */
struct fsi_device *fsi; /* FSI2SPI CFAM engine device */ struct fsi2spi *bridge; /* FSI2SPI device */
u32 base; u32 base;
}; };
...@@ -104,7 +109,7 @@ static int fsi_spi_check_status(struct fsi_spi *ctx) ...@@ -104,7 +109,7 @@ static int fsi_spi_check_status(struct fsi_spi *ctx)
u32 sts; u32 sts;
__be32 sts_be; __be32 sts_be;
rc = fsi_device_read(ctx->fsi, FSI2SPI_STATUS, &sts_be, rc = fsi_device_read(ctx->bridge->fsi, FSI2SPI_STATUS, &sts_be,
sizeof(sts_be)); sizeof(sts_be));
if (rc) if (rc)
return rc; return rc;
...@@ -120,73 +125,91 @@ static int fsi_spi_check_status(struct fsi_spi *ctx) ...@@ -120,73 +125,91 @@ static int fsi_spi_check_status(struct fsi_spi *ctx)
static int fsi_spi_read_reg(struct fsi_spi *ctx, u32 offset, u64 *value) static int fsi_spi_read_reg(struct fsi_spi *ctx, u32 offset, u64 *value)
{ {
int rc; int rc = 0;
__be32 cmd_be; __be32 cmd_be;
__be32 data_be; __be32 data_be;
u32 cmd = offset + ctx->base; u32 cmd = offset + ctx->base;
struct fsi2spi *bridge = ctx->bridge;
*value = 0ULL; *value = 0ULL;
if (cmd & FSI2SPI_CMD_WRITE) if (cmd & FSI2SPI_CMD_WRITE)
return -EINVAL; return -EINVAL;
cmd_be = cpu_to_be32(cmd); rc = mutex_lock_interruptible(&bridge->lock);
rc = fsi_device_write(ctx->fsi, FSI2SPI_CMD, &cmd_be, sizeof(cmd_be));
if (rc) if (rc)
return rc; return rc;
cmd_be = cpu_to_be32(cmd);
rc = fsi_device_write(bridge->fsi, FSI2SPI_CMD, &cmd_be,
sizeof(cmd_be));
if (rc)
goto unlock;
rc = fsi_spi_check_status(ctx); rc = fsi_spi_check_status(ctx);
if (rc) if (rc)
return rc; goto unlock;
rc = fsi_device_read(ctx->fsi, FSI2SPI_DATA0, &data_be, rc = fsi_device_read(bridge->fsi, FSI2SPI_DATA0, &data_be,
sizeof(data_be)); sizeof(data_be));
if (rc) if (rc)
return rc; goto unlock;
*value |= (u64)be32_to_cpu(data_be) << 32; *value |= (u64)be32_to_cpu(data_be) << 32;
rc = fsi_device_read(ctx->fsi, FSI2SPI_DATA1, &data_be, rc = fsi_device_read(bridge->fsi, FSI2SPI_DATA1, &data_be,
sizeof(data_be)); sizeof(data_be));
if (rc) if (rc)
return rc; goto unlock;
*value |= (u64)be32_to_cpu(data_be); *value |= (u64)be32_to_cpu(data_be);
dev_dbg(ctx->dev, "Read %02x[%016llx].\n", offset, *value); dev_dbg(ctx->dev, "Read %02x[%016llx].\n", offset, *value);
return 0; unlock:
mutex_unlock(&bridge->lock);
return rc;
} }
static int fsi_spi_write_reg(struct fsi_spi *ctx, u32 offset, u64 value) static int fsi_spi_write_reg(struct fsi_spi *ctx, u32 offset, u64 value)
{ {
int rc; int rc = 0;
__be32 cmd_be; __be32 cmd_be;
__be32 data_be; __be32 data_be;
u32 cmd = offset + ctx->base; u32 cmd = offset + ctx->base;
struct fsi2spi *bridge = ctx->bridge;
if (cmd & FSI2SPI_CMD_WRITE) if (cmd & FSI2SPI_CMD_WRITE)
return -EINVAL; return -EINVAL;
rc = mutex_lock_interruptible(&bridge->lock);
if (rc)
return rc;
dev_dbg(ctx->dev, "Write %02x[%016llx].\n", offset, value); dev_dbg(ctx->dev, "Write %02x[%016llx].\n", offset, value);
data_be = cpu_to_be32(upper_32_bits(value)); data_be = cpu_to_be32(upper_32_bits(value));
rc = fsi_device_write(ctx->fsi, FSI2SPI_DATA0, &data_be, rc = fsi_device_write(bridge->fsi, FSI2SPI_DATA0, &data_be,
sizeof(data_be)); sizeof(data_be));
if (rc) if (rc)
return rc; goto unlock;
data_be = cpu_to_be32(lower_32_bits(value)); data_be = cpu_to_be32(lower_32_bits(value));
rc = fsi_device_write(ctx->fsi, FSI2SPI_DATA1, &data_be, rc = fsi_device_write(bridge->fsi, FSI2SPI_DATA1, &data_be,
sizeof(data_be)); sizeof(data_be));
if (rc) if (rc)
return rc; goto unlock;
cmd_be = cpu_to_be32(cmd | FSI2SPI_CMD_WRITE); cmd_be = cpu_to_be32(cmd | FSI2SPI_CMD_WRITE);
rc = fsi_device_write(ctx->fsi, FSI2SPI_CMD, &cmd_be, sizeof(cmd_be)); rc = fsi_device_write(bridge->fsi, FSI2SPI_CMD, &cmd_be,
sizeof(cmd_be));
if (rc) if (rc)
return rc; goto unlock;
return fsi_spi_check_status(ctx); rc = fsi_spi_check_status(ctx);
unlock:
mutex_unlock(&bridge->lock);
return rc;
} }
static int fsi_spi_data_in(u64 in, u8 *rx, int len) static int fsi_spi_data_in(u64 in, u8 *rx, int len)
...@@ -234,6 +257,26 @@ static int fsi_spi_reset(struct fsi_spi *ctx) ...@@ -234,6 +257,26 @@ static int fsi_spi_reset(struct fsi_spi *ctx)
return fsi_spi_write_reg(ctx, SPI_FSI_STATUS, 0ULL); return fsi_spi_write_reg(ctx, SPI_FSI_STATUS, 0ULL);
} }
static int fsi_spi_status(struct fsi_spi *ctx, u64 *status, const char *dir)
{
int rc = fsi_spi_read_reg(ctx, SPI_FSI_STATUS, status);
if (rc)
return rc;
if (*status & SPI_FSI_STATUS_ANY_ERROR) {
dev_err(ctx->dev, "%s error: %016llx\n", dir, *status);
rc = fsi_spi_reset(ctx);
if (rc)
return rc;
return -EREMOTEIO;
}
return 0;
}
static void fsi_spi_sequence_add(struct fsi_spi_sequence *seq, u8 val) static void fsi_spi_sequence_add(struct fsi_spi_sequence *seq, u8 val)
{ {
/* /*
...@@ -273,18 +316,9 @@ static int fsi_spi_transfer_data(struct fsi_spi *ctx, ...@@ -273,18 +316,9 @@ static int fsi_spi_transfer_data(struct fsi_spi *ctx,
return rc; return rc;
do { do {
rc = fsi_spi_read_reg(ctx, SPI_FSI_STATUS, rc = fsi_spi_status(ctx, &status, "TX");
&status);
if (rc) if (rc)
return rc; return rc;
if (status & SPI_FSI_STATUS_ANY_ERROR) {
rc = fsi_spi_reset(ctx);
if (rc)
return rc;
return -EREMOTEIO;
}
} while (status & SPI_FSI_STATUS_TDR_FULL); } while (status & SPI_FSI_STATUS_TDR_FULL);
sent += nb; sent += nb;
...@@ -296,18 +330,9 @@ static int fsi_spi_transfer_data(struct fsi_spi *ctx, ...@@ -296,18 +330,9 @@ static int fsi_spi_transfer_data(struct fsi_spi *ctx,
while (transfer->len > recv) { while (transfer->len > recv) {
do { do {
rc = fsi_spi_read_reg(ctx, SPI_FSI_STATUS, rc = fsi_spi_status(ctx, &status, "RX");
&status);
if (rc) if (rc)
return rc; return rc;
if (status & SPI_FSI_STATUS_ANY_ERROR) {
rc = fsi_spi_reset(ctx);
if (rc)
return rc;
return -EREMOTEIO;
}
} while (!(status & SPI_FSI_STATUS_RDR_FULL)); } while (!(status & SPI_FSI_STATUS_RDR_FULL));
rc = fsi_spi_read_reg(ctx, SPI_FSI_DATA_RX, &in); rc = fsi_spi_read_reg(ctx, SPI_FSI_DATA_RX, &in);
...@@ -348,8 +373,12 @@ static int fsi_spi_transfer_init(struct fsi_spi *ctx) ...@@ -348,8 +373,12 @@ static int fsi_spi_transfer_init(struct fsi_spi *ctx)
if (status & (SPI_FSI_STATUS_ANY_ERROR | if (status & (SPI_FSI_STATUS_ANY_ERROR |
SPI_FSI_STATUS_TDR_FULL | SPI_FSI_STATUS_TDR_FULL |
SPI_FSI_STATUS_RDR_FULL)) { SPI_FSI_STATUS_RDR_FULL)) {
if (reset) if (reset) {
dev_err(ctx->dev,
"Initialization error: %08llx\n",
status);
return -EIO; return -EIO;
}
rc = fsi_spi_reset(ctx); rc = fsi_spi_reset(ctx);
if (rc) if (rc)
...@@ -388,7 +417,7 @@ static int fsi_spi_transfer_one_message(struct spi_controller *ctlr, ...@@ -388,7 +417,7 @@ static int fsi_spi_transfer_one_message(struct spi_controller *ctlr,
struct spi_transfer *transfer; struct spi_transfer *transfer;
struct fsi_spi *ctx = spi_controller_get_devdata(ctlr); struct fsi_spi *ctx = spi_controller_get_devdata(ctlr);
rc = fsi_spi_check_mux(ctx->fsi, ctx->dev); rc = fsi_spi_check_mux(ctx->bridge->fsi, ctx->dev);
if (rc) if (rc)
goto error; goto error;
...@@ -478,12 +507,20 @@ static int fsi_spi_probe(struct device *dev) ...@@ -478,12 +507,20 @@ static int fsi_spi_probe(struct device *dev)
int rc; int rc;
struct device_node *np; struct device_node *np;
int num_controllers_registered = 0; int num_controllers_registered = 0;
struct fsi2spi *bridge;
struct fsi_device *fsi = to_fsi_dev(dev); struct fsi_device *fsi = to_fsi_dev(dev);
rc = fsi_spi_check_mux(fsi, dev); rc = fsi_spi_check_mux(fsi, dev);
if (rc) if (rc)
return -ENODEV; return -ENODEV;
bridge = devm_kzalloc(dev, sizeof(*bridge), GFP_KERNEL);
if (!bridge)
return -ENOMEM;
bridge->fsi = fsi;
mutex_init(&bridge->lock);
for_each_available_child_of_node(dev->of_node, np) { for_each_available_child_of_node(dev->of_node, np) {
u32 base; u32 base;
struct fsi_spi *ctx; struct fsi_spi *ctx;
...@@ -506,7 +543,7 @@ static int fsi_spi_probe(struct device *dev) ...@@ -506,7 +543,7 @@ static int fsi_spi_probe(struct device *dev)
ctx = spi_controller_get_devdata(ctlr); ctx = spi_controller_get_devdata(ctlr);
ctx->dev = &ctlr->dev; ctx->dev = &ctlr->dev;
ctx->fsi = fsi; ctx->bridge = bridge;
ctx->base = base + SPI_FSI_BASE; ctx->base = base + SPI_FSI_BASE;
rc = devm_spi_register_controller(dev, ctlr); rc = devm_spi_register_controller(dev, ctlr);
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
// Copyright (c) 2017-2018, The Linux foundation. All rights reserved. // Copyright (c) 2017-2018, The Linux foundation. All rights reserved.
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/dma/qcom-gpi-dma.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/log2.h> #include <linux/log2.h>
...@@ -63,6 +66,15 @@ ...@@ -63,6 +66,15 @@
#define TIMESTAMP_AFTER BIT(3) #define TIMESTAMP_AFTER BIT(3)
#define POST_CMD_DELAY BIT(4) #define POST_CMD_DELAY BIT(4)
#define GSI_LOOPBACK_EN BIT(0)
#define GSI_CS_TOGGLE BIT(3)
#define GSI_CPHA BIT(4)
#define GSI_CPOL BIT(5)
#define MAX_TX_SG 3
#define NUM_SPI_XFER 8
#define SPI_XFER_TIMEOUT_MS 250
struct spi_geni_master { struct spi_geni_master {
struct geni_se se; struct geni_se se;
struct device *dev; struct device *dev;
...@@ -84,6 +96,9 @@ struct spi_geni_master { ...@@ -84,6 +96,9 @@ struct spi_geni_master {
int irq; int irq;
bool cs_flag; bool cs_flag;
bool abort_failed; bool abort_failed;
struct dma_chan *tx;
struct dma_chan *rx;
int cur_xfer_mode;
}; };
static int get_spi_clk_cfg(unsigned int speed_hz, static int get_spi_clk_cfg(unsigned int speed_hz,
...@@ -330,34 +345,197 @@ static int setup_fifo_params(struct spi_device *spi_slv, ...@@ -330,34 +345,197 @@ static int setup_fifo_params(struct spi_device *spi_slv,
return geni_spi_set_clock_and_bw(mas, spi_slv->max_speed_hz); return geni_spi_set_clock_and_bw(mas, spi_slv->max_speed_hz);
} }
static void
spi_gsi_callback_result(void *cb, const struct dmaengine_result *result)
{
struct spi_master *spi = cb;
if (result->result != DMA_TRANS_NOERROR) {
dev_err(&spi->dev, "DMA txn failed: %d\n", result->result);
return;
}
if (!result->residue) {
dev_dbg(&spi->dev, "DMA txn completed\n");
spi_finalize_current_transfer(spi);
} else {
dev_err(&spi->dev, "DMA xfer has pending: %d\n", result->residue);
}
}
static int setup_gsi_xfer(struct spi_transfer *xfer, struct spi_geni_master *mas,
struct spi_device *spi_slv, struct spi_master *spi)
{
unsigned long flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK;
struct dma_slave_config config = {};
struct gpi_spi_config peripheral = {};
struct dma_async_tx_descriptor *tx_desc, *rx_desc;
int ret;
config.peripheral_config = &peripheral;
config.peripheral_size = sizeof(peripheral);
peripheral.set_config = true;
if (xfer->bits_per_word != mas->cur_bits_per_word ||
xfer->speed_hz != mas->cur_speed_hz) {
mas->cur_bits_per_word = xfer->bits_per_word;
mas->cur_speed_hz = xfer->speed_hz;
}
if (xfer->tx_buf && xfer->rx_buf) {
peripheral.cmd = SPI_DUPLEX;
} else if (xfer->tx_buf) {
peripheral.cmd = SPI_TX;
peripheral.rx_len = 0;
} else if (xfer->rx_buf) {
peripheral.cmd = SPI_RX;
if (!(mas->cur_bits_per_word % MIN_WORD_LEN)) {
peripheral.rx_len = ((xfer->len << 3) / mas->cur_bits_per_word);
} else {
int bytes_per_word = (mas->cur_bits_per_word / BITS_PER_BYTE) + 1;
peripheral.rx_len = (xfer->len / bytes_per_word);
}
}
peripheral.loopback_en = !!(spi_slv->mode & SPI_LOOP);
peripheral.clock_pol_high = !!(spi_slv->mode & SPI_CPOL);
peripheral.data_pol_high = !!(spi_slv->mode & SPI_CPHA);
peripheral.cs = spi_slv->chip_select;
peripheral.pack_en = true;
peripheral.word_len = xfer->bits_per_word - MIN_WORD_LEN;
ret = get_spi_clk_cfg(mas->cur_speed_hz, mas,
&peripheral.clk_src, &peripheral.clk_div);
if (ret) {
dev_err(mas->dev, "Err in get_spi_clk_cfg() :%d\n", ret);
return ret;
}
if (!xfer->cs_change) {
if (!list_is_last(&xfer->transfer_list, &spi->cur_msg->transfers))
peripheral.fragmentation = FRAGMENTATION;
}
if (peripheral.cmd & SPI_RX) {
dmaengine_slave_config(mas->rx, &config);
rx_desc = dmaengine_prep_slave_sg(mas->rx, xfer->rx_sg.sgl, xfer->rx_sg.nents,
DMA_DEV_TO_MEM, flags);
if (!rx_desc) {
dev_err(mas->dev, "Err setting up rx desc\n");
return -EIO;
}
}
/*
* Prepare the TX always, even for RX or tx_buf being null, we would
* need TX to be prepared per GSI spec
*/
dmaengine_slave_config(mas->tx, &config);
tx_desc = dmaengine_prep_slave_sg(mas->tx, xfer->tx_sg.sgl, xfer->tx_sg.nents,
DMA_MEM_TO_DEV, flags);
if (!tx_desc) {
dev_err(mas->dev, "Err setting up tx desc\n");
return -EIO;
}
tx_desc->callback_result = spi_gsi_callback_result;
tx_desc->callback_param = spi;
if (peripheral.cmd & SPI_RX)
dmaengine_submit(rx_desc);
dmaengine_submit(tx_desc);
if (peripheral.cmd & SPI_RX)
dma_async_issue_pending(mas->rx);
dma_async_issue_pending(mas->tx);
return 1;
}
static bool geni_can_dma(struct spi_controller *ctlr,
struct spi_device *slv, struct spi_transfer *xfer)
{
struct spi_geni_master *mas = spi_master_get_devdata(slv->master);
/* check if dma is supported */
return mas->cur_xfer_mode != GENI_SE_FIFO;
}
static int spi_geni_prepare_message(struct spi_master *spi, static int spi_geni_prepare_message(struct spi_master *spi,
struct spi_message *spi_msg) struct spi_message *spi_msg)
{ {
int ret;
struct spi_geni_master *mas = spi_master_get_devdata(spi); struct spi_geni_master *mas = spi_master_get_devdata(spi);
int ret;
if (spi_geni_is_abort_still_pending(mas)) switch (mas->cur_xfer_mode) {
return -EBUSY; case GENI_SE_FIFO:
if (spi_geni_is_abort_still_pending(mas))
return -EBUSY;
ret = setup_fifo_params(spi_msg->spi, spi);
if (ret)
dev_err(mas->dev, "Couldn't select mode %d\n", ret);
return ret;
ret = setup_fifo_params(spi_msg->spi, spi); case GENI_GPI_DMA:
if (ret) /* nothing to do for GPI DMA */
dev_err(mas->dev, "Couldn't select mode %d\n", ret); return 0;
}
dev_err(mas->dev, "Mode not supported %d", mas->cur_xfer_mode);
return -EINVAL;
}
static int spi_geni_grab_gpi_chan(struct spi_geni_master *mas)
{
int ret;
mas->tx = dma_request_chan(mas->dev, "tx");
ret = dev_err_probe(mas->dev, IS_ERR(mas->tx), "Failed to get tx DMA ch\n");
if (ret < 0)
goto err_tx;
mas->rx = dma_request_chan(mas->dev, "rx");
ret = dev_err_probe(mas->dev, IS_ERR(mas->rx), "Failed to get rx DMA ch\n");
if (ret < 0)
goto err_rx;
return 0;
err_rx:
dma_release_channel(mas->tx);
mas->tx = NULL;
err_tx:
mas->rx = NULL;
return ret; return ret;
} }
static void spi_geni_release_dma_chan(struct spi_geni_master *mas)
{
if (mas->rx) {
dma_release_channel(mas->rx);
mas->rx = NULL;
}
if (mas->tx) {
dma_release_channel(mas->tx);
mas->tx = NULL;
}
}
static int spi_geni_init(struct spi_geni_master *mas) static int spi_geni_init(struct spi_geni_master *mas)
{ {
struct geni_se *se = &mas->se; struct geni_se *se = &mas->se;
unsigned int proto, major, minor, ver; unsigned int proto, major, minor, ver;
u32 spi_tx_cfg; u32 spi_tx_cfg, fifo_disable;
int ret = -ENXIO;
pm_runtime_get_sync(mas->dev); pm_runtime_get_sync(mas->dev);
proto = geni_se_read_proto(se); proto = geni_se_read_proto(se);
if (proto != GENI_SE_SPI) { if (proto != GENI_SE_SPI) {
dev_err(mas->dev, "Invalid proto %d\n", proto); dev_err(mas->dev, "Invalid proto %d\n", proto);
pm_runtime_put(mas->dev); goto out_pm;
return -ENXIO;
} }
mas->tx_fifo_depth = geni_se_get_tx_fifo_depth(se); mas->tx_fifo_depth = geni_se_get_tx_fifo_depth(se);
...@@ -380,15 +558,38 @@ static int spi_geni_init(struct spi_geni_master *mas) ...@@ -380,15 +558,38 @@ static int spi_geni_init(struct spi_geni_master *mas)
else else
mas->oversampling = 1; mas->oversampling = 1;
geni_se_select_mode(se, GENI_SE_FIFO); fifo_disable = readl(se->base + GENI_IF_DISABLE_RO) & FIFO_IF_DISABLE;
switch (fifo_disable) {
case 1:
ret = spi_geni_grab_gpi_chan(mas);
if (!ret) { /* success case */
mas->cur_xfer_mode = GENI_GPI_DMA;
geni_se_select_mode(se, GENI_GPI_DMA);
dev_dbg(mas->dev, "Using GPI DMA mode for SPI\n");
break;
}
/*
* in case of failure to get dma channel, we can still do the
* FIFO mode, so fallthrough
*/
dev_warn(mas->dev, "FIFO mode disabled, but couldn't get DMA, fall back to FIFO mode\n");
fallthrough;
case 0:
mas->cur_xfer_mode = GENI_SE_FIFO;
geni_se_select_mode(se, GENI_SE_FIFO);
ret = 0;
break;
}
/* We always control CS manually */ /* We always control CS manually */
spi_tx_cfg = readl(se->base + SE_SPI_TRANS_CFG); spi_tx_cfg = readl(se->base + SE_SPI_TRANS_CFG);
spi_tx_cfg &= ~CS_TOGGLE; spi_tx_cfg &= ~CS_TOGGLE;
writel(spi_tx_cfg, se->base + SE_SPI_TRANS_CFG); writel(spi_tx_cfg, se->base + SE_SPI_TRANS_CFG);
out_pm:
pm_runtime_put(mas->dev); pm_runtime_put(mas->dev);
return 0; return ret;
} }
static unsigned int geni_byte_per_fifo_word(struct spi_geni_master *mas) static unsigned int geni_byte_per_fifo_word(struct spi_geni_master *mas)
...@@ -569,8 +770,11 @@ static int spi_geni_transfer_one(struct spi_master *spi, ...@@ -569,8 +770,11 @@ static int spi_geni_transfer_one(struct spi_master *spi,
if (!xfer->len) if (!xfer->len)
return 0; return 0;
setup_fifo_xfer(xfer, mas, slv->mode, spi); if (mas->cur_xfer_mode == GENI_SE_FIFO) {
return 1; setup_fifo_xfer(xfer, mas, slv->mode, spi);
return 1;
}
return setup_gsi_xfer(xfer, mas, slv, spi);
} }
static irqreturn_t geni_spi_isr(int irq, void *data) static irqreturn_t geni_spi_isr(int irq, void *data)
...@@ -665,6 +869,13 @@ static int spi_geni_probe(struct platform_device *pdev) ...@@ -665,6 +869,13 @@ static int spi_geni_probe(struct platform_device *pdev)
if (irq < 0) if (irq < 0)
return irq; return irq;
ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
if (ret) {
ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
if (ret)
return dev_err_probe(dev, ret, "could not set DMA mask\n");
}
base = devm_platform_ioremap_resource(pdev, 0); base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base)) if (IS_ERR(base))
return PTR_ERR(base); return PTR_ERR(base);
...@@ -704,9 +915,10 @@ static int spi_geni_probe(struct platform_device *pdev) ...@@ -704,9 +915,10 @@ static int spi_geni_probe(struct platform_device *pdev)
spi->max_speed_hz = 50000000; spi->max_speed_hz = 50000000;
spi->prepare_message = spi_geni_prepare_message; spi->prepare_message = spi_geni_prepare_message;
spi->transfer_one = spi_geni_transfer_one; spi->transfer_one = spi_geni_transfer_one;
spi->can_dma = geni_can_dma;
spi->dma_map_dev = dev->parent;
spi->auto_runtime_pm = true; spi->auto_runtime_pm = true;
spi->handle_err = handle_fifo_timeout; spi->handle_err = handle_fifo_timeout;
spi->set_cs = spi_geni_set_cs;
spi->use_gpio_descriptors = true; spi->use_gpio_descriptors = true;
init_completion(&mas->cs_done); init_completion(&mas->cs_done);
...@@ -732,9 +944,17 @@ static int spi_geni_probe(struct platform_device *pdev) ...@@ -732,9 +944,17 @@ static int spi_geni_probe(struct platform_device *pdev)
if (ret) if (ret)
goto spi_geni_probe_runtime_disable; goto spi_geni_probe_runtime_disable;
/*
* check the mode supported and set_cs for fifo mode only
* for dma (gsi) mode, the gsi will set cs based on params passed in
* TRE
*/
if (mas->cur_xfer_mode == GENI_SE_FIFO)
spi->set_cs = spi_geni_set_cs;
ret = request_irq(mas->irq, geni_spi_isr, 0, dev_name(dev), spi); ret = request_irq(mas->irq, geni_spi_isr, 0, dev_name(dev), spi);
if (ret) if (ret)
goto spi_geni_probe_runtime_disable; goto spi_geni_release_dma;
ret = spi_register_master(spi); ret = spi_register_master(spi);
if (ret) if (ret)
...@@ -743,6 +963,8 @@ static int spi_geni_probe(struct platform_device *pdev) ...@@ -743,6 +963,8 @@ static int spi_geni_probe(struct platform_device *pdev)
return 0; return 0;
spi_geni_probe_free_irq: spi_geni_probe_free_irq:
free_irq(mas->irq, spi); free_irq(mas->irq, spi);
spi_geni_release_dma:
spi_geni_release_dma_chan(mas);
spi_geni_probe_runtime_disable: spi_geni_probe_runtime_disable:
pm_runtime_disable(dev); pm_runtime_disable(dev);
return ret; return ret;
...@@ -756,6 +978,8 @@ static int spi_geni_remove(struct platform_device *pdev) ...@@ -756,6 +978,8 @@ static int spi_geni_remove(struct platform_device *pdev)
/* Unregister _before_ disabling pm_runtime() so we stop transfers */ /* Unregister _before_ disabling pm_runtime() so we stop transfers */
spi_unregister_master(spi); spi_unregister_master(spi);
spi_geni_release_dma_chan(mas);
free_irq(mas->irq, spi); free_irq(mas->irq, spi);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
return 0; return 0;
......
This diff is collapsed.
...@@ -160,7 +160,7 @@ static bool mtk_nor_match_read(const struct spi_mem_op *op) ...@@ -160,7 +160,7 @@ static bool mtk_nor_match_read(const struct spi_mem_op *op)
{ {
int dummy = 0; int dummy = 0;
if (op->dummy.buswidth) if (op->dummy.nbytes)
dummy = op->dummy.nbytes * BITS_PER_BYTE / op->dummy.buswidth; dummy = op->dummy.nbytes * BITS_PER_BYTE / op->dummy.buswidth;
if ((op->data.buswidth == 2) || (op->data.buswidth == 4)) { if ((op->data.buswidth == 2) || (op->data.buswidth == 4)) {
......
...@@ -769,6 +769,7 @@ static int orion_spi_probe(struct platform_device *pdev) ...@@ -769,6 +769,7 @@ static int orion_spi_probe(struct platform_device *pdev)
dir_acc->vaddr = devm_ioremap(&pdev->dev, r->start, PAGE_SIZE); dir_acc->vaddr = devm_ioremap(&pdev->dev, r->start, PAGE_SIZE);
if (!dir_acc->vaddr) { if (!dir_acc->vaddr) {
status = -ENOMEM; status = -ENOMEM;
of_node_put(np);
goto out_rel_axi_clk; goto out_rel_axi_clk;
} }
dir_acc->size = PAGE_SIZE; dir_acc->size = PAGE_SIZE;
......
...@@ -139,7 +139,9 @@ static int rpcif_spi_probe(struct platform_device *pdev) ...@@ -139,7 +139,9 @@ static int rpcif_spi_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
rpc = spi_controller_get_devdata(ctlr); rpc = spi_controller_get_devdata(ctlr);
rpcif_sw_init(rpc, parent); error = rpcif_sw_init(rpc, parent);
if (error)
return error;
platform_set_drvdata(pdev, ctlr); platform_set_drvdata(pdev, ctlr);
......
...@@ -1427,4 +1427,3 @@ module_platform_driver(rspi_driver); ...@@ -1427,4 +1427,3 @@ module_platform_driver(rspi_driver);
MODULE_DESCRIPTION("Renesas RSPI bus driver"); MODULE_DESCRIPTION("Renesas RSPI bus driver");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Yoshihiro Shimoda"); MODULE_AUTHOR("Yoshihiro Shimoda");
MODULE_ALIAS("platform:rspi");
...@@ -1426,4 +1426,3 @@ module_platform_driver(sh_msiof_spi_drv); ...@@ -1426,4 +1426,3 @@ module_platform_driver(sh_msiof_spi_drv);
MODULE_DESCRIPTION("SuperH MSIOF SPI Controller Interface Driver"); MODULE_DESCRIPTION("SuperH MSIOF SPI Controller Interface Driver");
MODULE_AUTHOR("Magnus Damm"); MODULE_AUTHOR("Magnus Damm");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:spi_sh_msiof");
...@@ -397,7 +397,7 @@ static int stm32_qspi_send(struct spi_mem *mem, const struct spi_mem_op *op) ...@@ -397,7 +397,7 @@ static int stm32_qspi_send(struct spi_mem *mem, const struct spi_mem_op *op)
ccr |= FIELD_PREP(CCR_ADSIZE_MASK, op->addr.nbytes - 1); ccr |= FIELD_PREP(CCR_ADSIZE_MASK, op->addr.nbytes - 1);
} }
if (op->dummy.buswidth && op->dummy.nbytes) if (op->dummy.nbytes)
ccr |= FIELD_PREP(CCR_DCYC_MASK, ccr |= FIELD_PREP(CCR_DCYC_MASK,
op->dummy.nbytes * 8 / op->dummy.buswidth); op->dummy.nbytes * 8 / op->dummy.buswidth);
......
...@@ -1124,7 +1124,7 @@ static int tegra_slink_probe(struct platform_device *pdev) ...@@ -1124,7 +1124,7 @@ static int tegra_slink_probe(struct platform_device *pdev)
exit_pm_put: exit_pm_put:
pm_runtime_put(&pdev->dev); pm_runtime_put(&pdev->dev);
exit_pm_disable: exit_pm_disable:
pm_runtime_disable(&pdev->dev); pm_runtime_force_suspend(&pdev->dev);
tegra_slink_deinit_dma_param(tspi, false); tegra_slink_deinit_dma_param(tspi, false);
exit_rx_dma_free: exit_rx_dma_free:
...@@ -1143,7 +1143,7 @@ static int tegra_slink_remove(struct platform_device *pdev) ...@@ -1143,7 +1143,7 @@ static int tegra_slink_remove(struct platform_device *pdev)
free_irq(tspi->irq, tspi); free_irq(tspi->irq, tspi);
pm_runtime_disable(&pdev->dev); pm_runtime_force_suspend(&pdev->dev);
if (tspi->tx_dma_chan) if (tspi->tx_dma_chan)
tegra_slink_deinit_dma_param(tspi, false); tegra_slink_deinit_dma_param(tspi, false);
......
...@@ -1318,7 +1318,7 @@ static int tegra_qspi_probe(struct platform_device *pdev) ...@@ -1318,7 +1318,7 @@ static int tegra_qspi_probe(struct platform_device *pdev)
exit_free_irq: exit_free_irq:
free_irq(qspi_irq, tqspi); free_irq(qspi_irq, tqspi);
exit_pm_disable: exit_pm_disable:
pm_runtime_disable(&pdev->dev); pm_runtime_force_suspend(&pdev->dev);
tegra_qspi_deinit_dma(tqspi); tegra_qspi_deinit_dma(tqspi);
return ret; return ret;
} }
...@@ -1330,7 +1330,7 @@ static int tegra_qspi_remove(struct platform_device *pdev) ...@@ -1330,7 +1330,7 @@ static int tegra_qspi_remove(struct platform_device *pdev)
spi_unregister_master(master); spi_unregister_master(master);
free_irq(tqspi->irq, tqspi); free_irq(tqspi->irq, tqspi);
pm_runtime_disable(&pdev->dev); pm_runtime_force_suspend(&pdev->dev);
tegra_qspi_deinit_dma(tqspi); tegra_qspi_deinit_dma(tqspi);
return 0; return 0;
......
...@@ -141,7 +141,7 @@ static ssize_t tle62x0_gpio_show(struct device *dev, ...@@ -141,7 +141,7 @@ static ssize_t tle62x0_gpio_show(struct device *dev,
value = (st->gpio_state >> gpio_num) & 1; value = (st->gpio_state >> gpio_num) & 1;
mutex_unlock(&st->lock); mutex_unlock(&st->lock);
return snprintf(buf, PAGE_SIZE, "%d", value); return sysfs_emit(buf, "%d", value);
} }
static ssize_t tle62x0_gpio_store(struct device *dev, static ssize_t tle62x0_gpio_store(struct device *dev,
......
This diff is collapsed.
...@@ -123,6 +123,7 @@ enum pm_ioctl_id { ...@@ -123,6 +123,7 @@ enum pm_ioctl_id {
IOCTL_READ_PGGS = 15, IOCTL_READ_PGGS = 15,
/* Set healthy bit value */ /* Set healthy bit value */
IOCTL_SET_BOOT_HEALTH_STATUS = 17, IOCTL_SET_BOOT_HEALTH_STATUS = 17,
IOCTL_OSPI_MUX_SELECT = 21,
}; };
enum pm_query_id { enum pm_query_id {
...@@ -351,6 +352,11 @@ enum zynqmp_pm_shutdown_subtype { ...@@ -351,6 +352,11 @@ enum zynqmp_pm_shutdown_subtype {
ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM = 2, ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM = 2,
}; };
enum ospi_mux_select_type {
PM_OSPI_MUX_SEL_DMA = 0,
PM_OSPI_MUX_SEL_LINEAR = 1,
};
/** /**
* struct zynqmp_pm_query_data - PM query data * struct zynqmp_pm_query_data - PM query data
* @qid: query ID * @qid: query ID
...@@ -387,6 +393,7 @@ int zynqmp_pm_set_pll_frac_data(u32 clk_id, u32 data); ...@@ -387,6 +393,7 @@ int zynqmp_pm_set_pll_frac_data(u32 clk_id, u32 data);
int zynqmp_pm_get_pll_frac_data(u32 clk_id, u32 *data); int zynqmp_pm_get_pll_frac_data(u32 clk_id, u32 *data);
int zynqmp_pm_set_sd_tapdelay(u32 node_id, u32 type, u32 value); int zynqmp_pm_set_sd_tapdelay(u32 node_id, u32 type, u32 value);
int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type); int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type);
int zynqmp_pm_ospi_mux_select(u32 dev_id, u32 select);
int zynqmp_pm_reset_assert(const enum zynqmp_pm_reset reset, int zynqmp_pm_reset_assert(const enum zynqmp_pm_reset reset,
const enum zynqmp_pm_reset_action assert_flag); const enum zynqmp_pm_reset_action assert_flag);
int zynqmp_pm_reset_get_status(const enum zynqmp_pm_reset reset, u32 *status); int zynqmp_pm_reset_get_status(const enum zynqmp_pm_reset reset, u32 *status);
...@@ -508,6 +515,11 @@ static inline int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type) ...@@ -508,6 +515,11 @@ static inline int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type)
return -ENODEV; return -ENODEV;
} }
static inline int zynqmp_pm_ospi_mux_select(u32 dev_id, u32 select)
{
return -ENODEV;
}
static inline int zynqmp_pm_reset_assert(const enum zynqmp_pm_reset reset, static inline int zynqmp_pm_reset_assert(const enum zynqmp_pm_reset reset,
const enum zynqmp_pm_reset_action assert_flag) const enum zynqmp_pm_reset_action assert_flag)
{ {
......
...@@ -78,10 +78,6 @@ struct spi_statistics { ...@@ -78,10 +78,6 @@ struct spi_statistics {
unsigned long transfers_split_maxsize; unsigned long transfers_split_maxsize;
}; };
void spi_statistics_add_transfer_stats(struct spi_statistics *stats,
struct spi_transfer *xfer,
struct spi_controller *ctlr);
#define SPI_STATISTICS_ADD_TO_FIELD(stats, field, count) \ #define SPI_STATISTICS_ADD_TO_FIELD(stats, field, count) \
do { \ do { \
unsigned long flags; \ unsigned long flags; \
...@@ -763,8 +759,6 @@ extern int devm_spi_register_controller(struct device *dev, ...@@ -763,8 +759,6 @@ extern int devm_spi_register_controller(struct device *dev,
struct spi_controller *ctlr); struct spi_controller *ctlr);
extern void spi_unregister_controller(struct spi_controller *ctlr); extern void spi_unregister_controller(struct spi_controller *ctlr);
extern struct spi_controller *spi_busnum_to_master(u16 busnum);
/* /*
* SPI resource management while processing a SPI message * SPI resource management while processing a SPI message
*/ */
...@@ -788,15 +782,6 @@ struct spi_res { ...@@ -788,15 +782,6 @@ struct spi_res {
unsigned long long data[]; /* guarantee ull alignment */ unsigned long long data[]; /* guarantee ull alignment */
}; };
extern void *spi_res_alloc(struct spi_device *spi,
spi_res_release_t release,
size_t size, gfp_t gfp);
extern void spi_res_add(struct spi_message *message, void *res);
extern void spi_res_free(void *res);
extern void spi_res_release(struct spi_controller *ctlr,
struct spi_message *message);
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* /*
...@@ -1114,8 +1099,6 @@ static inline void spi_message_free(struct spi_message *m) ...@@ -1114,8 +1099,6 @@ static inline void spi_message_free(struct spi_message *m)
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,
struct spi_message *message);
extern int spi_slave_abort(struct spi_device *spi); extern int spi_slave_abort(struct spi_device *spi);
static inline size_t static inline size_t
...@@ -1198,15 +1181,6 @@ struct spi_replaced_transfers { ...@@ -1198,15 +1181,6 @@ struct spi_replaced_transfers {
struct spi_transfer inserted_transfers[]; struct spi_transfer inserted_transfers[];
}; };
extern struct spi_replaced_transfers *spi_replace_transfers(
struct spi_message *msg,
struct spi_transfer *xfer_first,
size_t remove,
size_t insert,
spi_replaced_release_t release,
size_t extradatasize,
gfp_t gfp);
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* SPI transfer transformation methods */ /* SPI transfer transformation methods */
...@@ -1478,19 +1452,7 @@ spi_register_board_info(struct spi_board_info const *info, unsigned n) ...@@ -1478,19 +1452,7 @@ spi_register_board_info(struct spi_board_info const *info, unsigned n)
* use spi_new_device() to describe each device. You can also call * use spi_new_device() to describe each device. You can also call
* spi_unregister_device() to start making that device vanish, but * spi_unregister_device() to start making that device vanish, but
* normally that would be handled by spi_unregister_controller(). * normally that would be handled by spi_unregister_controller().
*
* You can also use spi_alloc_device() and spi_add_device() to use a two
* stage registration sequence for each spi_device. This gives the caller
* some more control over the spi_device structure before it is registered,
* but requires that caller to initialize fields that would otherwise
* be defined using the board info.
*/ */
extern struct spi_device *
spi_alloc_device(struct spi_controller *ctlr);
extern int
spi_add_device(struct spi_device *spi);
extern struct spi_device * extern struct spi_device *
spi_new_device(struct spi_controller *, struct spi_board_info *); spi_new_device(struct spi_controller *, struct spi_board_info *);
...@@ -1505,23 +1467,6 @@ spi_transfer_is_last(struct spi_controller *ctlr, struct spi_transfer *xfer) ...@@ -1505,23 +1467,6 @@ spi_transfer_is_last(struct spi_controller *ctlr, struct spi_transfer *xfer)
return list_is_last(&xfer->transfer_list, &ctlr->cur_msg->transfers); return list_is_last(&xfer->transfer_list, &ctlr->cur_msg->transfers);
} }
/* OF support code */
#if IS_ENABLED(CONFIG_OF)
/* must call put_device() when done with returned spi_device device */
extern struct spi_device *
of_find_spi_device_by_node(struct device_node *node);
#else
static inline struct spi_device *
of_find_spi_device_by_node(struct device_node *node)
{
return NULL;
}
#endif /* IS_ENABLED(CONFIG_OF) */
/* Compatibility layer */ /* Compatibility layer */
#define spi_master spi_controller #define spi_master spi_controller
......
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