Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
754a36a5
Commit
754a36a5
authored
5 years ago
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'spi-5.6' into spi-next
parents
7265e8fc
a5362b84
Changes
35
Hide whitespace changes
Inline
Side-by-side
Showing
35 changed files
with
1175 additions
and
608 deletions
+1175
-608
Documentation/devicetree/bindings/spi/nuvoton,npcm-pspi.txt
Documentation/devicetree/bindings/spi/nuvoton,npcm-pspi.txt
+2
-10
Documentation/devicetree/bindings/spi/spi-stm32.txt
Documentation/devicetree/bindings/spi/spi-stm32.txt
+0
-62
Documentation/devicetree/bindings/spi/spi_atmel.txt
Documentation/devicetree/bindings/spi/spi_atmel.txt
+1
-1
Documentation/devicetree/bindings/spi/st,stm32-spi.yaml
Documentation/devicetree/bindings/spi/st,stm32-spi.yaml
+105
-0
MAINTAINERS
MAINTAINERS
+6
-0
drivers/spi/Kconfig
drivers/spi/Kconfig
+9
-0
drivers/spi/Makefile
drivers/spi/Makefile
+1
-0
drivers/spi/spi-atmel.c
drivers/spi/spi-atmel.c
+11
-18
drivers/spi/spi-bcm-qspi.c
drivers/spi/spi-bcm-qspi.c
+1
-1
drivers/spi/spi-bcm2835.c
drivers/spi/spi-bcm2835.c
+33
-14
drivers/spi/spi-bitbang.c
drivers/spi/spi-bitbang.c
+19
-2
drivers/spi/spi-dw.c
drivers/spi/spi-dw.c
+2
-1
drivers/spi/spi-fsl-dspi.c
drivers/spi/spi-fsl-dspi.c
+6
-6
drivers/spi/spi-fsl-lpspi.c
drivers/spi/spi-fsl-lpspi.c
+18
-18
drivers/spi/spi-fsl-spi.c
drivers/spi/spi-fsl-spi.c
+8
-19
drivers/spi/spi-hisi-sfc-v3xx.c
drivers/spi/spi-hisi-sfc-v3xx.c
+284
-0
drivers/spi/spi-img-spfi.c
drivers/spi/spi-img-spfi.c
+16
-2
drivers/spi/spi-imx.c
drivers/spi/spi-imx.c
+2
-2
drivers/spi/spi-meson-spicc.c
drivers/spi/spi-meson-spicc.c
+2
-23
drivers/spi/spi-mxs.c
drivers/spi/spi-mxs.c
+3
-3
drivers/spi/spi-npcm-pspi.c
drivers/spi/spi-npcm-pspi.c
+18
-22
drivers/spi/spi-oc-tiny.c
drivers/spi/spi-oc-tiny.c
+1
-49
drivers/spi/spi-qcom-qspi.c
drivers/spi/spi-qcom-qspi.c
+8
-1
drivers/spi/spi-rspi.c
drivers/spi/spi-rspi.c
+14
-9
drivers/spi/spi-sh-msiof.c
drivers/spi/spi-sh-msiof.c
+212
-259
drivers/spi/spi-sirf.c
drivers/spi/spi-sirf.c
+6
-6
drivers/spi/spi-stm32-qspi.c
drivers/spi/spi-stm32-qspi.c
+24
-6
drivers/spi/spi-stm32.c
drivers/spi/spi-stm32.c
+25
-54
drivers/spi/spi-tegra114.c
drivers/spi/spi-tegra114.c
+2
-2
drivers/spi/spi-ti-qspi.c
drivers/spi/spi-ti-qspi.c
+82
-5
drivers/spi/spi-topcliff-pch.c
drivers/spi/spi-topcliff-pch.c
+2
-2
drivers/spi/spi-uniphier.c
drivers/spi/spi-uniphier.c
+220
-7
drivers/spi/spi.c
drivers/spi/spi.c
+24
-0
include/linux/spi/spi.h
include/linux/spi/spi.h
+8
-0
include/linux/spi/spi_oc_tiny.h
include/linux/spi/spi_oc_tiny.h
+0
-4
No files found.
Documentation/devicetree/bindings/spi/nuvoton,npcm-pspi.txt
View file @
754a36a5
...
@@ -12,6 +12,7 @@ Required properties:
...
@@ -12,6 +12,7 @@ Required properties:
- clock-names: Should be "clk_apb5".
- clock-names: Should be "clk_apb5".
- pinctrl-names : a pinctrl state named "default" must be defined.
- pinctrl-names : a pinctrl state named "default" must be defined.
- pinctrl-0 : phandle referencing pin configuration of the device.
- pinctrl-0 : phandle referencing pin configuration of the device.
- resets : phandle to the reset control for this device.
- cs-gpios: Specifies the gpio pins to be used for chipselects.
- cs-gpios: Specifies the gpio pins to be used for chipselects.
See: Documentation/devicetree/bindings/spi/spi-bus.txt
See: Documentation/devicetree/bindings/spi/spi-bus.txt
...
@@ -19,16 +20,6 @@ Optional properties:
...
@@ -19,16 +20,6 @@ Optional properties:
- clock-frequency : Input clock frequency to the PSPI block in Hz.
- clock-frequency : Input clock frequency to the PSPI block in Hz.
Default is 25000000 Hz.
Default is 25000000 Hz.
Aliases:
- All the SPI controller nodes should be represented in the aliases node using
the following format 'spi{n}' withe the correct numbered in "aliases" node.
Example:
aliases {
spi0 = &spi0;
};
spi0: spi@f0200000 {
spi0: spi@f0200000 {
compatible = "nuvoton,npcm750-pspi";
compatible = "nuvoton,npcm750-pspi";
reg = <0xf0200000 0x1000>;
reg = <0xf0200000 0x1000>;
...
@@ -39,5 +30,6 @@ spi0: spi@f0200000 {
...
@@ -39,5 +30,6 @@ spi0: spi@f0200000 {
interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk NPCM7XX_CLK_APB5>;
clocks = <&clk NPCM7XX_CLK_APB5>;
clock-names = "clk_apb5";
clock-names = "clk_apb5";
resets = <&rstc NPCM7XX_RESET_IPSRST2 NPCM7XX_RESET_PSPI1>
cs-gpios = <&gpio6 11 GPIO_ACTIVE_LOW>;
cs-gpios = <&gpio6 11 GPIO_ACTIVE_LOW>;
};
};
This diff is collapsed.
Click to expand it.
Documentation/devicetree/bindings/spi/spi-stm32.txt
deleted
100644 → 0
View file @
7265e8fc
STMicroelectronics STM32 SPI Controller
The STM32 SPI controller is used to communicate with external devices using
the Serial Peripheral Interface. It supports full-duplex, half-duplex and
simplex synchronous serial communication with external devices. It supports
from 4 to 32-bit data size. Although it can be configured as master or slave,
only master is supported by the driver.
Required properties:
- compatible: Should be one of:
"st,stm32h7-spi"
"st,stm32f4-spi"
- reg: Offset and length of the device's register set.
- interrupts: Must contain the interrupt id.
- clocks: Must contain an entry for spiclk (which feeds the internal clock
generator).
- #address-cells: Number of cells required to define a chip select address.
- #size-cells: Should be zero.
Optional properties:
- resets: Must contain the phandle to the reset controller.
- A pinctrl state named "default" may be defined to set pins in mode of
operation for SPI transfer.
- dmas: DMA specifiers for tx and rx dma. DMA fifo mode must be used. See the
STM32 DMA bindings, Documentation/devicetree/bindings/dma/stm32-dma.txt.
- dma-names: DMA request names should include "tx" and "rx" if present.
- cs-gpios: list of GPIO chip selects. See the SPI bus bindings,
Documentation/devicetree/bindings/spi/spi-bus.txt
Child nodes represent devices on the SPI bus
See ../spi/spi-bus.txt
Optional properties:
- st,spi-midi-ns: Only for STM32H7, (Master Inter-Data Idleness) minimum time
delay in nanoseconds inserted between two consecutive data
frames.
Example:
spi2: spi@40003800 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "st,stm32h7-spi";
reg = <0x40003800 0x400>;
interrupts = <36>;
clocks = <&rcc SPI2_CK>;
resets = <&rcc 1166>;
dmas = <&dmamux1 0 39 0x400 0x01>,
<&dmamux1 1 40 0x400 0x01>;
dma-names = "rx", "tx";
pinctrl-0 = <&spi2_pins_b>;
pinctrl-names = "default";
cs-gpios = <&gpioa 11 0>;
aardvark@0 {
compatible = "totalphase,aardvark";
reg = <0>;
spi-max-frequency = <4000000>;
st,spi-midi-ns = <4000>;
};
};
This diff is collapsed.
Click to expand it.
Documentation/devicetree/bindings/spi/spi_atmel.txt
View file @
754a36a5
Atmel SPI device
Atmel SPI device
Required properties:
Required properties:
- compatible : should be "atmel,at91rm9200-spi".
- compatible : should be "atmel,at91rm9200-spi"
or "microchip,sam9x60-spi"
.
- reg: Address and length of the register set for the device
- reg: Address and length of the register set for the device
- interrupts: Should contain spi interrupt
- interrupts: Should contain spi interrupt
- cs-gpios: chipselects (optional for SPI controller version >= 2 with the
- cs-gpios: chipselects (optional for SPI controller version >= 2 with the
...
...
This diff is collapsed.
Click to expand it.
Documentation/devicetree/bindings/spi/st,stm32-spi.yaml
0 → 100644
View file @
754a36a5
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML
1.2
---
$id
:
http://devicetree.org/schemas/spi/st,stm32-spi.yaml#
$schema
:
http://devicetree.org/meta-schemas/core.yaml#
title
:
STMicroelectronics STM32 SPI Controller bindings
description
:
|
The STM32 SPI controller is used to communicate with external devices using
the Serial Peripheral Interface. It supports full-duplex, half-duplex and
simplex synchronous serial communication with external devices. It supports
from 4 to 32-bit data size.
maintainers
:
-
Erwan Leray <erwan.leray@st.com>
-
Fabrice Gasnier <fabrice.gasnier@st.com>
allOf
:
-
$ref
:
"
spi-controller.yaml#"
-
if
:
properties
:
compatible
:
contains
:
const
:
st,stm32f4-spi
then
:
properties
:
st,spi-midi-ns
:
false
properties
:
compatible
:
enum
:
-
st,stm32f4-spi
-
st,stm32h7-spi
reg
:
maxItems
:
1
clocks
:
maxItems
:
1
interrupts
:
maxItems
:
1
resets
:
maxItems
:
1
dmas
:
description
:
|
DMA specifiers for tx and rx dma. DMA fifo mode must be used. See
the STM32 DMA bindings Documentation/devicetree/bindings/dma/stm32-dma.txt.
items
:
-
description
:
rx DMA channel
-
description
:
tx DMA channel
dma-names
:
items
:
-
const
:
rx
-
const
:
tx
patternProperties
:
"
^[a-zA-Z][a-zA-Z0-9,+
\\
-._]{0,63}@[0-9a-f]+$"
:
type
:
object
# SPI slave nodes must be children of the SPI master node and can
# contain the following properties.
properties
:
st,spi-midi-ns
:
description
:
|
Only for STM32H7, (Master Inter-Data Idleness) minimum time
delay in nanoseconds inserted between two consecutive data frames.
required
:
-
compatible
-
reg
-
clocks
-
interrupts
examples
:
-
|
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/stm32mp1-clks.h>
#include <dt-bindings/reset/stm32mp1-resets.h>
spi@4000b000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "st,stm32h7-spi";
reg = <0x4000b000 0x400>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc SPI2_K>;
resets = <&rcc SPI2_R>;
dmas = <&dmamux1 0 39 0x400 0x05>,
<&dmamux1 1 40 0x400 0x05>;
dma-names = "rx", "tx";
cs-gpios = <&gpioa 11 0>;
aardvark@0 {
compatible = "totalphase,aardvark";
reg = <0>;
spi-max-frequency = <4000000>;
st,spi-midi-ns = <4000>;
};
};
...
This diff is collapsed.
Click to expand it.
MAINTAINERS
View file @
754a36a5
...
@@ -7498,6 +7498,12 @@ S: Supported
...
@@ -7498,6 +7498,12 @@ S: Supported
F: drivers/scsi/hisi_sas/
F: drivers/scsi/hisi_sas/
F: Documentation/devicetree/bindings/scsi/hisilicon-sas.txt
F: Documentation/devicetree/bindings/scsi/hisilicon-sas.txt
HISILICON V3XX SPI NOR FLASH Controller Driver
M: John Garry <john.garry@huawei.com>
W: http://www.hisilicon.com
S: Maintained
F: drivers/spi/spi-hisi-sfc-v3xx.c
HISILICON QM AND ZIP Controller DRIVER
HISILICON QM AND ZIP Controller DRIVER
M: Zhou Wang <wangzhou1@hisilicon.com>
M: Zhou Wang <wangzhou1@hisilicon.com>
L: linux-crypto@vger.kernel.org
L: linux-crypto@vger.kernel.org
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/Kconfig
View file @
754a36a5
...
@@ -281,6 +281,15 @@ config SPI_FSL_QUADSPI
...
@@ -281,6 +281,15 @@ config SPI_FSL_QUADSPI
This controller does not support generic SPI messages. It only
This controller does not support generic SPI messages. It only
supports the high-level SPI memory interface.
supports the high-level SPI memory interface.
config SPI_HISI_SFC_V3XX
tristate "HiSilicon SPI-NOR Flash Controller for Hi16XX chipsets"
depends on (ARM64 && ACPI) || COMPILE_TEST
depends on HAS_IOMEM
select CONFIG_MTD_SPI_NOR
help
This enables support for HiSilicon v3xx SPI-NOR flash controller
found in hi16xx chipsets.
config SPI_NXP_FLEXSPI
config SPI_NXP_FLEXSPI
tristate "NXP Flex SPI controller"
tristate "NXP Flex SPI controller"
depends on ARCH_LAYERSCAPE || HAS_IOMEM
depends on ARCH_LAYERSCAPE || HAS_IOMEM
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/Makefile
View file @
754a36a5
...
@@ -48,6 +48,7 @@ obj-$(CONFIG_SPI_FSL_LPSPI) += spi-fsl-lpspi.o
...
@@ -48,6 +48,7 @@ obj-$(CONFIG_SPI_FSL_LPSPI) += spi-fsl-lpspi.o
obj-$(CONFIG_SPI_FSL_QUADSPI)
+=
spi-fsl-qspi.o
obj-$(CONFIG_SPI_FSL_QUADSPI)
+=
spi-fsl-qspi.o
obj-$(CONFIG_SPI_FSL_SPI)
+=
spi-fsl-spi.o
obj-$(CONFIG_SPI_FSL_SPI)
+=
spi-fsl-spi.o
obj-$(CONFIG_SPI_GPIO)
+=
spi-gpio.o
obj-$(CONFIG_SPI_GPIO)
+=
spi-gpio.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_LANTIQ_SSC)
+=
spi-lantiq-ssc.o
obj-$(CONFIG_SPI_LANTIQ_SSC)
+=
spi-lantiq-ssc.o
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-atmel.c
View file @
754a36a5
...
@@ -514,26 +514,19 @@ static int atmel_spi_configure_dma(struct spi_master *master,
...
@@ -514,26 +514,19 @@ static int atmel_spi_configure_dma(struct spi_master *master,
master
->
dma_tx
=
dma_request_chan
(
dev
,
"tx"
);
master
->
dma_tx
=
dma_request_chan
(
dev
,
"tx"
);
if
(
IS_ERR
(
master
->
dma_tx
))
{
if
(
IS_ERR
(
master
->
dma_tx
))
{
err
=
PTR_ERR
(
master
->
dma_tx
);
err
=
PTR_ERR
(
master
->
dma_tx
);
if
(
err
==
-
EPROBE_DEFER
)
{
if
(
err
!=
-
EPROBE_DEFER
)
dev_warn
(
dev
,
"no DMA channel available at the moment
\n
"
);
dev_err
(
dev
,
"No TX DMA channel, DMA is disabled
\n
"
);
goto
error_clear
;
}
dev_err
(
dev
,
"DMA TX channel not available, SPI unable to use DMA
\n
"
);
err
=
-
EBUSY
;
goto
error_clear
;
goto
error_clear
;
}
}
/*
master
->
dma_rx
=
dma_request_chan
(
dev
,
"rx"
);
* No reason to check EPROBE_DEFER here since we have already requested
if
(
IS_ERR
(
master
->
dma_rx
))
{
* tx channel. If it fails here, it's for another reason.
err
=
PTR_ERR
(
master
->
dma_rx
);
*/
/*
master
->
dma_rx
=
dma_request_slave_channel
(
dev
,
"rx"
);
* No reason to check EPROBE_DEFER here since we have already
* requested tx channel.
if
(
!
master
->
dma_rx
)
{
*/
dev_err
(
dev
,
dev_err
(
dev
,
"No RX DMA channel, DMA is disabled
\n
"
);
"DMA RX channel not available, SPI unable to use DMA
\n
"
);
err
=
-
EBUSY
;
goto
error
;
goto
error
;
}
}
...
@@ -548,7 +541,7 @@ static int atmel_spi_configure_dma(struct spi_master *master,
...
@@ -548,7 +541,7 @@ static int atmel_spi_configure_dma(struct spi_master *master,
return
0
;
return
0
;
error:
error:
if
(
master
->
dma_rx
)
if
(
!
IS_ERR
(
master
->
dma_rx
)
)
dma_release_channel
(
master
->
dma_rx
);
dma_release_channel
(
master
->
dma_rx
);
if
(
!
IS_ERR
(
master
->
dma_tx
))
if
(
!
IS_ERR
(
master
->
dma_tx
))
dma_release_channel
(
master
->
dma_tx
);
dma_release_channel
(
master
->
dma_tx
);
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-bcm-qspi.c
View file @
754a36a5
...
@@ -1293,7 +1293,7 @@ int bcm_qspi_probe(struct platform_device *pdev,
...
@@ -1293,7 +1293,7 @@ int bcm_qspi_probe(struct platform_device *pdev,
name
=
qspi_irq_tab
[
val
].
irq_name
;
name
=
qspi_irq_tab
[
val
].
irq_name
;
if
(
qspi_irq_tab
[
val
].
irq_source
==
SINGLE_L2
)
{
if
(
qspi_irq_tab
[
val
].
irq_source
==
SINGLE_L2
)
{
/* get the l2 interrupts */
/* get the l2 interrupts */
irq
=
platform_get_irq_byname
(
pdev
,
name
);
irq
=
platform_get_irq_byname
_optional
(
pdev
,
name
);
}
else
if
(
!
num_ints
&&
soc_intc
)
{
}
else
if
(
!
num_ints
&&
soc_intc
)
{
/* all mspi, bspi intrs muxed to one L1 intr */
/* all mspi, bspi intrs muxed to one L1 intr */
irq
=
platform_get_irq
(
pdev
,
0
);
irq
=
platform_get_irq
(
pdev
,
0
);
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-bcm2835.c
View file @
754a36a5
...
@@ -68,7 +68,7 @@
...
@@ -68,7 +68,7 @@
#define BCM2835_SPI_FIFO_SIZE 64
#define BCM2835_SPI_FIFO_SIZE 64
#define BCM2835_SPI_FIFO_SIZE_3_4 48
#define BCM2835_SPI_FIFO_SIZE_3_4 48
#define BCM2835_SPI_DMA_MIN_LENGTH 96
#define BCM2835_SPI_DMA_MIN_LENGTH 96
#define BCM2835_SPI_NUM_CS
3
/* raise as necessary */
#define BCM2835_SPI_NUM_CS
4
/* raise as necessary */
#define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \
#define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \
| SPI_NO_CS | SPI_3WIRE)
| SPI_NO_CS | SPI_3WIRE)
...
@@ -888,8 +888,8 @@ static void bcm2835_dma_release(struct spi_controller *ctlr,
...
@@ -888,8 +888,8 @@ static void bcm2835_dma_release(struct spi_controller *ctlr,
}
}
}
}
static
void
bcm2835_dma_init
(
struct
spi_controller
*
ctlr
,
struct
device
*
dev
,
static
int
bcm2835_dma_init
(
struct
spi_controller
*
ctlr
,
struct
device
*
dev
,
struct
bcm2835_spi
*
bs
)
struct
bcm2835_spi
*
bs
)
{
{
struct
dma_slave_config
slave_config
;
struct
dma_slave_config
slave_config
;
const
__be32
*
addr
;
const
__be32
*
addr
;
...
@@ -900,19 +900,24 @@ static void bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev,
...
@@ -900,19 +900,24 @@ static void bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev,
addr
=
of_get_address
(
ctlr
->
dev
.
of_node
,
0
,
NULL
,
NULL
);
addr
=
of_get_address
(
ctlr
->
dev
.
of_node
,
0
,
NULL
,
NULL
);
if
(
!
addr
)
{
if
(
!
addr
)
{
dev_err
(
dev
,
"could not get DMA-register address - not using dma mode
\n
"
);
dev_err
(
dev
,
"could not get DMA-register address - not using dma mode
\n
"
);
goto
err
;
/* Fall back to interrupt mode */
return
0
;
}
}
dma_reg_base
=
be32_to_cpup
(
addr
);
dma_reg_base
=
be32_to_cpup
(
addr
);
/* get tx/rx dma */
/* get tx/rx dma */
ctlr
->
dma_tx
=
dma_request_
slave_channel
(
dev
,
"tx"
);
ctlr
->
dma_tx
=
dma_request_
chan
(
dev
,
"tx"
);
if
(
!
ctlr
->
dma_tx
)
{
if
(
IS_ERR
(
ctlr
->
dma_tx
)
)
{
dev_err
(
dev
,
"no tx-dma configuration found - not using dma mode
\n
"
);
dev_err
(
dev
,
"no tx-dma configuration found - not using dma mode
\n
"
);
ret
=
PTR_ERR
(
ctlr
->
dma_tx
);
ctlr
->
dma_tx
=
NULL
;
goto
err
;
goto
err
;
}
}
ctlr
->
dma_rx
=
dma_request_
slave_channel
(
dev
,
"rx"
);
ctlr
->
dma_rx
=
dma_request_
chan
(
dev
,
"rx"
);
if
(
!
ctlr
->
dma_rx
)
{
if
(
IS_ERR
(
ctlr
->
dma_rx
)
)
{
dev_err
(
dev
,
"no rx-dma configuration found - not using dma mode
\n
"
);
dev_err
(
dev
,
"no rx-dma configuration found - not using dma mode
\n
"
);
ret
=
PTR_ERR
(
ctlr
->
dma_rx
);
ctlr
->
dma_rx
=
NULL
;
goto
err_release
;
goto
err_release
;
}
}
...
@@ -997,7 +1002,7 @@ static void bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev,
...
@@ -997,7 +1002,7 @@ static void bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev,
/* all went well, so set can_dma */
/* all went well, so set can_dma */
ctlr
->
can_dma
=
bcm2835_spi_can_dma
;
ctlr
->
can_dma
=
bcm2835_spi_can_dma
;
return
;
return
0
;
err_config:
err_config:
dev_err
(
dev
,
"issue configuring dma: %d - not using DMA mode
\n
"
,
dev_err
(
dev
,
"issue configuring dma: %d - not using DMA mode
\n
"
,
...
@@ -1005,7 +1010,14 @@ static void bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev,
...
@@ -1005,7 +1010,14 @@ static void bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev,
err_release:
err_release:
bcm2835_dma_release
(
ctlr
,
bs
);
bcm2835_dma_release
(
ctlr
,
bs
);
err:
err:
return
;
/*
* Only report error for deferred probing, otherwise fall back to
* interrupt mode
*/
if
(
ret
!=
-
EPROBE_DEFER
)
ret
=
0
;
return
ret
;
}
}
static
int
bcm2835_spi_transfer_one_poll
(
struct
spi_controller
*
ctlr
,
static
int
bcm2835_spi_transfer_one_poll
(
struct
spi_controller
*
ctlr
,
...
@@ -1305,7 +1317,10 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
...
@@ -1305,7 +1317,10 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
bs
->
clk
=
devm_clk_get
(
&
pdev
->
dev
,
NULL
);
bs
->
clk
=
devm_clk_get
(
&
pdev
->
dev
,
NULL
);
if
(
IS_ERR
(
bs
->
clk
))
{
if
(
IS_ERR
(
bs
->
clk
))
{
err
=
PTR_ERR
(
bs
->
clk
);
err
=
PTR_ERR
(
bs
->
clk
);
dev_err
(
&
pdev
->
dev
,
"could not get clk: %d
\n
"
,
err
);
if
(
err
==
-
EPROBE_DEFER
)
dev_dbg
(
&
pdev
->
dev
,
"could not get clk: %d
\n
"
,
err
);
else
dev_err
(
&
pdev
->
dev
,
"could not get clk: %d
\n
"
,
err
);
goto
out_controller_put
;
goto
out_controller_put
;
}
}
...
@@ -1317,7 +1332,9 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
...
@@ -1317,7 +1332,9 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
clk_prepare_enable
(
bs
->
clk
);
clk_prepare_enable
(
bs
->
clk
);
bcm2835_dma_init
(
ctlr
,
&
pdev
->
dev
,
bs
);
err
=
bcm2835_dma_init
(
ctlr
,
&
pdev
->
dev
,
bs
);
if
(
err
)
goto
out_clk_disable
;
/* initialise the hardware with the default polarities */
/* initialise the hardware with the default polarities */
bcm2835_wr
(
bs
,
BCM2835_SPI_CS
,
bcm2835_wr
(
bs
,
BCM2835_SPI_CS
,
...
@@ -1327,20 +1344,22 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
...
@@ -1327,20 +1344,22 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
dev_name
(
&
pdev
->
dev
),
ctlr
);
dev_name
(
&
pdev
->
dev
),
ctlr
);
if
(
err
)
{
if
(
err
)
{
dev_err
(
&
pdev
->
dev
,
"could not request IRQ: %d
\n
"
,
err
);
dev_err
(
&
pdev
->
dev
,
"could not request IRQ: %d
\n
"
,
err
);
goto
out_
clk_disabl
e
;
goto
out_
dma_releas
e
;
}
}
err
=
devm_spi_register_controller
(
&
pdev
->
dev
,
ctlr
);
err
=
devm_spi_register_controller
(
&
pdev
->
dev
,
ctlr
);
if
(
err
)
{
if
(
err
)
{
dev_err
(
&
pdev
->
dev
,
"could not register SPI controller: %d
\n
"
,
dev_err
(
&
pdev
->
dev
,
"could not register SPI controller: %d
\n
"
,
err
);
err
);
goto
out_
clk_disabl
e
;
goto
out_
dma_releas
e
;
}
}
bcm2835_debugfs_create
(
bs
,
dev_name
(
&
pdev
->
dev
));
bcm2835_debugfs_create
(
bs
,
dev_name
(
&
pdev
->
dev
));
return
0
;
return
0
;
out_dma_release:
bcm2835_dma_release
(
ctlr
,
bs
);
out_clk_disable:
out_clk_disable:
clk_disable_unprepare
(
bs
->
clk
);
clk_disable_unprepare
(
bs
->
clk
);
out_controller_put:
out_controller_put:
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-bitbang.c
View file @
754a36a5
...
@@ -329,8 +329,20 @@ static void spi_bitbang_set_cs(struct spi_device *spi, bool enable)
...
@@ -329,8 +329,20 @@ static void spi_bitbang_set_cs(struct spi_device *spi, bool enable)
int
spi_bitbang_init
(
struct
spi_bitbang
*
bitbang
)
int
spi_bitbang_init
(
struct
spi_bitbang
*
bitbang
)
{
{
struct
spi_master
*
master
=
bitbang
->
master
;
struct
spi_master
*
master
=
bitbang
->
master
;
bool
custom_cs
;
if
(
!
master
||
!
bitbang
->
chipselect
)
if
(
!
master
)
return
-
EINVAL
;
/*
* We only need the chipselect callback if we are actually using it.
* If we just use GPIO descriptors, it is surplus. If the
* SPI_MASTER_GPIO_SS flag is set, we always need to call the
* driver-specific chipselect routine.
*/
custom_cs
=
(
!
master
->
use_gpio_descriptors
||
(
master
->
flags
&
SPI_MASTER_GPIO_SS
));
if
(
custom_cs
&&
!
bitbang
->
chipselect
)
return
-
EINVAL
;
return
-
EINVAL
;
mutex_init
(
&
bitbang
->
lock
);
mutex_init
(
&
bitbang
->
lock
);
...
@@ -344,7 +356,12 @@ int spi_bitbang_init(struct spi_bitbang *bitbang)
...
@@ -344,7 +356,12 @@ int spi_bitbang_init(struct spi_bitbang *bitbang)
master
->
prepare_transfer_hardware
=
spi_bitbang_prepare_hardware
;
master
->
prepare_transfer_hardware
=
spi_bitbang_prepare_hardware
;
master
->
unprepare_transfer_hardware
=
spi_bitbang_unprepare_hardware
;
master
->
unprepare_transfer_hardware
=
spi_bitbang_unprepare_hardware
;
master
->
transfer_one
=
spi_bitbang_transfer_one
;
master
->
transfer_one
=
spi_bitbang_transfer_one
;
master
->
set_cs
=
spi_bitbang_set_cs
;
/*
* When using GPIO descriptors, the ->set_cs() callback doesn't even
* get called unless SPI_MASTER_GPIO_SS is set.
*/
if
(
custom_cs
)
master
->
set_cs
=
spi_bitbang_set_cs
;
if
(
!
bitbang
->
txrx_bufs
)
{
if
(
!
bitbang
->
txrx_bufs
)
{
bitbang
->
use_dma
=
0
;
bitbang
->
use_dma
=
0
;
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-dw.c
View file @
754a36a5
...
@@ -472,7 +472,8 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
...
@@ -472,7 +472,8 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
struct
spi_controller
*
master
;
struct
spi_controller
*
master
;
int
ret
;
int
ret
;
BUG_ON
(
dws
==
NULL
);
if
(
!
dws
)
return
-
EINVAL
;
master
=
spi_alloc_master
(
dev
,
0
);
master
=
spi_alloc_master
(
dev
,
0
);
if
(
!
master
)
if
(
!
master
)
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-fsl-dspi.c
View file @
754a36a5
...
@@ -396,17 +396,17 @@ static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr)
...
@@ -396,17 +396,17 @@ static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr)
if
(
!
dma
)
if
(
!
dma
)
return
-
ENOMEM
;
return
-
ENOMEM
;
dma
->
chan_rx
=
dma_request_
slave_channel
(
dev
,
"rx"
);
dma
->
chan_rx
=
dma_request_
chan
(
dev
,
"rx"
);
if
(
!
dma
->
chan_rx
)
{
if
(
IS_ERR
(
dma
->
chan_rx
)
)
{
dev_err
(
dev
,
"rx dma channel not available
\n
"
);
dev_err
(
dev
,
"rx dma channel not available
\n
"
);
ret
=
-
ENODEV
;
ret
=
PTR_ERR
(
dma
->
chan_rx
)
;
return
ret
;
return
ret
;
}
}
dma
->
chan_tx
=
dma_request_
slave_channel
(
dev
,
"tx"
);
dma
->
chan_tx
=
dma_request_
chan
(
dev
,
"tx"
);
if
(
!
dma
->
chan_tx
)
{
if
(
IS_ERR
(
dma
->
chan_tx
)
)
{
dev_err
(
dev
,
"tx dma channel not available
\n
"
);
dev_err
(
dev
,
"tx dma channel not available
\n
"
);
ret
=
-
ENODEV
;
ret
=
PTR_ERR
(
dma
->
chan_tx
)
;
goto
err_tx_channel
;
goto
err_tx_channel
;
}
}
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-fsl-lpspi.c
View file @
754a36a5
...
@@ -469,9 +469,9 @@ static int fsl_lpspi_setup_transfer(struct spi_controller *controller,
...
@@ -469,9 +469,9 @@ static int fsl_lpspi_setup_transfer(struct spi_controller *controller,
fsl_lpspi
->
watermark
=
fsl_lpspi
->
txfifosize
;
fsl_lpspi
->
watermark
=
fsl_lpspi
->
txfifosize
;
if
(
fsl_lpspi_can_dma
(
controller
,
spi
,
t
))
if
(
fsl_lpspi_can_dma
(
controller
,
spi
,
t
))
fsl_lpspi
->
usedma
=
1
;
fsl_lpspi
->
usedma
=
true
;
else
else
fsl_lpspi
->
usedma
=
0
;
fsl_lpspi
->
usedma
=
false
;
return
fsl_lpspi_config
(
fsl_lpspi
);
return
fsl_lpspi_config
(
fsl_lpspi
);
}
}
...
@@ -862,6 +862,22 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
...
@@ -862,6 +862,22 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
fsl_lpspi
->
dev
=
&
pdev
->
dev
;
fsl_lpspi
->
dev
=
&
pdev
->
dev
;
fsl_lpspi
->
is_slave
=
is_slave
;
fsl_lpspi
->
is_slave
=
is_slave
;
controller
->
bits_per_word_mask
=
SPI_BPW_RANGE_MASK
(
8
,
32
);
controller
->
transfer_one
=
fsl_lpspi_transfer_one
;
controller
->
prepare_transfer_hardware
=
lpspi_prepare_xfer_hardware
;
controller
->
unprepare_transfer_hardware
=
lpspi_unprepare_xfer_hardware
;
controller
->
mode_bits
=
SPI_CPOL
|
SPI_CPHA
|
SPI_CS_HIGH
;
controller
->
flags
=
SPI_MASTER_MUST_RX
|
SPI_MASTER_MUST_TX
;
controller
->
dev
.
of_node
=
pdev
->
dev
.
of_node
;
controller
->
bus_num
=
pdev
->
id
;
controller
->
slave_abort
=
fsl_lpspi_slave_abort
;
ret
=
devm_spi_register_controller
(
&
pdev
->
dev
,
controller
);
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"spi_register_controller error.
\n
"
);
goto
out_controller_put
;
}
if
(
!
fsl_lpspi
->
is_slave
)
{
if
(
!
fsl_lpspi
->
is_slave
)
{
for
(
i
=
0
;
i
<
controller
->
num_chipselect
;
i
++
)
{
for
(
i
=
0
;
i
<
controller
->
num_chipselect
;
i
++
)
{
int
cs_gpio
=
of_get_named_gpio
(
np
,
"cs-gpios"
,
i
);
int
cs_gpio
=
of_get_named_gpio
(
np
,
"cs-gpios"
,
i
);
...
@@ -885,16 +901,6 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
...
@@ -885,16 +901,6 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
controller
->
prepare_message
=
fsl_lpspi_prepare_message
;
controller
->
prepare_message
=
fsl_lpspi_prepare_message
;
}
}
controller
->
bits_per_word_mask
=
SPI_BPW_RANGE_MASK
(
8
,
32
);
controller
->
transfer_one
=
fsl_lpspi_transfer_one
;
controller
->
prepare_transfer_hardware
=
lpspi_prepare_xfer_hardware
;
controller
->
unprepare_transfer_hardware
=
lpspi_unprepare_xfer_hardware
;
controller
->
mode_bits
=
SPI_CPOL
|
SPI_CPHA
|
SPI_CS_HIGH
;
controller
->
flags
=
SPI_MASTER_MUST_RX
|
SPI_MASTER_MUST_TX
;
controller
->
dev
.
of_node
=
pdev
->
dev
.
of_node
;
controller
->
bus_num
=
pdev
->
id
;
controller
->
slave_abort
=
fsl_lpspi_slave_abort
;
init_completion
(
&
fsl_lpspi
->
xfer_done
);
init_completion
(
&
fsl_lpspi
->
xfer_done
);
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
...
@@ -952,12 +958,6 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
...
@@ -952,12 +958,6 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
if
(
ret
<
0
)
if
(
ret
<
0
)
dev_err
(
&
pdev
->
dev
,
"dma setup error %d, use pio
\n
"
,
ret
);
dev_err
(
&
pdev
->
dev
,
"dma setup error %d, use pio
\n
"
,
ret
);
ret
=
devm_spi_register_controller
(
&
pdev
->
dev
,
controller
);
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"spi_register_controller error.
\n
"
);
goto
out_controller_put
;
}
return
0
;
return
0
;
out_controller_put:
out_controller_put:
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-fsl-spi.c
View file @
754a36a5
...
@@ -706,8 +706,8 @@ static int of_fsl_spi_probe(struct platform_device *ofdev)
...
@@ -706,8 +706,8 @@ static int of_fsl_spi_probe(struct platform_device *ofdev)
struct
device_node
*
np
=
ofdev
->
dev
.
of_node
;
struct
device_node
*
np
=
ofdev
->
dev
.
of_node
;
struct
spi_master
*
master
;
struct
spi_master
*
master
;
struct
resource
mem
;
struct
resource
mem
;
int
irq
=
0
,
type
;
int
irq
,
type
;
int
ret
=
-
ENOMEM
;
int
ret
;
ret
=
of_mpc8xxx_spi_probe
(
ofdev
);
ret
=
of_mpc8xxx_spi_probe
(
ofdev
);
if
(
ret
)
if
(
ret
)
...
@@ -722,10 +722,8 @@ static int of_fsl_spi_probe(struct platform_device *ofdev)
...
@@ -722,10 +722,8 @@ static int of_fsl_spi_probe(struct platform_device *ofdev)
if
(
spisel_boot
)
{
if
(
spisel_boot
)
{
pinfo
->
immr_spi_cs
=
ioremap
(
get_immrbase
()
+
IMMR_SPI_CS_OFFSET
,
4
);
pinfo
->
immr_spi_cs
=
ioremap
(
get_immrbase
()
+
IMMR_SPI_CS_OFFSET
,
4
);
if
(
!
pinfo
->
immr_spi_cs
)
{
if
(
!
pinfo
->
immr_spi_cs
)
ret
=
-
ENOMEM
;
return
-
ENOMEM
;
goto
err
;
}
}
}
#endif
#endif
/*
/*
...
@@ -744,24 +742,15 @@ static int of_fsl_spi_probe(struct platform_device *ofdev)
...
@@ -744,24 +742,15 @@ static int of_fsl_spi_probe(struct platform_device *ofdev)
ret
=
of_address_to_resource
(
np
,
0
,
&
mem
);
ret
=
of_address_to_resource
(
np
,
0
,
&
mem
);
if
(
ret
)
if
(
ret
)
goto
err
;
return
ret
;
irq
=
platform_get_irq
(
ofdev
,
0
);
irq
=
platform_get_irq
(
ofdev
,
0
);
if
(
irq
<
0
)
{
if
(
irq
<
0
)
ret
=
irq
;
return
irq
;
goto
err
;
}
master
=
fsl_spi_probe
(
dev
,
&
mem
,
irq
);
master
=
fsl_spi_probe
(
dev
,
&
mem
,
irq
);
if
(
IS_ERR
(
master
))
{
ret
=
PTR_ERR
(
master
);
goto
err
;
}
return
0
;
err:
return
PTR_ERR_OR_ZERO
(
master
);
return
ret
;
}
}
static
int
of_fsl_spi_remove
(
struct
platform_device
*
ofdev
)
static
int
of_fsl_spi_remove
(
struct
platform_device
*
ofdev
)
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-hisi-sfc-v3xx.c
0 → 100644
View file @
754a36a5
// SPDX-License-Identifier: GPL-2.0-only
//
// HiSilicon SPI NOR V3XX Flash Controller Driver for hi16xx chipsets
//
// Copyright (c) 2019 HiSilicon Technologies Co., Ltd.
// Author: John Garry <john.garry@huawei.com>
#include <linux/acpi.h>
#include <linux/bitops.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi-mem.h>
#define HISI_SFC_V3XX_VERSION (0x1f8)
#define HISI_SFC_V3XX_CMD_CFG (0x300)
#define HISI_SFC_V3XX_CMD_CFG_DATA_CNT_OFF 9
#define HISI_SFC_V3XX_CMD_CFG_RW_MSK BIT(8)
#define HISI_SFC_V3XX_CMD_CFG_DATA_EN_MSK BIT(7)
#define HISI_SFC_V3XX_CMD_CFG_DUMMY_CNT_OFF 4
#define HISI_SFC_V3XX_CMD_CFG_ADDR_EN_MSK BIT(3)
#define HISI_SFC_V3XX_CMD_CFG_CS_SEL_OFF 1
#define HISI_SFC_V3XX_CMD_CFG_START_MSK BIT(0)
#define HISI_SFC_V3XX_CMD_INS (0x308)
#define HISI_SFC_V3XX_CMD_ADDR (0x30c)
#define HISI_SFC_V3XX_CMD_DATABUF0 (0x400)
struct
hisi_sfc_v3xx_host
{
struct
device
*
dev
;
void
__iomem
*
regbase
;
int
max_cmd_dword
;
};
#define HISI_SFC_V3XX_WAIT_TIMEOUT_US 1000000
#define HISI_SFC_V3XX_WAIT_POLL_INTERVAL_US 10
static
int
hisi_sfc_v3xx_wait_cmd_idle
(
struct
hisi_sfc_v3xx_host
*
host
)
{
u32
reg
;
return
readl_poll_timeout
(
host
->
regbase
+
HISI_SFC_V3XX_CMD_CFG
,
reg
,
!
(
reg
&
HISI_SFC_V3XX_CMD_CFG_START_MSK
),
HISI_SFC_V3XX_WAIT_POLL_INTERVAL_US
,
HISI_SFC_V3XX_WAIT_TIMEOUT_US
);
}
static
int
hisi_sfc_v3xx_adjust_op_size
(
struct
spi_mem
*
mem
,
struct
spi_mem_op
*
op
)
{
struct
spi_device
*
spi
=
mem
->
spi
;
struct
hisi_sfc_v3xx_host
*
host
;
uintptr_t
addr
=
(
uintptr_t
)
op
->
data
.
buf
.
in
;
int
max_byte_count
;
host
=
spi_controller_get_devdata
(
spi
->
master
);
max_byte_count
=
host
->
max_cmd_dword
*
4
;
if
(
!
IS_ALIGNED
(
addr
,
4
)
&&
op
->
data
.
nbytes
>=
4
)
op
->
data
.
nbytes
=
4
-
(
addr
%
4
);
else
if
(
op
->
data
.
nbytes
>
max_byte_count
)
op
->
data
.
nbytes
=
max_byte_count
;
return
0
;
}
/*
* memcpy_{to,from}io doesn't gurantee 32b accesses - which we require for the
* DATABUF registers -so use __io{read,write}32_copy when possible. For
* trailing bytes, copy them byte-by-byte from the DATABUF register, as we
* can't clobber outside the source/dest buffer.
*
* For efficient data read/write, we try to put any start 32b unaligned data
* into a separate transaction in hisi_sfc_v3xx_adjust_op_size().
*/
static
void
hisi_sfc_v3xx_read_databuf
(
struct
hisi_sfc_v3xx_host
*
host
,
u8
*
to
,
unsigned
int
len
)
{
void
__iomem
*
from
;
int
i
;
from
=
host
->
regbase
+
HISI_SFC_V3XX_CMD_DATABUF0
;
if
(
IS_ALIGNED
((
uintptr_t
)
to
,
4
))
{
int
words
=
len
/
4
;
__ioread32_copy
(
to
,
from
,
words
);
len
-=
words
*
4
;
if
(
len
)
{
u32
val
;
to
+=
words
*
4
;
from
+=
words
*
4
;
val
=
__raw_readl
(
from
);
for
(
i
=
0
;
i
<
len
;
i
++
,
val
>>=
8
,
to
++
)
*
to
=
(
u8
)
val
;
}
}
else
{
for
(
i
=
0
;
i
<
DIV_ROUND_UP
(
len
,
4
);
i
++
,
from
+=
4
)
{
u32
val
=
__raw_readl
(
from
);
int
j
;
for
(
j
=
0
;
j
<
4
&&
(
j
+
(
i
*
4
)
<
len
);
to
++
,
val
>>=
8
,
j
++
)
*
to
=
(
u8
)
val
;
}
}
}
static
void
hisi_sfc_v3xx_write_databuf
(
struct
hisi_sfc_v3xx_host
*
host
,
const
u8
*
from
,
unsigned
int
len
)
{
void
__iomem
*
to
;
int
i
;
to
=
host
->
regbase
+
HISI_SFC_V3XX_CMD_DATABUF0
;
if
(
IS_ALIGNED
((
uintptr_t
)
from
,
4
))
{
int
words
=
len
/
4
;
__iowrite32_copy
(
to
,
from
,
words
);
len
-=
words
*
4
;
if
(
len
)
{
u32
val
=
0
;
to
+=
words
*
4
;
from
+=
words
*
4
;
for
(
i
=
0
;
i
<
len
;
i
++
,
from
++
)
val
|=
*
from
<<
i
*
8
;
__raw_writel
(
val
,
to
);
}
}
else
{
for
(
i
=
0
;
i
<
DIV_ROUND_UP
(
len
,
4
);
i
++
,
to
+=
4
)
{
u32
val
=
0
;
int
j
;
for
(
j
=
0
;
j
<
4
&&
(
j
+
(
i
*
4
)
<
len
);
from
++
,
j
++
)
val
|=
*
from
<<
j
*
8
;
__raw_writel
(
val
,
to
);
}
}
}
static
int
hisi_sfc_v3xx_generic_exec_op
(
struct
hisi_sfc_v3xx_host
*
host
,
const
struct
spi_mem_op
*
op
,
u8
chip_select
)
{
int
ret
,
len
=
op
->
data
.
nbytes
;
u32
config
=
0
;
if
(
op
->
addr
.
nbytes
)
config
|=
HISI_SFC_V3XX_CMD_CFG_ADDR_EN_MSK
;
if
(
op
->
data
.
dir
!=
SPI_MEM_NO_DATA
)
{
config
|=
(
len
-
1
)
<<
HISI_SFC_V3XX_CMD_CFG_DATA_CNT_OFF
;
config
|=
HISI_SFC_V3XX_CMD_CFG_DATA_EN_MSK
;
}
if
(
op
->
data
.
dir
==
SPI_MEM_DATA_OUT
)
hisi_sfc_v3xx_write_databuf
(
host
,
op
->
data
.
buf
.
out
,
len
);
else
if
(
op
->
data
.
dir
==
SPI_MEM_DATA_IN
)
config
|=
HISI_SFC_V3XX_CMD_CFG_RW_MSK
;
config
|=
op
->
dummy
.
nbytes
<<
HISI_SFC_V3XX_CMD_CFG_DUMMY_CNT_OFF
|
chip_select
<<
HISI_SFC_V3XX_CMD_CFG_CS_SEL_OFF
|
HISI_SFC_V3XX_CMD_CFG_START_MSK
;
writel
(
op
->
addr
.
val
,
host
->
regbase
+
HISI_SFC_V3XX_CMD_ADDR
);
writel
(
op
->
cmd
.
opcode
,
host
->
regbase
+
HISI_SFC_V3XX_CMD_INS
);
writel
(
config
,
host
->
regbase
+
HISI_SFC_V3XX_CMD_CFG
);
ret
=
hisi_sfc_v3xx_wait_cmd_idle
(
host
);
if
(
ret
)
return
ret
;
if
(
op
->
data
.
dir
==
SPI_MEM_DATA_IN
)
hisi_sfc_v3xx_read_databuf
(
host
,
op
->
data
.
buf
.
in
,
len
);
return
0
;
}
static
int
hisi_sfc_v3xx_exec_op
(
struct
spi_mem
*
mem
,
const
struct
spi_mem_op
*
op
)
{
struct
hisi_sfc_v3xx_host
*
host
;
struct
spi_device
*
spi
=
mem
->
spi
;
u8
chip_select
=
spi
->
chip_select
;
host
=
spi_controller_get_devdata
(
spi
->
master
);
return
hisi_sfc_v3xx_generic_exec_op
(
host
,
op
,
chip_select
);
}
static
const
struct
spi_controller_mem_ops
hisi_sfc_v3xx_mem_ops
=
{
.
adjust_op_size
=
hisi_sfc_v3xx_adjust_op_size
,
.
exec_op
=
hisi_sfc_v3xx_exec_op
,
};
static
int
hisi_sfc_v3xx_probe
(
struct
platform_device
*
pdev
)
{
struct
device
*
dev
=
&
pdev
->
dev
;
struct
hisi_sfc_v3xx_host
*
host
;
struct
spi_controller
*
ctlr
;
u32
version
;
int
ret
;
ctlr
=
spi_alloc_master
(
&
pdev
->
dev
,
sizeof
(
*
host
));
if
(
!
ctlr
)
return
-
ENOMEM
;
ctlr
->
mode_bits
=
SPI_RX_DUAL
|
SPI_RX_QUAD
|
SPI_TX_DUAL
|
SPI_TX_QUAD
;
host
=
spi_controller_get_devdata
(
ctlr
);
host
->
dev
=
dev
;
platform_set_drvdata
(
pdev
,
host
);
host
->
regbase
=
devm_platform_ioremap_resource
(
pdev
,
0
);
if
(
IS_ERR
(
host
->
regbase
))
{
ret
=
PTR_ERR
(
host
->
regbase
);
goto
err_put_master
;
}
ctlr
->
bus_num
=
-
1
;
ctlr
->
num_chipselect
=
1
;
ctlr
->
mem_ops
=
&
hisi_sfc_v3xx_mem_ops
;
version
=
readl
(
host
->
regbase
+
HISI_SFC_V3XX_VERSION
);
switch
(
version
)
{
case
0x351
:
host
->
max_cmd_dword
=
64
;
break
;
default:
host
->
max_cmd_dword
=
16
;
break
;
}
ret
=
devm_spi_register_controller
(
dev
,
ctlr
);
if
(
ret
)
goto
err_put_master
;
dev_info
(
&
pdev
->
dev
,
"hw version 0x%x
\n
"
,
version
);
return
0
;
err_put_master:
spi_master_put
(
ctlr
);
return
ret
;
}
#if IS_ENABLED(CONFIG_ACPI)
static
const
struct
acpi_device_id
hisi_sfc_v3xx_acpi_ids
[]
=
{
{
"HISI0341"
,
0
},
{}
};
MODULE_DEVICE_TABLE
(
acpi
,
hisi_sfc_v3xx_acpi_ids
);
#endif
static
struct
platform_driver
hisi_sfc_v3xx_spi_driver
=
{
.
driver
=
{
.
name
=
"hisi-sfc-v3xx"
,
.
acpi_match_table
=
ACPI_PTR
(
hisi_sfc_v3xx_acpi_ids
),
},
.
probe
=
hisi_sfc_v3xx_probe
,
};
module_platform_driver
(
hisi_sfc_v3xx_spi_driver
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"John Garry <john.garry@huawei.com>"
);
MODULE_DESCRIPTION
(
"HiSilicon SPI NOR V3XX Flash Controller Driver for hi16xx chipsets"
);
This diff is collapsed.
Click to expand it.
drivers/spi/spi-img-spfi.c
View file @
754a36a5
...
@@ -666,8 +666,22 @@ static int img_spfi_probe(struct platform_device *pdev)
...
@@ -666,8 +666,22 @@ static int img_spfi_probe(struct platform_device *pdev)
master
->
unprepare_message
=
img_spfi_unprepare
;
master
->
unprepare_message
=
img_spfi_unprepare
;
master
->
handle_err
=
img_spfi_handle_err
;
master
->
handle_err
=
img_spfi_handle_err
;
spfi
->
tx_ch
=
dma_request_slave_channel
(
spfi
->
dev
,
"tx"
);
spfi
->
tx_ch
=
dma_request_chan
(
spfi
->
dev
,
"tx"
);
spfi
->
rx_ch
=
dma_request_slave_channel
(
spfi
->
dev
,
"rx"
);
if
(
IS_ERR
(
spfi
->
tx_ch
))
{
ret
=
PTR_ERR
(
spfi
->
tx_ch
);
spfi
->
tx_ch
=
NULL
;
if
(
ret
==
-
EPROBE_DEFER
)
goto
disable_pm
;
}
spfi
->
rx_ch
=
dma_request_chan
(
spfi
->
dev
,
"rx"
);
if
(
IS_ERR
(
spfi
->
rx_ch
))
{
ret
=
PTR_ERR
(
spfi
->
rx_ch
);
spfi
->
rx_ch
=
NULL
;
if
(
ret
==
-
EPROBE_DEFER
)
goto
disable_pm
;
}
if
(
!
spfi
->
tx_ch
||
!
spfi
->
rx_ch
)
{
if
(
!
spfi
->
tx_ch
||
!
spfi
->
rx_ch
)
{
if
(
spfi
->
tx_ch
)
if
(
spfi
->
tx_ch
)
dma_release_channel
(
spfi
->
tx_ch
);
dma_release_channel
(
spfi
->
tx_ch
);
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-imx.c
View file @
754a36a5
...
@@ -1230,9 +1230,9 @@ static int spi_imx_setupxfer(struct spi_device *spi,
...
@@ -1230,9 +1230,9 @@ static int spi_imx_setupxfer(struct spi_device *spi,
}
}
if
(
spi_imx_can_dma
(
spi_imx
->
bitbang
.
master
,
spi
,
t
))
if
(
spi_imx_can_dma
(
spi_imx
->
bitbang
.
master
,
spi
,
t
))
spi_imx
->
usedma
=
1
;
spi_imx
->
usedma
=
true
;
else
else
spi_imx
->
usedma
=
0
;
spi_imx
->
usedma
=
false
;
if
(
is_imx53_ecspi
(
spi_imx
)
&&
spi_imx
->
slave_mode
)
{
if
(
is_imx53_ecspi
(
spi_imx
)
&&
spi_imx
->
slave_mode
)
{
spi_imx
->
rx
=
mx53_ecspi_rx_slave
;
spi_imx
->
rx
=
mx53_ecspi_rx_slave
;
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-meson-spicc.c
View file @
754a36a5
...
@@ -19,7 +19,6 @@
...
@@ -19,7 +19,6 @@
#include <linux/types.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/reset.h>
#include <linux/reset.h>
#include <linux/gpio.h>
/*
/*
* The Meson SPICC controller could support DMA based transfers, but is not
* The Meson SPICC controller could support DMA based transfers, but is not
...
@@ -467,35 +466,14 @@ static int meson_spicc_unprepare_transfer(struct spi_master *master)
...
@@ -467,35 +466,14 @@ static int meson_spicc_unprepare_transfer(struct spi_master *master)
static
int
meson_spicc_setup
(
struct
spi_device
*
spi
)
static
int
meson_spicc_setup
(
struct
spi_device
*
spi
)
{
{
int
ret
=
0
;
if
(
!
spi
->
controller_state
)
if
(
!
spi
->
controller_state
)
spi
->
controller_state
=
spi_master_get_devdata
(
spi
->
master
);
spi
->
controller_state
=
spi_master_get_devdata
(
spi
->
master
);
else
if
(
gpio_is_valid
(
spi
->
cs_gpio
))
goto
out_gpio
;
else
if
(
spi
->
cs_gpio
==
-
ENOENT
)
return
0
;
if
(
gpio_is_valid
(
spi
->
cs_gpio
))
{
ret
=
gpio_request
(
spi
->
cs_gpio
,
dev_name
(
&
spi
->
dev
));
if
(
ret
)
{
dev_err
(
&
spi
->
dev
,
"failed to request cs gpio
\n
"
);
return
ret
;
}
}
out_gpio:
ret
=
gpio_direction_output
(
spi
->
cs_gpio
,
!
(
spi
->
mode
&
SPI_CS_HIGH
));
return
ret
;
return
0
;
}
}
static
void
meson_spicc_cleanup
(
struct
spi_device
*
spi
)
static
void
meson_spicc_cleanup
(
struct
spi_device
*
spi
)
{
{
if
(
gpio_is_valid
(
spi
->
cs_gpio
))
gpio_free
(
spi
->
cs_gpio
);
spi
->
controller_state
=
NULL
;
spi
->
controller_state
=
NULL
;
}
}
...
@@ -564,6 +542,7 @@ static int meson_spicc_probe(struct platform_device *pdev)
...
@@ -564,6 +542,7 @@ static int meson_spicc_probe(struct platform_device *pdev)
master
->
prepare_message
=
meson_spicc_prepare_message
;
master
->
prepare_message
=
meson_spicc_prepare_message
;
master
->
unprepare_transfer_hardware
=
meson_spicc_unprepare_transfer
;
master
->
unprepare_transfer_hardware
=
meson_spicc_unprepare_transfer
;
master
->
transfer_one
=
meson_spicc_transfer_one
;
master
->
transfer_one
=
meson_spicc_transfer_one
;
master
->
use_gpio_descriptors
=
true
;
/* Setup max rate according to the Meson GX datasheet */
/* Setup max rate according to the Meson GX datasheet */
if
((
rate
>>
2
)
>
SPICC_MAX_FREQ
)
if
((
rate
>>
2
)
>
SPICC_MAX_FREQ
)
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-mxs.c
View file @
754a36a5
...
@@ -590,10 +590,10 @@ static int mxs_spi_probe(struct platform_device *pdev)
...
@@ -590,10 +590,10 @@ static int mxs_spi_probe(struct platform_device *pdev)
if
(
ret
)
if
(
ret
)
goto
out_master_free
;
goto
out_master_free
;
ssp
->
dmach
=
dma_request_
slave_channel
(
&
pdev
->
dev
,
"rx-tx"
);
ssp
->
dmach
=
dma_request_
chan
(
&
pdev
->
dev
,
"rx-tx"
);
if
(
!
ssp
->
dmach
)
{
if
(
IS_ERR
(
ssp
->
dmach
)
)
{
dev_err
(
ssp
->
dev
,
"Failed to request DMA
\n
"
);
dev_err
(
ssp
->
dev
,
"Failed to request DMA
\n
"
);
ret
=
-
ENODEV
;
ret
=
PTR_ERR
(
ssp
->
dmach
)
;
goto
out_master_free
;
goto
out_master_free
;
}
}
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-npcm-pspi.c
View file @
754a36a5
...
@@ -12,6 +12,7 @@
...
@@ -12,6 +12,7 @@
#include <linux/spi/spi.h>
#include <linux/spi/spi.h>
#include <linux/gpio.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/of_gpio.h>
#include <linux/reset.h>
#include <asm/unaligned.h>
#include <asm/unaligned.h>
...
@@ -20,7 +21,7 @@
...
@@ -20,7 +21,7 @@
struct
npcm_pspi
{
struct
npcm_pspi
{
struct
completion
xfer_done
;
struct
completion
xfer_done
;
struct
re
gmap
*
rst_regmap
;
struct
re
set_control
*
reset
;
struct
spi_master
*
master
;
struct
spi_master
*
master
;
unsigned
int
tx_bytes
;
unsigned
int
tx_bytes
;
unsigned
int
rx_bytes
;
unsigned
int
rx_bytes
;
...
@@ -59,12 +60,6 @@ struct npcm_pspi {
...
@@ -59,12 +60,6 @@ struct npcm_pspi {
#define NPCM_PSPI_MIN_CLK_DIVIDER 4
#define NPCM_PSPI_MIN_CLK_DIVIDER 4
#define NPCM_PSPI_DEFAULT_CLK 25000000
#define NPCM_PSPI_DEFAULT_CLK 25000000
/* reset register */
#define NPCM7XX_IPSRST2_OFFSET 0x24
#define NPCM7XX_PSPI1_RESET BIT(22)
#define NPCM7XX_PSPI2_RESET BIT(23)
static
inline
unsigned
int
bytes_per_word
(
unsigned
int
bits
)
static
inline
unsigned
int
bytes_per_word
(
unsigned
int
bits
)
{
{
return
bits
<=
8
?
1
:
2
;
return
bits
<=
8
?
1
:
2
;
...
@@ -178,6 +173,13 @@ static void npcm_pspi_setup_transfer(struct spi_device *spi,
...
@@ -178,6 +173,13 @@ static void npcm_pspi_setup_transfer(struct spi_device *spi,
priv
->
mode
=
spi
->
mode
;
priv
->
mode
=
spi
->
mode
;
}
}
/*
* If transfer is even length, and 8 bits per word transfer,
* then implement 16 bits-per-word transfer.
*/
if
(
priv
->
bits_per_word
==
8
&&
!
(
t
->
len
&
0x1
))
t
->
bits_per_word
=
16
;
if
(
!
priv
->
is_save_param
||
priv
->
bits_per_word
!=
t
->
bits_per_word
)
{
if
(
!
priv
->
is_save_param
||
priv
->
bits_per_word
!=
t
->
bits_per_word
)
{
npcm_pspi_set_transfer_size
(
priv
,
t
->
bits_per_word
);
npcm_pspi_set_transfer_size
(
priv
,
t
->
bits_per_word
);
priv
->
bits_per_word
=
t
->
bits_per_word
;
priv
->
bits_per_word
=
t
->
bits_per_word
;
...
@@ -286,9 +288,9 @@ static int npcm_pspi_unprepare_transfer_hardware(struct spi_master *master)
...
@@ -286,9 +288,9 @@ static int npcm_pspi_unprepare_transfer_hardware(struct spi_master *master)
static
void
npcm_pspi_reset_hw
(
struct
npcm_pspi
*
priv
)
static
void
npcm_pspi_reset_hw
(
struct
npcm_pspi
*
priv
)
{
{
re
gmap_write
(
priv
->
rst_regmap
,
NPCM7XX_IPSRST2_OFFSET
,
re
set_control_assert
(
priv
->
reset
);
NPCM7XX_PSPI1_RESET
<<
priv
->
id
);
udelay
(
5
);
re
gmap_write
(
priv
->
rst_regmap
,
NPCM7XX_IPSRST2_OFFSET
,
0x0
);
re
set_control_deassert
(
priv
->
reset
);
}
}
static
irqreturn_t
npcm_pspi_handler
(
int
irq
,
void
*
dev_id
)
static
irqreturn_t
npcm_pspi_handler
(
int
irq
,
void
*
dev_id
)
...
@@ -352,10 +354,6 @@ static int npcm_pspi_probe(struct platform_device *pdev)
...
@@ -352,10 +354,6 @@ static int npcm_pspi_probe(struct platform_device *pdev)
if
(
num_cs
<
0
)
if
(
num_cs
<
0
)
return
num_cs
;
return
num_cs
;
pdev
->
id
=
of_alias_get_id
(
np
,
"spi"
);
if
(
pdev
->
id
<
0
)
pdev
->
id
=
0
;
master
=
spi_alloc_master
(
&
pdev
->
dev
,
sizeof
(
*
priv
));
master
=
spi_alloc_master
(
&
pdev
->
dev
,
sizeof
(
*
priv
));
if
(
!
master
)
if
(
!
master
)
return
-
ENOMEM
;
return
-
ENOMEM
;
...
@@ -365,7 +363,6 @@ static int npcm_pspi_probe(struct platform_device *pdev)
...
@@ -365,7 +363,6 @@ static int npcm_pspi_probe(struct platform_device *pdev)
priv
=
spi_master_get_devdata
(
master
);
priv
=
spi_master_get_devdata
(
master
);
priv
->
master
=
master
;
priv
->
master
=
master
;
priv
->
is_save_param
=
false
;
priv
->
is_save_param
=
false
;
priv
->
id
=
pdev
->
id
;
priv
->
base
=
devm_platform_ioremap_resource
(
pdev
,
0
);
priv
->
base
=
devm_platform_ioremap_resource
(
pdev
,
0
);
if
(
IS_ERR
(
priv
->
base
))
{
if
(
IS_ERR
(
priv
->
base
))
{
...
@@ -390,11 +387,10 @@ static int npcm_pspi_probe(struct platform_device *pdev)
...
@@ -390,11 +387,10 @@ static int npcm_pspi_probe(struct platform_device *pdev)
goto
out_disable_clk
;
goto
out_disable_clk
;
}
}
priv
->
rst_regmap
=
priv
->
reset
=
devm_reset_control_get
(
&
pdev
->
dev
,
NULL
);
syscon_regmap_lookup_by_compatible
(
"nuvoton,npcm750-rst"
);
if
(
IS_ERR
(
priv
->
reset
))
{
if
(
IS_ERR
(
priv
->
rst_regmap
))
{
ret
=
PTR_ERR
(
priv
->
reset
);
dev_err
(
&
pdev
->
dev
,
"failed to find nuvoton,npcm750-rst
\n
"
);
goto
out_disable_clk
;
return
PTR_ERR
(
priv
->
rst_regmap
);
}
}
/* reset SPI-HW block */
/* reset SPI-HW block */
...
@@ -415,7 +411,7 @@ static int npcm_pspi_probe(struct platform_device *pdev)
...
@@ -415,7 +411,7 @@ static int npcm_pspi_probe(struct platform_device *pdev)
master
->
min_speed_hz
=
DIV_ROUND_UP
(
clk_hz
,
NPCM_PSPI_MAX_CLK_DIVIDER
);
master
->
min_speed_hz
=
DIV_ROUND_UP
(
clk_hz
,
NPCM_PSPI_MAX_CLK_DIVIDER
);
master
->
mode_bits
=
SPI_CPHA
|
SPI_CPOL
;
master
->
mode_bits
=
SPI_CPHA
|
SPI_CPOL
;
master
->
dev
.
of_node
=
pdev
->
dev
.
of_node
;
master
->
dev
.
of_node
=
pdev
->
dev
.
of_node
;
master
->
bus_num
=
pdev
->
id
;
master
->
bus_num
=
-
1
;
master
->
bits_per_word_mask
=
SPI_BPW_MASK
(
8
)
|
SPI_BPW_MASK
(
16
);
master
->
bits_per_word_mask
=
SPI_BPW_MASK
(
8
)
|
SPI_BPW_MASK
(
16
);
master
->
transfer_one
=
npcm_pspi_transfer_one
;
master
->
transfer_one
=
npcm_pspi_transfer_one
;
master
->
prepare_transfer_hardware
=
master
->
prepare_transfer_hardware
=
...
@@ -448,7 +444,7 @@ static int npcm_pspi_probe(struct platform_device *pdev)
...
@@ -448,7 +444,7 @@ static int npcm_pspi_probe(struct platform_device *pdev)
if
(
ret
)
if
(
ret
)
goto
out_disable_clk
;
goto
out_disable_clk
;
pr_info
(
"NPCM Peripheral SPI %d probed
\n
"
,
pdev
->
id
);
pr_info
(
"NPCM Peripheral SPI %d probed
\n
"
,
master
->
bus_num
);
return
0
;
return
0
;
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-oc-tiny.c
View file @
754a36a5
...
@@ -20,7 +20,6 @@
...
@@ -20,7 +20,6 @@
#include <linux/spi/spi_bitbang.h>
#include <linux/spi/spi_bitbang.h>
#include <linux/spi/spi_oc_tiny.h>
#include <linux/spi/spi_oc_tiny.h>
#include <linux/io.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of.h>
#define DRV_NAME "spi_oc_tiny"
#define DRV_NAME "spi_oc_tiny"
...
@@ -50,8 +49,6 @@ struct tiny_spi {
...
@@ -50,8 +49,6 @@ struct tiny_spi {
unsigned
int
txc
,
rxc
;
unsigned
int
txc
,
rxc
;
const
u8
*
txp
;
const
u8
*
txp
;
u8
*
rxp
;
u8
*
rxp
;
int
gpio_cs_count
;
int
*
gpio_cs
;
};
};
static
inline
struct
tiny_spi
*
tiny_spi_to_hw
(
struct
spi_device
*
sdev
)
static
inline
struct
tiny_spi
*
tiny_spi_to_hw
(
struct
spi_device
*
sdev
)
...
@@ -66,16 +63,6 @@ static unsigned int tiny_spi_baud(struct spi_device *spi, unsigned int hz)
...
@@ -66,16 +63,6 @@ static unsigned int tiny_spi_baud(struct spi_device *spi, unsigned int hz)
return
min
(
DIV_ROUND_UP
(
hw
->
freq
,
hz
*
2
),
(
1U
<<
hw
->
baudwidth
))
-
1
;
return
min
(
DIV_ROUND_UP
(
hw
->
freq
,
hz
*
2
),
(
1U
<<
hw
->
baudwidth
))
-
1
;
}
}
static
void
tiny_spi_chipselect
(
struct
spi_device
*
spi
,
int
is_active
)
{
struct
tiny_spi
*
hw
=
tiny_spi_to_hw
(
spi
);
if
(
hw
->
gpio_cs_count
>
0
)
{
gpio_set_value
(
hw
->
gpio_cs
[
spi
->
chip_select
],
(
spi
->
mode
&
SPI_CS_HIGH
)
?
is_active
:
!
is_active
);
}
}
static
int
tiny_spi_setup_transfer
(
struct
spi_device
*
spi
,
static
int
tiny_spi_setup_transfer
(
struct
spi_device
*
spi
,
struct
spi_transfer
*
t
)
struct
spi_transfer
*
t
)
{
{
...
@@ -203,24 +190,10 @@ static int tiny_spi_of_probe(struct platform_device *pdev)
...
@@ -203,24 +190,10 @@ static int tiny_spi_of_probe(struct platform_device *pdev)
{
{
struct
tiny_spi
*
hw
=
platform_get_drvdata
(
pdev
);
struct
tiny_spi
*
hw
=
platform_get_drvdata
(
pdev
);
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
unsigned
int
i
;
u32
val
;
u32
val
;
if
(
!
np
)
if
(
!
np
)
return
0
;
return
0
;
hw
->
gpio_cs_count
=
of_gpio_count
(
np
);
if
(
hw
->
gpio_cs_count
>
0
)
{
hw
->
gpio_cs
=
devm_kcalloc
(
&
pdev
->
dev
,
hw
->
gpio_cs_count
,
sizeof
(
unsigned
int
),
GFP_KERNEL
);
if
(
!
hw
->
gpio_cs
)
return
-
ENOMEM
;
}
for
(
i
=
0
;
i
<
hw
->
gpio_cs_count
;
i
++
)
{
hw
->
gpio_cs
[
i
]
=
of_get_gpio_flags
(
np
,
i
,
NULL
);
if
(
hw
->
gpio_cs
[
i
]
<
0
)
return
-
ENODEV
;
}
hw
->
bitbang
.
master
->
dev
.
of_node
=
pdev
->
dev
.
of_node
;
hw
->
bitbang
.
master
->
dev
.
of_node
=
pdev
->
dev
.
of_node
;
if
(
!
of_property_read_u32
(
np
,
"clock-frequency"
,
&
val
))
if
(
!
of_property_read_u32
(
np
,
"clock-frequency"
,
&
val
))
hw
->
freq
=
val
;
hw
->
freq
=
val
;
...
@@ -240,7 +213,6 @@ static int tiny_spi_probe(struct platform_device *pdev)
...
@@ -240,7 +213,6 @@ static int tiny_spi_probe(struct platform_device *pdev)
struct
tiny_spi_platform_data
*
platp
=
dev_get_platdata
(
&
pdev
->
dev
);
struct
tiny_spi_platform_data
*
platp
=
dev_get_platdata
(
&
pdev
->
dev
);
struct
tiny_spi
*
hw
;
struct
tiny_spi
*
hw
;
struct
spi_master
*
master
;
struct
spi_master
*
master
;
unsigned
int
i
;
int
err
=
-
ENODEV
;
int
err
=
-
ENODEV
;
master
=
spi_alloc_master
(
&
pdev
->
dev
,
sizeof
(
struct
tiny_spi
));
master
=
spi_alloc_master
(
&
pdev
->
dev
,
sizeof
(
struct
tiny_spi
));
...
@@ -249,9 +221,9 @@ static int tiny_spi_probe(struct platform_device *pdev)
...
@@ -249,9 +221,9 @@ static int tiny_spi_probe(struct platform_device *pdev)
/* setup the master state. */
/* setup the master state. */
master
->
bus_num
=
pdev
->
id
;
master
->
bus_num
=
pdev
->
id
;
master
->
num_chipselect
=
255
;
master
->
mode_bits
=
SPI_CPOL
|
SPI_CPHA
|
SPI_CS_HIGH
;
master
->
mode_bits
=
SPI_CPOL
|
SPI_CPHA
|
SPI_CS_HIGH
;
master
->
setup
=
tiny_spi_setup
;
master
->
setup
=
tiny_spi_setup
;
master
->
use_gpio_descriptors
=
true
;
hw
=
spi_master_get_devdata
(
master
);
hw
=
spi_master_get_devdata
(
master
);
platform_set_drvdata
(
pdev
,
hw
);
platform_set_drvdata
(
pdev
,
hw
);
...
@@ -259,7 +231,6 @@ static int tiny_spi_probe(struct platform_device *pdev)
...
@@ -259,7 +231,6 @@ static int tiny_spi_probe(struct platform_device *pdev)
/* setup the state for the bitbang driver */
/* setup the state for the bitbang driver */
hw
->
bitbang
.
master
=
master
;
hw
->
bitbang
.
master
=
master
;
hw
->
bitbang
.
setup_transfer
=
tiny_spi_setup_transfer
;
hw
->
bitbang
.
setup_transfer
=
tiny_spi_setup_transfer
;
hw
->
bitbang
.
chipselect
=
tiny_spi_chipselect
;
hw
->
bitbang
.
txrx_bufs
=
tiny_spi_txrx_bufs
;
hw
->
bitbang
.
txrx_bufs
=
tiny_spi_txrx_bufs
;
/* find and map our resources */
/* find and map our resources */
...
@@ -279,12 +250,6 @@ static int tiny_spi_probe(struct platform_device *pdev)
...
@@ -279,12 +250,6 @@ static int tiny_spi_probe(struct platform_device *pdev)
}
}
/* find platform data */
/* find platform data */
if
(
platp
)
{
if
(
platp
)
{
hw
->
gpio_cs_count
=
platp
->
gpio_cs_count
;
hw
->
gpio_cs
=
platp
->
gpio_cs
;
if
(
platp
->
gpio_cs_count
&&
!
platp
->
gpio_cs
)
{
err
=
-
EBUSY
;
goto
exit
;
}
hw
->
freq
=
platp
->
freq
;
hw
->
freq
=
platp
->
freq
;
hw
->
baudwidth
=
platp
->
baudwidth
;
hw
->
baudwidth
=
platp
->
baudwidth
;
}
else
{
}
else
{
...
@@ -292,13 +257,6 @@ static int tiny_spi_probe(struct platform_device *pdev)
...
@@ -292,13 +257,6 @@ static int tiny_spi_probe(struct platform_device *pdev)
if
(
err
)
if
(
err
)
goto
exit
;
goto
exit
;
}
}
for
(
i
=
0
;
i
<
hw
->
gpio_cs_count
;
i
++
)
{
err
=
gpio_request
(
hw
->
gpio_cs
[
i
],
dev_name
(
&
pdev
->
dev
));
if
(
err
)
goto
exit_gpio
;
gpio_direction_output
(
hw
->
gpio_cs
[
i
],
1
);
}
hw
->
bitbang
.
master
->
num_chipselect
=
max
(
1
,
hw
->
gpio_cs_count
);
/* register our spi controller */
/* register our spi controller */
err
=
spi_bitbang_start
(
&
hw
->
bitbang
);
err
=
spi_bitbang_start
(
&
hw
->
bitbang
);
...
@@ -308,9 +266,6 @@ static int tiny_spi_probe(struct platform_device *pdev)
...
@@ -308,9 +266,6 @@ static int tiny_spi_probe(struct platform_device *pdev)
return
0
;
return
0
;
exit_gpio:
while
(
i
--
>
0
)
gpio_free
(
hw
->
gpio_cs
[
i
]);
exit:
exit:
spi_master_put
(
master
);
spi_master_put
(
master
);
return
err
;
return
err
;
...
@@ -320,11 +275,8 @@ static int tiny_spi_remove(struct platform_device *pdev)
...
@@ -320,11 +275,8 @@ static int tiny_spi_remove(struct platform_device *pdev)
{
{
struct
tiny_spi
*
hw
=
platform_get_drvdata
(
pdev
);
struct
tiny_spi
*
hw
=
platform_get_drvdata
(
pdev
);
struct
spi_master
*
master
=
hw
->
bitbang
.
master
;
struct
spi_master
*
master
=
hw
->
bitbang
.
master
;
unsigned
int
i
;
spi_bitbang_stop
(
&
hw
->
bitbang
);
spi_bitbang_stop
(
&
hw
->
bitbang
);
for
(
i
=
0
;
i
<
hw
->
gpio_cs_count
;
i
++
)
gpio_free
(
hw
->
gpio_cs
[
i
]);
spi_master_put
(
master
);
spi_master_put
(
master
);
return
0
;
return
0
;
}
}
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-qcom-qspi.c
View file @
754a36a5
...
@@ -137,7 +137,7 @@ enum qspi_clocks {
...
@@ -137,7 +137,7 @@ enum qspi_clocks {
struct
qcom_qspi
{
struct
qcom_qspi
{
void
__iomem
*
base
;
void
__iomem
*
base
;
struct
device
*
dev
;
struct
device
*
dev
;
struct
clk_bulk_data
clks
[
QSPI_NUM_CLKS
]
;
struct
clk_bulk_data
*
clks
;
struct
qspi_xfer
xfer
;
struct
qspi_xfer
xfer
;
/* Lock to protect xfer and IRQ accessed registers */
/* Lock to protect xfer and IRQ accessed registers */
spinlock_t
lock
;
spinlock_t
lock
;
...
@@ -445,6 +445,13 @@ static int qcom_qspi_probe(struct platform_device *pdev)
...
@@ -445,6 +445,13 @@ static int qcom_qspi_probe(struct platform_device *pdev)
goto
exit_probe_master_put
;
goto
exit_probe_master_put
;
}
}
ctrl
->
clks
=
devm_kcalloc
(
dev
,
QSPI_NUM_CLKS
,
sizeof
(
*
ctrl
->
clks
),
GFP_KERNEL
);
if
(
!
ctrl
->
clks
)
{
ret
=
-
ENOMEM
;
goto
exit_probe_master_put
;
}
ctrl
->
clks
[
QSPI_CLK_CORE
].
id
=
"core"
;
ctrl
->
clks
[
QSPI_CLK_CORE
].
id
=
"core"
;
ctrl
->
clks
[
QSPI_CLK_IFACE
].
id
=
"iface"
;
ctrl
->
clks
[
QSPI_CLK_IFACE
].
id
=
"iface"
;
ret
=
devm_clk_bulk_get
(
dev
,
QSPI_NUM_CLKS
,
ctrl
->
clks
);
ret
=
devm_clk_bulk_get
(
dev
,
QSPI_NUM_CLKS
,
ctrl
->
clks
);
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-rspi.c
View file @
754a36a5
...
@@ -159,7 +159,7 @@
...
@@ -159,7 +159,7 @@
#define SPCMD_SPIMOD_DUAL SPCMD_SPIMOD0
#define SPCMD_SPIMOD_DUAL SPCMD_SPIMOD0
#define SPCMD_SPIMOD_QUAD SPCMD_SPIMOD1
#define SPCMD_SPIMOD_QUAD SPCMD_SPIMOD1
#define SPCMD_SPRW 0x0010
/* SPI Read/Write Access (Dual/Quad) */
#define SPCMD_SPRW 0x0010
/* SPI Read/Write Access (Dual/Quad) */
#define SPCMD_SSLA
_MASK 0x0030
/* SSL Assert Signal Setting (RSPI)
*/
#define SPCMD_SSLA
(i) ((i) << 4)
/* SSL Assert Signal Setting
*/
#define SPCMD_BRDV_MASK 0x000c
/* Bit Rate Division Setting */
#define SPCMD_BRDV_MASK 0x000c
/* Bit Rate Division Setting */
#define SPCMD_CPOL 0x0002
/* Clock Polarity Setting */
#define SPCMD_CPOL 0x0002
/* Clock Polarity Setting */
#define SPCMD_CPHA 0x0001
/* Clock Phase Setting */
#define SPCMD_CPHA 0x0001
/* Clock Phase Setting */
...
@@ -242,6 +242,7 @@ struct spi_ops {
...
@@ -242,6 +242,7 @@ struct spi_ops {
u16
mode_bits
;
u16
mode_bits
;
u16
flags
;
u16
flags
;
u16
fifo_size
;
u16
fifo_size
;
u8
num_hw_ss
;
};
};
/*
/*
...
@@ -426,8 +427,6 @@ static int qspi_set_receive_trigger(struct rspi_data *rspi, unsigned int len)
...
@@ -426,8 +427,6 @@ static int qspi_set_receive_trigger(struct rspi_data *rspi, unsigned int len)
return
n
;
return
n
;
}
}
#define set_config_register(spi, n) spi->ops->set_config_register(spi, n)
static
void
rspi_enable_irq
(
const
struct
rspi_data
*
rspi
,
u8
enable
)
static
void
rspi_enable_irq
(
const
struct
rspi_data
*
rspi
,
u8
enable
)
{
{
rspi_write8
(
rspi
,
rspi_read8
(
rspi
,
RSPI_SPCR
)
|
enable
,
RSPI_SPCR
);
rspi_write8
(
rspi
,
rspi_read8
(
rspi
,
RSPI_SPCR
)
|
enable
,
RSPI_SPCR
);
...
@@ -620,9 +619,8 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
...
@@ -620,9 +619,8 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
dmaengine_terminate_all
(
rspi
->
ctlr
->
dma_rx
);
dmaengine_terminate_all
(
rspi
->
ctlr
->
dma_rx
);
no_dma_rx:
no_dma_rx:
if
(
ret
==
-
EAGAIN
)
{
if
(
ret
==
-
EAGAIN
)
{
pr_warn_once
(
"%s %s: DMA not available, falling back to PIO
\n
"
,
dev_warn_once
(
&
rspi
->
ctlr
->
dev
,
dev_driver_string
(
&
rspi
->
ctlr
->
dev
),
"DMA not available, falling back to PIO
\n
"
);
dev_name
(
&
rspi
->
ctlr
->
dev
));
}
}
return
ret
;
return
ret
;
}
}
...
@@ -936,12 +934,16 @@ static int rspi_prepare_message(struct spi_controller *ctlr,
...
@@ -936,12 +934,16 @@ static int rspi_prepare_message(struct spi_controller *ctlr,
if
(
spi
->
mode
&
SPI_CPHA
)
if
(
spi
->
mode
&
SPI_CPHA
)
rspi
->
spcmd
|=
SPCMD_CPHA
;
rspi
->
spcmd
|=
SPCMD_CPHA
;
/* Configure slave signal to assert */
rspi
->
spcmd
|=
SPCMD_SSLA
(
spi
->
cs_gpiod
?
rspi
->
ctlr
->
unused_native_cs
:
spi
->
chip_select
);
/* CMOS output mode and MOSI signal from previous transfer */
/* CMOS output mode and MOSI signal from previous transfer */
rspi
->
sppcr
=
0
;
rspi
->
sppcr
=
0
;
if
(
spi
->
mode
&
SPI_LOOP
)
if
(
spi
->
mode
&
SPI_LOOP
)
rspi
->
sppcr
|=
SPPCR_SPLP
;
rspi
->
sppcr
|=
SPPCR_SPLP
;
set_config_register
(
rspi
,
8
);
rspi
->
ops
->
set_config_register
(
rspi
,
8
);
if
(
msg
->
spi
->
mode
&
if
(
msg
->
spi
->
mode
&
(
SPI_TX_DUAL
|
SPI_TX_QUAD
|
SPI_RX_DUAL
|
SPI_RX_QUAD
))
{
(
SPI_TX_DUAL
|
SPI_TX_QUAD
|
SPI_RX_DUAL
|
SPI_RX_QUAD
))
{
...
@@ -1123,6 +1125,7 @@ static const struct spi_ops rspi_ops = {
...
@@ -1123,6 +1125,7 @@ static const struct spi_ops rspi_ops = {
.
mode_bits
=
SPI_CPHA
|
SPI_CPOL
|
SPI_LOOP
,
.
mode_bits
=
SPI_CPHA
|
SPI_CPOL
|
SPI_LOOP
,
.
flags
=
SPI_CONTROLLER_MUST_TX
,
.
flags
=
SPI_CONTROLLER_MUST_TX
,
.
fifo_size
=
8
,
.
fifo_size
=
8
,
.
num_hw_ss
=
2
,
};
};
static
const
struct
spi_ops
rspi_rz_ops
=
{
static
const
struct
spi_ops
rspi_rz_ops
=
{
...
@@ -1131,6 +1134,7 @@ static const struct spi_ops rspi_rz_ops = {
...
@@ -1131,6 +1134,7 @@ static const struct spi_ops rspi_rz_ops = {
.
mode_bits
=
SPI_CPHA
|
SPI_CPOL
|
SPI_LOOP
,
.
mode_bits
=
SPI_CPHA
|
SPI_CPOL
|
SPI_LOOP
,
.
flags
=
SPI_CONTROLLER_MUST_RX
|
SPI_CONTROLLER_MUST_TX
,
.
flags
=
SPI_CONTROLLER_MUST_RX
|
SPI_CONTROLLER_MUST_TX
,
.
fifo_size
=
8
,
/* 8 for TX, 32 for RX */
.
fifo_size
=
8
,
/* 8 for TX, 32 for RX */
.
num_hw_ss
=
1
,
};
};
static
const
struct
spi_ops
qspi_ops
=
{
static
const
struct
spi_ops
qspi_ops
=
{
...
@@ -1141,6 +1145,7 @@ static const struct spi_ops qspi_ops = {
...
@@ -1141,6 +1145,7 @@ static const struct spi_ops qspi_ops = {
SPI_RX_DUAL
|
SPI_RX_QUAD
,
SPI_RX_DUAL
|
SPI_RX_QUAD
,
.
flags
=
SPI_CONTROLLER_MUST_RX
|
SPI_CONTROLLER_MUST_TX
,
.
flags
=
SPI_CONTROLLER_MUST_RX
|
SPI_CONTROLLER_MUST_TX
,
.
fifo_size
=
32
,
.
fifo_size
=
32
,
.
num_hw_ss
=
1
,
};
};
#ifdef CONFIG_OF
#ifdef CONFIG_OF
...
@@ -1256,6 +1261,8 @@ static int rspi_probe(struct platform_device *pdev)
...
@@ -1256,6 +1261,8 @@ static int rspi_probe(struct platform_device *pdev)
ctlr
->
mode_bits
=
ops
->
mode_bits
;
ctlr
->
mode_bits
=
ops
->
mode_bits
;
ctlr
->
flags
=
ops
->
flags
;
ctlr
->
flags
=
ops
->
flags
;
ctlr
->
dev
.
of_node
=
pdev
->
dev
.
of_node
;
ctlr
->
dev
.
of_node
=
pdev
->
dev
.
of_node
;
ctlr
->
use_gpio_descriptors
=
true
;
ctlr
->
max_native_cs
=
rspi
->
ops
->
num_hw_ss
;
ret
=
platform_get_irq_byname_optional
(
pdev
,
"rx"
);
ret
=
platform_get_irq_byname_optional
(
pdev
,
"rx"
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
...
@@ -1314,8 +1321,6 @@ static int rspi_probe(struct platform_device *pdev)
...
@@ -1314,8 +1321,6 @@ static int rspi_probe(struct platform_device *pdev)
static
const
struct
platform_device_id
spi_driver_ids
[]
=
{
static
const
struct
platform_device_id
spi_driver_ids
[]
=
{
{
"rspi"
,
(
kernel_ulong_t
)
&
rspi_ops
},
{
"rspi"
,
(
kernel_ulong_t
)
&
rspi_ops
},
{
"rspi-rz"
,
(
kernel_ulong_t
)
&
rspi_rz_ops
},
{
"qspi"
,
(
kernel_ulong_t
)
&
qspi_ops
},
{},
{},
};
};
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-sh-msiof.c
View file @
754a36a5
...
@@ -14,8 +14,6 @@
...
@@ -14,8 +14,6 @@
#include <linux/dma-mapping.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/dmaengine.h>
#include <linux/err.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/iopoll.h>
...
@@ -55,7 +53,6 @@ struct sh_msiof_spi_priv {
...
@@ -55,7 +53,6 @@ struct sh_msiof_spi_priv {
void
*
rx_dma_page
;
void
*
rx_dma_page
;
dma_addr_t
tx_dma_addr
;
dma_addr_t
tx_dma_addr
;
dma_addr_t
rx_dma_addr
;
dma_addr_t
rx_dma_addr
;
unsigned
short
unused_ss
;
bool
native_cs_inited
;
bool
native_cs_inited
;
bool
native_cs_high
;
bool
native_cs_high
;
bool
slave_aborted
;
bool
slave_aborted
;
...
@@ -63,140 +60,140 @@ struct sh_msiof_spi_priv {
...
@@ -63,140 +60,140 @@ struct sh_msiof_spi_priv {
#define MAX_SS 3
/* Maximum number of native chip selects */
#define MAX_SS 3
/* Maximum number of native chip selects */
#define TMDR1 0x00
/* Transmit Mode Register 1 */
#define
SI
TMDR1 0x00
/* Transmit Mode Register 1 */
#define TMDR2 0x04
/* Transmit Mode Register 2 */
#define
SI
TMDR2 0x04
/* Transmit Mode Register 2 */
#define TMDR3 0x08
/* Transmit Mode Register 3 */
#define
SI
TMDR3 0x08
/* Transmit Mode Register 3 */
#define RMDR1 0x10
/* Receive Mode Register 1 */
#define
SI
RMDR1 0x10
/* Receive Mode Register 1 */
#define RMDR2 0x14
/* Receive Mode Register 2 */
#define
SI
RMDR2 0x14
/* Receive Mode Register 2 */
#define RMDR3 0x18
/* Receive Mode Register 3 */
#define
SI
RMDR3 0x18
/* Receive Mode Register 3 */
#define TSCR 0x20
/* Transmit Clock Select Register */
#define
SI
TSCR 0x20
/* Transmit Clock Select Register */
#define RSCR 0x22
/* Receive Clock Select Register (SH, A1, APE6) */
#define
SI
RSCR 0x22
/* Receive Clock Select Register (SH, A1, APE6) */
#define CTR 0x28
/* Control Register */
#define
SI
CTR 0x28
/* Control Register */
#define FCTR 0x30
/* FIFO Control Register */
#define
SI
FCTR 0x30
/* FIFO Control Register */
#define STR 0x40
/* Status Register */
#define S
IS
TR 0x40
/* Status Register */
#define IER 0x44
/* Interrupt Enable Register */
#define
SI
IER 0x44
/* Interrupt Enable Register */
#define TDR1 0x48
/* Transmit Control Data Register 1 (SH, A1) */
#define
SI
TDR1 0x48
/* Transmit Control Data Register 1 (SH, A1) */
#define TDR2 0x4c
/* Transmit Control Data Register 2 (SH, A1) */
#define
SI
TDR2 0x4c
/* Transmit Control Data Register 2 (SH, A1) */
#define TFDR 0x50
/* Transmit FIFO Data Register */
#define
SI
TFDR 0x50
/* Transmit FIFO Data Register */
#define RDR1 0x58
/* Receive Control Data Register 1 (SH, A1) */
#define
SI
RDR1 0x58
/* Receive Control Data Register 1 (SH, A1) */
#define RDR2 0x5c
/* Receive Control Data Register 2 (SH, A1) */
#define
SI
RDR2 0x5c
/* Receive Control Data Register 2 (SH, A1) */
#define RFDR 0x60
/* Receive FIFO Data Register */
#define
SI
RFDR 0x60
/* Receive FIFO Data Register */
/*
TMDR1 and
RMDR1 */
/*
SITMDR1 and SI
RMDR1 */
#define
MDR1_TRMD BIT(31)
/* Transfer Mode (1 = Master mode) */
#define
SIMDR1_TRMD BIT(31)
/* Transfer Mode (1 = Master mode) */
#define
MDR1_SYNCMD_MASK GENMASK(29, 28)
/* SYNC Mode */
#define
SIMDR1_SYNCMD_MASK GENMASK(29, 28)
/* SYNC Mode */
#define
MDR1_SYNCMD_SPI (2 << 28)
/* Level mode/SPI */
#define
SIMDR1_SYNCMD_SPI (2 << 28)
/* Level mode/SPI */
#define
MDR1_SYNCMD_LR (3 << 28)
/* L/R mode */
#define
SIMDR1_SYNCMD_LR (3 << 28)
/* L/R mode */
#define
MDR1_SYNCAC_SHIFT 25
/* Sync Polarity (1 = Active-low) */
#define
SIMDR1_SYNCAC_SHIFT 25
/* Sync Polarity (1 = Active-low) */
#define
MDR1_BITLSB_SHIFT 24
/* MSB/LSB First (1 = LSB first) */
#define
SIMDR1_BITLSB_SHIFT 24
/* MSB/LSB First (1 = LSB first) */
#define
MDR1_DTDL_SHIFT 20
/* Data Pin Bit Delay for MSIOF_SYNC */
#define
SIMDR1_DTDL_SHIFT 20
/* Data Pin Bit Delay for MSIOF_SYNC */
#define
MDR1_SYNCDL_SHIFT 16
/* Frame Sync Signal Timing Delay */
#define
SIMDR1_SYNCDL_SHIFT 16
/* Frame Sync Signal Timing Delay */
#define
MDR1_FLD_MASK GENMASK(3, 2)
/* Frame Sync Signal Interval (0-3) */
#define
SIMDR1_FLD_MASK GENMASK(3, 2)
/* Frame Sync Signal Interval (0-3) */
#define
MDR1_FLD_SHIFT
2
#define
SIMDR1_FLD_SHIFT
2
#define
MDR1_XXSTP BIT(0)
/* Transmission/Reception Stop on FIFO */
#define
SIMDR1_XXSTP BIT(0)
/* Transmission/Reception Stop on FIFO */
/* TMDR1 */
/*
SI
TMDR1 */
#define
TMDR1_PCON BIT(30)
/* Transfer Signal Connection */
#define
SITMDR1_PCON BIT(30)
/* Transfer Signal Connection */
#define
TMDR1_SYNCCH_MASK GENMASK(27, 26)
/* Sync Signal Channel Select */
#define
SITMDR1_SYNCCH_MASK GENMASK(27, 26)
/* Sync Signal Channel Select */
#define
TMDR1_SYNCCH_SHIFT 26
/* 0=MSIOF_SYNC, 1=MSIOF_SS1, 2=MSIOF_SS2 */
#define
SITMDR1_SYNCCH_SHIFT 26
/* 0=MSIOF_SYNC, 1=MSIOF_SS1, 2=MSIOF_SS2 */
/*
TMDR2 and
RMDR2 */
/*
SITMDR2 and SI
RMDR2 */
#define MDR2_BITLEN1(i) (((i) - 1) << 24)
/* Data Size (8-32 bits) */
#define
SI
MDR2_BITLEN1(i) (((i) - 1) << 24)
/* Data Size (8-32 bits) */
#define MDR2_WDLEN1(i) (((i) - 1) << 16)
/* Word Count (1-64/256 (SH, A1))) */
#define
SI
MDR2_WDLEN1(i) (((i) - 1) << 16)
/* Word Count (1-64/256 (SH, A1))) */
#define
MDR2_GRPMASK1 BIT(0)
/* Group Output Mask 1 (SH, A1) */
#define
SIMDR2_GRPMASK1 BIT(0)
/* Group Output Mask 1 (SH, A1) */
/*
TSCR and
RSCR */
/*
SITSCR and SI
RSCR */
#define S
CR_BRPS_MASK GENMASK(12, 8)
/* Prescaler Setting (1-32) */
#define S
ISCR_BRPS_MASK GENMASK(12, 8)
/* Prescaler Setting (1-32) */
#define S
CR_BRPS(i)
(((i) - 1) << 8)
#define S
ISCR_BRPS(i)
(((i) - 1) << 8)
#define S
CR_BRDV_MASK GENMASK(2, 0)
/* Baud Rate Generator's Division Ratio */
#define S
ISCR_BRDV_MASK GENMASK(2, 0)
/* Baud Rate Generator's Division Ratio */
#define SCR_BRDV_DIV_2 0
#define S
IS
CR_BRDV_DIV_2 0
#define SCR_BRDV_DIV_4 1
#define S
IS
CR_BRDV_DIV_4 1
#define SCR_BRDV_DIV_8 2
#define S
IS
CR_BRDV_DIV_8 2
#define SCR_BRDV_DIV_16 3
#define S
IS
CR_BRDV_DIV_16 3
#define SCR_BRDV_DIV_32 4
#define S
IS
CR_BRDV_DIV_32 4
#define SCR_BRDV_DIV_1 7
#define S
IS
CR_BRDV_DIV_1 7
/* CTR */
/*
SI
CTR */
#define
CTR_TSCKIZ_MASK GENMASK(31, 30)
/* Transmit Clock I/O Polarity Select */
#define
SICTR_TSCKIZ_MASK GENMASK(31, 30)
/* Transmit Clock I/O Polarity Select */
#define
CTR_TSCKIZ_SCK BIT(31)
/* Disable SCK when TX disabled */
#define
SICTR_TSCKIZ_SCK BIT(31)
/* Disable SCK when TX disabled */
#define
CTR_TSCKIZ_POL_SHIFT 30
/* Transmit Clock Polarity */
#define
SICTR_TSCKIZ_POL_SHIFT 30
/* Transmit Clock Polarity */
#define CTR_RSCKIZ_MASK GENMASK(29, 28)
/* Receive Clock Polarity Select */
#define
SI
CTR_RSCKIZ_MASK GENMASK(29, 28)
/* Receive Clock Polarity Select */
#define
CTR_RSCKIZ_SCK BIT(29)
/* Must match CTR_TSCKIZ_SCK */
#define
SICTR_RSCKIZ_SCK BIT(29)
/* Must match CTR_TSCKIZ_SCK */
#define
CTR_RSCKIZ_POL_SHIFT 28
/* Receive Clock Polarity */
#define
SICTR_RSCKIZ_POL_SHIFT 28
/* Receive Clock Polarity */
#define
CTR_TEDG_SHIFT 27
/* Transmit Timing (1 = falling edge) */
#define
SICTR_TEDG_SHIFT 27
/* Transmit Timing (1 = falling edge) */
#define
CTR_REDG_SHIFT 26
/* Receive Timing (1 = falling edge) */
#define
SICTR_REDG_SHIFT 26
/* Receive Timing (1 = falling edge) */
#define
CTR_TXDIZ_MASK GENMASK(23, 22)
/* Pin Output When TX is Disabled */
#define
SICTR_TXDIZ_MASK GENMASK(23, 22)
/* Pin Output When TX is Disabled */
#define
CTR_TXDIZ_LOW (0 << 22)
/* 0 */
#define
SICTR_TXDIZ_LOW (0 << 22)
/* 0 */
#define
CTR_TXDIZ_HIGH (1 << 22)
/* 1 */
#define
SICTR_TXDIZ_HIGH (1 << 22)
/* 1 */
#define
CTR_TXDIZ_HIZ (2 << 22)
/* High-impedance */
#define
SICTR_TXDIZ_HIZ (2 << 22)
/* High-impedance */
#define
CTR_TSCKE BIT(15)
/* Transmit Serial Clock Output Enable */
#define
SICTR_TSCKE BIT(15)
/* Transmit Serial Clock Output Enable */
#define
CTR_TFSE BIT(14)
/* Transmit Frame Sync Signal Output Enable */
#define
SICTR_TFSE BIT(14)
/* Transmit Frame Sync Signal Output Enable */
#define
CTR_TXE BIT(9)
/* Transmit Enable */
#define
SICTR_TXE BIT(9)
/* Transmit Enable */
#define
CTR_RXE BIT(8)
/* Receive Enable */
#define
SICTR_RXE BIT(8)
/* Receive Enable */
#define
CTR_TXRST BIT(1)
/* Transmit Reset */
#define
SICTR_TXRST BIT(1)
/* Transmit Reset */
#define
CTR_RXRST BIT(0)
/* Receive Reset */
#define
SICTR_RXRST BIT(0)
/* Receive Reset */
/* FCTR */
/*
SI
FCTR */
#define
FCTR_TFWM_MASK GENMASK(31, 29)
/* Transmit FIFO Watermark */
#define
SIFCTR_TFWM_MASK GENMASK(31, 29)
/* Transmit FIFO Watermark */
#define
FCTR_TFWM_64 (0 << 29)
/* Transfer Request when 64 empty stages */
#define
SIFCTR_TFWM_64 (0 << 29)
/* Transfer Request when 64 empty stages */
#define
FCTR_TFWM_32 (1 << 29)
/* Transfer Request when 32 empty stages */
#define
SIFCTR_TFWM_32 (1 << 29)
/* Transfer Request when 32 empty stages */
#define
FCTR_TFWM_24 (2 << 29)
/* Transfer Request when 24 empty stages */
#define
SIFCTR_TFWM_24 (2 << 29)
/* Transfer Request when 24 empty stages */
#define
FCTR_TFWM_16 (3 << 29)
/* Transfer Request when 16 empty stages */
#define
SIFCTR_TFWM_16 (3 << 29)
/* Transfer Request when 16 empty stages */
#define
FCTR_TFWM_12 (4 << 29)
/* Transfer Request when 12 empty stages */
#define
SIFCTR_TFWM_12 (4 << 29)
/* Transfer Request when 12 empty stages */
#define
FCTR_TFWM_8 (5 << 29)
/* Transfer Request when 8 empty stages */
#define
SIFCTR_TFWM_8 (5 << 29)
/* Transfer Request when 8 empty stages */
#define
FCTR_TFWM_4 (6 << 29)
/* Transfer Request when 4 empty stages */
#define
SIFCTR_TFWM_4 (6 << 29)
/* Transfer Request when 4 empty stages */
#define
FCTR_TFWM_1 (7 << 29)
/* Transfer Request when 1 empty stage */
#define
SIFCTR_TFWM_1 (7 << 29)
/* Transfer Request when 1 empty stage */
#define FCTR_TFUA_MASK GENMASK(26, 20)
/* Transmit FIFO Usable Area */
#define
SI
FCTR_TFUA_MASK GENMASK(26, 20)
/* Transmit FIFO Usable Area */
#define FCTR_TFUA_SHIFT 20
#define
SI
FCTR_TFUA_SHIFT 20
#define
FCTR_TFUA(i) ((i) <<
FCTR_TFUA_SHIFT)
#define
SIFCTR_TFUA(i) ((i) << SI
FCTR_TFUA_SHIFT)
#define
FCTR_RFWM_MASK GENMASK(15, 13)
/* Receive FIFO Watermark */
#define
SIFCTR_RFWM_MASK GENMASK(15, 13)
/* Receive FIFO Watermark */
#define
FCTR_RFWM_1 (0 << 13)
/* Transfer Request when 1 valid stages */
#define
SIFCTR_RFWM_1 (0 << 13)
/* Transfer Request when 1 valid stages */
#define
FCTR_RFWM_4 (1 << 13)
/* Transfer Request when 4 valid stages */
#define
SIFCTR_RFWM_4 (1 << 13)
/* Transfer Request when 4 valid stages */
#define
FCTR_RFWM_8 (2 << 13)
/* Transfer Request when 8 valid stages */
#define
SIFCTR_RFWM_8 (2 << 13)
/* Transfer Request when 8 valid stages */
#define
FCTR_RFWM_16 (3 << 13)
/* Transfer Request when 16 valid stages */
#define
SIFCTR_RFWM_16 (3 << 13)
/* Transfer Request when 16 valid stages */
#define
FCTR_RFWM_32 (4 << 13)
/* Transfer Request when 32 valid stages */
#define
SIFCTR_RFWM_32 (4 << 13)
/* Transfer Request when 32 valid stages */
#define
FCTR_RFWM_64 (5 << 13)
/* Transfer Request when 64 valid stages */
#define
SIFCTR_RFWM_64 (5 << 13)
/* Transfer Request when 64 valid stages */
#define
FCTR_RFWM_128 (6 << 13)
/* Transfer Request when 128 valid stages */
#define
SIFCTR_RFWM_128 (6 << 13)
/* Transfer Request when 128 valid stages */
#define
FCTR_RFWM_256 (7 << 13)
/* Transfer Request when 256 valid stages */
#define
SIFCTR_RFWM_256 (7 << 13)
/* Transfer Request when 256 valid stages */
#define
FCTR_RFUA_MASK GENMASK(12, 4)
/* Receive FIFO Usable Area (0x40 = full) */
#define
SIFCTR_RFUA_MASK GENMASK(12, 4)
/* Receive FIFO Usable Area (0x40 = full) */
#define FCTR_RFUA_SHIFT 4
#define
SI
FCTR_RFUA_SHIFT 4
#define
FCTR_RFUA(i) ((i) <<
FCTR_RFUA_SHIFT)
#define
SIFCTR_RFUA(i) ((i) << SI
FCTR_RFUA_SHIFT)
/* STR */
/* S
IS
TR */
#define S
TR_TFEMP
BIT(29)
/* Transmit FIFO Empty */
#define S
ISTR_TFEMP
BIT(29)
/* Transmit FIFO Empty */
#define S
TR_TDREQ
BIT(28)
/* Transmit Data Transfer Request */
#define S
ISTR_TDREQ
BIT(28)
/* Transmit Data Transfer Request */
#define S
TR_TEOF
BIT(23)
/* Frame Transmission End */
#define S
ISTR_TEOF
BIT(23)
/* Frame Transmission End */
#define S
TR_TFSERR
BIT(21)
/* Transmit Frame Synchronization Error */
#define S
ISTR_TFSERR
BIT(21)
/* Transmit Frame Synchronization Error */
#define S
TR_TFOVF
BIT(20)
/* Transmit FIFO Overflow */
#define S
ISTR_TFOVF
BIT(20)
/* Transmit FIFO Overflow */
#define S
TR_TFUDF
BIT(19)
/* Transmit FIFO Underflow */
#define S
ISTR_TFUDF
BIT(19)
/* Transmit FIFO Underflow */
#define S
TR_RFFUL
BIT(13)
/* Receive FIFO Full */
#define S
ISTR_RFFUL
BIT(13)
/* Receive FIFO Full */
#define S
TR_RDREQ
BIT(12)
/* Receive Data Transfer Request */
#define S
ISTR_RDREQ
BIT(12)
/* Receive Data Transfer Request */
#define S
TR_REOF
BIT(7)
/* Frame Reception End */
#define S
ISTR_REOF
BIT(7)
/* Frame Reception End */
#define S
TR_RFSERR
BIT(5)
/* Receive Frame Synchronization Error */
#define S
ISTR_RFSERR
BIT(5)
/* Receive Frame Synchronization Error */
#define S
TR_RFUDF
BIT(4)
/* Receive FIFO Underflow */
#define S
ISTR_RFUDF
BIT(4)
/* Receive FIFO Underflow */
#define S
TR_RFOVF
BIT(3)
/* Receive FIFO Overflow */
#define S
ISTR_RFOVF
BIT(3)
/* Receive FIFO Overflow */
/* IER */
/*
SI
IER */
#define
IER_TDMAE
BIT(31)
/* Transmit Data DMA Transfer Req. Enable */
#define
SIIER_TDMAE
BIT(31)
/* Transmit Data DMA Transfer Req. Enable */
#define
IER_TFEMPE
BIT(29)
/* Transmit FIFO Empty Enable */
#define
SIIER_TFEMPE
BIT(29)
/* Transmit FIFO Empty Enable */
#define
IER_TDREQE
BIT(28)
/* Transmit Data Transfer Request Enable */
#define
SIIER_TDREQE
BIT(28)
/* Transmit Data Transfer Request Enable */
#define
IER_TEOFE
BIT(23)
/* Frame Transmission End Enable */
#define
SIIER_TEOFE
BIT(23)
/* Frame Transmission End Enable */
#define
IER_TFSERRE
BIT(21)
/* Transmit Frame Sync Error Enable */
#define
SIIER_TFSERRE
BIT(21)
/* Transmit Frame Sync Error Enable */
#define
IER_TFOVFE
BIT(20)
/* Transmit FIFO Overflow Enable */
#define
SIIER_TFOVFE
BIT(20)
/* Transmit FIFO Overflow Enable */
#define
IER_TFUDFE
BIT(19)
/* Transmit FIFO Underflow Enable */
#define
SIIER_TFUDFE
BIT(19)
/* Transmit FIFO Underflow Enable */
#define
IER_RDMAE
BIT(15)
/* Receive Data DMA Transfer Req. Enable */
#define
SIIER_RDMAE
BIT(15)
/* Receive Data DMA Transfer Req. Enable */
#define
IER_RFFULE
BIT(13)
/* Receive FIFO Full Enable */
#define
SIIER_RFFULE
BIT(13)
/* Receive FIFO Full Enable */
#define
IER_RDREQE
BIT(12)
/* Receive Data Transfer Request Enable */
#define
SIIER_RDREQE
BIT(12)
/* Receive Data Transfer Request Enable */
#define
IER_REOFE
BIT(7)
/* Frame Reception End Enable */
#define
SIIER_REOFE
BIT(7)
/* Frame Reception End Enable */
#define
IER_RFSERRE
BIT(5)
/* Receive Frame Sync Error Enable */
#define
SIIER_RFSERRE
BIT(5)
/* Receive Frame Sync Error Enable */
#define
IER_RFUDFE
BIT(4)
/* Receive FIFO Underflow Enable */
#define
SIIER_RFUDFE
BIT(4)
/* Receive FIFO Underflow Enable */
#define
IER_RFOVFE
BIT(3)
/* Receive FIFO Overflow Enable */
#define
SIIER_RFOVFE
BIT(3)
/* Receive FIFO Overflow Enable */
static
u32
sh_msiof_read
(
struct
sh_msiof_spi_priv
*
p
,
int
reg_offs
)
static
u32
sh_msiof_read
(
struct
sh_msiof_spi_priv
*
p
,
int
reg_offs
)
{
{
switch
(
reg_offs
)
{
switch
(
reg_offs
)
{
case
TSCR
:
case
SI
TSCR
:
case
RSCR
:
case
SI
RSCR
:
return
ioread16
(
p
->
mapbase
+
reg_offs
);
return
ioread16
(
p
->
mapbase
+
reg_offs
);
default:
default:
return
ioread32
(
p
->
mapbase
+
reg_offs
);
return
ioread32
(
p
->
mapbase
+
reg_offs
);
...
@@ -207,8 +204,8 @@ static void sh_msiof_write(struct sh_msiof_spi_priv *p, int reg_offs,
...
@@ -207,8 +204,8 @@ static void sh_msiof_write(struct sh_msiof_spi_priv *p, int reg_offs,
u32
value
)
u32
value
)
{
{
switch
(
reg_offs
)
{
switch
(
reg_offs
)
{
case
TSCR
:
case
SI
TSCR
:
case
RSCR
:
case
SI
RSCR
:
iowrite16
(
value
,
p
->
mapbase
+
reg_offs
);
iowrite16
(
value
,
p
->
mapbase
+
reg_offs
);
break
;
break
;
default:
default:
...
@@ -223,12 +220,12 @@ static int sh_msiof_modify_ctr_wait(struct sh_msiof_spi_priv *p,
...
@@ -223,12 +220,12 @@ static int sh_msiof_modify_ctr_wait(struct sh_msiof_spi_priv *p,
u32
mask
=
clr
|
set
;
u32
mask
=
clr
|
set
;
u32
data
;
u32
data
;
data
=
sh_msiof_read
(
p
,
CTR
);
data
=
sh_msiof_read
(
p
,
SI
CTR
);
data
&=
~
clr
;
data
&=
~
clr
;
data
|=
set
;
data
|=
set
;
sh_msiof_write
(
p
,
CTR
,
data
);
sh_msiof_write
(
p
,
SI
CTR
,
data
);
return
readl_poll_timeout_atomic
(
p
->
mapbase
+
CTR
,
data
,
return
readl_poll_timeout_atomic
(
p
->
mapbase
+
SI
CTR
,
data
,
(
data
&
mask
)
==
set
,
1
,
100
);
(
data
&
mask
)
==
set
,
1
,
100
);
}
}
...
@@ -237,7 +234,7 @@ static irqreturn_t sh_msiof_spi_irq(int irq, void *data)
...
@@ -237,7 +234,7 @@ static irqreturn_t sh_msiof_spi_irq(int irq, void *data)
struct
sh_msiof_spi_priv
*
p
=
data
;
struct
sh_msiof_spi_priv
*
p
=
data
;
/* just disable the interrupt and wake up */
/* just disable the interrupt and wake up */
sh_msiof_write
(
p
,
IER
,
0
);
sh_msiof_write
(
p
,
SI
IER
,
0
);
complete
(
&
p
->
done
);
complete
(
&
p
->
done
);
return
IRQ_HANDLED
;
return
IRQ_HANDLED
;
...
@@ -245,20 +242,20 @@ static irqreturn_t sh_msiof_spi_irq(int irq, void *data)
...
@@ -245,20 +242,20 @@ static irqreturn_t sh_msiof_spi_irq(int irq, void *data)
static
void
sh_msiof_spi_reset_regs
(
struct
sh_msiof_spi_priv
*
p
)
static
void
sh_msiof_spi_reset_regs
(
struct
sh_msiof_spi_priv
*
p
)
{
{
u32
mask
=
CTR_TXRST
|
CTR_RXRST
;
u32
mask
=
SICTR_TXRST
|
SI
CTR_RXRST
;
u32
data
;
u32
data
;
data
=
sh_msiof_read
(
p
,
CTR
);
data
=
sh_msiof_read
(
p
,
SI
CTR
);
data
|=
mask
;
data
|=
mask
;
sh_msiof_write
(
p
,
CTR
,
data
);
sh_msiof_write
(
p
,
SI
CTR
,
data
);
readl_poll_timeout_atomic
(
p
->
mapbase
+
CTR
,
data
,
!
(
data
&
mask
),
1
,
readl_poll_timeout_atomic
(
p
->
mapbase
+
SI
CTR
,
data
,
!
(
data
&
mask
),
1
,
100
);
100
);
}
}
static
const
u32
sh_msiof_spi_div_array
[]
=
{
static
const
u32
sh_msiof_spi_div_array
[]
=
{
S
CR_BRDV_DIV_1
,
SCR_BRDV_DIV_2
,
SCR_BRDV_DIV_4
,
S
ISCR_BRDV_DIV_1
,
SISCR_BRDV_DIV_2
,
SI
SCR_BRDV_DIV_4
,
S
CR_BRDV_DIV_8
,
SCR_BRDV_DIV_16
,
SCR_BRDV_DIV_32
,
S
ISCR_BRDV_DIV_8
,
SISCR_BRDV_DIV_16
,
SI
SCR_BRDV_DIV_32
,
};
};
static
void
sh_msiof_spi_set_clk_regs
(
struct
sh_msiof_spi_priv
*
p
,
static
void
sh_msiof_spi_set_clk_regs
(
struct
sh_msiof_spi_priv
*
p
,
...
@@ -276,7 +273,7 @@ static void sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p,
...
@@ -276,7 +273,7 @@ static void sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p,
div
=
DIV_ROUND_UP
(
parent_rate
,
spi_hz
);
div
=
DIV_ROUND_UP
(
parent_rate
,
spi_hz
);
if
(
div
<=
1024
)
{
if
(
div
<=
1024
)
{
/* SCR_BRDV_DIV_1 is valid only if BRPS is x 1/1 or x 1/2 */
/* S
IS
CR_BRDV_DIV_1 is valid only if BRPS is x 1/1 or x 1/2 */
if
(
!
div_pow
&&
div
<=
32
&&
div
>
2
)
if
(
!
div_pow
&&
div
<=
32
&&
div
>
2
)
div_pow
=
1
;
div_pow
=
1
;
...
@@ -295,10 +292,10 @@ static void sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p,
...
@@ -295,10 +292,10 @@ static void sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p,
brps
=
32
;
brps
=
32
;
}
}
scr
=
sh_msiof_spi_div_array
[
div_pow
]
|
SCR_BRPS
(
brps
);
scr
=
sh_msiof_spi_div_array
[
div_pow
]
|
S
IS
CR_BRPS
(
brps
);
sh_msiof_write
(
p
,
TSCR
,
scr
);
sh_msiof_write
(
p
,
SI
TSCR
,
scr
);
if
(
!
(
p
->
ctlr
->
flags
&
SPI_CONTROLLER_MUST_TX
))
if
(
!
(
p
->
ctlr
->
flags
&
SPI_CONTROLLER_MUST_TX
))
sh_msiof_write
(
p
,
RSCR
,
scr
);
sh_msiof_write
(
p
,
SI
RSCR
,
scr
);
}
}
static
u32
sh_msiof_get_delay_bit
(
u32
dtdl_or_syncdl
)
static
u32
sh_msiof_get_delay_bit
(
u32
dtdl_or_syncdl
)
...
@@ -337,8 +334,8 @@ static u32 sh_msiof_spi_get_dtdl_and_syncdl(struct sh_msiof_spi_priv *p)
...
@@ -337,8 +334,8 @@ static u32 sh_msiof_spi_get_dtdl_and_syncdl(struct sh_msiof_spi_priv *p)
return
0
;
return
0
;
}
}
val
=
sh_msiof_get_delay_bit
(
p
->
info
->
dtdl
)
<<
MDR1_DTDL_SHIFT
;
val
=
sh_msiof_get_delay_bit
(
p
->
info
->
dtdl
)
<<
SI
MDR1_DTDL_SHIFT
;
val
|=
sh_msiof_get_delay_bit
(
p
->
info
->
syncdl
)
<<
MDR1_SYNCDL_SHIFT
;
val
|=
sh_msiof_get_delay_bit
(
p
->
info
->
syncdl
)
<<
SI
MDR1_SYNCDL_SHIFT
;
return
val
;
return
val
;
}
}
...
@@ -357,54 +354,54 @@ static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p, u32 ss,
...
@@ -357,54 +354,54 @@ static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p, u32 ss,
* 1 0 11 11 0 0
* 1 0 11 11 0 0
* 1 1 11 11 1 1
* 1 1 11 11 1 1
*/
*/
tmp
=
MDR1_SYNCMD_SPI
|
1
<<
MDR1_FLD_SHIFT
|
MDR1_XXSTP
;
tmp
=
SIMDR1_SYNCMD_SPI
|
1
<<
SIMDR1_FLD_SHIFT
|
SI
MDR1_XXSTP
;
tmp
|=
!
cs_high
<<
MDR1_SYNCAC_SHIFT
;
tmp
|=
!
cs_high
<<
SI
MDR1_SYNCAC_SHIFT
;
tmp
|=
lsb_first
<<
MDR1_BITLSB_SHIFT
;
tmp
|=
lsb_first
<<
SI
MDR1_BITLSB_SHIFT
;
tmp
|=
sh_msiof_spi_get_dtdl_and_syncdl
(
p
);
tmp
|=
sh_msiof_spi_get_dtdl_and_syncdl
(
p
);
if
(
spi_controller_is_slave
(
p
->
ctlr
))
{
if
(
spi_controller_is_slave
(
p
->
ctlr
))
{
sh_msiof_write
(
p
,
TMDR1
,
tmp
|
TMDR1_PCON
);
sh_msiof_write
(
p
,
SITMDR1
,
tmp
|
SI
TMDR1_PCON
);
}
else
{
}
else
{
sh_msiof_write
(
p
,
TMDR1
,
sh_msiof_write
(
p
,
SI
TMDR1
,
tmp
|
MDR1_TRMD
|
TMDR1_PCON
|
tmp
|
SIMDR1_TRMD
|
SI
TMDR1_PCON
|
(
ss
<
MAX_SS
?
ss
:
0
)
<<
TMDR1_SYNCCH_SHIFT
);
(
ss
<
MAX_SS
?
ss
:
0
)
<<
SI
TMDR1_SYNCCH_SHIFT
);
}
}
if
(
p
->
ctlr
->
flags
&
SPI_CONTROLLER_MUST_TX
)
{
if
(
p
->
ctlr
->
flags
&
SPI_CONTROLLER_MUST_TX
)
{
/* These bits are reserved if RX needs TX */
/* These bits are reserved if RX needs TX */
tmp
&=
~
0x0000ffff
;
tmp
&=
~
0x0000ffff
;
}
}
sh_msiof_write
(
p
,
RMDR1
,
tmp
);
sh_msiof_write
(
p
,
SI
RMDR1
,
tmp
);
tmp
=
0
;
tmp
=
0
;
tmp
|=
CTR_TSCKIZ_SCK
|
cpol
<<
CTR_TSCKIZ_POL_SHIFT
;
tmp
|=
SICTR_TSCKIZ_SCK
|
cpol
<<
SI
CTR_TSCKIZ_POL_SHIFT
;
tmp
|=
CTR_RSCKIZ_SCK
|
cpol
<<
CTR_RSCKIZ_POL_SHIFT
;
tmp
|=
SICTR_RSCKIZ_SCK
|
cpol
<<
SI
CTR_RSCKIZ_POL_SHIFT
;
edge
=
cpol
^
!
cpha
;
edge
=
cpol
^
!
cpha
;
tmp
|=
edge
<<
CTR_TEDG_SHIFT
;
tmp
|=
edge
<<
SI
CTR_TEDG_SHIFT
;
tmp
|=
edge
<<
CTR_REDG_SHIFT
;
tmp
|=
edge
<<
SI
CTR_REDG_SHIFT
;
tmp
|=
tx_hi_z
?
CTR_TXDIZ_HIZ
:
CTR_TXDIZ_LOW
;
tmp
|=
tx_hi_z
?
SICTR_TXDIZ_HIZ
:
SI
CTR_TXDIZ_LOW
;
sh_msiof_write
(
p
,
CTR
,
tmp
);
sh_msiof_write
(
p
,
SI
CTR
,
tmp
);
}
}
static
void
sh_msiof_spi_set_mode_regs
(
struct
sh_msiof_spi_priv
*
p
,
static
void
sh_msiof_spi_set_mode_regs
(
struct
sh_msiof_spi_priv
*
p
,
const
void
*
tx_buf
,
void
*
rx_buf
,
const
void
*
tx_buf
,
void
*
rx_buf
,
u32
bits
,
u32
words
)
u32
bits
,
u32
words
)
{
{
u32
dr2
=
MDR2_BITLEN1
(
bits
)
|
MDR2_WDLEN1
(
words
);
u32
dr2
=
SIMDR2_BITLEN1
(
bits
)
|
SI
MDR2_WDLEN1
(
words
);
if
(
tx_buf
||
(
p
->
ctlr
->
flags
&
SPI_CONTROLLER_MUST_TX
))
if
(
tx_buf
||
(
p
->
ctlr
->
flags
&
SPI_CONTROLLER_MUST_TX
))
sh_msiof_write
(
p
,
TMDR2
,
dr2
);
sh_msiof_write
(
p
,
SI
TMDR2
,
dr2
);
else
else
sh_msiof_write
(
p
,
TMDR2
,
dr2
|
MDR2_GRPMASK1
);
sh_msiof_write
(
p
,
SITMDR2
,
dr2
|
SI
MDR2_GRPMASK1
);
if
(
rx_buf
)
if
(
rx_buf
)
sh_msiof_write
(
p
,
RMDR2
,
dr2
);
sh_msiof_write
(
p
,
SI
RMDR2
,
dr2
);
}
}
static
void
sh_msiof_reset_str
(
struct
sh_msiof_spi_priv
*
p
)
static
void
sh_msiof_reset_str
(
struct
sh_msiof_spi_priv
*
p
)
{
{
sh_msiof_write
(
p
,
STR
,
sh_msiof_write
(
p
,
S
IS
TR
,
sh_msiof_read
(
p
,
S
TR
)
&
~
(
STR_TDREQ
|
STR_RDREQ
));
sh_msiof_read
(
p
,
S
ISTR
)
&
~
(
SISTR_TDREQ
|
SI
STR_RDREQ
));
}
}
static
void
sh_msiof_spi_write_fifo_8
(
struct
sh_msiof_spi_priv
*
p
,
static
void
sh_msiof_spi_write_fifo_8
(
struct
sh_msiof_spi_priv
*
p
,
...
@@ -414,7 +411,7 @@ static void sh_msiof_spi_write_fifo_8(struct sh_msiof_spi_priv *p,
...
@@ -414,7 +411,7 @@ static void sh_msiof_spi_write_fifo_8(struct sh_msiof_spi_priv *p,
int
k
;
int
k
;
for
(
k
=
0
;
k
<
words
;
k
++
)
for
(
k
=
0
;
k
<
words
;
k
++
)
sh_msiof_write
(
p
,
TFDR
,
buf_8
[
k
]
<<
fs
);
sh_msiof_write
(
p
,
SI
TFDR
,
buf_8
[
k
]
<<
fs
);
}
}
static
void
sh_msiof_spi_write_fifo_16
(
struct
sh_msiof_spi_priv
*
p
,
static
void
sh_msiof_spi_write_fifo_16
(
struct
sh_msiof_spi_priv
*
p
,
...
@@ -424,7 +421,7 @@ static void sh_msiof_spi_write_fifo_16(struct sh_msiof_spi_priv *p,
...
@@ -424,7 +421,7 @@ static void sh_msiof_spi_write_fifo_16(struct sh_msiof_spi_priv *p,
int
k
;
int
k
;
for
(
k
=
0
;
k
<
words
;
k
++
)
for
(
k
=
0
;
k
<
words
;
k
++
)
sh_msiof_write
(
p
,
TFDR
,
buf_16
[
k
]
<<
fs
);
sh_msiof_write
(
p
,
SI
TFDR
,
buf_16
[
k
]
<<
fs
);
}
}
static
void
sh_msiof_spi_write_fifo_16u
(
struct
sh_msiof_spi_priv
*
p
,
static
void
sh_msiof_spi_write_fifo_16u
(
struct
sh_msiof_spi_priv
*
p
,
...
@@ -434,7 +431,7 @@ static void sh_msiof_spi_write_fifo_16u(struct sh_msiof_spi_priv *p,
...
@@ -434,7 +431,7 @@ static void sh_msiof_spi_write_fifo_16u(struct sh_msiof_spi_priv *p,
int
k
;
int
k
;
for
(
k
=
0
;
k
<
words
;
k
++
)
for
(
k
=
0
;
k
<
words
;
k
++
)
sh_msiof_write
(
p
,
TFDR
,
get_unaligned
(
&
buf_16
[
k
])
<<
fs
);
sh_msiof_write
(
p
,
SI
TFDR
,
get_unaligned
(
&
buf_16
[
k
])
<<
fs
);
}
}
static
void
sh_msiof_spi_write_fifo_32
(
struct
sh_msiof_spi_priv
*
p
,
static
void
sh_msiof_spi_write_fifo_32
(
struct
sh_msiof_spi_priv
*
p
,
...
@@ -444,7 +441,7 @@ static void sh_msiof_spi_write_fifo_32(struct sh_msiof_spi_priv *p,
...
@@ -444,7 +441,7 @@ static void sh_msiof_spi_write_fifo_32(struct sh_msiof_spi_priv *p,
int
k
;
int
k
;
for
(
k
=
0
;
k
<
words
;
k
++
)
for
(
k
=
0
;
k
<
words
;
k
++
)
sh_msiof_write
(
p
,
TFDR
,
buf_32
[
k
]
<<
fs
);
sh_msiof_write
(
p
,
SI
TFDR
,
buf_32
[
k
]
<<
fs
);
}
}
static
void
sh_msiof_spi_write_fifo_32u
(
struct
sh_msiof_spi_priv
*
p
,
static
void
sh_msiof_spi_write_fifo_32u
(
struct
sh_msiof_spi_priv
*
p
,
...
@@ -454,7 +451,7 @@ static void sh_msiof_spi_write_fifo_32u(struct sh_msiof_spi_priv *p,
...
@@ -454,7 +451,7 @@ static void sh_msiof_spi_write_fifo_32u(struct sh_msiof_spi_priv *p,
int
k
;
int
k
;
for
(
k
=
0
;
k
<
words
;
k
++
)
for
(
k
=
0
;
k
<
words
;
k
++
)
sh_msiof_write
(
p
,
TFDR
,
get_unaligned
(
&
buf_32
[
k
])
<<
fs
);
sh_msiof_write
(
p
,
SI
TFDR
,
get_unaligned
(
&
buf_32
[
k
])
<<
fs
);
}
}
static
void
sh_msiof_spi_write_fifo_s32
(
struct
sh_msiof_spi_priv
*
p
,
static
void
sh_msiof_spi_write_fifo_s32
(
struct
sh_msiof_spi_priv
*
p
,
...
@@ -464,7 +461,7 @@ static void sh_msiof_spi_write_fifo_s32(struct sh_msiof_spi_priv *p,
...
@@ -464,7 +461,7 @@ static void sh_msiof_spi_write_fifo_s32(struct sh_msiof_spi_priv *p,
int
k
;
int
k
;
for
(
k
=
0
;
k
<
words
;
k
++
)
for
(
k
=
0
;
k
<
words
;
k
++
)
sh_msiof_write
(
p
,
TFDR
,
swab32
(
buf_32
[
k
]
<<
fs
));
sh_msiof_write
(
p
,
SI
TFDR
,
swab32
(
buf_32
[
k
]
<<
fs
));
}
}
static
void
sh_msiof_spi_write_fifo_s32u
(
struct
sh_msiof_spi_priv
*
p
,
static
void
sh_msiof_spi_write_fifo_s32u
(
struct
sh_msiof_spi_priv
*
p
,
...
@@ -474,7 +471,7 @@ static void sh_msiof_spi_write_fifo_s32u(struct sh_msiof_spi_priv *p,
...
@@ -474,7 +471,7 @@ static void sh_msiof_spi_write_fifo_s32u(struct sh_msiof_spi_priv *p,
int
k
;
int
k
;
for
(
k
=
0
;
k
<
words
;
k
++
)
for
(
k
=
0
;
k
<
words
;
k
++
)
sh_msiof_write
(
p
,
TFDR
,
swab32
(
get_unaligned
(
&
buf_32
[
k
])
<<
fs
));
sh_msiof_write
(
p
,
SI
TFDR
,
swab32
(
get_unaligned
(
&
buf_32
[
k
])
<<
fs
));
}
}
static
void
sh_msiof_spi_read_fifo_8
(
struct
sh_msiof_spi_priv
*
p
,
static
void
sh_msiof_spi_read_fifo_8
(
struct
sh_msiof_spi_priv
*
p
,
...
@@ -484,7 +481,7 @@ static void sh_msiof_spi_read_fifo_8(struct sh_msiof_spi_priv *p,
...
@@ -484,7 +481,7 @@ static void sh_msiof_spi_read_fifo_8(struct sh_msiof_spi_priv *p,
int
k
;
int
k
;
for
(
k
=
0
;
k
<
words
;
k
++
)
for
(
k
=
0
;
k
<
words
;
k
++
)
buf_8
[
k
]
=
sh_msiof_read
(
p
,
RFDR
)
>>
fs
;
buf_8
[
k
]
=
sh_msiof_read
(
p
,
SI
RFDR
)
>>
fs
;
}
}
static
void
sh_msiof_spi_read_fifo_16
(
struct
sh_msiof_spi_priv
*
p
,
static
void
sh_msiof_spi_read_fifo_16
(
struct
sh_msiof_spi_priv
*
p
,
...
@@ -494,7 +491,7 @@ static void sh_msiof_spi_read_fifo_16(struct sh_msiof_spi_priv *p,
...
@@ -494,7 +491,7 @@ static void sh_msiof_spi_read_fifo_16(struct sh_msiof_spi_priv *p,
int
k
;
int
k
;
for
(
k
=
0
;
k
<
words
;
k
++
)
for
(
k
=
0
;
k
<
words
;
k
++
)
buf_16
[
k
]
=
sh_msiof_read
(
p
,
RFDR
)
>>
fs
;
buf_16
[
k
]
=
sh_msiof_read
(
p
,
SI
RFDR
)
>>
fs
;
}
}
static
void
sh_msiof_spi_read_fifo_16u
(
struct
sh_msiof_spi_priv
*
p
,
static
void
sh_msiof_spi_read_fifo_16u
(
struct
sh_msiof_spi_priv
*
p
,
...
@@ -504,7 +501,7 @@ static void sh_msiof_spi_read_fifo_16u(struct sh_msiof_spi_priv *p,
...
@@ -504,7 +501,7 @@ static void sh_msiof_spi_read_fifo_16u(struct sh_msiof_spi_priv *p,
int
k
;
int
k
;
for
(
k
=
0
;
k
<
words
;
k
++
)
for
(
k
=
0
;
k
<
words
;
k
++
)
put_unaligned
(
sh_msiof_read
(
p
,
RFDR
)
>>
fs
,
&
buf_16
[
k
]);
put_unaligned
(
sh_msiof_read
(
p
,
SI
RFDR
)
>>
fs
,
&
buf_16
[
k
]);
}
}
static
void
sh_msiof_spi_read_fifo_32
(
struct
sh_msiof_spi_priv
*
p
,
static
void
sh_msiof_spi_read_fifo_32
(
struct
sh_msiof_spi_priv
*
p
,
...
@@ -514,7 +511,7 @@ static void sh_msiof_spi_read_fifo_32(struct sh_msiof_spi_priv *p,
...
@@ -514,7 +511,7 @@ static void sh_msiof_spi_read_fifo_32(struct sh_msiof_spi_priv *p,
int
k
;
int
k
;
for
(
k
=
0
;
k
<
words
;
k
++
)
for
(
k
=
0
;
k
<
words
;
k
++
)
buf_32
[
k
]
=
sh_msiof_read
(
p
,
RFDR
)
>>
fs
;
buf_32
[
k
]
=
sh_msiof_read
(
p
,
SI
RFDR
)
>>
fs
;
}
}
static
void
sh_msiof_spi_read_fifo_32u
(
struct
sh_msiof_spi_priv
*
p
,
static
void
sh_msiof_spi_read_fifo_32u
(
struct
sh_msiof_spi_priv
*
p
,
...
@@ -524,7 +521,7 @@ static void sh_msiof_spi_read_fifo_32u(struct sh_msiof_spi_priv *p,
...
@@ -524,7 +521,7 @@ static void sh_msiof_spi_read_fifo_32u(struct sh_msiof_spi_priv *p,
int
k
;
int
k
;
for
(
k
=
0
;
k
<
words
;
k
++
)
for
(
k
=
0
;
k
<
words
;
k
++
)
put_unaligned
(
sh_msiof_read
(
p
,
RFDR
)
>>
fs
,
&
buf_32
[
k
]);
put_unaligned
(
sh_msiof_read
(
p
,
SI
RFDR
)
>>
fs
,
&
buf_32
[
k
]);
}
}
static
void
sh_msiof_spi_read_fifo_s32
(
struct
sh_msiof_spi_priv
*
p
,
static
void
sh_msiof_spi_read_fifo_s32
(
struct
sh_msiof_spi_priv
*
p
,
...
@@ -534,7 +531,7 @@ static void sh_msiof_spi_read_fifo_s32(struct sh_msiof_spi_priv *p,
...
@@ -534,7 +531,7 @@ static void sh_msiof_spi_read_fifo_s32(struct sh_msiof_spi_priv *p,
int
k
;
int
k
;
for
(
k
=
0
;
k
<
words
;
k
++
)
for
(
k
=
0
;
k
<
words
;
k
++
)
buf_32
[
k
]
=
swab32
(
sh_msiof_read
(
p
,
RFDR
)
>>
fs
);
buf_32
[
k
]
=
swab32
(
sh_msiof_read
(
p
,
SI
RFDR
)
>>
fs
);
}
}
static
void
sh_msiof_spi_read_fifo_s32u
(
struct
sh_msiof_spi_priv
*
p
,
static
void
sh_msiof_spi_read_fifo_s32u
(
struct
sh_msiof_spi_priv
*
p
,
...
@@ -544,7 +541,7 @@ static void sh_msiof_spi_read_fifo_s32u(struct sh_msiof_spi_priv *p,
...
@@ -544,7 +541,7 @@ static void sh_msiof_spi_read_fifo_s32u(struct sh_msiof_spi_priv *p,
int
k
;
int
k
;
for
(
k
=
0
;
k
<
words
;
k
++
)
for
(
k
=
0
;
k
<
words
;
k
++
)
put_unaligned
(
swab32
(
sh_msiof_read
(
p
,
RFDR
)
>>
fs
),
&
buf_32
[
k
]);
put_unaligned
(
swab32
(
sh_msiof_read
(
p
,
SI
RFDR
)
>>
fs
),
&
buf_32
[
k
]);
}
}
static
int
sh_msiof_spi_setup
(
struct
spi_device
*
spi
)
static
int
sh_msiof_spi_setup
(
struct
spi_device
*
spi
)
...
@@ -561,17 +558,17 @@ static int sh_msiof_spi_setup(struct spi_device *spi)
...
@@ -561,17 +558,17 @@ static int sh_msiof_spi_setup(struct spi_device *spi)
return
0
;
return
0
;
/* Configure native chip select mode/polarity early */
/* Configure native chip select mode/polarity early */
clr
=
MDR1_SYNCMD_MASK
;
clr
=
SI
MDR1_SYNCMD_MASK
;
set
=
MDR1_SYNCMD_SPI
;
set
=
SI
MDR1_SYNCMD_SPI
;
if
(
spi
->
mode
&
SPI_CS_HIGH
)
if
(
spi
->
mode
&
SPI_CS_HIGH
)
clr
|=
BIT
(
MDR1_SYNCAC_SHIFT
);
clr
|=
BIT
(
SI
MDR1_SYNCAC_SHIFT
);
else
else
set
|=
BIT
(
MDR1_SYNCAC_SHIFT
);
set
|=
BIT
(
SI
MDR1_SYNCAC_SHIFT
);
pm_runtime_get_sync
(
&
p
->
pdev
->
dev
);
pm_runtime_get_sync
(
&
p
->
pdev
->
dev
);
tmp
=
sh_msiof_read
(
p
,
TMDR1
)
&
~
clr
;
tmp
=
sh_msiof_read
(
p
,
SI
TMDR1
)
&
~
clr
;
sh_msiof_write
(
p
,
TMDR1
,
tmp
|
set
|
MDR1_TRMD
|
TMDR1_PCON
);
sh_msiof_write
(
p
,
SITMDR1
,
tmp
|
set
|
SIMDR1_TRMD
|
SI
TMDR1_PCON
);
tmp
=
sh_msiof_read
(
p
,
RMDR1
)
&
~
clr
;
tmp
=
sh_msiof_read
(
p
,
SI
RMDR1
)
&
~
clr
;
sh_msiof_write
(
p
,
RMDR1
,
tmp
|
set
);
sh_msiof_write
(
p
,
SI
RMDR1
,
tmp
|
set
);
pm_runtime_put
(
&
p
->
pdev
->
dev
);
pm_runtime_put
(
&
p
->
pdev
->
dev
);
p
->
native_cs_high
=
spi
->
mode
&
SPI_CS_HIGH
;
p
->
native_cs_high
=
spi
->
mode
&
SPI_CS_HIGH
;
p
->
native_cs_inited
=
true
;
p
->
native_cs_inited
=
true
;
...
@@ -587,7 +584,7 @@ static int sh_msiof_prepare_message(struct spi_controller *ctlr,
...
@@ -587,7 +584,7 @@ static int sh_msiof_prepare_message(struct spi_controller *ctlr,
/* Configure pins before asserting CS */
/* Configure pins before asserting CS */
if
(
spi
->
cs_gpiod
)
{
if
(
spi
->
cs_gpiod
)
{
ss
=
p
->
unused_s
s
;
ss
=
ctlr
->
unused_native_c
s
;
cs_high
=
p
->
native_cs_high
;
cs_high
=
p
->
native_cs_high
;
}
else
{
}
else
{
ss
=
spi
->
chip_select
;
ss
=
spi
->
chip_select
;
...
@@ -607,15 +604,15 @@ static int sh_msiof_spi_start(struct sh_msiof_spi_priv *p, void *rx_buf)
...
@@ -607,15 +604,15 @@ static int sh_msiof_spi_start(struct sh_msiof_spi_priv *p, void *rx_buf)
/* setup clock and rx/tx signals */
/* setup clock and rx/tx signals */
if
(
!
slave
)
if
(
!
slave
)
ret
=
sh_msiof_modify_ctr_wait
(
p
,
0
,
CTR_TSCKE
);
ret
=
sh_msiof_modify_ctr_wait
(
p
,
0
,
SI
CTR_TSCKE
);
if
(
rx_buf
&&
!
ret
)
if
(
rx_buf
&&
!
ret
)
ret
=
sh_msiof_modify_ctr_wait
(
p
,
0
,
CTR_RXE
);
ret
=
sh_msiof_modify_ctr_wait
(
p
,
0
,
SI
CTR_RXE
);
if
(
!
ret
)
if
(
!
ret
)
ret
=
sh_msiof_modify_ctr_wait
(
p
,
0
,
CTR_TXE
);
ret
=
sh_msiof_modify_ctr_wait
(
p
,
0
,
SI
CTR_TXE
);
/* start by setting frame bit */
/* start by setting frame bit */
if
(
!
ret
&&
!
slave
)
if
(
!
ret
&&
!
slave
)
ret
=
sh_msiof_modify_ctr_wait
(
p
,
0
,
CTR_TFSE
);
ret
=
sh_msiof_modify_ctr_wait
(
p
,
0
,
SI
CTR_TFSE
);
return
ret
;
return
ret
;
}
}
...
@@ -627,13 +624,13 @@ static int sh_msiof_spi_stop(struct sh_msiof_spi_priv *p, void *rx_buf)
...
@@ -627,13 +624,13 @@ static int sh_msiof_spi_stop(struct sh_msiof_spi_priv *p, void *rx_buf)
/* shut down frame, rx/tx and clock signals */
/* shut down frame, rx/tx and clock signals */
if
(
!
slave
)
if
(
!
slave
)
ret
=
sh_msiof_modify_ctr_wait
(
p
,
CTR_TFSE
,
0
);
ret
=
sh_msiof_modify_ctr_wait
(
p
,
SI
CTR_TFSE
,
0
);
if
(
!
ret
)
if
(
!
ret
)
ret
=
sh_msiof_modify_ctr_wait
(
p
,
CTR_TXE
,
0
);
ret
=
sh_msiof_modify_ctr_wait
(
p
,
SI
CTR_TXE
,
0
);
if
(
rx_buf
&&
!
ret
)
if
(
rx_buf
&&
!
ret
)
ret
=
sh_msiof_modify_ctr_wait
(
p
,
CTR_RXE
,
0
);
ret
=
sh_msiof_modify_ctr_wait
(
p
,
SI
CTR_RXE
,
0
);
if
(
!
ret
&&
!
slave
)
if
(
!
ret
&&
!
slave
)
ret
=
sh_msiof_modify_ctr_wait
(
p
,
CTR_TSCKE
,
0
);
ret
=
sh_msiof_modify_ctr_wait
(
p
,
SI
CTR_TSCKE
,
0
);
return
ret
;
return
ret
;
}
}
...
@@ -688,11 +685,11 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
...
@@ -688,11 +685,11 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
fifo_shift
=
32
-
bits
;
fifo_shift
=
32
-
bits
;
/* default FIFO watermarks for PIO */
/* default FIFO watermarks for PIO */
sh_msiof_write
(
p
,
FCTR
,
0
);
sh_msiof_write
(
p
,
SI
FCTR
,
0
);
/* setup msiof transfer mode registers */
/* setup msiof transfer mode registers */
sh_msiof_spi_set_mode_regs
(
p
,
tx_buf
,
rx_buf
,
bits
,
words
);
sh_msiof_spi_set_mode_regs
(
p
,
tx_buf
,
rx_buf
,
bits
,
words
);
sh_msiof_write
(
p
,
IER
,
IER_TEOFE
|
IER_REOFE
);
sh_msiof_write
(
p
,
SIIER
,
SIIER_TEOFE
|
SI
IER_REOFE
);
/* write tx fifo */
/* write tx fifo */
if
(
tx_buf
)
if
(
tx_buf
)
...
@@ -731,7 +728,7 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
...
@@ -731,7 +728,7 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
sh_msiof_reset_str
(
p
);
sh_msiof_reset_str
(
p
);
sh_msiof_spi_stop
(
p
,
rx_buf
);
sh_msiof_spi_stop
(
p
,
rx_buf
);
stop_ier:
stop_ier:
sh_msiof_write
(
p
,
IER
,
0
);
sh_msiof_write
(
p
,
SI
IER
,
0
);
return
ret
;
return
ret
;
}
}
...
@@ -750,7 +747,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
...
@@ -750,7 +747,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
/* First prepare and submit the DMA request(s), as this may fail */
/* First prepare and submit the DMA request(s), as this may fail */
if
(
rx
)
{
if
(
rx
)
{
ier_bits
|=
IER_RDREQE
|
IER_RDMAE
;
ier_bits
|=
SIIER_RDREQE
|
SI
IER_RDMAE
;
desc_rx
=
dmaengine_prep_slave_single
(
p
->
ctlr
->
dma_rx
,
desc_rx
=
dmaengine_prep_slave_single
(
p
->
ctlr
->
dma_rx
,
p
->
rx_dma_addr
,
len
,
DMA_DEV_TO_MEM
,
p
->
rx_dma_addr
,
len
,
DMA_DEV_TO_MEM
,
DMA_PREP_INTERRUPT
|
DMA_CTRL_ACK
);
DMA_PREP_INTERRUPT
|
DMA_CTRL_ACK
);
...
@@ -765,7 +762,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
...
@@ -765,7 +762,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
}
}
if
(
tx
)
{
if
(
tx
)
{
ier_bits
|=
IER_TDREQE
|
IER_TDMAE
;
ier_bits
|=
SIIER_TDREQE
|
SI
IER_TDMAE
;
dma_sync_single_for_device
(
p
->
ctlr
->
dma_tx
->
device
->
dev
,
dma_sync_single_for_device
(
p
->
ctlr
->
dma_tx
->
device
->
dev
,
p
->
tx_dma_addr
,
len
,
DMA_TO_DEVICE
);
p
->
tx_dma_addr
,
len
,
DMA_TO_DEVICE
);
desc_tx
=
dmaengine_prep_slave_single
(
p
->
ctlr
->
dma_tx
,
desc_tx
=
dmaengine_prep_slave_single
(
p
->
ctlr
->
dma_tx
,
...
@@ -786,12 +783,12 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
...
@@ -786,12 +783,12 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
}
}
/* 1 stage FIFO watermarks for DMA */
/* 1 stage FIFO watermarks for DMA */
sh_msiof_write
(
p
,
FCTR
,
FCTR_TFWM_1
|
FCTR_RFWM_1
);
sh_msiof_write
(
p
,
SIFCTR
,
SIFCTR_TFWM_1
|
SI
FCTR_RFWM_1
);
/* setup msiof transfer mode registers (32-bit words) */
/* setup msiof transfer mode registers (32-bit words) */
sh_msiof_spi_set_mode_regs
(
p
,
tx
,
rx
,
32
,
len
/
4
);
sh_msiof_spi_set_mode_regs
(
p
,
tx
,
rx
,
32
,
len
/
4
);
sh_msiof_write
(
p
,
IER
,
ier_bits
);
sh_msiof_write
(
p
,
SI
IER
,
ier_bits
);
reinit_completion
(
&
p
->
done
);
reinit_completion
(
&
p
->
done
);
if
(
tx
)
if
(
tx
)
...
@@ -823,10 +820,10 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
...
@@ -823,10 +820,10 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
if
(
ret
)
if
(
ret
)
goto
stop_reset
;
goto
stop_reset
;
sh_msiof_write
(
p
,
IER
,
0
);
sh_msiof_write
(
p
,
SI
IER
,
0
);
}
else
{
}
else
{
/* wait for tx fifo to be emptied */
/* wait for tx fifo to be emptied */
sh_msiof_write
(
p
,
IER
,
IER_TEOFE
);
sh_msiof_write
(
p
,
SIIER
,
SI
IER_TEOFE
);
ret
=
sh_msiof_wait_for_completion
(
p
,
&
p
->
done
);
ret
=
sh_msiof_wait_for_completion
(
p
,
&
p
->
done
);
if
(
ret
)
if
(
ret
)
goto
stop_reset
;
goto
stop_reset
;
...
@@ -856,7 +853,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
...
@@ -856,7 +853,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
no_dma_tx:
no_dma_tx:
if
(
rx
)
if
(
rx
)
dmaengine_terminate_all
(
p
->
ctlr
->
dma_rx
);
dmaengine_terminate_all
(
p
->
ctlr
->
dma_rx
);
sh_msiof_write
(
p
,
IER
,
0
);
sh_msiof_write
(
p
,
SI
IER
,
0
);
return
ret
;
return
ret
;
}
}
...
@@ -1124,46 +1121,6 @@ static struct sh_msiof_spi_info *sh_msiof_spi_parse_dt(struct device *dev)
...
@@ -1124,46 +1121,6 @@ static struct sh_msiof_spi_info *sh_msiof_spi_parse_dt(struct device *dev)
}
}
#endif
#endif
static
int
sh_msiof_get_cs_gpios
(
struct
sh_msiof_spi_priv
*
p
)
{
struct
device
*
dev
=
&
p
->
pdev
->
dev
;
unsigned
int
used_ss_mask
=
0
;
unsigned
int
cs_gpios
=
0
;
unsigned
int
num_cs
,
i
;
int
ret
;
ret
=
gpiod_count
(
dev
,
"cs"
);
if
(
ret
<=
0
)
return
0
;
num_cs
=
max_t
(
unsigned
int
,
ret
,
p
->
ctlr
->
num_chipselect
);
for
(
i
=
0
;
i
<
num_cs
;
i
++
)
{
struct
gpio_desc
*
gpiod
;
gpiod
=
devm_gpiod_get_index
(
dev
,
"cs"
,
i
,
GPIOD_ASIS
);
if
(
!
IS_ERR
(
gpiod
))
{
devm_gpiod_put
(
dev
,
gpiod
);
cs_gpios
++
;
continue
;
}
if
(
PTR_ERR
(
gpiod
)
!=
-
ENOENT
)
return
PTR_ERR
(
gpiod
);
if
(
i
>=
MAX_SS
)
{
dev_err
(
dev
,
"Invalid native chip select %d
\n
"
,
i
);
return
-
EINVAL
;
}
used_ss_mask
|=
BIT
(
i
);
}
p
->
unused_ss
=
ffz
(
used_ss_mask
);
if
(
cs_gpios
&&
p
->
unused_ss
>=
MAX_SS
)
{
dev_err
(
dev
,
"No unused native chip select available
\n
"
);
return
-
EINVAL
;
}
return
0
;
}
static
struct
dma_chan
*
sh_msiof_request_dma_chan
(
struct
device
*
dev
,
static
struct
dma_chan
*
sh_msiof_request_dma_chan
(
struct
device
*
dev
,
enum
dma_transfer_direction
dir
,
unsigned
int
id
,
dma_addr_t
port_addr
)
enum
dma_transfer_direction
dir
,
unsigned
int
id
,
dma_addr_t
port_addr
)
{
{
...
@@ -1232,12 +1189,12 @@ static int sh_msiof_request_dma(struct sh_msiof_spi_priv *p)
...
@@ -1232,12 +1189,12 @@ static int sh_msiof_request_dma(struct sh_msiof_spi_priv *p)
ctlr
=
p
->
ctlr
;
ctlr
=
p
->
ctlr
;
ctlr
->
dma_tx
=
sh_msiof_request_dma_chan
(
dev
,
DMA_MEM_TO_DEV
,
ctlr
->
dma_tx
=
sh_msiof_request_dma_chan
(
dev
,
DMA_MEM_TO_DEV
,
dma_tx_id
,
res
->
start
+
TFDR
);
dma_tx_id
,
res
->
start
+
SI
TFDR
);
if
(
!
ctlr
->
dma_tx
)
if
(
!
ctlr
->
dma_tx
)
return
-
ENODEV
;
return
-
ENODEV
;
ctlr
->
dma_rx
=
sh_msiof_request_dma_chan
(
dev
,
DMA_DEV_TO_MEM
,
ctlr
->
dma_rx
=
sh_msiof_request_dma_chan
(
dev
,
DMA_DEV_TO_MEM
,
dma_rx_id
,
res
->
start
+
RFDR
);
dma_rx_id
,
res
->
start
+
SI
RFDR
);
if
(
!
ctlr
->
dma_rx
)
if
(
!
ctlr
->
dma_rx
)
goto
free_tx_chan
;
goto
free_tx_chan
;
...
@@ -1373,17 +1330,12 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
...
@@ -1373,17 +1330,12 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
if
(
p
->
info
->
rx_fifo_override
)
if
(
p
->
info
->
rx_fifo_override
)
p
->
rx_fifo_size
=
p
->
info
->
rx_fifo_override
;
p
->
rx_fifo_size
=
p
->
info
->
rx_fifo_override
;
/* Setup GPIO chip selects */
ctlr
->
num_chipselect
=
p
->
info
->
num_chipselect
;
ret
=
sh_msiof_get_cs_gpios
(
p
);
if
(
ret
)
goto
err1
;
/* init controller code */
/* init controller code */
ctlr
->
mode_bits
=
SPI_CPOL
|
SPI_CPHA
|
SPI_CS_HIGH
;
ctlr
->
mode_bits
=
SPI_CPOL
|
SPI_CPHA
|
SPI_CS_HIGH
;
ctlr
->
mode_bits
|=
SPI_LSB_FIRST
|
SPI_3WIRE
;
ctlr
->
mode_bits
|=
SPI_LSB_FIRST
|
SPI_3WIRE
;
ctlr
->
flags
=
chipdata
->
ctlr_flags
;
ctlr
->
flags
=
chipdata
->
ctlr_flags
;
ctlr
->
bus_num
=
pdev
->
id
;
ctlr
->
bus_num
=
pdev
->
id
;
ctlr
->
num_chipselect
=
p
->
info
->
num_chipselect
;
ctlr
->
dev
.
of_node
=
pdev
->
dev
.
of_node
;
ctlr
->
dev
.
of_node
=
pdev
->
dev
.
of_node
;
ctlr
->
setup
=
sh_msiof_spi_setup
;
ctlr
->
setup
=
sh_msiof_spi_setup
;
ctlr
->
prepare_message
=
sh_msiof_prepare_message
;
ctlr
->
prepare_message
=
sh_msiof_prepare_message
;
...
@@ -1392,6 +1344,7 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
...
@@ -1392,6 +1344,7 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
ctlr
->
auto_runtime_pm
=
true
;
ctlr
->
auto_runtime_pm
=
true
;
ctlr
->
transfer_one
=
sh_msiof_transfer_one
;
ctlr
->
transfer_one
=
sh_msiof_transfer_one
;
ctlr
->
use_gpio_descriptors
=
true
;
ctlr
->
use_gpio_descriptors
=
true
;
ctlr
->
max_native_cs
=
MAX_SS
;
ret
=
sh_msiof_request_dma
(
p
);
ret
=
sh_msiof_request_dma
(
p
);
if
(
ret
<
0
)
if
(
ret
<
0
)
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-sirf.c
View file @
754a36a5
...
@@ -1126,16 +1126,16 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)
...
@@ -1126,16 +1126,16 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)
sspi
->
bitbang
.
master
->
dev
.
of_node
=
pdev
->
dev
.
of_node
;
sspi
->
bitbang
.
master
->
dev
.
of_node
=
pdev
->
dev
.
of_node
;
/* request DMA channels */
/* request DMA channels */
sspi
->
rx_chan
=
dma_request_
slave_channel
(
&
pdev
->
dev
,
"rx"
);
sspi
->
rx_chan
=
dma_request_
chan
(
&
pdev
->
dev
,
"rx"
);
if
(
!
sspi
->
rx_chan
)
{
if
(
IS_ERR
(
sspi
->
rx_chan
)
)
{
dev_err
(
&
pdev
->
dev
,
"can not allocate rx dma channel
\n
"
);
dev_err
(
&
pdev
->
dev
,
"can not allocate rx dma channel
\n
"
);
ret
=
-
ENODEV
;
ret
=
PTR_ERR
(
sspi
->
rx_chan
)
;
goto
free_master
;
goto
free_master
;
}
}
sspi
->
tx_chan
=
dma_request_
slave_channel
(
&
pdev
->
dev
,
"tx"
);
sspi
->
tx_chan
=
dma_request_
chan
(
&
pdev
->
dev
,
"tx"
);
if
(
!
sspi
->
tx_chan
)
{
if
(
IS_ERR
(
sspi
->
tx_chan
)
)
{
dev_err
(
&
pdev
->
dev
,
"can not allocate tx dma channel
\n
"
);
dev_err
(
&
pdev
->
dev
,
"can not allocate tx dma channel
\n
"
);
ret
=
-
ENODEV
;
ret
=
PTR_ERR
(
sspi
->
tx_chan
)
;
goto
free_rx_dma
;
goto
free_rx_dma
;
}
}
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-stm32-qspi.c
View file @
754a36a5
...
@@ -470,10 +470,11 @@ static int stm32_qspi_setup(struct spi_device *spi)
...
@@ -470,10 +470,11 @@ static int stm32_qspi_setup(struct spi_device *spi)
return
0
;
return
0
;
}
}
static
void
stm32_qspi_dma_setup
(
struct
stm32_qspi
*
qspi
)
static
int
stm32_qspi_dma_setup
(
struct
stm32_qspi
*
qspi
)
{
{
struct
dma_slave_config
dma_cfg
;
struct
dma_slave_config
dma_cfg
;
struct
device
*
dev
=
qspi
->
dev
;
struct
device
*
dev
=
qspi
->
dev
;
int
ret
=
0
;
memset
(
&
dma_cfg
,
0
,
sizeof
(
dma_cfg
));
memset
(
&
dma_cfg
,
0
,
sizeof
(
dma_cfg
));
...
@@ -484,8 +485,13 @@ static void stm32_qspi_dma_setup(struct stm32_qspi *qspi)
...
@@ -484,8 +485,13 @@ static void stm32_qspi_dma_setup(struct stm32_qspi *qspi)
dma_cfg
.
src_maxburst
=
4
;
dma_cfg
.
src_maxburst
=
4
;
dma_cfg
.
dst_maxburst
=
4
;
dma_cfg
.
dst_maxburst
=
4
;
qspi
->
dma_chrx
=
dma_request_slave_channel
(
dev
,
"rx"
);
qspi
->
dma_chrx
=
dma_request_chan
(
dev
,
"rx"
);
if
(
qspi
->
dma_chrx
)
{
if
(
IS_ERR
(
qspi
->
dma_chrx
))
{
ret
=
PTR_ERR
(
qspi
->
dma_chrx
);
qspi
->
dma_chrx
=
NULL
;
if
(
ret
==
-
EPROBE_DEFER
)
goto
out
;
}
else
{
if
(
dmaengine_slave_config
(
qspi
->
dma_chrx
,
&
dma_cfg
))
{
if
(
dmaengine_slave_config
(
qspi
->
dma_chrx
,
&
dma_cfg
))
{
dev_err
(
dev
,
"dma rx config failed
\n
"
);
dev_err
(
dev
,
"dma rx config failed
\n
"
);
dma_release_channel
(
qspi
->
dma_chrx
);
dma_release_channel
(
qspi
->
dma_chrx
);
...
@@ -493,8 +499,11 @@ static void stm32_qspi_dma_setup(struct stm32_qspi *qspi)
...
@@ -493,8 +499,11 @@ static void stm32_qspi_dma_setup(struct stm32_qspi *qspi)
}
}
}
}
qspi
->
dma_chtx
=
dma_request_slave_channel
(
dev
,
"tx"
);
qspi
->
dma_chtx
=
dma_request_chan
(
dev
,
"tx"
);
if
(
qspi
->
dma_chtx
)
{
if
(
IS_ERR
(
qspi
->
dma_chtx
))
{
ret
=
PTR_ERR
(
qspi
->
dma_chtx
);
qspi
->
dma_chtx
=
NULL
;
}
else
{
if
(
dmaengine_slave_config
(
qspi
->
dma_chtx
,
&
dma_cfg
))
{
if
(
dmaengine_slave_config
(
qspi
->
dma_chtx
,
&
dma_cfg
))
{
dev_err
(
dev
,
"dma tx config failed
\n
"
);
dev_err
(
dev
,
"dma tx config failed
\n
"
);
dma_release_channel
(
qspi
->
dma_chtx
);
dma_release_channel
(
qspi
->
dma_chtx
);
...
@@ -502,7 +511,13 @@ static void stm32_qspi_dma_setup(struct stm32_qspi *qspi)
...
@@ -502,7 +511,13 @@ static void stm32_qspi_dma_setup(struct stm32_qspi *qspi)
}
}
}
}
out:
init_completion
(
&
qspi
->
dma_completion
);
init_completion
(
&
qspi
->
dma_completion
);
if
(
ret
!=
-
EPROBE_DEFER
)
ret
=
0
;
return
ret
;
}
}
static
void
stm32_qspi_dma_free
(
struct
stm32_qspi
*
qspi
)
static
void
stm32_qspi_dma_free
(
struct
stm32_qspi
*
qspi
)
...
@@ -608,7 +623,10 @@ static int stm32_qspi_probe(struct platform_device *pdev)
...
@@ -608,7 +623,10 @@ static int stm32_qspi_probe(struct platform_device *pdev)
qspi
->
dev
=
dev
;
qspi
->
dev
=
dev
;
platform_set_drvdata
(
pdev
,
qspi
);
platform_set_drvdata
(
pdev
,
qspi
);
stm32_qspi_dma_setup
(
qspi
);
ret
=
stm32_qspi_dma_setup
(
qspi
);
if
(
ret
)
goto
err
;
mutex_init
(
&
qspi
->
lock
);
mutex_init
(
&
qspi
->
lock
);
ctrl
->
mode_bits
=
SPI_RX_DUAL
|
SPI_RX_QUAD
ctrl
->
mode_bits
=
SPI_RX_DUAL
|
SPI_RX_QUAD
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-stm32.c
View file @
754a36a5
...
@@ -9,7 +9,6 @@
...
@@ -9,7 +9,6 @@
#include <linux/clk.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/dmaengine.h>
#include <linux/dmaengine.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/iopoll.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/module.h>
...
@@ -973,29 +972,6 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id)
...
@@ -973,29 +972,6 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id)
return
IRQ_HANDLED
;
return
IRQ_HANDLED
;
}
}
/**
* stm32_spi_setup - setup device chip select
*/
static
int
stm32_spi_setup
(
struct
spi_device
*
spi_dev
)
{
int
ret
=
0
;
if
(
!
gpio_is_valid
(
spi_dev
->
cs_gpio
))
{
dev_err
(
&
spi_dev
->
dev
,
"%d is not a valid gpio
\n
"
,
spi_dev
->
cs_gpio
);
return
-
EINVAL
;
}
dev_dbg
(
&
spi_dev
->
dev
,
"%s: set gpio%d output %s
\n
"
,
__func__
,
spi_dev
->
cs_gpio
,
(
spi_dev
->
mode
&
SPI_CS_HIGH
)
?
"low"
:
"high"
);
ret
=
gpio_direction_output
(
spi_dev
->
cs_gpio
,
!
(
spi_dev
->
mode
&
SPI_CS_HIGH
));
return
ret
;
}
/**
/**
* stm32_spi_prepare_msg - set up the controller to transfer a single message
* stm32_spi_prepare_msg - set up the controller to transfer a single message
*/
*/
...
@@ -1810,7 +1786,7 @@ static int stm32_spi_probe(struct platform_device *pdev)
...
@@ -1810,7 +1786,7 @@ static int stm32_spi_probe(struct platform_device *pdev)
struct
spi_master
*
master
;
struct
spi_master
*
master
;
struct
stm32_spi
*
spi
;
struct
stm32_spi
*
spi
;
struct
resource
*
res
;
struct
resource
*
res
;
int
i
,
ret
;
int
ret
;
master
=
spi_alloc_master
(
&
pdev
->
dev
,
sizeof
(
struct
stm32_spi
));
master
=
spi_alloc_master
(
&
pdev
->
dev
,
sizeof
(
struct
stm32_spi
));
if
(
!
master
)
{
if
(
!
master
)
{
...
@@ -1898,22 +1874,34 @@ static int stm32_spi_probe(struct platform_device *pdev)
...
@@ -1898,22 +1874,34 @@ static int stm32_spi_probe(struct platform_device *pdev)
master
->
bits_per_word_mask
=
spi
->
cfg
->
get_bpw_mask
(
spi
);
master
->
bits_per_word_mask
=
spi
->
cfg
->
get_bpw_mask
(
spi
);
master
->
max_speed_hz
=
spi
->
clk_rate
/
spi
->
cfg
->
baud_rate_div_min
;
master
->
max_speed_hz
=
spi
->
clk_rate
/
spi
->
cfg
->
baud_rate_div_min
;
master
->
min_speed_hz
=
spi
->
clk_rate
/
spi
->
cfg
->
baud_rate_div_max
;
master
->
min_speed_hz
=
spi
->
clk_rate
/
spi
->
cfg
->
baud_rate_div_max
;
master
->
setup
=
stm32_spi_setup
;
master
->
use_gpio_descriptors
=
true
;
master
->
prepare_message
=
stm32_spi_prepare_msg
;
master
->
prepare_message
=
stm32_spi_prepare_msg
;
master
->
transfer_one
=
stm32_spi_transfer_one
;
master
->
transfer_one
=
stm32_spi_transfer_one
;
master
->
unprepare_message
=
stm32_spi_unprepare_msg
;
master
->
unprepare_message
=
stm32_spi_unprepare_msg
;
spi
->
dma_tx
=
dma_request_slave_channel
(
spi
->
dev
,
"tx"
);
spi
->
dma_tx
=
dma_request_chan
(
spi
->
dev
,
"tx"
);
if
(
!
spi
->
dma_tx
)
if
(
IS_ERR
(
spi
->
dma_tx
))
{
ret
=
PTR_ERR
(
spi
->
dma_tx
);
spi
->
dma_tx
=
NULL
;
if
(
ret
==
-
EPROBE_DEFER
)
goto
err_clk_disable
;
dev_warn
(
&
pdev
->
dev
,
"failed to request tx dma channel
\n
"
);
dev_warn
(
&
pdev
->
dev
,
"failed to request tx dma channel
\n
"
);
else
}
else
{
master
->
dma_tx
=
spi
->
dma_tx
;
master
->
dma_tx
=
spi
->
dma_tx
;
}
spi
->
dma_rx
=
dma_request_chan
(
spi
->
dev
,
"rx"
);
if
(
IS_ERR
(
spi
->
dma_rx
))
{
ret
=
PTR_ERR
(
spi
->
dma_rx
);
spi
->
dma_rx
=
NULL
;
if
(
ret
==
-
EPROBE_DEFER
)
goto
err_dma_release
;
spi
->
dma_rx
=
dma_request_slave_channel
(
spi
->
dev
,
"rx"
);
if
(
!
spi
->
dma_rx
)
dev_warn
(
&
pdev
->
dev
,
"failed to request rx dma channel
\n
"
);
dev_warn
(
&
pdev
->
dev
,
"failed to request rx dma channel
\n
"
);
else
}
else
{
master
->
dma_rx
=
spi
->
dma_rx
;
master
->
dma_rx
=
spi
->
dma_rx
;
}
if
(
spi
->
dma_tx
||
spi
->
dma_rx
)
if
(
spi
->
dma_tx
||
spi
->
dma_rx
)
master
->
can_dma
=
stm32_spi_can_dma
;
master
->
can_dma
=
stm32_spi_can_dma
;
...
@@ -1925,43 +1913,26 @@ static int stm32_spi_probe(struct platform_device *pdev)
...
@@ -1925,43 +1913,26 @@ static int stm32_spi_probe(struct platform_device *pdev)
if
(
ret
)
{
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"spi master registration failed: %d
\n
"
,
dev_err
(
&
pdev
->
dev
,
"spi master registration failed: %d
\n
"
,
ret
);
ret
);
goto
err_
dma_releas
e
;
goto
err_
pm_disabl
e
;
}
}
if
(
!
master
->
cs_gpios
)
{
if
(
!
master
->
cs_gpio
d
s
)
{
dev_err
(
&
pdev
->
dev
,
"no CS gpios available
\n
"
);
dev_err
(
&
pdev
->
dev
,
"no CS gpios available
\n
"
);
ret
=
-
EINVAL
;
ret
=
-
EINVAL
;
goto
err_dma_release
;
goto
err_pm_disable
;
}
for
(
i
=
0
;
i
<
master
->
num_chipselect
;
i
++
)
{
if
(
!
gpio_is_valid
(
master
->
cs_gpios
[
i
]))
{
dev_err
(
&
pdev
->
dev
,
"%i is not a valid gpio
\n
"
,
master
->
cs_gpios
[
i
]);
ret
=
-
EINVAL
;
goto
err_dma_release
;
}
ret
=
devm_gpio_request
(
&
pdev
->
dev
,
master
->
cs_gpios
[
i
],
DRIVER_NAME
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"can't get CS gpio %i
\n
"
,
master
->
cs_gpios
[
i
]);
goto
err_dma_release
;
}
}
}
dev_info
(
&
pdev
->
dev
,
"driver initialized
\n
"
);
dev_info
(
&
pdev
->
dev
,
"driver initialized
\n
"
);
return
0
;
return
0
;
err_pm_disable:
pm_runtime_disable
(
&
pdev
->
dev
);
err_dma_release:
err_dma_release:
if
(
spi
->
dma_tx
)
if
(
spi
->
dma_tx
)
dma_release_channel
(
spi
->
dma_tx
);
dma_release_channel
(
spi
->
dma_tx
);
if
(
spi
->
dma_rx
)
if
(
spi
->
dma_rx
)
dma_release_channel
(
spi
->
dma_rx
);
dma_release_channel
(
spi
->
dma_rx
);
pm_runtime_disable
(
&
pdev
->
dev
);
err_clk_disable:
err_clk_disable:
clk_disable_unprepare
(
spi
->
clk
);
clk_disable_unprepare
(
spi
->
clk
);
err_master_put:
err_master_put:
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-tegra114.c
View file @
754a36a5
...
@@ -269,10 +269,10 @@ static unsigned tegra_spi_calculate_curr_xfer_param(
...
@@ -269,10 +269,10 @@ static unsigned tegra_spi_calculate_curr_xfer_param(
if
((
bits_per_word
==
8
||
bits_per_word
==
16
||
if
((
bits_per_word
==
8
||
bits_per_word
==
16
||
bits_per_word
==
32
)
&&
t
->
len
>
3
)
{
bits_per_word
==
32
)
&&
t
->
len
>
3
)
{
tspi
->
is_packed
=
1
;
tspi
->
is_packed
=
true
;
tspi
->
words_per_32bit
=
32
/
bits_per_word
;
tspi
->
words_per_32bit
=
32
/
bits_per_word
;
}
else
{
}
else
{
tspi
->
is_packed
=
0
;
tspi
->
is_packed
=
false
;
tspi
->
words_per_32bit
=
1
;
tspi
->
words_per_32bit
=
1
;
}
}
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-ti-qspi.c
View file @
754a36a5
...
@@ -80,8 +80,6 @@ struct ti_qspi {
...
@@ -80,8 +80,6 @@ struct ti_qspi {
#define QSPI_COMPLETION_TIMEOUT msecs_to_jiffies(2000)
#define QSPI_COMPLETION_TIMEOUT msecs_to_jiffies(2000)
#define QSPI_FCLK 192000000
/* Clock Control */
/* Clock Control */
#define QSPI_CLK_EN (1 << 31)
#define QSPI_CLK_EN (1 << 31)
#define QSPI_CLK_DIV_MAX 0xffff
#define QSPI_CLK_DIV_MAX 0xffff
...
@@ -316,6 +314,8 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t,
...
@@ -316,6 +314,8 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t,
{
{
int
wlen
;
int
wlen
;
unsigned
int
cmd
;
unsigned
int
cmd
;
u32
rx
;
u8
rxlen
,
rx_wlen
;
u8
*
rxbuf
;
u8
*
rxbuf
;
rxbuf
=
t
->
rx_buf
;
rxbuf
=
t
->
rx_buf
;
...
@@ -332,20 +332,67 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t,
...
@@ -332,20 +332,67 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t,
break
;
break
;
}
}
wlen
=
t
->
bits_per_word
>>
3
;
/* in bytes */
wlen
=
t
->
bits_per_word
>>
3
;
/* in bytes */
rx_wlen
=
wlen
;
while
(
count
)
{
while
(
count
)
{
dev_dbg
(
qspi
->
dev
,
"rx cmd %08x dc %08x
\n
"
,
cmd
,
qspi
->
dc
);
dev_dbg
(
qspi
->
dev
,
"rx cmd %08x dc %08x
\n
"
,
cmd
,
qspi
->
dc
);
if
(
qspi_is_busy
(
qspi
))
if
(
qspi_is_busy
(
qspi
))
return
-
EBUSY
;
return
-
EBUSY
;
switch
(
wlen
)
{
case
1
:
/*
* Optimize the 8-bit words transfers, as used by
* the SPI flash devices.
*/
if
(
count
>=
QSPI_WLEN_MAX_BYTES
)
{
rxlen
=
QSPI_WLEN_MAX_BYTES
;
}
else
{
rxlen
=
min
(
count
,
4
);
}
rx_wlen
=
rxlen
<<
3
;
cmd
&=
~
QSPI_WLEN_MASK
;
cmd
|=
QSPI_WLEN
(
rx_wlen
);
break
;
default:
rxlen
=
wlen
;
break
;
}
ti_qspi_write
(
qspi
,
cmd
,
QSPI_SPI_CMD_REG
);
ti_qspi_write
(
qspi
,
cmd
,
QSPI_SPI_CMD_REG
);
if
(
ti_qspi_poll_wc
(
qspi
))
{
if
(
ti_qspi_poll_wc
(
qspi
))
{
dev_err
(
qspi
->
dev
,
"read timed out
\n
"
);
dev_err
(
qspi
->
dev
,
"read timed out
\n
"
);
return
-
ETIMEDOUT
;
return
-
ETIMEDOUT
;
}
}
switch
(
wlen
)
{
switch
(
wlen
)
{
case
1
:
case
1
:
*
rxbuf
=
readb
(
qspi
->
base
+
QSPI_SPI_DATA_REG
);
/*
* Optimize the 8-bit words transfers, as used by
* the SPI flash devices.
*/
if
(
count
>=
QSPI_WLEN_MAX_BYTES
)
{
u32
*
rxp
=
(
u32
*
)
rxbuf
;
rx
=
readl
(
qspi
->
base
+
QSPI_SPI_DATA_REG_3
);
*
rxp
++
=
be32_to_cpu
(
rx
);
rx
=
readl
(
qspi
->
base
+
QSPI_SPI_DATA_REG_2
);
*
rxp
++
=
be32_to_cpu
(
rx
);
rx
=
readl
(
qspi
->
base
+
QSPI_SPI_DATA_REG_1
);
*
rxp
++
=
be32_to_cpu
(
rx
);
rx
=
readl
(
qspi
->
base
+
QSPI_SPI_DATA_REG
);
*
rxp
++
=
be32_to_cpu
(
rx
);
}
else
{
u8
*
rxp
=
rxbuf
;
rx
=
readl
(
qspi
->
base
+
QSPI_SPI_DATA_REG
);
if
(
rx_wlen
>=
8
)
*
rxp
++
=
rx
>>
(
rx_wlen
-
8
);
if
(
rx_wlen
>=
16
)
*
rxp
++
=
rx
>>
(
rx_wlen
-
16
);
if
(
rx_wlen
>=
24
)
*
rxp
++
=
rx
>>
(
rx_wlen
-
24
);
if
(
rx_wlen
>=
32
)
*
rxp
++
=
rx
;
}
break
;
break
;
case
2
:
case
2
:
*
((
u16
*
)
rxbuf
)
=
readw
(
qspi
->
base
+
QSPI_SPI_DATA_REG
);
*
((
u16
*
)
rxbuf
)
=
readw
(
qspi
->
base
+
QSPI_SPI_DATA_REG
);
...
@@ -354,8 +401,8 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t,
...
@@ -354,8 +401,8 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t,
*
((
u32
*
)
rxbuf
)
=
readl
(
qspi
->
base
+
QSPI_SPI_DATA_REG
);
*
((
u32
*
)
rxbuf
)
=
readl
(
qspi
->
base
+
QSPI_SPI_DATA_REG
);
break
;
break
;
}
}
rxbuf
+=
w
len
;
rxbuf
+=
rx
len
;
count
-=
w
len
;
count
-=
rx
len
;
}
}
return
0
;
return
0
;
...
@@ -527,6 +574,35 @@ static void ti_qspi_setup_mmap_read(struct spi_device *spi, u8 opcode,
...
@@ -527,6 +574,35 @@ static void ti_qspi_setup_mmap_read(struct spi_device *spi, u8 opcode,
QSPI_SPI_SETUP_REG
(
spi
->
chip_select
));
QSPI_SPI_SETUP_REG
(
spi
->
chip_select
));
}
}
static
int
ti_qspi_adjust_op_size
(
struct
spi_mem
*
mem
,
struct
spi_mem_op
*
op
)
{
struct
ti_qspi
*
qspi
=
spi_controller_get_devdata
(
mem
->
spi
->
master
);
size_t
max_len
;
if
(
op
->
data
.
dir
==
SPI_MEM_DATA_IN
)
{
if
(
op
->
addr
.
val
<
qspi
->
mmap_size
)
{
/* Limit MMIO to the mmaped region */
if
(
op
->
addr
.
val
+
op
->
data
.
nbytes
>
qspi
->
mmap_size
)
{
max_len
=
qspi
->
mmap_size
-
op
->
addr
.
val
;
op
->
data
.
nbytes
=
min
((
size_t
)
op
->
data
.
nbytes
,
max_len
);
}
}
else
{
/*
* Use fallback mode (SW generated transfers) above the
* mmaped region.
* Adjust size to comply with the QSPI max frame length.
*/
max_len
=
QSPI_FRAME
;
max_len
-=
1
+
op
->
addr
.
nbytes
+
op
->
dummy
.
nbytes
;
op
->
data
.
nbytes
=
min
((
size_t
)
op
->
data
.
nbytes
,
max_len
);
}
}
return
0
;
}
static
int
ti_qspi_exec_mem_op
(
struct
spi_mem
*
mem
,
static
int
ti_qspi_exec_mem_op
(
struct
spi_mem
*
mem
,
const
struct
spi_mem_op
*
op
)
const
struct
spi_mem_op
*
op
)
{
{
...
@@ -577,6 +653,7 @@ static int ti_qspi_exec_mem_op(struct spi_mem *mem,
...
@@ -577,6 +653,7 @@ static int ti_qspi_exec_mem_op(struct spi_mem *mem,
static
const
struct
spi_controller_mem_ops
ti_qspi_mem_ops
=
{
static
const
struct
spi_controller_mem_ops
ti_qspi_mem_ops
=
{
.
exec_op
=
ti_qspi_exec_mem_op
,
.
exec_op
=
ti_qspi_exec_mem_op
,
.
adjust_op_size
=
ti_qspi_adjust_op_size
,
};
};
static
int
ti_qspi_start_transfer_one
(
struct
spi_master
*
master
,
static
int
ti_qspi_start_transfer_one
(
struct
spi_master
*
master
,
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-topcliff-pch.c
View file @
754a36a5
...
@@ -863,7 +863,7 @@ static void pch_spi_request_dma(struct pch_spi_data *data, int bpw)
...
@@ -863,7 +863,7 @@ static void pch_spi_request_dma(struct pch_spi_data *data, int bpw)
/* Set Tx DMA */
/* Set Tx DMA */
param
=
&
dma
->
param_tx
;
param
=
&
dma
->
param_tx
;
param
->
dma_dev
=
&
dma_dev
->
dev
;
param
->
dma_dev
=
&
dma_dev
->
dev
;
param
->
chan_id
=
data
->
ch
*
2
;
/* Tx = 0, 2 */
;
param
->
chan_id
=
data
->
ch
*
2
;
/* Tx = 0, 2 */
param
->
tx_reg
=
data
->
io_base_addr
+
PCH_SPDWR
;
param
->
tx_reg
=
data
->
io_base_addr
+
PCH_SPDWR
;
param
->
width
=
width
;
param
->
width
=
width
;
chan
=
dma_request_channel
(
mask
,
pch_spi_filter
,
param
);
chan
=
dma_request_channel
(
mask
,
pch_spi_filter
,
param
);
...
@@ -878,7 +878,7 @@ static void pch_spi_request_dma(struct pch_spi_data *data, int bpw)
...
@@ -878,7 +878,7 @@ static void pch_spi_request_dma(struct pch_spi_data *data, int bpw)
/* Set Rx DMA */
/* Set Rx DMA */
param
=
&
dma
->
param_rx
;
param
=
&
dma
->
param_rx
;
param
->
dma_dev
=
&
dma_dev
->
dev
;
param
->
dma_dev
=
&
dma_dev
->
dev
;
param
->
chan_id
=
data
->
ch
*
2
+
1
;
/* Rx = Tx + 1 */
;
param
->
chan_id
=
data
->
ch
*
2
+
1
;
/* Rx = Tx + 1 */
param
->
rx_reg
=
data
->
io_base_addr
+
PCH_SPDRR
;
param
->
rx_reg
=
data
->
io_base_addr
+
PCH_SPDRR
;
param
->
width
=
width
;
param
->
width
=
width
;
chan
=
dma_request_channel
(
mask
,
pch_spi_filter
,
param
);
chan
=
dma_request_channel
(
mask
,
pch_spi_filter
,
param
);
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-uniphier.c
View file @
754a36a5
...
@@ -8,6 +8,7 @@
...
@@ -8,6 +8,7 @@
#include <linux/bitops.h>
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/dmaengine.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/module.h>
...
@@ -23,6 +24,7 @@
...
@@ -23,6 +24,7 @@
struct
uniphier_spi_priv
{
struct
uniphier_spi_priv
{
void
__iomem
*
base
;
void
__iomem
*
base
;
dma_addr_t
base_dma_addr
;
struct
clk
*
clk
;
struct
clk
*
clk
;
struct
spi_master
*
master
;
struct
spi_master
*
master
;
struct
completion
xfer_done
;
struct
completion
xfer_done
;
...
@@ -32,6 +34,7 @@ struct uniphier_spi_priv {
...
@@ -32,6 +34,7 @@ struct uniphier_spi_priv {
unsigned
int
rx_bytes
;
unsigned
int
rx_bytes
;
const
u8
*
tx_buf
;
const
u8
*
tx_buf
;
u8
*
rx_buf
;
u8
*
rx_buf
;
atomic_t
dma_busy
;
bool
is_save_param
;
bool
is_save_param
;
u8
bits_per_word
;
u8
bits_per_word
;
...
@@ -61,11 +64,16 @@ struct uniphier_spi_priv {
...
@@ -61,11 +64,16 @@ struct uniphier_spi_priv {
#define SSI_FPS_FSTRT BIT(14)
#define SSI_FPS_FSTRT BIT(14)
#define SSI_SR 0x14
#define SSI_SR 0x14
#define SSI_SR_BUSY BIT(7)
#define SSI_SR_RNE BIT(0)
#define SSI_SR_RNE BIT(0)
#define SSI_IE 0x18
#define SSI_IE 0x18
#define SSI_IE_TCIE BIT(4)
#define SSI_IE_RCIE BIT(3)
#define SSI_IE_RCIE BIT(3)
#define SSI_IE_TXRE BIT(2)
#define SSI_IE_RXRE BIT(1)
#define SSI_IE_RORIE BIT(0)
#define SSI_IE_RORIE BIT(0)
#define SSI_IE_ALL_MASK GENMASK(4, 0)
#define SSI_IS 0x1c
#define SSI_IS 0x1c
#define SSI_IS_RXRS BIT(9)
#define SSI_IS_RXRS BIT(9)
...
@@ -87,15 +95,19 @@ struct uniphier_spi_priv {
...
@@ -87,15 +95,19 @@ struct uniphier_spi_priv {
#define SSI_RXDR 0x24
#define SSI_RXDR 0x24
#define SSI_FIFO_DEPTH 8U
#define SSI_FIFO_DEPTH 8U
#define SSI_FIFO_BURST_NUM 1
#define SSI_DMA_RX_BUSY BIT(1)
#define SSI_DMA_TX_BUSY BIT(0)
static
inline
unsigned
int
bytes_per_word
(
unsigned
int
bits
)
static
inline
unsigned
int
bytes_per_word
(
unsigned
int
bits
)
{
{
return
bits
<=
8
?
1
:
(
bits
<=
16
?
2
:
4
);
return
bits
<=
8
?
1
:
(
bits
<=
16
?
2
:
4
);
}
}
static
inline
void
uniphier_spi_irq_enable
(
struct
spi_device
*
spi
,
u32
mask
)
static
inline
void
uniphier_spi_irq_enable
(
struct
uniphier_spi_priv
*
priv
,
u32
mask
)
{
{
struct
uniphier_spi_priv
*
priv
=
spi_master_get_devdata
(
spi
->
master
);
u32
val
;
u32
val
;
val
=
readl
(
priv
->
base
+
SSI_IE
);
val
=
readl
(
priv
->
base
+
SSI_IE
);
...
@@ -103,9 +115,9 @@ static inline void uniphier_spi_irq_enable(struct spi_device *spi, u32 mask)
...
@@ -103,9 +115,9 @@ static inline void uniphier_spi_irq_enable(struct spi_device *spi, u32 mask)
writel
(
val
,
priv
->
base
+
SSI_IE
);
writel
(
val
,
priv
->
base
+
SSI_IE
);
}
}
static
inline
void
uniphier_spi_irq_disable
(
struct
spi_device
*
spi
,
u32
mask
)
static
inline
void
uniphier_spi_irq_disable
(
struct
uniphier_spi_priv
*
priv
,
u32
mask
)
{
{
struct
uniphier_spi_priv
*
priv
=
spi_master_get_devdata
(
spi
->
master
);
u32
val
;
u32
val
;
val
=
readl
(
priv
->
base
+
SSI_IE
);
val
=
readl
(
priv
->
base
+
SSI_IE
);
...
@@ -334,6 +346,128 @@ static void uniphier_spi_set_cs(struct spi_device *spi, bool enable)
...
@@ -334,6 +346,128 @@ static void uniphier_spi_set_cs(struct spi_device *spi, bool enable)
writel
(
val
,
priv
->
base
+
SSI_FPS
);
writel
(
val
,
priv
->
base
+
SSI_FPS
);
}
}
static
bool
uniphier_spi_can_dma
(
struct
spi_master
*
master
,
struct
spi_device
*
spi
,
struct
spi_transfer
*
t
)
{
struct
uniphier_spi_priv
*
priv
=
spi_master_get_devdata
(
master
);
unsigned
int
bpw
=
bytes_per_word
(
priv
->
bits_per_word
);
if
((
!
master
->
dma_tx
&&
!
master
->
dma_rx
)
||
(
!
master
->
dma_tx
&&
t
->
tx_buf
)
||
(
!
master
->
dma_rx
&&
t
->
rx_buf
))
return
false
;
return
DIV_ROUND_UP
(
t
->
len
,
bpw
)
>
SSI_FIFO_DEPTH
;
}
static
void
uniphier_spi_dma_rxcb
(
void
*
data
)
{
struct
spi_master
*
master
=
data
;
struct
uniphier_spi_priv
*
priv
=
spi_master_get_devdata
(
master
);
int
state
=
atomic_fetch_andnot
(
SSI_DMA_RX_BUSY
,
&
priv
->
dma_busy
);
uniphier_spi_irq_disable
(
priv
,
SSI_IE_RXRE
);
if
(
!
(
state
&
SSI_DMA_TX_BUSY
))
spi_finalize_current_transfer
(
master
);
}
static
void
uniphier_spi_dma_txcb
(
void
*
data
)
{
struct
spi_master
*
master
=
data
;
struct
uniphier_spi_priv
*
priv
=
spi_master_get_devdata
(
master
);
int
state
=
atomic_fetch_andnot
(
SSI_DMA_TX_BUSY
,
&
priv
->
dma_busy
);
uniphier_spi_irq_disable
(
priv
,
SSI_IE_TXRE
);
if
(
!
(
state
&
SSI_DMA_RX_BUSY
))
spi_finalize_current_transfer
(
master
);
}
static
int
uniphier_spi_transfer_one_dma
(
struct
spi_master
*
master
,
struct
spi_device
*
spi
,
struct
spi_transfer
*
t
)
{
struct
uniphier_spi_priv
*
priv
=
spi_master_get_devdata
(
master
);
struct
dma_async_tx_descriptor
*
rxdesc
=
NULL
,
*
txdesc
=
NULL
;
int
buswidth
;
atomic_set
(
&
priv
->
dma_busy
,
0
);
uniphier_spi_set_fifo_threshold
(
priv
,
SSI_FIFO_BURST_NUM
);
if
(
priv
->
bits_per_word
<=
8
)
buswidth
=
DMA_SLAVE_BUSWIDTH_1_BYTE
;
else
if
(
priv
->
bits_per_word
<=
16
)
buswidth
=
DMA_SLAVE_BUSWIDTH_2_BYTES
;
else
buswidth
=
DMA_SLAVE_BUSWIDTH_4_BYTES
;
if
(
priv
->
rx_buf
)
{
struct
dma_slave_config
rxconf
=
{
.
direction
=
DMA_DEV_TO_MEM
,
.
src_addr
=
priv
->
base_dma_addr
+
SSI_RXDR
,
.
src_addr_width
=
buswidth
,
.
src_maxburst
=
SSI_FIFO_BURST_NUM
,
};
dmaengine_slave_config
(
master
->
dma_rx
,
&
rxconf
);
rxdesc
=
dmaengine_prep_slave_sg
(
master
->
dma_rx
,
t
->
rx_sg
.
sgl
,
t
->
rx_sg
.
nents
,
DMA_DEV_TO_MEM
,
DMA_PREP_INTERRUPT
|
DMA_CTRL_ACK
);
if
(
!
rxdesc
)
goto
out_err_prep
;
rxdesc
->
callback
=
uniphier_spi_dma_rxcb
;
rxdesc
->
callback_param
=
master
;
uniphier_spi_irq_enable
(
priv
,
SSI_IE_RXRE
);
atomic_or
(
SSI_DMA_RX_BUSY
,
&
priv
->
dma_busy
);
dmaengine_submit
(
rxdesc
);
dma_async_issue_pending
(
master
->
dma_rx
);
}
if
(
priv
->
tx_buf
)
{
struct
dma_slave_config
txconf
=
{
.
direction
=
DMA_MEM_TO_DEV
,
.
dst_addr
=
priv
->
base_dma_addr
+
SSI_TXDR
,
.
dst_addr_width
=
buswidth
,
.
dst_maxburst
=
SSI_FIFO_BURST_NUM
,
};
dmaengine_slave_config
(
master
->
dma_tx
,
&
txconf
);
txdesc
=
dmaengine_prep_slave_sg
(
master
->
dma_tx
,
t
->
tx_sg
.
sgl
,
t
->
tx_sg
.
nents
,
DMA_MEM_TO_DEV
,
DMA_PREP_INTERRUPT
|
DMA_CTRL_ACK
);
if
(
!
txdesc
)
goto
out_err_prep
;
txdesc
->
callback
=
uniphier_spi_dma_txcb
;
txdesc
->
callback_param
=
master
;
uniphier_spi_irq_enable
(
priv
,
SSI_IE_TXRE
);
atomic_or
(
SSI_DMA_TX_BUSY
,
&
priv
->
dma_busy
);
dmaengine_submit
(
txdesc
);
dma_async_issue_pending
(
master
->
dma_tx
);
}
/* signal that we need to wait for completion */
return
(
priv
->
tx_buf
||
priv
->
rx_buf
);
out_err_prep:
if
(
rxdesc
)
dmaengine_terminate_sync
(
master
->
dma_rx
);
return
-
EINVAL
;
}
static
int
uniphier_spi_transfer_one_irq
(
struct
spi_master
*
master
,
static
int
uniphier_spi_transfer_one_irq
(
struct
spi_master
*
master
,
struct
spi_device
*
spi
,
struct
spi_device
*
spi
,
struct
spi_transfer
*
t
)
struct
spi_transfer
*
t
)
...
@@ -346,12 +480,12 @@ static int uniphier_spi_transfer_one_irq(struct spi_master *master,
...
@@ -346,12 +480,12 @@ static int uniphier_spi_transfer_one_irq(struct spi_master *master,
uniphier_spi_fill_tx_fifo
(
priv
);
uniphier_spi_fill_tx_fifo
(
priv
);
uniphier_spi_irq_enable
(
spi
,
SSI_IE_RCIE
|
SSI_IE_RORIE
);
uniphier_spi_irq_enable
(
priv
,
SSI_IE_RCIE
|
SSI_IE_RORIE
);
time_left
=
wait_for_completion_timeout
(
&
priv
->
xfer_done
,
time_left
=
wait_for_completion_timeout
(
&
priv
->
xfer_done
,
msecs_to_jiffies
(
SSI_TIMEOUT_MS
));
msecs_to_jiffies
(
SSI_TIMEOUT_MS
));
uniphier_spi_irq_disable
(
spi
,
SSI_IE_RCIE
|
SSI_IE_RORIE
);
uniphier_spi_irq_disable
(
priv
,
SSI_IE_RCIE
|
SSI_IE_RORIE
);
if
(
!
time_left
)
{
if
(
!
time_left
)
{
dev_err
(
dev
,
"transfer timeout.
\n
"
);
dev_err
(
dev
,
"transfer timeout.
\n
"
);
...
@@ -395,6 +529,7 @@ static int uniphier_spi_transfer_one(struct spi_master *master,
...
@@ -395,6 +529,7 @@ static int uniphier_spi_transfer_one(struct spi_master *master,
{
{
struct
uniphier_spi_priv
*
priv
=
spi_master_get_devdata
(
master
);
struct
uniphier_spi_priv
*
priv
=
spi_master_get_devdata
(
master
);
unsigned
long
threshold
;
unsigned
long
threshold
;
bool
use_dma
;
/* Terminate and return success for 0 byte length transfer */
/* Terminate and return success for 0 byte length transfer */
if
(
!
t
->
len
)
if
(
!
t
->
len
)
...
@@ -402,6 +537,10 @@ static int uniphier_spi_transfer_one(struct spi_master *master,
...
@@ -402,6 +537,10 @@ static int uniphier_spi_transfer_one(struct spi_master *master,
uniphier_spi_setup_transfer
(
spi
,
t
);
uniphier_spi_setup_transfer
(
spi
,
t
);
use_dma
=
master
->
can_dma
?
master
->
can_dma
(
master
,
spi
,
t
)
:
false
;
if
(
use_dma
)
return
uniphier_spi_transfer_one_dma
(
master
,
spi
,
t
);
/*
/*
* If the transfer operation will take longer than
* If the transfer operation will take longer than
* SSI_POLL_TIMEOUT_US, it should use irq.
* SSI_POLL_TIMEOUT_US, it should use irq.
...
@@ -432,6 +571,32 @@ static int uniphier_spi_unprepare_transfer_hardware(struct spi_master *master)
...
@@ -432,6 +571,32 @@ static int uniphier_spi_unprepare_transfer_hardware(struct spi_master *master)
return
0
;
return
0
;
}
}
static
void
uniphier_spi_handle_err
(
struct
spi_master
*
master
,
struct
spi_message
*
msg
)
{
struct
uniphier_spi_priv
*
priv
=
spi_master_get_devdata
(
master
);
u32
val
;
/* stop running spi transfer */
writel
(
0
,
priv
->
base
+
SSI_CTL
);
/* reset FIFOs */
val
=
SSI_FC_TXFFL
|
SSI_FC_RXFFL
;
writel
(
val
,
priv
->
base
+
SSI_FC
);
uniphier_spi_irq_disable
(
priv
,
SSI_IE_ALL_MASK
);
if
(
atomic_read
(
&
priv
->
dma_busy
)
&
SSI_DMA_TX_BUSY
)
{
dmaengine_terminate_async
(
master
->
dma_tx
);
atomic_andnot
(
SSI_DMA_TX_BUSY
,
&
priv
->
dma_busy
);
}
if
(
atomic_read
(
&
priv
->
dma_busy
)
&
SSI_DMA_RX_BUSY
)
{
dmaengine_terminate_async
(
master
->
dma_rx
);
atomic_andnot
(
SSI_DMA_RX_BUSY
,
&
priv
->
dma_busy
);
}
}
static
irqreturn_t
uniphier_spi_handler
(
int
irq
,
void
*
dev_id
)
static
irqreturn_t
uniphier_spi_handler
(
int
irq
,
void
*
dev_id
)
{
{
struct
uniphier_spi_priv
*
priv
=
dev_id
;
struct
uniphier_spi_priv
*
priv
=
dev_id
;
...
@@ -477,6 +642,9 @@ static int uniphier_spi_probe(struct platform_device *pdev)
...
@@ -477,6 +642,9 @@ static int uniphier_spi_probe(struct platform_device *pdev)
{
{
struct
uniphier_spi_priv
*
priv
;
struct
uniphier_spi_priv
*
priv
;
struct
spi_master
*
master
;
struct
spi_master
*
master
;
struct
resource
*
res
;
struct
dma_slave_caps
caps
;
u32
dma_tx_burst
=
0
,
dma_rx_burst
=
0
;
unsigned
long
clk_rate
;
unsigned
long
clk_rate
;
int
irq
;
int
irq
;
int
ret
;
int
ret
;
...
@@ -491,11 +659,13 @@ static int uniphier_spi_probe(struct platform_device *pdev)
...
@@ -491,11 +659,13 @@ static int uniphier_spi_probe(struct platform_device *pdev)
priv
->
master
=
master
;
priv
->
master
=
master
;
priv
->
is_save_param
=
false
;
priv
->
is_save_param
=
false
;
priv
->
base
=
devm_platform_ioremap_resource
(
pdev
,
0
);
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
priv
->
base
=
devm_ioremap_resource
(
&
pdev
->
dev
,
res
);
if
(
IS_ERR
(
priv
->
base
))
{
if
(
IS_ERR
(
priv
->
base
))
{
ret
=
PTR_ERR
(
priv
->
base
);
ret
=
PTR_ERR
(
priv
->
base
);
goto
out_master_put
;
goto
out_master_put
;
}
}
priv
->
base_dma_addr
=
res
->
start
;
priv
->
clk
=
devm_clk_get
(
&
pdev
->
dev
,
NULL
);
priv
->
clk
=
devm_clk_get
(
&
pdev
->
dev
,
NULL
);
if
(
IS_ERR
(
priv
->
clk
))
{
if
(
IS_ERR
(
priv
->
clk
))
{
...
@@ -538,7 +708,45 @@ static int uniphier_spi_probe(struct platform_device *pdev)
...
@@ -538,7 +708,45 @@ static int uniphier_spi_probe(struct platform_device *pdev)
=
uniphier_spi_prepare_transfer_hardware
;
=
uniphier_spi_prepare_transfer_hardware
;
master
->
unprepare_transfer_hardware
master
->
unprepare_transfer_hardware
=
uniphier_spi_unprepare_transfer_hardware
;
=
uniphier_spi_unprepare_transfer_hardware
;
master
->
handle_err
=
uniphier_spi_handle_err
;
master
->
can_dma
=
uniphier_spi_can_dma
;
master
->
num_chipselect
=
1
;
master
->
num_chipselect
=
1
;
master
->
flags
=
SPI_CONTROLLER_MUST_RX
|
SPI_CONTROLLER_MUST_TX
;
master
->
dma_tx
=
dma_request_chan
(
&
pdev
->
dev
,
"tx"
);
if
(
IS_ERR_OR_NULL
(
master
->
dma_tx
))
{
if
(
PTR_ERR
(
master
->
dma_tx
)
==
-
EPROBE_DEFER
)
goto
out_disable_clk
;
master
->
dma_tx
=
NULL
;
dma_tx_burst
=
INT_MAX
;
}
else
{
ret
=
dma_get_slave_caps
(
master
->
dma_tx
,
&
caps
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to get TX DMA capacities: %d
\n
"
,
ret
);
goto
out_disable_clk
;
}
dma_tx_burst
=
caps
.
max_burst
;
}
master
->
dma_rx
=
dma_request_chan
(
&
pdev
->
dev
,
"rx"
);
if
(
IS_ERR_OR_NULL
(
master
->
dma_rx
))
{
if
(
PTR_ERR
(
master
->
dma_rx
)
==
-
EPROBE_DEFER
)
goto
out_disable_clk
;
master
->
dma_rx
=
NULL
;
dma_rx_burst
=
INT_MAX
;
}
else
{
ret
=
dma_get_slave_caps
(
master
->
dma_rx
,
&
caps
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to get RX DMA capacities: %d
\n
"
,
ret
);
goto
out_disable_clk
;
}
dma_rx_burst
=
caps
.
max_burst
;
}
master
->
max_dma_len
=
min
(
dma_tx_burst
,
dma_rx_burst
);
ret
=
devm_spi_register_master
(
&
pdev
->
dev
,
master
);
ret
=
devm_spi_register_master
(
&
pdev
->
dev
,
master
);
if
(
ret
)
if
(
ret
)
...
@@ -558,6 +766,11 @@ static int uniphier_spi_remove(struct platform_device *pdev)
...
@@ -558,6 +766,11 @@ static int uniphier_spi_remove(struct platform_device *pdev)
{
{
struct
uniphier_spi_priv
*
priv
=
platform_get_drvdata
(
pdev
);
struct
uniphier_spi_priv
*
priv
=
platform_get_drvdata
(
pdev
);
if
(
priv
->
master
->
dma_tx
)
dma_release_channel
(
priv
->
master
->
dma_tx
);
if
(
priv
->
master
->
dma_rx
)
dma_release_channel
(
priv
->
master
->
dma_rx
);
clk_disable_unprepare
(
priv
->
clk
);
clk_disable_unprepare
(
priv
->
clk
);
return
0
;
return
0
;
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi.c
View file @
754a36a5
...
@@ -1674,6 +1674,13 @@ void spi_finalize_current_message(struct spi_controller *ctlr)
...
@@ -1674,6 +1674,13 @@ void spi_finalize_current_message(struct spi_controller *ctlr)
}
}
}
}
if
(
unlikely
(
ctlr
->
ptp_sts_supported
))
{
list_for_each_entry
(
xfer
,
&
mesg
->
transfers
,
transfer_list
)
{
WARN_ON_ONCE
(
xfer
->
ptp_sts
&&
!
xfer
->
timestamped_pre
);
WARN_ON_ONCE
(
xfer
->
ptp_sts
&&
!
xfer
->
timestamped_post
);
}
}
spi_unmap_msg
(
ctlr
,
mesg
);
spi_unmap_msg
(
ctlr
,
mesg
);
if
(
ctlr
->
cur_msg_prepared
&&
ctlr
->
unprepare_message
)
{
if
(
ctlr
->
cur_msg_prepared
&&
ctlr
->
unprepare_message
)
{
...
@@ -2451,6 +2458,8 @@ static int spi_get_gpio_descs(struct spi_controller *ctlr)
...
@@ -2451,6 +2458,8 @@ static int spi_get_gpio_descs(struct spi_controller *ctlr)
int
nb
,
i
;
int
nb
,
i
;
struct
gpio_desc
**
cs
;
struct
gpio_desc
**
cs
;
struct
device
*
dev
=
&
ctlr
->
dev
;
struct
device
*
dev
=
&
ctlr
->
dev
;
unsigned
long
native_cs_mask
=
0
;
unsigned
int
num_cs_gpios
=
0
;
nb
=
gpiod_count
(
dev
,
"cs"
);
nb
=
gpiod_count
(
dev
,
"cs"
);
ctlr
->
num_chipselect
=
max_t
(
int
,
nb
,
ctlr
->
num_chipselect
);
ctlr
->
num_chipselect
=
max_t
(
int
,
nb
,
ctlr
->
num_chipselect
);
...
@@ -2492,7 +2501,22 @@ static int spi_get_gpio_descs(struct spi_controller *ctlr)
...
@@ -2492,7 +2501,22 @@ static int spi_get_gpio_descs(struct spi_controller *ctlr)
if
(
!
gpioname
)
if
(
!
gpioname
)
return
-
ENOMEM
;
return
-
ENOMEM
;
gpiod_set_consumer_name
(
cs
[
i
],
gpioname
);
gpiod_set_consumer_name
(
cs
[
i
],
gpioname
);
num_cs_gpios
++
;
continue
;
}
}
if
(
ctlr
->
max_native_cs
&&
i
>=
ctlr
->
max_native_cs
)
{
dev_err
(
dev
,
"Invalid native chip select %d
\n
"
,
i
);
return
-
EINVAL
;
}
native_cs_mask
|=
BIT
(
i
);
}
ctlr
->
unused_native_cs
=
ffz
(
native_cs_mask
);
if
(
num_cs_gpios
&&
ctlr
->
max_native_cs
&&
ctlr
->
unused_native_cs
>=
ctlr
->
max_native_cs
)
{
dev_err
(
dev
,
"No unused native chip select available
\n
"
);
return
-
EINVAL
;
}
}
return
0
;
return
0
;
...
...
This diff is collapsed.
Click to expand it.
include/linux/spi/spi.h
View file @
754a36a5
...
@@ -423,6 +423,12 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
...
@@ -423,6 +423,12 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
* GPIO descriptors rather than using global GPIO numbers grabbed by the
* GPIO descriptors rather than using global GPIO numbers grabbed by the
* driver. This will fill in @cs_gpiods and @cs_gpios should not be used,
* driver. This will fill in @cs_gpiods and @cs_gpios should not be used,
* and SPI devices will have the cs_gpiod assigned rather than cs_gpio.
* and SPI devices will have the cs_gpiod assigned rather than cs_gpio.
* @unused_native_cs: When cs_gpiods is used, spi_register_controller() will
* fill in this field with the first unused native CS, to be used by SPI
* controller drivers that need to drive a native CS when using GPIO CS.
* @max_native_cs: When cs_gpiods is used, and this field is filled in,
* spi_register_controller() will validate all native CS (including the
* unused native CS) against this value.
* @statistics: statistics for the spi_controller
* @statistics: statistics for the spi_controller
* @dma_tx: DMA transmit channel
* @dma_tx: DMA transmit channel
* @dma_rx: DMA receive channel
* @dma_rx: DMA receive channel
...
@@ -624,6 +630,8 @@ struct spi_controller {
...
@@ -624,6 +630,8 @@ struct spi_controller {
int
*
cs_gpios
;
int
*
cs_gpios
;
struct
gpio_desc
**
cs_gpiods
;
struct
gpio_desc
**
cs_gpiods
;
bool
use_gpio_descriptors
;
bool
use_gpio_descriptors
;
u8
unused_native_cs
;
u8
max_native_cs
;
/* statistics */
/* statistics */
struct
spi_statistics
statistics
;
struct
spi_statistics
statistics
;
...
...
This diff is collapsed.
Click to expand it.
include/linux/spi/spi_oc_tiny.h
View file @
754a36a5
...
@@ -6,16 +6,12 @@
...
@@ -6,16 +6,12 @@
* struct tiny_spi_platform_data - platform data of the OpenCores tiny SPI
* struct tiny_spi_platform_data - platform data of the OpenCores tiny SPI
* @freq: input clock freq to the core.
* @freq: input clock freq to the core.
* @baudwidth: baud rate divider width of the core.
* @baudwidth: baud rate divider width of the core.
* @gpio_cs_count: number of gpio pins used for chipselect.
* @gpio_cs: array of gpio pins used for chipselect.
*
*
* freq and baudwidth are used only if the divider is programmable.
* freq and baudwidth are used only if the divider is programmable.
*/
*/
struct
tiny_spi_platform_data
{
struct
tiny_spi_platform_data
{
unsigned
int
freq
;
unsigned
int
freq
;
unsigned
int
baudwidth
;
unsigned
int
baudwidth
;
unsigned
int
gpio_cs_count
;
int
*
gpio_cs
;
};
};
#endif
/* _LINUX_SPI_SPI_OC_TINY_H */
#endif
/* _LINUX_SPI_SPI_OC_TINY_H */
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment