There's been quite a lot of generic activity here, but more
 administrative than featuers.  We also have a bunch of new drivers,
 including one that's part of a MFD so we pulled in the core parts of
 that:
 
  - Lots of work from both Yang Yingliang and Andy Shevchenko on moving
    to host/device/controller based terminology for devices.
  - QuadSPI SPI support for Allwinner sun6i.
  - New device support Cirrus Logic CS43L43, Longsoon, Qualcomm GENI
    QuPv3 and StarFive JH7110 QSPI.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmTp6KQACgkQJNaLcl1U
 h9BHMQf+Jtvdx8cIhzVyMRBUfmeEzpi5oGiurPiQVBM5RsO0APULbxdy1kBsQ4FO
 5Omv7juG323XiZc1hrtBPNoZfnn83pjjMFZZZYse8Ntd6e5iesHzxRQJaml8NPBA
 0ktJQiB6Eh9WTjYT6LgN8T5j4SLT5F2jiDinBPUj1vHGSy0YXGWpYFq9QIkXwMbE
 8n0jyf5+Neccs4CIiPR3ap8NjIyPE/b761acRFkOmF+iiHWmnFrQYNS4CSxR2kOC
 yL0SlzuoG2feYSfiHyCKIPC0MGT5/Vn1tzNqoEam6B6Ecql24W8BMdU0/No3yKPT
 22LIfRWR9Wb5usFxjDxIs9YaWD4abA==
 =oj/i
 -----END PGP SIGNATURE-----

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

Pull spi updates from Mark Brown:
 "There's been quite a lot of generic activity here, but more
  administrative than featuers. We also have a bunch of new drivers,
  including one that's part of a MFD so we pulled in the core parts of
  that:

   - Lots of work from both Yang Yingliang and Andy Shevchenko on moving
     to host/device/controller based terminology for devices.

   - QuadSPI SPI support for Allwinner sun6i.

   - New device support Cirrus Logic CS43L43, Longsoon, Qualcomm GENI
     QuPv3 and StarFive JH7110 QSPI"

* tag 'spi-v6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (151 commits)
  spi: at91-usart: Use PTR_ERR_OR_ZERO() to simplify code
  spi: spi-sn-f-ospi: switch to use modern name
  spi: sifive: switch to use modern name
  spi: sh: switch to use modern name
  spi: sh-sci: switch to use modern name
  spi: sh-msiof: switch to use modern name
  spi: sh-hspi: switch to use modern name
  spi: sc18is602: switch to use modern name
  spi: s3c64xx: switch to use modern name
  spi: rzv2m-csi: switch to use devm_spi_alloc_host()
  spi: rspi: switch to use spi_alloc_host()
  spi: rockchip: switch to use modern name
  spi: rockchip-sfc: switch to use modern name
  spi: realtek-rtl: switch to use devm_spi_alloc_host()
  spi: rb4xx: switch to use modern name
  spi: qup: switch to use modern name
  spi: spi-qcom-qspi: switch to use modern name
  spi: pxa2xx: switch to use modern name
  spi: ppc4xx: switch to use modern name
  spi: spl022: switch to use modern name
  ...
This commit is contained in:
Linus Torvalds 2023-08-29 09:47:33 -07:00
Родитель 65234f96f2 60ea3db33f
Коммит 3b6bf5b1f8
153 изменённых файлов: 7494 добавлений и 2576 удалений

Просмотреть файл

@ -0,0 +1,313 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/cirrus,cs42l43.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Cirrus Logic CS42L43 Audio CODEC
maintainers:
- patches@opensource.cirrus.com
description: |
The CS42L43 is an audio CODEC with integrated MIPI SoundWire interface
(Version 1.2.1 compliant), I2C, SPI, and I2S/TDM interfaces designed
for portable applications. It provides a high dynamic range, stereo
DAC for headphone output, two integrated Class D amplifiers for
loudspeakers, and two ADCs for wired headset microphone input or
stereo line input. PDM inputs are provided for digital microphones.
allOf:
- $ref: dai-common.yaml#
properties:
compatible:
enum:
- cirrus,cs42l43
reg:
maxItems: 1
vdd-p-supply:
description:
Power supply for the high voltage interface.
vdd-a-supply:
description:
Power supply for internal analog circuits.
vdd-d-supply:
description:
Power supply for internal digital circuits. Can be internally supplied.
vdd-io-supply:
description:
Power supply for external interface and internal digital logic.
vdd-cp-supply:
description:
Power supply for the amplifier 3 and 4 charge pump.
vdd-amp-supply:
description:
Power supply for amplifier 1 and 2.
reset-gpios:
maxItems: 1
interrupt-controller: true
"#interrupt-cells":
const: 2
interrupts:
maxItems: 1
"#sound-dai-cells":
const: 1
clocks:
items:
- description: Synchronous audio clock provided on mclk_in.
clock-names:
const: mclk
cirrus,bias-low:
type: boolean
description:
Select a 1.8V headset micbias rather than 2.8V.
cirrus,bias-sense-microamp:
description:
Current at which the headset micbias sense clamp will engage, 0 to
disable.
enum: [ 0, 14, 23, 41, 50, 60, 68, 86, 95 ]
default: 0
cirrus,bias-ramp-ms:
description:
Time in milliseconds the hardware allows for the headset micbias to
ramp up.
enum: [ 10, 40, 90, 170 ]
default: 170
cirrus,detect-us:
description:
Time in microseconds the type detection will run for. Long values will
cause more audible effects, but give more accurate detection.
enum: [ 20, 100, 1000, 10000, 50000, 75000, 100000, 200000 ]
default: 10000
cirrus,button-automute:
type: boolean
description:
Enable the hardware automuting of decimator 1 when a headset button is
pressed.
cirrus,buttons-ohms:
description:
Impedance in Ohms for each headset button, these should be listed in
ascending order.
minItems: 1
maxItems: 6
cirrus,tip-debounce-ms:
description:
Software debounce on tip sense triggering in milliseconds.
default: 0
cirrus,tip-invert:
type: boolean
description:
Indicates tip detect polarity, inverted implies open-circuit whilst the
jack is inserted.
cirrus,tip-disable-pullup:
type: boolean
description:
Indicates if the internal pullup on the tip detect should be disabled.
cirrus,tip-fall-db-ms:
description:
Time in milliseconds a falling edge on the tip detect should be hardware
debounced for. Note the falling edge is considered after the invert.
enum: [ 0, 125, 250, 500, 750, 1000, 1250, 1500 ]
default: 500
cirrus,tip-rise-db-ms:
description:
Time in milliseconds a rising edge on the tip detect should be hardware
debounced for. Note the rising edge is considered after the invert.
enum: [ 0, 125, 250, 500, 750, 1000, 1250, 1500 ]
default: 500
cirrus,use-ring-sense:
type: boolean
description:
Indicates if the ring sense should be used.
cirrus,ring-invert:
type: boolean
description:
Indicates ring detect polarity, inverted implies open-circuit whilst the
jack is inserted.
cirrus,ring-disable-pullup:
type: boolean
description:
Indicates if the internal pullup on the ring detect should be disabled.
cirrus,ring-fall-db-ms:
description:
Time in milliseconds a falling edge on the ring detect should be hardware
debounced for. Note the falling edge is considered after the invert.
enum: [ 0, 125, 250, 500, 750, 1000, 1250, 1500 ]
default: 500
cirrus,ring-rise-db-ms:
description:
Time in milliseconds a rising edge on the ring detect should be hardware
debounced for. Note the rising edge is considered after the invert.
enum: [ 0, 125, 250, 500, 750, 1000, 1250, 1500 ]
default: 500
pinctrl:
type: object
$ref: /schemas/pinctrl/pinctrl.yaml#
additionalProperties: false
properties:
gpio-controller: true
"#gpio-cells":
const: 2
gpio-ranges:
items:
- description: A phandle to the CODEC pinctrl node
minimum: 0
- const: 0
- const: 0
- const: 3
patternProperties:
"-state$":
oneOf:
- $ref: "#/$defs/cirrus-cs42l43-state"
- patternProperties:
"-pins$":
$ref: "#/$defs/cirrus-cs42l43-state"
additionalProperties: false
spi:
type: object
$ref: /schemas/spi/spi-controller.yaml#
unevaluatedProperties: false
$defs:
cirrus-cs42l43-state:
type: object
allOf:
- $ref: /schemas/pinctrl/pincfg-node.yaml#
- $ref: /schemas/pinctrl/pinmux-node.yaml#
oneOf:
- required: [ groups ]
- required: [ pins ]
additionalProperties: false
properties:
groups:
enum: [ gpio1, gpio2, gpio3, asp, pdmout2, pdmout1, i2c, spi ]
pins:
enum: [ gpio1, gpio2, gpio3,
asp_dout, asp_fsync, asp_bclk,
pdmout2_clk, pdmout2_data, pdmout1_clk, pdmout1_data,
i2c_sda, i2c_scl,
spi_miso, spi_sck, spi_ssb ]
function:
enum: [ gpio, spdif, irq, mic-shutter, spk-shutter ]
drive-strength:
description: Set drive strength in mA
enum: [ 1, 2, 4, 8, 9, 10, 12, 16 ]
input-debounce:
description: Set input debounce in uS
enum: [ 0, 85 ]
required:
- compatible
- reg
- vdd-p-supply
- vdd-a-supply
- vdd-io-supply
- vdd-cp-supply
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
cs42l43: codec@1a {
compatible = "cirrus,cs42l43";
reg = <0x1a>;
vdd-p-supply = <&vdd5v0>;
vdd-a-supply = <&vdd1v8>;
vdd-io-supply = <&vdd1v8>;
vdd-cp-supply = <&vdd1v8>;
vdd-amp-supply = <&vdd5v0>;
reset-gpios = <&gpio 0>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&gpio>;
interrupts = <56 IRQ_TYPE_LEVEL_LOW>;
#sound-dai-cells = <1>;
clocks = <&clks 0>;
clock-names = "mclk";
cs42l43_pins: pinctrl {
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&cs42l43_pins 0 0 3>;
pinctrl-names = "default";
pinctrl-0 = <&pinsettings>;
pinsettings: default-state {
shutter-pins {
groups = "gpio3";
function = "mic-shutter";
};
};
};
spi {
#address-cells = <1>;
#size-cells = <0>;
cs-gpios = <&cs42l43_pins 1 0>;
sensor@0 {
compatible = "bosch,bme680";
reg = <0>;
spi-max-frequency = <1400000>;
};
};
};
};

Просмотреть файл

@ -0,0 +1,71 @@
# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/spi/brcm,bcm63xx-spi.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Broadcom BCM6348/BCM6358 SPI controller
maintainers:
- Jonas Gorski <jonas.gorski@gmail.com>
description: |
Broadcom "Low Speed" SPI controller found in many older MIPS based Broadband
SoCs.
This controller has a limitation that can not keep the chip select line active
between the SPI transfers within the same SPI message. This can terminate the
transaction to some SPI devices prematurely. The issue can be worked around by
the controller's prepend mode.
allOf:
- $ref: spi-controller.yaml#
properties:
compatible:
oneOf:
- items:
- enum:
- brcm,bcm6368-spi
- brcm,bcm6362-spi
- brcm,bcm63268-spi
- const: brcm,bcm6358-spi
- enum:
- brcm,bcm6348-spi
- brcm,bcm6358-spi
reg:
maxItems: 1
clocks:
items:
- description: SPI master reference clock
clock-names:
items:
- const: spi
interrupts:
maxItems: 1
required:
- compatible
- reg
- clocks
- clock-names
- interrupts
unevaluatedProperties: false
examples:
- |
spi@10000800 {
compatible = "brcm,bcm6368-spi", "brcm,bcm6358-spi";
reg = <0x10000800 0x70c>;
interrupts = <1>;
clocks = <&clkctl 9>;
clock-names = "spi";
num-cs = <5>;
#address-cells = <1>;
#size-cells = <0>;
};

Просмотреть файл

@ -86,7 +86,17 @@ properties:
maxItems: 1
clocks:
maxItems: 1
minItems: 1
maxItems: 3
clock-names:
oneOf:
- items:
- const: ref
- items:
- const: ref
- const: ahb
- const: apb
cdns,fifo-depth:
description:

Просмотреть файл

@ -0,0 +1,46 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/spi/loongson,ls2k-spi.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Loongson SPI controller
maintainers:
- Yinbo Zhu <zhuyinbo@loongson.cn>
allOf:
- $ref: /schemas/spi/spi-controller.yaml#
properties:
compatible:
oneOf:
- enum:
- loongson,ls2k1000-spi
- items:
- enum:
- loongson,ls2k0500-spi
- const: loongson,ls2k1000-spi
reg:
maxItems: 1
clocks:
maxItems: 1
required:
- compatible
- reg
- clocks
unevaluatedProperties: false
examples:
- |
spi0: spi@1fff0220{
compatible = "loongson,ls2k1000-spi";
reg = <0x1fff0220 0x10>;
clocks = <&clk 17>;
#address-cells = <1>;
#size-cells = <0>;
};

Просмотреть файл

@ -1,61 +0,0 @@
NVIDIA Tegra114 SPI controller.
Required properties:
- compatible : For Tegra114, must contain "nvidia,tegra114-spi".
Otherwise, must contain '"nvidia,<chip>-spi", "nvidia,tegra114-spi"' where
<chip> is tegra124, tegra132, or tegra210.
- reg: Should contain SPI registers location and length.
- interrupts: Should contain SPI interrupts.
- clock-names : Must include the following entries:
- spi
- resets : Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- reset-names : Must include the following entries:
- spi
- dmas : Must contain an entry for each entry in clock-names.
See ../dma/dma.txt for details.
- dma-names : Must include the following entries:
- rx
- tx
- clocks : Must contain an entry for each entry in clock-names.
See ../clocks/clock-bindings.txt for details.
Recommended properties:
- spi-max-frequency: Definition as per
Documentation/devicetree/bindings/spi/spi-bus.txt
Optional properties:
- nvidia,tx-clk-tap-delay: Delays the clock going out to the external device
with this tap value. This property is used to tune the outgoing data from
Tegra SPI master with respect to outgoing Tegra SPI master clock.
Tap values vary based on the platform design trace lengths from Tegra SPI
to corresponding slave devices. Valid tap values are from 0 thru 63.
- nvidia,rx-clk-tap-delay: Delays the clock coming in from the external device
with this tap value. This property is used to adjust the Tegra SPI master
clock with respect to the data from the SPI slave device.
Tap values vary based on the platform design trace lengths from Tegra SPI
to corresponding slave devices. Valid tap values are from 0 thru 63.
Example:
spi@7000d600 {
compatible = "nvidia,tegra114-spi";
reg = <0x7000d600 0x200>;
interrupts = <0 82 0x04>;
spi-max-frequency = <25000000>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&tegra_car 44>;
clock-names = "spi";
resets = <&tegra_car 44>;
reset-names = "spi";
dmas = <&apbdma 16>, <&apbdma 16>;
dma-names = "rx", "tx";
<spi-client>@<bus_num> {
...
...
nvidia,rx-clk-tap-delay = <0>;
nvidia,tx-clk-tap-delay = <16>;
...
};
};

Просмотреть файл

@ -0,0 +1,100 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/spi/nvidia,tegra114-spi.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NVIDIA Tegra114 SPI controller
maintainers:
- Thierry Reding <thierry.reding@gmail.com>
- Jon Hunter <jonathanh@nvidia.com>
properties:
compatible:
oneOf:
- const: nvidia,tegra114-spi
- items:
- enum:
- nvidia,tegra210-spi
- nvidia,tegra124-spi
- const: nvidia,tegra114-spi
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
items:
- description: SPI module clock
clock-names:
items:
- const: spi
resets:
items:
- description: SPI module reset
reset-names:
items:
- const: spi
dmas:
items:
- description: DMA channel for the reception FIFO
- description: DMA channel for the transmission FIFO
dma-names:
items:
- const: rx
- const: tx
spi-max-frequency:
description: Maximum SPI clocking speed of the controller in Hz.
$ref: /schemas/types.yaml#/definitions/uint32
allOf:
- $ref: spi-controller.yaml
unevaluatedProperties: false
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
- resets
- reset-names
- dmas
- dma-names
examples:
- |
spi@7000d600 {
compatible = "nvidia,tegra114-spi";
reg = <0x7000d600 0x200>;
interrupts = <0 82 0x04>;
clocks = <&tegra_car 44>;
clock-names = "spi";
resets = <&tegra_car 44>;
reset-names = "spi";
dmas = <&apbdma 16>, <&apbdma 16>;
dma-names = "rx", "tx";
spi-max-frequency = <25000000>;
#address-cells = <1>;
#size-cells = <0>;
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <20000000>;
nvidia,rx-clk-tap-delay = <0>;
nvidia,tx-clk-tap-delay = <16>;
};
};

Просмотреть файл

@ -1,37 +0,0 @@
NVIDIA Tegra20 SFLASH controller.
Required properties:
- compatible : should be "nvidia,tegra20-sflash".
- reg: Should contain SFLASH registers location and length.
- interrupts: Should contain SFLASH interrupts.
- clocks : Must contain one entry, for the module clock.
See ../clocks/clock-bindings.txt for details.
- resets : Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- reset-names : Must include the following entries:
- spi
- dmas : Must contain an entry for each entry in clock-names.
See ../dma/dma.txt for details.
- dma-names : Must include the following entries:
- rx
- tx
Recommended properties:
- spi-max-frequency: Definition as per
Documentation/devicetree/bindings/spi/spi-bus.txt
Example:
spi@7000c380 {
compatible = "nvidia,tegra20-sflash";
reg = <0x7000c380 0x80>;
interrupts = <0 39 0x04>;
spi-max-frequency = <25000000>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&tegra_car 43>;
resets = <&tegra_car 43>;
reset-names = "spi";
dmas = <&apbdma 11>, <&apbdma 11>;
dma-names = "rx", "tx";
};

Просмотреть файл

@ -0,0 +1,81 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/spi/nvidia,tegra20-sflash.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NVIDIA Tegra20 SFLASH controller
maintainers:
- Thierry Reding <thierry.reding@gmail.com>
- Jon Hunter <jonathanh@nvidia.com>
properties:
compatible:
const: nvidia,tegra20-sflash
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
items:
- description: module clock
resets:
items:
- description: module reset
reset-names:
items:
- const: spi
dmas:
items:
- description: DMA channel used for reception
- description: DMA channel used for transmission
dma-names:
items:
- const: rx
- const: tx
spi-max-frequency:
description: Maximum SPI clocking speed of the controller in Hz.
$ref: /schemas/types.yaml#/definitions/uint32
allOf:
- $ref: spi-controller.yaml
unevaluatedProperties: false
required:
- compatible
- reg
- interrupts
- clocks
- resets
- reset-names
- dmas
- dma-names
examples:
- |
#include <dt-bindings/clock/tegra20-car.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
spi@7000c380 {
compatible = "nvidia,tegra20-sflash";
reg = <0x7000c380 0x80>;
interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
spi-max-frequency = <25000000>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&tegra_car TEGRA20_CLK_SPI>;
resets = <&tegra_car 43>;
reset-names = "spi";
dmas = <&apbdma 11>, <&apbdma 11>;
dma-names = "rx", "tx";
};

Просмотреть файл

@ -1,37 +0,0 @@
NVIDIA Tegra20/Tegra30 SLINK controller.
Required properties:
- compatible : should be "nvidia,tegra20-slink", "nvidia,tegra30-slink".
- reg: Should contain SLINK registers location and length.
- interrupts: Should contain SLINK interrupts.
- clocks : Must contain one entry, for the module clock.
See ../clocks/clock-bindings.txt for details.
- resets : Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- reset-names : Must include the following entries:
- spi
- dmas : Must contain an entry for each entry in clock-names.
See ../dma/dma.txt for details.
- dma-names : Must include the following entries:
- rx
- tx
Recommended properties:
- spi-max-frequency: Definition as per
Documentation/devicetree/bindings/spi/spi-bus.txt
Example:
spi@7000d600 {
compatible = "nvidia,tegra20-slink";
reg = <0x7000d600 0x200>;
interrupts = <0 82 0x04>;
spi-max-frequency = <25000000>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&tegra_car 44>;
resets = <&tegra_car 44>;
reset-names = "spi";
dmas = <&apbdma 16>, <&apbdma 16>;
dma-names = "rx", "tx";
};

Просмотреть файл

@ -0,0 +1,90 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/spi/nvidia,tegra20-slink.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NVIDIA Tegra20/30 SLINK controller
maintainers:
- Thierry Reding <thierry.reding@gmail.com>
- Jon Hunter <jonathanh@nvidia.com>
properties:
compatible:
enum:
- nvidia,tegra20-slink
- nvidia,tegra30-slink
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
items:
- description: module clock
resets:
items:
- description: module reset
reset-names:
items:
- const: spi
dmas:
items:
- description: DMA channel used for reception
- description: DMA channel used for transmission
dma-names:
items:
- const: rx
- const: tx
operating-points-v2:
$ref: /schemas/types.yaml#/definitions/phandle
power-domains:
items:
- description: phandle to the core power domain
spi-max-frequency:
description: Maximum SPI clocking speed of the controller in Hz.
$ref: /schemas/types.yaml#/definitions/uint32
allOf:
- $ref: spi-controller.yaml
unevaluatedProperties: false
required:
- compatible
- reg
- interrupts
- clocks
- resets
- reset-names
- dmas
- dma-names
examples:
- |
#include <dt-bindings/clock/tegra20-car.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
spi@7000d600 {
compatible = "nvidia,tegra20-slink";
reg = <0x7000d600 0x200>;
interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
spi-max-frequency = <25000000>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&tegra_car TEGRA20_CLK_SBC2>;
resets = <&tegra_car 44>;
reset-names = "spi";
dmas = <&apbdma 16>, <&apbdma 16>;
dma-names = "rx", "tx";
};

Просмотреть файл

@ -1,33 +0,0 @@
Binding for Broadcom BCM6348/BCM6358 SPI controller
Required properties:
- compatible: must contain one of "brcm,bcm6348-spi", "brcm,bcm6358-spi".
- reg: Base address and size of the controllers memory area.
- interrupts: Interrupt for the SPI block.
- clocks: phandle of the SPI clock.
- clock-names: has to be "spi".
- #address-cells: <1>, as required by generic SPI binding.
- #size-cells: <0>, also as required by generic SPI binding.
Optional properties:
- num-cs: some controllers have less than 8 cs signals. Defaults to 8
if absent.
Child nodes as per the generic SPI binding.
Example:
spi@10000800 {
compatible = "brcm,bcm6368-spi", "brcm,bcm6358-spi";
reg = <0x10000800 0x70c>;
interrupts = <1>;
clocks = <&clkctl 9>;
clock-names = "spi";
num-cs = <5>;
#address-cells = <1>;
#size-cells = <0>;
};

Просмотреть файл

@ -49,6 +49,12 @@ properties:
enum: [ 0, 1 ]
default: 0
power-domains:
maxItems: 1
label:
description: Descriptive name of the SPI controller.
required:
- compatible
- reg

Просмотреть файл

@ -63,6 +63,9 @@ properties:
maximum: 2
default: 1
power-domains:
maxItems: 1
required:
- compatible
- reg

Просмотреть файл

@ -45,6 +45,9 @@ properties:
- const: fspi_en
- const: fspi
power-domains:
maxItems: 1
required:
- compatible
- reg

Просмотреть файл

@ -11,6 +11,7 @@ maintainers:
allOf:
- $ref: spi-controller.yaml#
- $ref: /schemas/arm/primecell.yaml#
# We need a select here so we don't match all nodes with 'arm,primecell'
select:

Просмотреть файл

@ -4126,7 +4126,7 @@ BROADCOM BCM6348/BCM6358 SPI controller DRIVER
M: Jonas Gorski <jonas.gorski@gmail.com>
L: linux-spi@vger.kernel.org
S: Odd Fixes
F: Documentation/devicetree/bindings/spi/spi-bcm63xx.txt
F: Documentation/devicetree/bindings/spi/brcm,bcm63xx-spi.yaml
F: drivers/spi/spi-bcm63xx.c
BROADCOM ETHERNET PHY DRIVERS
@ -4887,7 +4887,11 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers)
L: patches@opensource.cirrus.com
S: Maintained
F: Documentation/devicetree/bindings/sound/cirrus,cs*
F: drivers/mfd/cs42l43*
F: drivers/pinctrl/cirrus/pinctrl-cs42l43*
F: drivers/spi/spi-cs42l43*
F: include/dt-bindings/sound/cs*
F: include/linux/mfd/cs42l43*
F: include/sound/cs*
F: sound/pci/hda/cs*
F: sound/pci/hda/hda_cs_dsp_ctl.*
@ -12282,6 +12286,16 @@ F: Documentation/devicetree/bindings/clock/loongson,ls2k-clk.yaml
F: drivers/clk/clk-loongson2.c
F: include/dt-bindings/clock/loongson,ls2k-clk.h
LOONGSON SPI DRIVER
M: Yinbo Zhu <zhuyinbo@loongson.cn>
L: linux-spi@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/spi/loongson,ls2k-spi.yaml
F: drivers/spi/spi-loongson-core.c
F: drivers/spi/spi-loongson-pci.c
F: drivers/spi/spi-loongson-plat.c
F: drivers/spi/spi-loongson.h
LOONGSON-2 SOC SERIES GUTS DRIVER
M: Yinbo Zhu <zhuyinbo@loongson.cn>
L: loongarch@lists.linux.dev

Просмотреть файл

@ -237,6 +237,29 @@ config MFD_CROS_EC_DEV
To compile this driver as a module, choose M here: the module will be
called cros-ec-dev.
config MFD_CS42L43
tristate
select MFD_CORE
select REGMAP
config MFD_CS42L43_I2C
tristate "Cirrus Logic CS42L43 (I2C)"
depends on I2C
select REGMAP_I2C
select MFD_CS42L43
help
Select this to support the Cirrus Logic CS42L43 PC CODEC with
headphone and class D speaker drivers over I2C.
config MFD_CS42L43_SDW
tristate "Cirrus Logic CS42L43 (SoundWire)"
depends on SOUNDWIRE
select REGMAP_SOUNDWIRE
select MFD_CS42L43
help
Select this to support the Cirrus Logic CS42L43 PC CODEC with
headphone and class D speaker drivers over SoundWire.
config MFD_MADERA
tristate "Cirrus Logic Madera codecs"
select MFD_CORE

Просмотреть файл

@ -13,6 +13,9 @@ obj-$(CONFIG_ARCH_BCM2835) += bcm2835-pm.o
obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o
obj-$(CONFIG_MFD_BD9571MWV) += bd9571mwv.o
obj-$(CONFIG_MFD_CROS_EC_DEV) += cros_ec_dev.o
obj-$(CONFIG_MFD_CS42L43) += cs42l43.o
obj-$(CONFIG_MFD_CS42L43_I2C) += cs42l43-i2c.o
obj-$(CONFIG_MFD_CS42L43_SDW) += cs42l43-sdw.o
obj-$(CONFIG_MFD_ENE_KB3930) += ene-kb3930.o
obj-$(CONFIG_MFD_EXYNOS_LPASS) += exynos-lpass.o
obj-$(CONFIG_MFD_GATEWORKS_GSC) += gateworks-gsc.o

98
drivers/mfd/cs42l43-i2c.c Normal file
Просмотреть файл

@ -0,0 +1,98 @@
// SPDX-License-Identifier: GPL-2.0
/*
* CS42L43 I2C driver
*
* Copyright (C) 2022-2023 Cirrus Logic, Inc. and
* Cirrus Logic International Semiconductor Ltd.
*/
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/i2c.h>
#include <linux/mfd/cs42l43-regs.h>
#include <linux/module.h>
#include "cs42l43.h"
static const struct regmap_config cs42l43_i2c_regmap = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
.reg_format_endian = REGMAP_ENDIAN_BIG,
.val_format_endian = REGMAP_ENDIAN_BIG,
.max_register = CS42L43_MCU_RAM_MAX,
.readable_reg = cs42l43_readable_register,
.volatile_reg = cs42l43_volatile_register,
.precious_reg = cs42l43_precious_register,
.cache_type = REGCACHE_MAPLE,
.reg_defaults = cs42l43_reg_default,
.num_reg_defaults = ARRAY_SIZE(cs42l43_reg_default),
};
static int cs42l43_i2c_probe(struct i2c_client *i2c)
{
struct cs42l43 *cs42l43;
int ret;
cs42l43 = devm_kzalloc(&i2c->dev, sizeof(*cs42l43), GFP_KERNEL);
if (!cs42l43)
return -ENOMEM;
cs42l43->dev = &i2c->dev;
cs42l43->irq = i2c->irq;
/* A device on an I2C is always attached by definition. */
cs42l43->attached = true;
cs42l43->regmap = devm_regmap_init_i2c(i2c, &cs42l43_i2c_regmap);
if (IS_ERR(cs42l43->regmap)) {
ret = PTR_ERR(cs42l43->regmap);
dev_err(cs42l43->dev, "Failed to allocate regmap: %d\n", ret);
return ret;
}
return cs42l43_dev_probe(cs42l43);
}
static void cs42l43_i2c_remove(struct i2c_client *i2c)
{
struct cs42l43 *cs42l43 = dev_get_drvdata(&i2c->dev);
cs42l43_dev_remove(cs42l43);
}
#if IS_ENABLED(CONFIG_OF)
static const struct of_device_id cs42l43_of_match[] = {
{ .compatible = "cirrus,cs42l43", },
{}
};
MODULE_DEVICE_TABLE(of, cs42l43_of_match);
#endif
#if IS_ENABLED(CONFIG_ACPI)
static const struct acpi_device_id cs42l43_acpi_match[] = {
{ "CSC4243", 0 },
{}
};
MODULE_DEVICE_TABLE(acpi, cs42l43_acpi_match);
#endif
static struct i2c_driver cs42l43_i2c_driver = {
.driver = {
.name = "cs42l43",
.pm = pm_ptr(&cs42l43_pm_ops),
.of_match_table = of_match_ptr(cs42l43_of_match),
.acpi_match_table = ACPI_PTR(cs42l43_acpi_match),
},
.probe = cs42l43_i2c_probe,
.remove = cs42l43_i2c_remove,
};
module_i2c_driver(cs42l43_i2c_driver);
MODULE_IMPORT_NS(MFD_CS42L43);
MODULE_DESCRIPTION("CS42L43 I2C Driver");
MODULE_AUTHOR("Charles Keepax <ckeepax@opensource.cirrus.com>");
MODULE_LICENSE("GPL");

239
drivers/mfd/cs42l43-sdw.c Normal file
Просмотреть файл

@ -0,0 +1,239 @@
// SPDX-License-Identifier: GPL-2.0
/*
* CS42L43 SoundWire driver
*
* Copyright (C) 2022-2023 Cirrus Logic, Inc. and
* Cirrus Logic International Semiconductor Ltd.
*/
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/mfd/cs42l43-regs.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/soundwire/sdw.h>
#include <linux/soundwire/sdw_registers.h>
#include <linux/soundwire/sdw_type.h>
#include "cs42l43.h"
enum cs42l43_sdw_ports {
CS42L43_DMIC_DEC_ASP_PORT = 1,
CS42L43_SPK_TX_PORT,
CS42L43_SPDIF_HP_PORT,
CS42L43_SPK_RX_PORT,
CS42L43_ASP_PORT,
};
static const struct regmap_config cs42l43_sdw_regmap = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
.reg_format_endian = REGMAP_ENDIAN_LITTLE,
.val_format_endian = REGMAP_ENDIAN_LITTLE,
.max_register = CS42L43_MCU_RAM_MAX,
.readable_reg = cs42l43_readable_register,
.volatile_reg = cs42l43_volatile_register,
.precious_reg = cs42l43_precious_register,
.cache_type = REGCACHE_MAPLE,
.reg_defaults = cs42l43_reg_default,
.num_reg_defaults = ARRAY_SIZE(cs42l43_reg_default),
};
static int cs42l43_read_prop(struct sdw_slave *sdw)
{
struct sdw_slave_prop *prop = &sdw->prop;
struct device *dev = &sdw->dev;
struct sdw_dpn_prop *dpn;
unsigned long addr;
int nval;
int i;
u32 bit;
prop->use_domain_irq = true;
prop->paging_support = true;
prop->wake_capable = true;
prop->source_ports = BIT(CS42L43_DMIC_DEC_ASP_PORT) | BIT(CS42L43_SPK_TX_PORT);
prop->sink_ports = BIT(CS42L43_SPDIF_HP_PORT) |
BIT(CS42L43_SPK_RX_PORT) | BIT(CS42L43_ASP_PORT);
prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY;
prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY |
SDW_SCP_INT1_IMPL_DEF;
nval = hweight32(prop->source_ports);
prop->src_dpn_prop = devm_kcalloc(dev, nval, sizeof(*prop->src_dpn_prop),
GFP_KERNEL);
if (!prop->src_dpn_prop)
return -ENOMEM;
i = 0;
dpn = prop->src_dpn_prop;
addr = prop->source_ports;
for_each_set_bit(bit, &addr, 32) {
dpn[i].num = bit;
dpn[i].max_ch = 2;
dpn[i].type = SDW_DPN_FULL;
dpn[i].max_word = 24;
i++;
}
/*
* All ports are 2 channels max, except the first one,
* CS42L43_DMIC_DEC_ASP_PORT.
*/
dpn[CS42L43_DMIC_DEC_ASP_PORT].max_ch = 4;
nval = hweight32(prop->sink_ports);
prop->sink_dpn_prop = devm_kcalloc(dev, nval, sizeof(*prop->sink_dpn_prop),
GFP_KERNEL);
if (!prop->sink_dpn_prop)
return -ENOMEM;
i = 0;
dpn = prop->sink_dpn_prop;
addr = prop->sink_ports;
for_each_set_bit(bit, &addr, 32) {
dpn[i].num = bit;
dpn[i].max_ch = 2;
dpn[i].type = SDW_DPN_FULL;
dpn[i].max_word = 24;
i++;
}
return 0;
}
static int cs42l43_sdw_update_status(struct sdw_slave *sdw, enum sdw_slave_status status)
{
struct cs42l43 *cs42l43 = dev_get_drvdata(&sdw->dev);
switch (status) {
case SDW_SLAVE_ATTACHED:
dev_dbg(cs42l43->dev, "Device attach\n");
sdw_write_no_pm(sdw, CS42L43_GEN_INT_MASK_1,
CS42L43_INT_STAT_GEN1_MASK);
cs42l43->attached = true;
complete(&cs42l43->device_attach);
break;
case SDW_SLAVE_UNATTACHED:
dev_dbg(cs42l43->dev, "Device detach\n");
cs42l43->attached = false;
reinit_completion(&cs42l43->device_attach);
complete(&cs42l43->device_detach);
break;
default:
break;
}
return 0;
}
static int cs42l43_sdw_interrupt(struct sdw_slave *sdw,
struct sdw_slave_intr_status *status)
{
/*
* The IRQ itself was handled through the regmap_irq handler, this is
* just clearing up the additional Cirrus SoundWire registers that are
* not covered by the SoundWire framework or the IRQ handler itself.
* There is only a single bit in GEN_INT_STAT_1 and it doesn't clear if
* IRQs are still pending so doing a read/write here after handling the
* IRQ is fine.
*/
sdw_read_no_pm(sdw, CS42L43_GEN_INT_STAT_1);
sdw_write_no_pm(sdw, CS42L43_GEN_INT_STAT_1, CS42L43_INT_STAT_GEN1_MASK);
return 0;
}
static int cs42l43_sdw_bus_config(struct sdw_slave *sdw,
struct sdw_bus_params *params)
{
struct cs42l43 *cs42l43 = dev_get_drvdata(&sdw->dev);
int ret = 0;
mutex_lock(&cs42l43->pll_lock);
if (cs42l43->sdw_freq != params->curr_dr_freq / 2) {
if (cs42l43->sdw_pll_active) {
dev_err(cs42l43->dev,
"PLL active can't change SoundWire bus clock\n");
ret = -EBUSY;
} else {
cs42l43->sdw_freq = params->curr_dr_freq / 2;
}
}
mutex_unlock(&cs42l43->pll_lock);
return ret;
}
static const struct sdw_slave_ops cs42l43_sdw_ops = {
.read_prop = cs42l43_read_prop,
.update_status = cs42l43_sdw_update_status,
.interrupt_callback = cs42l43_sdw_interrupt,
.bus_config = cs42l43_sdw_bus_config,
};
static int cs42l43_sdw_probe(struct sdw_slave *sdw, const struct sdw_device_id *id)
{
struct cs42l43 *cs42l43;
struct device *dev = &sdw->dev;
int ret;
cs42l43 = devm_kzalloc(dev, sizeof(*cs42l43), GFP_KERNEL);
if (!cs42l43)
return -ENOMEM;
cs42l43->dev = dev;
cs42l43->sdw = sdw;
cs42l43->regmap = devm_regmap_init_sdw(sdw, &cs42l43_sdw_regmap);
if (IS_ERR(cs42l43->regmap)) {
ret = PTR_ERR(cs42l43->regmap);
dev_err(cs42l43->dev, "Failed to allocate regmap: %d\n", ret);
return ret;
}
return cs42l43_dev_probe(cs42l43);
}
static int cs42l43_sdw_remove(struct sdw_slave *sdw)
{
struct cs42l43 *cs42l43 = dev_get_drvdata(&sdw->dev);
cs42l43_dev_remove(cs42l43);
return 0;
}
static const struct sdw_device_id cs42l43_sdw_id[] = {
SDW_SLAVE_ENTRY(0x01FA, 0x4243, 0),
{}
};
MODULE_DEVICE_TABLE(sdw, cs42l43_sdw_id);
static struct sdw_driver cs42l43_sdw_driver = {
.driver = {
.name = "cs42l43",
.pm = pm_ptr(&cs42l43_pm_ops),
},
.probe = cs42l43_sdw_probe,
.remove = cs42l43_sdw_remove,
.id_table = cs42l43_sdw_id,
.ops = &cs42l43_sdw_ops,
};
module_sdw_driver(cs42l43_sdw_driver);
MODULE_IMPORT_NS(MFD_CS42L43);
MODULE_DESCRIPTION("CS42L43 SoundWire Driver");
MODULE_AUTHOR("Lucas Tanure <tanureal@opensource.cirrus.com>");
MODULE_LICENSE("GPL");

1188
drivers/mfd/cs42l43.c Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

28
drivers/mfd/cs42l43.h Normal file
Просмотреть файл

@ -0,0 +1,28 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* CS42L43 core driver internal data
*
* Copyright (C) 2022-2023 Cirrus Logic, Inc. and
* Cirrus Logic International Semiconductor Ltd.
*/
#include <linux/mfd/cs42l43.h>
#include <linux/pm.h>
#include <linux/regmap.h>
#ifndef CS42L43_CORE_INT_H
#define CS42L43_CORE_INT_H
#define CS42L43_N_DEFAULTS 176
extern const struct dev_pm_ops cs42l43_pm_ops;
extern const struct reg_default cs42l43_reg_default[CS42L43_N_DEFAULTS];
bool cs42l43_readable_register(struct device *dev, unsigned int reg);
bool cs42l43_precious_register(struct device *dev, unsigned int reg);
bool cs42l43_volatile_register(struct device *dev, unsigned int reg);
int cs42l43_dev_probe(struct cs42l43 *cs42l43);
void cs42l43_dev_remove(struct cs42l43 *cs42l43);
#endif /* CS42L43_CORE_INT_H */

Просмотреть файл

@ -1,4 +1,15 @@
# SPDX-License-Identifier: GPL-2.0-only
config PINCTRL_CS42L43
tristate "Cirrus Logic CS42L43 Pinctrl Driver"
depends on MFD_CS42L43
select GPIOLIB
select PINMUX
select PINCONF
select GENERIC_PINCONF
help
Select this to support the GPIO/Pinctrl functions of the Cirrus
Logic CS42L43 PC CODEC.
config PINCTRL_LOCHNAGAR
tristate "Cirrus Logic Lochnagar pinctrl driver"
depends on MFD_LOCHNAGAR

Просмотреть файл

@ -1,5 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
# Cirrus Logic pinctrl drivers
obj-$(CONFIG_PINCTRL_CS42L43) += pinctrl-cs42l43.o
obj-$(CONFIG_PINCTRL_LOCHNAGAR) += pinctrl-lochnagar.o
pinctrl-madera-objs := pinctrl-madera-core.o

Просмотреть файл

@ -0,0 +1,609 @@
// SPDX-License-Identifier: GPL-2.0
//
// CS42L43 Pinctrl and GPIO driver
//
// Copyright (c) 2023 Cirrus Logic, Inc. and
// Cirrus Logic International Semiconductor Ltd.
#include <linux/bits.h>
#include <linux/build_bug.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/gpio/driver.h>
#include <linux/mfd/cs42l43.h>
#include <linux/mfd/cs42l43-regs.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/string_helpers.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinmux.h>
#include "../pinctrl-utils.h"
#define CS42L43_NUM_GPIOS 3
struct cs42l43_pin {
struct gpio_chip gpio_chip;
struct device *dev;
struct regmap *regmap;
bool shutters_locked;
};
struct cs42l43_pin_data {
unsigned int reg;
unsigned int shift;
unsigned int mask;
};
#define CS42L43_PIN(_number, _name, _reg, _field) { \
.number = _number, .name = _name, \
.drv_data = &((struct cs42l43_pin_data){ \
.reg = CS42L43_##_reg, \
.shift = CS42L43_##_field##_DRV_SHIFT, \
.mask = CS42L43_##_field##_DRV_MASK, \
}), \
}
static const struct pinctrl_pin_desc cs42l43_pin_pins[] = {
CS42L43_PIN(0, "gpio1", DRV_CTRL4, GPIO1),
CS42L43_PIN(1, "gpio2", DRV_CTRL4, GPIO2),
CS42L43_PIN(2, "gpio3", DRV_CTRL4, GPIO3),
CS42L43_PIN(3, "asp_dout", DRV_CTRL1, ASP_DOUT),
CS42L43_PIN(4, "asp_fsync", DRV_CTRL1, ASP_FSYNC),
CS42L43_PIN(5, "asp_bclk", DRV_CTRL1, ASP_BCLK),
CS42L43_PIN(6, "pdmout2_clk", DRV_CTRL3, PDMOUT2_CLK),
CS42L43_PIN(7, "pdmout2_data", DRV_CTRL3, PDMOUT2_DATA),
CS42L43_PIN(8, "pdmout1_clk", DRV_CTRL3, PDMOUT1_CLK),
CS42L43_PIN(9, "pdmout1_data", DRV_CTRL3, PDMOUT1_DATA),
CS42L43_PIN(10, "i2c_sda", DRV_CTRL3, I2C_SDA),
CS42L43_PIN(11, "i2c_scl", DRV_CTRL_5, I2C_SCL),
CS42L43_PIN(12, "spi_miso", DRV_CTRL3, SPI_MISO),
CS42L43_PIN(13, "spi_sck", DRV_CTRL_5, SPI_SCK),
CS42L43_PIN(14, "spi_ssb", DRV_CTRL_5, SPI_SSB),
};
static const unsigned int cs42l43_pin_gpio1_pins[] = { 0 };
static const unsigned int cs42l43_pin_gpio2_pins[] = { 1 };
static const unsigned int cs42l43_pin_gpio3_pins[] = { 2 };
static const unsigned int cs42l43_pin_asp_pins[] = { 3, 4, 5 };
static const unsigned int cs42l43_pin_pdmout2_pins[] = { 6, 7 };
static const unsigned int cs42l43_pin_pdmout1_pins[] = { 8, 9 };
static const unsigned int cs42l43_pin_i2c_pins[] = { 10, 11 };
static const unsigned int cs42l43_pin_spi_pins[] = { 12, 13, 14 };
#define CS42L43_PINGROUP(_name) \
PINCTRL_PINGROUP(#_name, cs42l43_pin_##_name##_pins, \
ARRAY_SIZE(cs42l43_pin_##_name##_pins))
static const struct pingroup cs42l43_pin_groups[] = {
CS42L43_PINGROUP(gpio1),
CS42L43_PINGROUP(gpio2),
CS42L43_PINGROUP(gpio3),
CS42L43_PINGROUP(asp),
CS42L43_PINGROUP(pdmout2),
CS42L43_PINGROUP(pdmout1),
CS42L43_PINGROUP(i2c),
CS42L43_PINGROUP(spi),
};
static int cs42l43_pin_get_groups_count(struct pinctrl_dev *pctldev)
{
return ARRAY_SIZE(cs42l43_pin_groups);
}
static const char *cs42l43_pin_get_group_name(struct pinctrl_dev *pctldev,
unsigned int group_idx)
{
return cs42l43_pin_groups[group_idx].name;
}
static int cs42l43_pin_get_group_pins(struct pinctrl_dev *pctldev,
unsigned int group_idx,
const unsigned int **pins,
unsigned int *num_pins)
{
*pins = cs42l43_pin_groups[group_idx].pins;
*num_pins = cs42l43_pin_groups[group_idx].npins;
return 0;
}
static const struct pinctrl_ops cs42l43_pin_group_ops = {
.get_groups_count = cs42l43_pin_get_groups_count,
.get_group_name = cs42l43_pin_get_group_name,
.get_group_pins = cs42l43_pin_get_group_pins,
#if IS_ENABLED(CONFIG_OF)
.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
.dt_free_map = pinconf_generic_dt_free_map,
#endif
};
enum cs42l43_pin_funcs {
CS42L43_FUNC_GPIO,
CS42L43_FUNC_SPDIF,
CS42L43_FUNC_IRQ,
CS42L43_FUNC_MIC_SHT,
CS42L43_FUNC_SPK_SHT,
CS42L43_FUNC_MAX
};
static const char * const cs42l43_pin_funcs[] = {
"gpio", "spdif", "irq", "mic-shutter", "spk-shutter",
};
static const char * const cs42l43_pin_gpio_groups[] = { "gpio1", "gpio3" };
static const char * const cs42l43_pin_spdif_groups[] = { "gpio3" };
static const char * const cs42l43_pin_irq_groups[] = { "gpio1" };
static const char * const cs42l43_pin_shutter_groups[] = { "gpio1", "gpio2", "gpio3" };
static const struct pinfunction cs42l43_pin_func_groups[] = {
PINCTRL_PINFUNCTION("gpio", cs42l43_pin_gpio_groups,
ARRAY_SIZE(cs42l43_pin_gpio_groups)),
PINCTRL_PINFUNCTION("spdif", cs42l43_pin_spdif_groups,
ARRAY_SIZE(cs42l43_pin_spdif_groups)),
PINCTRL_PINFUNCTION("irq", cs42l43_pin_irq_groups,
ARRAY_SIZE(cs42l43_pin_irq_groups)),
PINCTRL_PINFUNCTION("mic-shutter", cs42l43_pin_shutter_groups,
ARRAY_SIZE(cs42l43_pin_shutter_groups)),
PINCTRL_PINFUNCTION("spk-shutter", cs42l43_pin_shutter_groups,
ARRAY_SIZE(cs42l43_pin_shutter_groups)),
};
static_assert(ARRAY_SIZE(cs42l43_pin_funcs) == CS42L43_FUNC_MAX);
static_assert(ARRAY_SIZE(cs42l43_pin_func_groups) == CS42L43_FUNC_MAX);
static int cs42l43_pin_get_func_count(struct pinctrl_dev *pctldev)
{
return ARRAY_SIZE(cs42l43_pin_funcs);
}
static const char *cs42l43_pin_get_func_name(struct pinctrl_dev *pctldev,
unsigned int func_idx)
{
return cs42l43_pin_funcs[func_idx];
}
static int cs42l43_pin_get_func_groups(struct pinctrl_dev *pctldev,
unsigned int func_idx,
const char * const **groups,
unsigned int * const num_groups)
{
*groups = cs42l43_pin_func_groups[func_idx].groups;
*num_groups = cs42l43_pin_func_groups[func_idx].ngroups;
return 0;
}
static int cs42l43_pin_set_mux(struct pinctrl_dev *pctldev,
unsigned int func_idx, unsigned int group_idx)
{
struct cs42l43_pin *priv = pinctrl_dev_get_drvdata(pctldev);
unsigned int reg, mask, val;
dev_dbg(priv->dev, "Setting %s to %s\n",
cs42l43_pin_groups[group_idx].name, cs42l43_pin_funcs[func_idx]);
switch (func_idx) {
case CS42L43_FUNC_MIC_SHT:
reg = CS42L43_SHUTTER_CONTROL;
mask = CS42L43_MIC_SHUTTER_CFG_MASK;
val = 0x2 << (group_idx + CS42L43_MIC_SHUTTER_CFG_SHIFT);
break;
case CS42L43_FUNC_SPK_SHT:
reg = CS42L43_SHUTTER_CONTROL;
mask = CS42L43_SPK_SHUTTER_CFG_MASK;
val = 0x2 << (group_idx + CS42L43_SPK_SHUTTER_CFG_SHIFT);
break;
default:
reg = CS42L43_GPIO_FN_SEL;
mask = BIT(group_idx + CS42L43_GPIO1_FN_SEL_SHIFT);
val = (func_idx == CS42L43_FUNC_GPIO) ?
(0x1 << (group_idx + CS42L43_GPIO1_FN_SEL_SHIFT)) : 0;
break;
}
if (priv->shutters_locked && reg == CS42L43_SHUTTER_CONTROL) {
dev_err(priv->dev, "Shutter configuration not available\n");
return -EPERM;
}
return regmap_update_bits(priv->regmap, reg, mask, val);
}
static int cs42l43_gpio_set_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int offset, bool input)
{
struct cs42l43_pin *priv = pinctrl_dev_get_drvdata(pctldev);
unsigned int shift = offset + CS42L43_GPIO1_DIR_SHIFT;
int ret;
dev_dbg(priv->dev, "Setting gpio%d to %s\n",
offset + 1, input ? "input" : "output");
ret = pm_runtime_resume_and_get(priv->dev);
if (ret) {
dev_err(priv->dev, "Failed to resume for direction: %d\n", ret);
return ret;
}
ret = regmap_update_bits(priv->regmap, CS42L43_GPIO_CTRL1,
BIT(shift), !!input << shift);
if (ret)
dev_err(priv->dev, "Failed to set gpio%d direction: %d\n",
offset + 1, ret);
pm_runtime_put(priv->dev);
return ret;
}
static int cs42l43_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int offset)
{
return cs42l43_pin_set_mux(pctldev, 0, offset);
}
static void cs42l43_gpio_disable_free(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned int offset)
{
cs42l43_gpio_set_direction(pctldev, range, offset, true);
}
static const struct pinmux_ops cs42l43_pin_mux_ops = {
.get_functions_count = cs42l43_pin_get_func_count,
.get_function_name = cs42l43_pin_get_func_name,
.get_function_groups = cs42l43_pin_get_func_groups,
.set_mux = cs42l43_pin_set_mux,
.gpio_request_enable = cs42l43_gpio_request_enable,
.gpio_disable_free = cs42l43_gpio_disable_free,
.gpio_set_direction = cs42l43_gpio_set_direction,
.strict = true,
};
static const unsigned int cs42l43_pin_drv_str_ma[] = { 1, 2, 4, 8, 9, 10, 12, 16 };
static inline int cs42l43_pin_get_drv_str(struct cs42l43_pin *priv, unsigned int pin)
{
const struct cs42l43_pin_data *pdat = cs42l43_pin_pins[pin].drv_data;
unsigned int val;
int ret;
ret = regmap_read(priv->regmap, pdat->reg, &val);
if (ret)
return ret;
return cs42l43_pin_drv_str_ma[(val & pdat->mask) >> pdat->shift];
}
static inline int cs42l43_pin_set_drv_str(struct cs42l43_pin *priv, unsigned int pin,
unsigned int ma)
{
const struct cs42l43_pin_data *pdat = cs42l43_pin_pins[pin].drv_data;
int i;
for (i = 0; i < ARRAY_SIZE(cs42l43_pin_drv_str_ma); i++) {
if (ma == cs42l43_pin_drv_str_ma[i]) {
if ((i << pdat->shift) > pdat->mask)
goto err;
dev_dbg(priv->dev, "Set drive strength for %s to %d mA\n",
cs42l43_pin_pins[pin].name, ma);
return regmap_update_bits(priv->regmap, pdat->reg,
pdat->mask, i << pdat->shift);
}
}
err:
dev_err(priv->dev, "Invalid drive strength for %s: %d mA\n",
cs42l43_pin_pins[pin].name, ma);
return -EINVAL;
}
static inline int cs42l43_pin_get_db(struct cs42l43_pin *priv, unsigned int pin)
{
unsigned int val;
int ret;
if (pin >= CS42L43_NUM_GPIOS)
return -ENOTSUPP;
ret = regmap_read(priv->regmap, CS42L43_GPIO_CTRL2, &val);
if (ret)
return ret;
if (val & (CS42L43_GPIO1_DEGLITCH_BYP_MASK << pin))
return 0;
return 85; // Debounce is roughly 85uS
}
static inline int cs42l43_pin_set_db(struct cs42l43_pin *priv, unsigned int pin,
unsigned int us)
{
if (pin >= CS42L43_NUM_GPIOS)
return -ENOTSUPP;
dev_dbg(priv->dev, "Set debounce %s for %s\n",
str_on_off(us), cs42l43_pin_pins[pin].name);
return regmap_update_bits(priv->regmap, CS42L43_GPIO_CTRL2,
CS42L43_GPIO1_DEGLITCH_BYP_MASK << pin,
!!us << pin);
}
static int cs42l43_pin_config_get(struct pinctrl_dev *pctldev,
unsigned int pin, unsigned long *config)
{
struct cs42l43_pin *priv = pinctrl_dev_get_drvdata(pctldev);
unsigned int param = pinconf_to_config_param(*config);
int ret;
switch (param) {
case PIN_CONFIG_DRIVE_STRENGTH:
ret = cs42l43_pin_get_drv_str(priv, pin);
if (ret < 0)
return ret;
break;
case PIN_CONFIG_INPUT_DEBOUNCE:
ret = cs42l43_pin_get_db(priv, pin);
if (ret < 0)
return ret;
break;
default:
return -ENOTSUPP;
}
*config = pinconf_to_config_packed(param, ret);
return 0;
}
static int cs42l43_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *configs, unsigned int num_configs)
{
struct cs42l43_pin *priv = pinctrl_dev_get_drvdata(pctldev);
unsigned int val;
int ret;
while (num_configs) {
val = pinconf_to_config_argument(*configs);
switch (pinconf_to_config_param(*configs)) {
case PIN_CONFIG_DRIVE_STRENGTH:
ret = cs42l43_pin_set_drv_str(priv, pin, val);
if (ret)
return ret;
break;
case PIN_CONFIG_INPUT_DEBOUNCE:
ret = cs42l43_pin_set_db(priv, pin, val);
if (ret)
return ret;
break;
default:
return -ENOTSUPP;
}
configs++;
num_configs--;
}
return 0;
}
static int cs42l43_pin_config_group_get(struct pinctrl_dev *pctldev,
unsigned int selector, unsigned long *config)
{
int i, ret;
for (i = 0; i < cs42l43_pin_groups[selector].npins; ++i) {
ret = cs42l43_pin_config_get(pctldev,
cs42l43_pin_groups[selector].pins[i],
config);
if (ret)
return ret;
}
return 0;
}
static int cs42l43_pin_config_group_set(struct pinctrl_dev *pctldev,
unsigned int selector,
unsigned long *configs,
unsigned int num_configs)
{
int i, ret;
for (i = 0; i < cs42l43_pin_groups[selector].npins; ++i) {
ret = cs42l43_pin_config_set(pctldev,
cs42l43_pin_groups[selector].pins[i],
configs, num_configs);
if (ret)
return ret;
}
return 0;
}
static const struct pinconf_ops cs42l43_pin_conf_ops = {
.is_generic = true,
.pin_config_get = cs42l43_pin_config_get,
.pin_config_set = cs42l43_pin_config_set,
.pin_config_group_get = cs42l43_pin_config_group_get,
.pin_config_group_set = cs42l43_pin_config_group_set,
};
static struct pinctrl_desc cs42l43_pin_desc = {
.name = "cs42l43-pinctrl",
.owner = THIS_MODULE,
.pins = cs42l43_pin_pins,
.npins = ARRAY_SIZE(cs42l43_pin_pins),
.pctlops = &cs42l43_pin_group_ops,
.pmxops = &cs42l43_pin_mux_ops,
.confops = &cs42l43_pin_conf_ops,
};
static int cs42l43_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
struct cs42l43_pin *priv = gpiochip_get_data(chip);
unsigned int val;
int ret;
ret = pm_runtime_resume_and_get(priv->dev);
if (ret) {
dev_err(priv->dev, "Failed to resume for get: %d\n", ret);
return ret;
}
ret = regmap_read(priv->regmap, CS42L43_GPIO_STS, &val);
if (ret)
dev_err(priv->dev, "Failed to get gpio%d: %d\n", offset + 1, ret);
else
ret = !!(val & BIT(offset + CS42L43_GPIO1_STS_SHIFT));
pm_runtime_put(priv->dev);
return ret;
}
static void cs42l43_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
{
struct cs42l43_pin *priv = gpiochip_get_data(chip);
unsigned int shift = offset + CS42L43_GPIO1_LVL_SHIFT;
int ret;
dev_dbg(priv->dev, "Setting gpio%d to %s\n",
offset + 1, value ? "high" : "low");
ret = pm_runtime_resume_and_get(priv->dev);
if (ret) {
dev_err(priv->dev, "Failed to resume for set: %d\n", ret);
return;
}
ret = regmap_update_bits(priv->regmap, CS42L43_GPIO_CTRL1,
BIT(shift), value << shift);
if (ret)
dev_err(priv->dev, "Failed to set gpio%d: %d\n", offset + 1, ret);
pm_runtime_put(priv->dev);
}
static int cs42l43_gpio_direction_in(struct gpio_chip *chip, unsigned int offset)
{
return pinctrl_gpio_direction_input(chip->base + offset);
}
static int cs42l43_gpio_direction_out(struct gpio_chip *chip,
unsigned int offset, int value)
{
cs42l43_gpio_set(chip, offset, value);
return pinctrl_gpio_direction_output(chip->base + offset);
}
static int cs42l43_gpio_add_pin_ranges(struct gpio_chip *chip)
{
struct cs42l43_pin *priv = gpiochip_get_data(chip);
int ret;
ret = gpiochip_add_pin_range(&priv->gpio_chip, priv->gpio_chip.label,
0, 0, CS42L43_NUM_GPIOS);
if (ret)
dev_err(priv->dev, "Failed to add GPIO pin range: %d\n", ret);
return ret;
}
static int cs42l43_pin_probe(struct platform_device *pdev)
{
struct cs42l43 *cs42l43 = dev_get_drvdata(pdev->dev.parent);
struct cs42l43_pin *priv;
struct pinctrl_dev *pctldev;
struct fwnode_handle *fwnode = dev_fwnode(cs42l43->dev);
int ret;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->dev = &pdev->dev;
priv->regmap = cs42l43->regmap;
priv->shutters_locked = cs42l43->hw_lock;
priv->gpio_chip.request = gpiochip_generic_request;
priv->gpio_chip.free = gpiochip_generic_free;
priv->gpio_chip.direction_input = cs42l43_gpio_direction_in;
priv->gpio_chip.direction_output = cs42l43_gpio_direction_out;
priv->gpio_chip.add_pin_ranges = cs42l43_gpio_add_pin_ranges;
priv->gpio_chip.get = cs42l43_gpio_get;
priv->gpio_chip.set = cs42l43_gpio_set;
priv->gpio_chip.label = dev_name(priv->dev);
priv->gpio_chip.parent = priv->dev;
priv->gpio_chip.can_sleep = true;
priv->gpio_chip.base = -1;
priv->gpio_chip.ngpio = CS42L43_NUM_GPIOS;
if (is_of_node(fwnode)) {
fwnode = fwnode_get_named_child_node(fwnode, "pinctrl");
if (fwnode && !fwnode->dev)
fwnode->dev = priv->dev;
}
priv->gpio_chip.fwnode = fwnode;
device_set_node(priv->dev, fwnode);
devm_pm_runtime_enable(priv->dev);
pm_runtime_idle(priv->dev);
pctldev = devm_pinctrl_register(priv->dev, &cs42l43_pin_desc, priv);
if (IS_ERR(pctldev))
return dev_err_probe(priv->dev, PTR_ERR(pctldev),
"Failed to register pinctrl\n");
ret = devm_gpiochip_add_data(priv->dev, &priv->gpio_chip, priv);
if (ret)
return dev_err_probe(priv->dev, ret,
"Failed to register gpiochip\n");
return 0;
}
static const struct platform_device_id cs42l43_pin_id_table[] = {
{ "cs42l43-pinctrl", },
{}
};
MODULE_DEVICE_TABLE(platform, cs42l43_pin_id_table);
static struct platform_driver cs42l43_pin_driver = {
.driver = {
.name = "cs42l43-pinctrl",
},
.probe = cs42l43_pin_probe,
.id_table = cs42l43_pin_id_table,
};
module_platform_driver(cs42l43_pin_driver);
MODULE_DESCRIPTION("CS42L43 Pinctrl Driver");
MODULE_AUTHOR("Charles Keepax <ckeepax@opensource.cirrus.com>");
MODULE_LICENSE("GPL");

Просмотреть файл

@ -3,6 +3,7 @@
#include <linux/acpi.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/mod_devicetable.h>
#include <linux/pm_runtime.h>
#include <linux/soundwire/sdw_registers.h>
@ -25,6 +26,23 @@ static int sdw_get_id(struct sdw_bus *bus)
return 0;
}
static int sdw_irq_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
struct sdw_bus *bus = h->host_data;
irq_set_chip_data(virq, bus);
irq_set_chip(virq, &bus->irq_chip);
irq_set_nested_thread(virq, 1);
irq_set_noprobe(virq);
return 0;
}
static const struct irq_domain_ops sdw_domain_ops = {
.map = sdw_irq_map,
};
/**
* sdw_bus_master_add() - add a bus Master instance
* @bus: bus instance
@ -151,6 +169,14 @@ int sdw_bus_master_add(struct sdw_bus *bus, struct device *parent,
bus->params.curr_bank = SDW_BANK0;
bus->params.next_bank = SDW_BANK1;
bus->irq_chip.name = dev_name(bus->dev);
bus->domain = irq_domain_create_linear(fwnode, SDW_MAX_DEVICES,
&sdw_domain_ops, bus);
if (!bus->domain) {
dev_err(bus->dev, "Failed to add IRQ domain\n");
return -EINVAL;
}
return 0;
}
EXPORT_SYMBOL(sdw_bus_master_add);
@ -187,6 +213,9 @@ static int sdw_delete_slave(struct device *dev, void *data)
void sdw_bus_master_delete(struct sdw_bus *bus)
{
device_for_each_child(bus->dev, NULL, sdw_delete_slave);
irq_domain_remove(bus->domain);
sdw_master_device_del(bus);
sdw_bus_debugfs_exit(bus);
@ -1725,6 +1754,9 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
struct device *dev = &slave->dev;
struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
if (slave->prop.use_domain_irq && slave->irq)
handle_nested_irq(slave->irq);
if (drv->ops && drv->ops->interrupt_callback) {
slave_intr.sdca_cascade = sdca_cascade;
slave_intr.control_port = clear;

Просмотреть файл

@ -122,6 +122,12 @@ static int sdw_drv_probe(struct device *dev)
if (drv->ops && drv->ops->read_prop)
drv->ops->read_prop(slave);
if (slave->prop.use_domain_irq) {
slave->irq = irq_create_mapping(slave->bus->domain, slave->dev_num);
if (!slave->irq)
dev_warn(dev, "Failed to map IRQ\n");
}
/* init the sysfs as we have properties now */
ret = sdw_slave_sysfs_init(slave);
if (ret < 0)
@ -166,7 +172,13 @@ static int sdw_drv_remove(struct device *dev)
int ret = 0;
mutex_lock(&slave->sdw_dev_lock);
slave->probed = false;
if (slave->prop.use_domain_irq)
irq_dispose_mapping(irq_find_mapping(slave->bus->domain,
slave->dev_num));
mutex_unlock(&slave->sdw_dev_lock);
if (drv->remove)

Просмотреть файл

@ -281,6 +281,13 @@ config SPI_COLDFIRE_QSPI
This enables support for the Coldfire QSPI controller in master
mode.
config SPI_CS42L43
tristate "Cirrus Logic CS42L43 SPI controller"
depends on MFD_CS42L43 && PINCTRL_CS42L43
help
This enables support for the SPI controller inside the Cirrus Logic
CS42L43 audio codec.
config SPI_DAVINCI
tristate "Texas Instruments DaVinci/DA8x/OMAP-L/AM1x SoC SPI controller"
depends on ARCH_DAVINCI || ARCH_KEYSTONE || COMPILE_TEST
@ -516,6 +523,32 @@ config SPI_LM70_LLP
which interfaces to an LM70 temperature sensor using
a parallel port.
config SPI_LOONGSON_CORE
tristate
depends on LOONGARCH || COMPILE_TEST
config SPI_LOONGSON_PCI
tristate "Loongson SPI Controller PCI Driver Support"
select SPI_LOONGSON_CORE
depends on PCI && (LOONGARCH || COMPILE_TEST)
help
This bus driver supports the Loongson SPI hardware controller in
the Loongson platforms and supports to use PCI framework to
register SPI device resources.
Say Y or M here if you want to use the SPI controller on
Loongson platform.
config SPI_LOONGSON_PLATFORM
tristate "Loongson SPI Controller Platform Driver Support"
select SPI_LOONGSON_CORE
depends on OF && (LOONGARCH || COMPILE_TEST)
help
This bus driver supports the Loongson SPI hardware controller in
the Loongson platforms and supports to use DTS framework to
register SPI device resources.
Say Y or M here if you want to use the SPI controller on
Loongson platform.
config SPI_LP8841_RTC
tristate "ICP DAS LP-8841 SPI Controller for RTC"
depends on MACH_PXA27X_DT || COMPILE_TEST

Просмотреть файл

@ -40,6 +40,7 @@ obj-$(CONFIG_SPI_CADENCE_QUADSPI) += spi-cadence-quadspi.o
obj-$(CONFIG_SPI_CADENCE_XSPI) += spi-cadence-xspi.o
obj-$(CONFIG_SPI_CLPS711X) += spi-clps711x.o
obj-$(CONFIG_SPI_COLDFIRE_QSPI) += spi-coldfire-qspi.o
obj-$(CONFIG_SPI_CS42L43) += spi-cs42l43.o
obj-$(CONFIG_SPI_DAVINCI) += spi-davinci.o
obj-$(CONFIG_SPI_DLN2) += spi-dln2.o
obj-$(CONFIG_SPI_DESIGNWARE) += spi-dw.o
@ -71,6 +72,9 @@ obj-$(CONFIG_SPI_INTEL_PLATFORM) += spi-intel-platform.o
obj-$(CONFIG_SPI_LANTIQ_SSC) += spi-lantiq-ssc.o
obj-$(CONFIG_SPI_JCORE) += spi-jcore.o
obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o
obj-$(CONFIG_SPI_LOONGSON_CORE) += spi-loongson-core.o
obj-$(CONFIG_SPI_LOONGSON_PCI) += spi-loongson-pci.o
obj-$(CONFIG_SPI_LOONGSON_PLATFORM) += spi-loongson-plat.o
obj-$(CONFIG_SPI_LP8841_RTC) += spi-lp8841-rtc.o
obj-$(CONFIG_SPI_MESON_SPICC) += spi-meson-spicc.o
obj-$(CONFIG_SPI_MESON_SPIFC) += spi-meson-spifc.o

Просмотреть файл

@ -215,9 +215,9 @@ static int amd_spi_execute_opcode(struct amd_spi *amd_spi)
}
}
static int amd_spi_master_setup(struct spi_device *spi)
static int amd_spi_host_setup(struct spi_device *spi)
{
struct amd_spi *amd_spi = spi_master_get_devdata(spi->master);
struct amd_spi *amd_spi = spi_controller_get_devdata(spi->controller);
amd_spi_clear_fifo_ptr(amd_spi);
@ -272,7 +272,7 @@ static int amd_set_spi_freq(struct amd_spi *amd_spi, u32 speed_hz)
}
static inline int amd_spi_fifo_xfer(struct amd_spi *amd_spi,
struct spi_master *master,
struct spi_controller *host,
struct spi_message *message)
{
struct spi_transfer *xfer = NULL;
@ -353,15 +353,15 @@ fin_msg:
return -ENODEV;
}
spi_finalize_current_message(master);
spi_finalize_current_message(host);
return message->status;
}
static int amd_spi_master_transfer(struct spi_master *master,
static int amd_spi_host_transfer(struct spi_controller *host,
struct spi_message *msg)
{
struct amd_spi *amd_spi = spi_master_get_devdata(master);
struct amd_spi *amd_spi = spi_controller_get_devdata(host);
struct spi_device *spi = msg->spi;
amd_spi_select_chip(amd_spi, spi_get_chipselect(spi, 0));
@ -370,7 +370,7 @@ static int amd_spi_master_transfer(struct spi_master *master,
* Extract spi_transfers from the spi message and
* program the controller.
*/
return amd_spi_fifo_xfer(amd_spi, master, msg);
return amd_spi_fifo_xfer(amd_spi, host, msg);
}
static size_t amd_spi_max_transfer_size(struct spi_device *spi)
@ -381,16 +381,16 @@ static size_t amd_spi_max_transfer_size(struct spi_device *spi)
static int amd_spi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct spi_master *master;
struct spi_controller *host;
struct amd_spi *amd_spi;
int err;
/* Allocate storage for spi_master and driver private data */
master = devm_spi_alloc_master(dev, sizeof(struct amd_spi));
if (!master)
return dev_err_probe(dev, -ENOMEM, "Error allocating SPI master\n");
/* Allocate storage for host and driver private data */
host = devm_spi_alloc_host(dev, sizeof(struct amd_spi));
if (!host)
return dev_err_probe(dev, -ENOMEM, "Error allocating SPI host\n");
amd_spi = spi_master_get_devdata(master);
amd_spi = spi_controller_get_devdata(host);
amd_spi->io_remap_addr = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(amd_spi->io_remap_addr))
return dev_err_probe(dev, PTR_ERR(amd_spi->io_remap_addr),
@ -398,22 +398,22 @@ static int amd_spi_probe(struct platform_device *pdev)
dev_dbg(dev, "io_remap_address: %p\n", amd_spi->io_remap_addr);
amd_spi->version = (enum amd_spi_versions) device_get_match_data(dev);
amd_spi->version = (uintptr_t) device_get_match_data(dev);
/* Initialize the spi_master fields */
master->bus_num = 0;
master->num_chipselect = 4;
master->mode_bits = 0;
master->flags = SPI_MASTER_HALF_DUPLEX;
master->max_speed_hz = AMD_SPI_MAX_HZ;
master->min_speed_hz = AMD_SPI_MIN_HZ;
master->setup = amd_spi_master_setup;
master->transfer_one_message = amd_spi_master_transfer;
master->max_transfer_size = amd_spi_max_transfer_size;
master->max_message_size = amd_spi_max_transfer_size;
/* Initialize the spi_controller fields */
host->bus_num = 0;
host->num_chipselect = 4;
host->mode_bits = 0;
host->flags = SPI_CONTROLLER_HALF_DUPLEX;
host->max_speed_hz = AMD_SPI_MAX_HZ;
host->min_speed_hz = AMD_SPI_MIN_HZ;
host->setup = amd_spi_host_setup;
host->transfer_one_message = amd_spi_host_transfer;
host->max_transfer_size = amd_spi_max_transfer_size;
host->max_message_size = amd_spi_max_transfer_size;
/* Register the controller with SPI framework */
err = devm_spi_register_master(dev, master);
err = devm_spi_register_controller(dev, host);
if (err)
return dev_err_probe(dev, err, "error registering SPI controller\n");

Просмотреть файл

@ -72,7 +72,7 @@
#define SPIFC_A1_USER_DBUF_ADDR_REG 0x248
#define SPIFC_A1_BUFFER_SIZE 512
#define SPIFC_A1_BUFFER_SIZE 512U
#define SPIFC_A1_MAX_HZ 200000000
#define SPIFC_A1_MIN_HZ 1000000
@ -107,6 +107,7 @@ struct amlogic_spifc_a1 {
struct clk *clk;
struct device *dev;
void __iomem *base;
u32 curr_speed_hz;
};
static int amlogic_spifc_a1_request(struct amlogic_spifc_a1 *spifc, bool read)
@ -235,66 +236,68 @@ static int amlogic_spifc_a1_write(struct amlogic_spifc_a1 *spifc,
return amlogic_spifc_a1_request(spifc, false);
}
static int amlogic_spifc_a1_set_freq(struct amlogic_spifc_a1 *spifc, u32 freq)
{
int ret;
if (freq == spifc->curr_speed_hz)
return 0;
ret = clk_set_rate(spifc->clk, freq);
if (ret)
return ret;
spifc->curr_speed_hz = freq;
return 0;
}
static int amlogic_spifc_a1_exec_op(struct spi_mem *mem,
const struct spi_mem_op *op)
{
struct amlogic_spifc_a1 *spifc =
spi_controller_get_devdata(mem->spi->controller);
size_t off, nbytes = op->data.nbytes;
u32 cmd_cfg, addr_cfg, dummy_cfg, dmode;
size_t data_size = op->data.nbytes;
int ret;
ret = amlogic_spifc_a1_set_freq(spifc, mem->spi->max_speed_hz);
if (ret)
return ret;
amlogic_spifc_a1_user_init(spifc);
amlogic_spifc_a1_set_cmd(spifc, SPIFC_A1_USER_CMD(op));
cmd_cfg = SPIFC_A1_USER_CMD(op);
amlogic_spifc_a1_set_cmd(spifc, cmd_cfg);
if (op->addr.nbytes)
amlogic_spifc_a1_set_addr(spifc, op->addr.val,
SPIFC_A1_USER_ADDR(op));
if (op->addr.nbytes) {
addr_cfg = SPIFC_A1_USER_ADDR(op);
amlogic_spifc_a1_set_addr(spifc, op->addr.val, addr_cfg);
}
if (op->dummy.nbytes)
amlogic_spifc_a1_set_dummy(spifc, SPIFC_A1_USER_DUMMY(op));
if (op->dummy.nbytes) {
dummy_cfg = SPIFC_A1_USER_DUMMY(op);
amlogic_spifc_a1_set_dummy(spifc, dummy_cfg);
}
if (!op->data.nbytes)
return amlogic_spifc_a1_request(spifc, false);
dmode = ilog2(op->data.buswidth);
off = 0;
do {
size_t block_size = min_t(size_t, nbytes, SPIFC_A1_BUFFER_SIZE);
amlogic_spifc_a1_set_cmd(spifc, cmd_cfg);
if (op->addr.nbytes)
amlogic_spifc_a1_set_addr(spifc, op->addr.val + off,
addr_cfg);
if (op->dummy.nbytes)
amlogic_spifc_a1_set_dummy(spifc, dummy_cfg);
if (data_size) {
u32 mode = ilog2(op->data.buswidth);
writel(0, spifc->base + SPIFC_A1_USER_DBUF_ADDR_REG);
if (op->data.dir == SPI_MEM_DATA_IN)
ret = amlogic_spifc_a1_read(spifc,
op->data.buf.in + off,
block_size, dmode);
ret = amlogic_spifc_a1_read(spifc, op->data.buf.in,
data_size, mode);
else
ret = amlogic_spifc_a1_write(spifc,
op->data.buf.out + off,
block_size, dmode);
nbytes -= block_size;
off += block_size;
} while (nbytes != 0 && !ret);
ret = amlogic_spifc_a1_write(spifc, op->data.buf.out,
data_size, mode);
} else {
ret = amlogic_spifc_a1_request(spifc, false);
}
return ret;
}
static int amlogic_spifc_a1_adjust_op_size(struct spi_mem *mem,
struct spi_mem_op *op)
{
op->data.nbytes = min(op->data.nbytes, SPIFC_A1_BUFFER_SIZE);
return 0;
}
static void amlogic_spifc_a1_hw_init(struct amlogic_spifc_a1 *spifc)
{
u32 regv;
@ -314,6 +317,7 @@ static void amlogic_spifc_a1_hw_init(struct amlogic_spifc_a1 *spifc)
static const struct spi_controller_mem_ops amlogic_spifc_a1_mem_ops = {
.exec_op = amlogic_spifc_a1_exec_op,
.adjust_op_size = amlogic_spifc_a1_adjust_op_size,
};
static int amlogic_spifc_a1_probe(struct platform_device *pdev)
@ -322,7 +326,7 @@ static int amlogic_spifc_a1_probe(struct platform_device *pdev)
struct amlogic_spifc_a1 *spifc;
int ret;
ctrl = devm_spi_alloc_master(&pdev->dev, sizeof(*spifc));
ctrl = devm_spi_alloc_host(&pdev->dev, sizeof(*spifc));
if (!ctrl)
return -ENOMEM;

Просмотреть файл

@ -14,7 +14,8 @@
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#define DRIVER_NAME "spi-ar934x"

Просмотреть файл

@ -17,8 +17,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/spi/spi.h>

Просмотреть файл

@ -295,7 +295,7 @@ static const struct aspeed_spi_data ast2400_spi_data;
static int do_aspeed_spi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
{
struct aspeed_spi *aspi = spi_controller_get_devdata(mem->spi->master);
struct aspeed_spi *aspi = spi_controller_get_devdata(mem->spi->controller);
struct aspeed_spi_chip *chip = &aspi->chips[spi_get_chipselect(mem->spi, 0)];
u32 addr_mode, addr_mode_backup;
u32 ctl_val;
@ -374,7 +374,7 @@ static int aspeed_spi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
static const char *aspeed_spi_get_name(struct spi_mem *mem)
{
struct aspeed_spi *aspi = spi_controller_get_devdata(mem->spi->master);
struct aspeed_spi *aspi = spi_controller_get_devdata(mem->spi->controller);
struct device *dev = aspi->dev;
return devm_kasprintf(dev, GFP_KERNEL, "%s.%d", dev_name(dev),
@ -553,7 +553,7 @@ static int aspeed_spi_do_calibration(struct aspeed_spi_chip *chip);
static int aspeed_spi_dirmap_create(struct spi_mem_dirmap_desc *desc)
{
struct aspeed_spi *aspi = spi_controller_get_devdata(desc->mem->spi->master);
struct aspeed_spi *aspi = spi_controller_get_devdata(desc->mem->spi->controller);
struct aspeed_spi_chip *chip = &aspi->chips[spi_get_chipselect(desc->mem->spi, 0)];
struct spi_mem_op *op = &desc->info.op_tmpl;
u32 ctl_val;
@ -620,7 +620,7 @@ static int aspeed_spi_dirmap_create(struct spi_mem_dirmap_desc *desc)
static ssize_t aspeed_spi_dirmap_read(struct spi_mem_dirmap_desc *desc,
u64 offset, size_t len, void *buf)
{
struct aspeed_spi *aspi = spi_controller_get_devdata(desc->mem->spi->master);
struct aspeed_spi *aspi = spi_controller_get_devdata(desc->mem->spi->controller);
struct aspeed_spi_chip *chip = &aspi->chips[spi_get_chipselect(desc->mem->spi, 0)];
/* Switch to USER command mode if mapping window is too small */
@ -669,7 +669,7 @@ static void aspeed_spi_chip_enable(struct aspeed_spi *aspi, unsigned int cs, boo
static int aspeed_spi_setup(struct spi_device *spi)
{
struct aspeed_spi *aspi = spi_controller_get_devdata(spi->master);
struct aspeed_spi *aspi = spi_controller_get_devdata(spi->controller);
const struct aspeed_spi_data *data = aspi->data;
unsigned int cs = spi_get_chipselect(spi, 0);
struct aspeed_spi_chip *chip = &aspi->chips[cs];
@ -697,7 +697,7 @@ static int aspeed_spi_setup(struct spi_device *spi)
static void aspeed_spi_cleanup(struct spi_device *spi)
{
struct aspeed_spi *aspi = spi_controller_get_devdata(spi->master);
struct aspeed_spi *aspi = spi_controller_get_devdata(spi->controller);
unsigned int cs = spi_get_chipselect(spi, 0);
aspeed_spi_chip_enable(aspi, cs, false);
@ -726,7 +726,7 @@ static int aspeed_spi_probe(struct platform_device *pdev)
if (!data)
return -ENODEV;
ctlr = devm_spi_alloc_master(dev, sizeof(*aspi));
ctlr = devm_spi_alloc_host(dev, sizeof(*aspi));
if (!ctlr)
return -ENOMEM;

Просмотреть файл

@ -13,7 +13,6 @@
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/gpio/consumer.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
@ -486,10 +485,7 @@ static int at91_usart_gpio_setup(struct platform_device *pdev)
cs_gpios = devm_gpiod_get_array_optional(&pdev->dev, "cs", GPIOD_OUT_LOW);
if (IS_ERR(cs_gpios))
return PTR_ERR(cs_gpios);
return 0;
return PTR_ERR_OR_ZERO(cs_gpios);
}
static int at91_usart_spi_probe(struct platform_device *pdev)
@ -527,7 +523,7 @@ static int at91_usart_spi_probe(struct platform_device *pdev)
controller->dev.of_node = pdev->dev.parent->of_node;
controller->bits_per_word_mask = SPI_BPW_MASK(8);
controller->setup = at91_usart_spi_setup;
controller->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX;
controller->flags = SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX;
controller->transfer_one = at91_usart_spi_transfer_one;
controller->prepare_message = at91_usart_spi_prepare_message;
controller->unprepare_message = at91_usart_spi_unprepare_message;

Просмотреть файл

@ -185,7 +185,7 @@ static int ath79_spi_probe(struct platform_device *pdev)
host->use_gpio_descriptors = true;
host->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
host->flags = SPI_MASTER_GPIO_SS;
host->flags = SPI_CONTROLLER_GPIO_SS;
host->num_chipselect = 3;
host->mem_ops = &ath79_mem_ops;

Просмотреть файл

@ -1450,10 +1450,6 @@ static int atmel_spi_probe(struct platform_device *pdev)
/* Select default pin state */
pinctrl_pm_select_default_state(&pdev->dev);
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs)
return -ENXIO;
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
@ -1475,8 +1471,8 @@ static int atmel_spi_probe(struct platform_device *pdev)
host->bus_num = pdev->id;
host->num_chipselect = 4;
host->setup = atmel_spi_setup;
host->flags = (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX |
SPI_MASTER_GPIO_SS);
host->flags = (SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX |
SPI_CONTROLLER_GPIO_SS);
host->transfer_one = atmel_spi_one_transfer;
host->set_cs = atmel_spi_set_cs;
host->cleanup = atmel_spi_cleanup;
@ -1490,7 +1486,7 @@ static int atmel_spi_probe(struct platform_device *pdev)
spin_lock_init(&as->lock);
as->pdev = pdev;
as->regs = devm_ioremap_resource(&pdev->dev, regs);
as->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &regs);
if (IS_ERR(as->regs)) {
ret = PTR_ERR(as->regs);
goto out_unmap_regs;

Просмотреть файл

@ -54,7 +54,7 @@ struct au1550_spi {
int (*txrx_bufs)(struct spi_device *spi, struct spi_transfer *t);
irqreturn_t (*irq_callback)(struct au1550_spi *hw);
struct completion master_done;
struct completion host_done;
unsigned int usedma;
u32 dma_tx_id;
@ -66,7 +66,7 @@ struct au1550_spi {
unsigned int dma_rx_tmpbuf_size;
u32 dma_rx_tmpbuf_addr;
struct spi_master *master;
struct spi_controller *host;
struct device *dev;
struct au1550_spi_info *pdata;
struct resource *ioarea;
@ -159,7 +159,7 @@ static void au1550_spi_reset_fifos(struct au1550_spi *hw)
*/
static void au1550_spi_chipsel(struct spi_device *spi, int value)
{
struct au1550_spi *hw = spi_master_get_devdata(spi->master);
struct au1550_spi *hw = spi_controller_get_devdata(spi->controller);
unsigned int cspol = spi->mode & SPI_CS_HIGH ? 1 : 0;
u32 cfg, stat;
@ -219,7 +219,7 @@ static void au1550_spi_chipsel(struct spi_device *spi, int value)
static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t)
{
struct au1550_spi *hw = spi_master_get_devdata(spi->master);
struct au1550_spi *hw = spi_controller_get_devdata(spi->controller);
unsigned int bpw, hz;
u32 cfg, stat;
@ -272,7 +272,7 @@ static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t)
* no reliable way how to recognize that spi transfer is done
* dma complete callbacks are called before real spi transfer is finished
* and if only tx dma channel is set up (and rx fifo overflow event masked)
* spi master done event irq is not generated unless rx fifo is empty (emptied)
* spi host done event irq is not generated unless rx fifo is empty (emptied)
* so we need rx tmp buffer to use for rx dma if user does not provide one
*/
static int au1550_spi_dma_rxtmp_alloc(struct au1550_spi *hw, unsigned int size)
@ -303,7 +303,7 @@ static void au1550_spi_dma_rxtmp_free(struct au1550_spi *hw)
static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t)
{
struct au1550_spi *hw = spi_master_get_devdata(spi->master);
struct au1550_spi *hw = spi_controller_get_devdata(spi->controller);
dma_addr_t dma_tx_addr;
dma_addr_t dma_rx_addr;
u32 res;
@ -387,7 +387,7 @@ static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t)
hw->regs->psc_spipcr = PSC_SPIPCR_MS;
wmb(); /* drain writebuffer */
wait_for_completion(&hw->master_done);
wait_for_completion(&hw->host_done);
au1xxx_dbdma_stop(hw->dma_tx_ch);
au1xxx_dbdma_stop(hw->dma_rx_ch);
@ -449,7 +449,7 @@ static irqreturn_t au1550_spi_dma_irq_callback(struct au1550_spi *hw)
"dma transfer: unexpected SPI error (event=0x%x stat=0x%x)!\n",
evnt, stat);
complete(&hw->master_done);
complete(&hw->host_done);
return IRQ_HANDLED;
}
@ -458,7 +458,7 @@ static irqreturn_t au1550_spi_dma_irq_callback(struct au1550_spi *hw)
au1550_spi_mask_ack_all(hw);
hw->rx_count = hw->len;
hw->tx_count = hw->len;
complete(&hw->master_done);
complete(&hw->host_done);
}
return IRQ_HANDLED;
}
@ -502,7 +502,7 @@ AU1550_SPI_TX_WORD(32, 0xffffff)
static int au1550_spi_pio_txrxb(struct spi_device *spi, struct spi_transfer *t)
{
u32 stat, mask;
struct au1550_spi *hw = spi_master_get_devdata(spi->master);
struct au1550_spi *hw = spi_controller_get_devdata(spi->controller);
hw->tx = t->tx_buf;
hw->rx = t->rx_buf;
@ -537,7 +537,7 @@ static int au1550_spi_pio_txrxb(struct spi_device *spi, struct spi_transfer *t)
hw->regs->psc_spipcr = PSC_SPIPCR_MS;
wmb(); /* drain writebuffer */
wait_for_completion(&hw->master_done);
wait_for_completion(&hw->host_done);
return min(hw->rx_count, hw->tx_count);
}
@ -568,7 +568,7 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw)
dev_err(hw->dev,
"pio transfer: unexpected SPI error (event=0x%x stat=0x%x)!\n",
evnt, stat);
complete(&hw->master_done);
complete(&hw->host_done);
return IRQ_HANDLED;
}
@ -605,11 +605,11 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw)
/*
* Restart the SPI transmission in case of a transmit underflow.
* This seems to work despite the notes in the Au1550 data book
* of Figure 8-4 with flowchart for SPI master operation:
* of Figure 8-4 with flowchart for SPI host operation:
*
* """Note 1: An XFR Error Interrupt occurs, unless masked,
* for any of the following events: Tx FIFO Underflow,
* Rx FIFO Overflow, or Multiple-master Error
* Rx FIFO Overflow, or Multiple-host Error
* Note 2: In case of a Tx Underflow Error, all zeroes are
* transmitted."""
*
@ -627,14 +627,14 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw)
if (hw->rx_count >= hw->len) {
/* transfer completed successfully */
au1550_spi_mask_ack_all(hw);
complete(&hw->master_done);
complete(&hw->host_done);
}
return IRQ_HANDLED;
}
static int au1550_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
{
struct au1550_spi *hw = spi_master_get_devdata(spi->master);
struct au1550_spi *hw = spi_controller_get_devdata(spi->controller);
return hw->txrx_bufs(spi, t);
}
@ -723,24 +723,24 @@ static void au1550_spi_setup_psc_as_spi(struct au1550_spi *hw)
static int au1550_spi_probe(struct platform_device *pdev)
{
struct au1550_spi *hw;
struct spi_master *master;
struct spi_controller *host;
struct resource *r;
int err = 0;
master = spi_alloc_master(&pdev->dev, sizeof(struct au1550_spi));
if (master == NULL) {
dev_err(&pdev->dev, "No memory for spi_master\n");
host = spi_alloc_host(&pdev->dev, sizeof(struct au1550_spi));
if (host == NULL) {
dev_err(&pdev->dev, "No memory for spi_controller\n");
err = -ENOMEM;
goto err_nomem;
}
/* the spi->mode bits understood by this driver: */
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 24);
host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
host->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 24);
hw = spi_master_get_devdata(master);
hw = spi_controller_get_devdata(host);
hw->master = master;
hw->host = host;
hw->pdata = dev_get_platdata(&pdev->dev);
hw->dev = &pdev->dev;
@ -798,9 +798,9 @@ static int au1550_spi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, hw);
init_completion(&hw->master_done);
init_completion(&hw->host_done);
hw->bitbang.master = hw->master;
hw->bitbang.master = hw->host;
hw->bitbang.setup_transfer = au1550_spi_setupxfer;
hw->bitbang.chipselect = au1550_spi_chipsel;
hw->bitbang.txrx_bufs = au1550_spi_txrx_bufs;
@ -858,8 +858,8 @@ static int au1550_spi_probe(struct platform_device *pdev)
goto err_no_irq;
}
master->bus_num = pdev->id;
master->num_chipselect = hw->pdata->num_chipselect;
host->bus_num = pdev->id;
host->num_chipselect = hw->pdata->num_chipselect;
/*
* precompute valid range for spi freq - from au1550 datasheet:
@ -874,8 +874,8 @@ static int au1550_spi_probe(struct platform_device *pdev)
int min_div = (2 << 0) * (2 * (4 + 1));
int max_div = (2 << 3) * (2 * (63 + 1));
master->max_speed_hz = hw->pdata->mainclk_hz / min_div;
master->min_speed_hz =
host->max_speed_hz = hw->pdata->mainclk_hz / min_div;
host->min_speed_hz =
hw->pdata->mainclk_hz / (max_div + 1) + 1;
}
@ -883,13 +883,13 @@ static int au1550_spi_probe(struct platform_device *pdev)
err = spi_bitbang_start(&hw->bitbang);
if (err) {
dev_err(&pdev->dev, "Failed to register SPI master\n");
dev_err(&pdev->dev, "Failed to register SPI host\n");
goto err_register;
}
dev_info(&pdev->dev,
"spi master registered: bus_num=%d num_chipselect=%d\n",
master->bus_num, master->num_chipselect);
"spi host registered: bus_num=%d num_chipselect=%d\n",
host->bus_num, host->num_chipselect);
return 0;
@ -917,7 +917,7 @@ err_ioremap:
err_no_iores:
err_no_pdata:
spi_master_put(hw->master);
spi_controller_put(hw->host);
err_nomem:
return err;
@ -927,8 +927,8 @@ static void au1550_spi_remove(struct platform_device *pdev)
{
struct au1550_spi *hw = platform_get_drvdata(pdev);
dev_info(&pdev->dev, "spi master remove: bus_num=%d\n",
hw->master->bus_num);
dev_info(&pdev->dev, "spi host remove: bus_num=%d\n",
hw->host->bus_num);
spi_bitbang_stop(&hw->bitbang);
free_irq(hw->irq, hw);
@ -941,7 +941,7 @@ static void au1550_spi_remove(struct platform_device *pdev)
au1xxx_dbdma_chan_free(hw->dma_tx_ch);
}
spi_master_put(hw->master);
spi_controller_put(hw->host);
}
/* work with hotplug and coldplug */

Просмотреть файл

@ -356,8 +356,8 @@ static bool spi_engine_read_rx_fifo(struct spi_engine *spi_engine)
static irqreturn_t spi_engine_irq(int irq, void *devid)
{
struct spi_master *master = devid;
struct spi_engine *spi_engine = spi_master_get_devdata(master);
struct spi_controller *host = devid;
struct spi_engine *spi_engine = spi_controller_get_devdata(host);
unsigned int disable_int = 0;
unsigned int pending;
@ -396,7 +396,7 @@ static irqreturn_t spi_engine_irq(int irq, void *devid)
msg->status = 0;
msg->actual_length = msg->frame_length;
spi_engine->msg = NULL;
spi_finalize_current_message(master);
spi_finalize_current_message(host);
disable_int |= SPI_ENGINE_INT_SYNC;
}
}
@ -412,11 +412,11 @@ static irqreturn_t spi_engine_irq(int irq, void *devid)
return IRQ_HANDLED;
}
static int spi_engine_transfer_one_message(struct spi_master *master,
static int spi_engine_transfer_one_message(struct spi_controller *host,
struct spi_message *msg)
{
struct spi_engine_program p_dry, *p;
struct spi_engine *spi_engine = spi_master_get_devdata(master);
struct spi_engine *spi_engine = spi_controller_get_devdata(host);
unsigned int int_enable = 0;
unsigned long flags;
size_t size;
@ -464,42 +464,42 @@ static int spi_engine_transfer_one_message(struct spi_master *master,
static int spi_engine_probe(struct platform_device *pdev)
{
struct spi_engine *spi_engine;
struct spi_master *master;
struct spi_controller *host;
unsigned int version;
int irq;
int ret;
irq = platform_get_irq(pdev, 0);
if (irq <= 0)
return -ENXIO;
if (irq < 0)
return irq;
spi_engine = devm_kzalloc(&pdev->dev, sizeof(*spi_engine), GFP_KERNEL);
if (!spi_engine)
return -ENOMEM;
master = spi_alloc_master(&pdev->dev, 0);
if (!master)
host = spi_alloc_host(&pdev->dev, 0);
if (!host)
return -ENOMEM;
spi_master_set_devdata(master, spi_engine);
spi_controller_set_devdata(host, spi_engine);
spin_lock_init(&spi_engine->lock);
spi_engine->clk = devm_clk_get(&pdev->dev, "s_axi_aclk");
if (IS_ERR(spi_engine->clk)) {
ret = PTR_ERR(spi_engine->clk);
goto err_put_master;
goto err_put_host;
}
spi_engine->ref_clk = devm_clk_get(&pdev->dev, "spi_clk");
if (IS_ERR(spi_engine->ref_clk)) {
ret = PTR_ERR(spi_engine->ref_clk);
goto err_put_master;
goto err_put_host;
}
ret = clk_prepare_enable(spi_engine->clk);
if (ret)
goto err_put_master;
goto err_put_host;
ret = clk_prepare_enable(spi_engine->ref_clk);
if (ret)
@ -525,46 +525,46 @@ static int spi_engine_probe(struct platform_device *pdev)
writel_relaxed(0xff, spi_engine->base + SPI_ENGINE_REG_INT_PENDING);
writel_relaxed(0x00, spi_engine->base + SPI_ENGINE_REG_INT_ENABLE);
ret = request_irq(irq, spi_engine_irq, 0, pdev->name, master);
ret = request_irq(irq, spi_engine_irq, 0, pdev->name, host);
if (ret)
goto err_ref_clk_disable;
master->dev.of_node = pdev->dev.of_node;
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_3WIRE;
master->bits_per_word_mask = SPI_BPW_MASK(8);
master->max_speed_hz = clk_get_rate(spi_engine->ref_clk) / 2;
master->transfer_one_message = spi_engine_transfer_one_message;
master->num_chipselect = 8;
host->dev.of_node = pdev->dev.of_node;
host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_3WIRE;
host->bits_per_word_mask = SPI_BPW_MASK(8);
host->max_speed_hz = clk_get_rate(spi_engine->ref_clk) / 2;
host->transfer_one_message = spi_engine_transfer_one_message;
host->num_chipselect = 8;
ret = spi_register_master(master);
ret = spi_register_controller(host);
if (ret)
goto err_free_irq;
platform_set_drvdata(pdev, master);
platform_set_drvdata(pdev, host);
return 0;
err_free_irq:
free_irq(irq, master);
free_irq(irq, host);
err_ref_clk_disable:
clk_disable_unprepare(spi_engine->ref_clk);
err_clk_disable:
clk_disable_unprepare(spi_engine->clk);
err_put_master:
spi_master_put(master);
err_put_host:
spi_controller_put(host);
return ret;
}
static void spi_engine_remove(struct platform_device *pdev)
{
struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
struct spi_engine *spi_engine = spi_master_get_devdata(master);
struct spi_controller *host = spi_controller_get(platform_get_drvdata(pdev));
struct spi_engine *spi_engine = spi_controller_get_devdata(host);
int irq = platform_get_irq(pdev, 0);
spi_unregister_master(master);
spi_unregister_controller(host);
free_irq(irq, master);
free_irq(irq, host);
spi_master_put(master);
spi_controller_put(host);
writel_relaxed(0xff, spi_engine->base + SPI_ENGINE_REG_INT_PENDING);
writel_relaxed(0x00, spi_engine->base + SPI_ENGINE_REG_INT_ENABLE);

Просмотреть файл

@ -220,7 +220,7 @@ struct qspi_trans {
struct bcm_qspi {
struct platform_device *pdev;
struct spi_master *master;
struct spi_controller *host;
struct clk *clk;
u32 base_clk;
u32 max_speed_hz;
@ -732,7 +732,7 @@ static bool bcm_qspi_mspi_transfer_is_last(struct bcm_qspi *qspi,
struct qspi_trans *qt)
{
if (qt->mspi_last_trans &&
spi_transfer_is_last(qspi->master, qt->trans))
spi_transfer_is_last(qspi->host, qt->trans))
return true;
else
return false;
@ -979,7 +979,7 @@ static int write_to_hw(struct bcm_qspi *qspi, struct spi_device *spi)
mspi_cdram |= ((tp.trans->bits_per_word <= 8) ? 0 :
MSPI_CDRAM_BITSE_BIT);
/* set 3wrire halfduplex mode data from master to slave */
/* set 3wrire halfduplex mode data from host to target */
if ((spi->mode & SPI_3WIRE) && tp.trans->tx_buf)
mspi_cdram |= MSPI_CDRAM_OUTP;
@ -1035,7 +1035,7 @@ done:
static int bcm_qspi_bspi_exec_mem_op(struct spi_device *spi,
const struct spi_mem_op *op)
{
struct bcm_qspi *qspi = spi_master_get_devdata(spi->master);
struct bcm_qspi *qspi = spi_controller_get_devdata(spi->controller);
u32 addr = 0, len, rdlen, len_words, from = 0;
int ret = 0;
unsigned long timeo = msecs_to_jiffies(100);
@ -1118,11 +1118,11 @@ static int bcm_qspi_bspi_exec_mem_op(struct spi_device *spi,
return ret;
}
static int bcm_qspi_transfer_one(struct spi_master *master,
static int bcm_qspi_transfer_one(struct spi_controller *host,
struct spi_device *spi,
struct spi_transfer *trans)
{
struct bcm_qspi *qspi = spi_master_get_devdata(master);
struct bcm_qspi *qspi = spi_controller_get_devdata(host);
int slots;
unsigned long timeo = msecs_to_jiffies(100);
@ -1150,8 +1150,8 @@ static int bcm_qspi_transfer_one(struct spi_master *master,
static int bcm_qspi_mspi_exec_mem_op(struct spi_device *spi,
const struct spi_mem_op *op)
{
struct spi_master *master = spi->master;
struct bcm_qspi *qspi = spi_master_get_devdata(master);
struct spi_controller *host = spi->controller;
struct bcm_qspi *qspi = spi_controller_get_devdata(host);
struct spi_transfer t[2];
u8 cmd[6] = { };
int ret, i;
@ -1171,7 +1171,7 @@ static int bcm_qspi_mspi_exec_mem_op(struct spi_device *spi,
t[0].tx_nbits = op->cmd.buswidth;
/* lets mspi know that this is not last transfer */
qspi->trans_pos.mspi_last_trans = false;
ret = bcm_qspi_transfer_one(master, spi, &t[0]);
ret = bcm_qspi_transfer_one(host, spi, &t[0]);
/* rx */
qspi->trans_pos.mspi_last_trans = true;
@ -1181,7 +1181,7 @@ static int bcm_qspi_mspi_exec_mem_op(struct spi_device *spi,
t[1].len = op->data.nbytes;
t[1].rx_nbits = op->data.buswidth;
t[1].bits_per_word = spi->bits_per_word;
ret = bcm_qspi_transfer_one(master, spi, &t[1]);
ret = bcm_qspi_transfer_one(host, spi, &t[1]);
}
return ret;
@ -1191,7 +1191,7 @@ static int bcm_qspi_exec_mem_op(struct spi_mem *mem,
const struct spi_mem_op *op)
{
struct spi_device *spi = mem->spi;
struct bcm_qspi *qspi = spi_master_get_devdata(spi->master);
struct bcm_qspi *qspi = spi_controller_get_devdata(spi->controller);
int ret = 0;
bool mspi_read = false;
u32 addr = 0, len;
@ -1486,7 +1486,7 @@ int bcm_qspi_probe(struct platform_device *pdev,
const struct bcm_qspi_data *data;
struct device *dev = &pdev->dev;
struct bcm_qspi *qspi;
struct spi_master *master;
struct spi_controller *host;
struct resource *res;
int irq, ret = 0, num_ints = 0;
u32 val;
@ -1504,13 +1504,13 @@ int bcm_qspi_probe(struct platform_device *pdev,
data = of_id->data;
master = devm_spi_alloc_master(dev, sizeof(struct bcm_qspi));
if (!master) {
dev_err(dev, "error allocating spi_master\n");
host = devm_spi_alloc_host(dev, sizeof(struct bcm_qspi));
if (!host) {
dev_err(dev, "error allocating spi_controller\n");
return -ENOMEM;
}
qspi = spi_master_get_devdata(master);
qspi = spi_controller_get_devdata(host);
qspi->clk = devm_clk_get_optional(&pdev->dev, NULL);
if (IS_ERR(qspi->clk))
@ -1520,23 +1520,23 @@ int bcm_qspi_probe(struct platform_device *pdev,
qspi->trans_pos.trans = NULL;
qspi->trans_pos.byte = 0;
qspi->trans_pos.mspi_last_trans = true;
qspi->master = master;
qspi->host = host;
master->bus_num = -1;
master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_RX_DUAL | SPI_RX_QUAD |
host->bus_num = -1;
host->mode_bits = SPI_CPHA | SPI_CPOL | SPI_RX_DUAL | SPI_RX_QUAD |
SPI_3WIRE;
master->setup = bcm_qspi_setup;
master->transfer_one = bcm_qspi_transfer_one;
master->mem_ops = &bcm_qspi_mem_ops;
master->cleanup = bcm_qspi_cleanup;
master->dev.of_node = dev->of_node;
master->num_chipselect = NUM_CHIPSELECT;
master->use_gpio_descriptors = true;
host->setup = bcm_qspi_setup;
host->transfer_one = bcm_qspi_transfer_one;
host->mem_ops = &bcm_qspi_mem_ops;
host->cleanup = bcm_qspi_cleanup;
host->dev.of_node = dev->of_node;
host->num_chipselect = NUM_CHIPSELECT;
host->use_gpio_descriptors = true;
qspi->big_endian = of_device_is_big_endian(dev->of_node);
if (!of_property_read_u32(dev->of_node, "num-cs", &val))
master->num_chipselect = val;
host->num_chipselect = val;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hif_mspi");
if (!res)
@ -1659,9 +1659,9 @@ int bcm_qspi_probe(struct platform_device *pdev,
qspi->xfer_mode.addrlen = -1;
qspi->xfer_mode.hp = -1;
ret = spi_register_master(master);
ret = spi_register_controller(host);
if (ret < 0) {
dev_err(dev, "can't register master\n");
dev_err(dev, "can't register host\n");
goto qspi_reg_err;
}
@ -1682,7 +1682,7 @@ void bcm_qspi_remove(struct platform_device *pdev)
{
struct bcm_qspi *qspi = platform_get_drvdata(pdev);
spi_unregister_master(qspi->master);
spi_unregister_controller(qspi->host);
bcm_qspi_hw_uninit(qspi);
clk_disable_unprepare(qspi->clk);
kfree(qspi->dev_ids);
@ -1700,7 +1700,7 @@ static int __maybe_unused bcm_qspi_suspend(struct device *dev)
qspi->s3_strap_override_ctrl =
bcm_qspi_read(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL);
spi_master_suspend(qspi->master);
spi_controller_suspend(qspi->host);
clk_disable_unprepare(qspi->clk);
bcm_qspi_hw_uninit(qspi);
@ -1721,7 +1721,7 @@ static int __maybe_unused bcm_qspi_resume(struct device *dev)
ret = clk_prepare_enable(qspi->clk);
if (!ret)
spi_master_resume(qspi->master);
spi_controller_resume(qspi->host);
return ret;
}

Просмотреть файл

@ -24,7 +24,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h> /* FIXME: using chip internals */
#include <linux/gpio/driver.h> /* FIXME: using chip internals */
@ -105,7 +105,7 @@ MODULE_PARM_DESC(polling_limit_us,
* These are counted as well in @count_transfer_polling and
* @count_transfer_irq
* @count_transfer_dma: count how often dma mode is used
* @slv: SPI slave currently selected
* @target: SPI target currently selected
* (used by bcm2835_spi_dma_tx_done() to write @clear_rx_cs)
* @tx_dma_active: whether a TX DMA descriptor is in progress
* @rx_dma_active: whether a RX DMA descriptor is in progress
@ -135,7 +135,7 @@ struct bcm2835_spi {
u64 count_transfer_irq_after_polling;
u64 count_transfer_dma;
struct bcm2835_spidev *slv;
struct bcm2835_spidev *target;
unsigned int tx_dma_active;
unsigned int rx_dma_active;
struct dma_async_tx_descriptor *fill_tx_desc;
@ -143,14 +143,14 @@ struct bcm2835_spi {
};
/**
* struct bcm2835_spidev - BCM2835 SPI slave
* struct bcm2835_spidev - BCM2835 SPI target
* @prepare_cs: precalculated CS register value for ->prepare_message()
* (uses slave-specific clock polarity and phase settings)
* (uses target-specific clock polarity and phase settings)
* @clear_rx_desc: preallocated RX DMA descriptor used for TX-only transfers
* (cyclically clears RX FIFO by writing @clear_rx_cs to CS register)
* @clear_rx_addr: bus address of @clear_rx_cs
* @clear_rx_cs: precalculated CS register value to clear RX FIFO
* (uses slave-specific clock polarity and phase settings)
* (uses target-specific clock polarity and phase settings)
*/
struct bcm2835_spidev {
u32 prepare_cs;
@ -434,7 +434,7 @@ static int bcm2835_spi_transfer_one_irq(struct spi_controller *ctlr,
/**
* bcm2835_spi_transfer_prologue() - transfer first few bytes without DMA
* @ctlr: SPI master controller
* @ctlr: SPI host controller
* @tfr: SPI transfer
* @bs: BCM2835 SPI controller
* @cs: CS register
@ -596,7 +596,7 @@ out:
/**
* bcm2835_spi_dma_rx_done() - callback for DMA RX channel
* @data: SPI master controller
* @data: SPI host controller
*
* Used for bidirectional and RX-only transfers.
*/
@ -624,7 +624,7 @@ static void bcm2835_spi_dma_rx_done(void *data)
/**
* bcm2835_spi_dma_tx_done() - callback for DMA TX channel
* @data: SPI master controller
* @data: SPI host controller
*
* Used for TX-only transfers.
*/
@ -635,7 +635,7 @@ static void bcm2835_spi_dma_tx_done(void *data)
/* busy-wait for TX FIFO to empty */
while (!(bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_DONE))
bcm2835_wr(bs, BCM2835_SPI_CS, bs->slv->clear_rx_cs);
bcm2835_wr(bs, BCM2835_SPI_CS, bs->target->clear_rx_cs);
bs->tx_dma_active = false;
smp_wmb();
@ -655,10 +655,10 @@ static void bcm2835_spi_dma_tx_done(void *data)
/**
* bcm2835_spi_prepare_sg() - prepare and submit DMA descriptor for sglist
* @ctlr: SPI master controller
* @ctlr: SPI host controller
* @tfr: SPI transfer
* @bs: BCM2835 SPI controller
* @slv: BCM2835 SPI slave
* @target: BCM2835 SPI target
* @is_tx: whether to submit DMA descriptor for TX or RX sglist
*
* Prepare and submit a DMA descriptor for the TX or RX sglist of @tfr.
@ -667,7 +667,7 @@ static void bcm2835_spi_dma_tx_done(void *data)
static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr,
struct spi_transfer *tfr,
struct bcm2835_spi *bs,
struct bcm2835_spidev *slv,
struct bcm2835_spidev *target,
bool is_tx)
{
struct dma_chan *chan;
@ -707,7 +707,7 @@ static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr,
} else if (!tfr->rx_buf) {
desc->callback = bcm2835_spi_dma_tx_done;
desc->callback_param = ctlr;
bs->slv = slv;
bs->target = target;
}
/* submit it to DMA-engine */
@ -718,9 +718,9 @@ static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr,
/**
* bcm2835_spi_transfer_one_dma() - perform SPI transfer using DMA engine
* @ctlr: SPI master controller
* @ctlr: SPI host controller
* @tfr: SPI transfer
* @slv: BCM2835 SPI slave
* @target: BCM2835 SPI target
* @cs: CS register
*
* For *bidirectional* transfers (both tx_buf and rx_buf are non-%NULL), set up
@ -732,7 +732,7 @@ static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr,
* clear the RX FIFO by setting the CLEAR_RX bit in the CS register.
*
* The CS register value is precalculated in bcm2835_spi_setup(). Normally
* this is called only once, on slave registration. A DMA descriptor to write
* this is called only once, on target registration. A DMA descriptor to write
* this value is preallocated in bcm2835_dma_init(). All that's left to do
* when performing a TX-only transfer is to submit this descriptor to the RX
* DMA channel. Latency is thereby minimized. The descriptor does not
@ -765,7 +765,7 @@ static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr,
*/
static int bcm2835_spi_transfer_one_dma(struct spi_controller *ctlr,
struct spi_transfer *tfr,
struct bcm2835_spidev *slv,
struct bcm2835_spidev *target,
u32 cs)
{
struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
@ -783,7 +783,7 @@ static int bcm2835_spi_transfer_one_dma(struct spi_controller *ctlr,
/* setup tx-DMA */
if (bs->tx_buf) {
ret = bcm2835_spi_prepare_sg(ctlr, tfr, bs, slv, true);
ret = bcm2835_spi_prepare_sg(ctlr, tfr, bs, target, true);
} else {
cookie = dmaengine_submit(bs->fill_tx_desc);
ret = dma_submit_error(cookie);
@ -809,9 +809,9 @@ static int bcm2835_spi_transfer_one_dma(struct spi_controller *ctlr,
* this saves 10us or more.
*/
if (bs->rx_buf) {
ret = bcm2835_spi_prepare_sg(ctlr, tfr, bs, slv, false);
ret = bcm2835_spi_prepare_sg(ctlr, tfr, bs, target, false);
} else {
cookie = dmaengine_submit(slv->clear_rx_desc);
cookie = dmaengine_submit(target->clear_rx_desc);
ret = dma_submit_error(cookie);
}
if (ret) {
@ -903,15 +903,15 @@ static int bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev,
/* get tx/rx dma */
ctlr->dma_tx = dma_request_chan(dev, "tx");
if (IS_ERR(ctlr->dma_tx)) {
dev_err(dev, "no tx-dma configuration found - not using dma mode\n");
ret = PTR_ERR(ctlr->dma_tx);
ret = dev_err_probe(dev, PTR_ERR(ctlr->dma_tx),
"no tx-dma configuration found - not using dma mode\n");
ctlr->dma_tx = NULL;
goto err;
}
ctlr->dma_rx = dma_request_chan(dev, "rx");
if (IS_ERR(ctlr->dma_rx)) {
dev_err(dev, "no rx-dma configuration found - not using dma mode\n");
ret = PTR_ERR(ctlr->dma_rx);
ret = dev_err_probe(dev, PTR_ERR(ctlr->dma_rx),
"no rx-dma configuration found - not using dma mode\n");
ctlr->dma_rx = NULL;
goto err_release;
}
@ -1050,10 +1050,10 @@ static int bcm2835_spi_transfer_one(struct spi_controller *ctlr,
struct spi_transfer *tfr)
{
struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
struct bcm2835_spidev *slv = spi_get_ctldata(spi);
struct bcm2835_spidev *target = spi_get_ctldata(spi);
unsigned long spi_hz, cdiv;
unsigned long hz_per_byte, byte_limit;
u32 cs = slv->prepare_cs;
u32 cs = target->prepare_cs;
/* set clock */
spi_hz = tfr->speed_hz;
@ -1101,7 +1101,7 @@ static int bcm2835_spi_transfer_one(struct spi_controller *ctlr,
* this 1 idle clock cycle pattern but runs the spi clock without gaps
*/
if (ctlr->can_dma && bcm2835_spi_can_dma(ctlr, spi, tfr))
return bcm2835_spi_transfer_one_dma(ctlr, tfr, slv, cs);
return bcm2835_spi_transfer_one_dma(ctlr, tfr, target, cs);
/* run in interrupt-mode */
return bcm2835_spi_transfer_one_irq(ctlr, spi, tfr, cs, true);
@ -1112,7 +1112,7 @@ static int bcm2835_spi_prepare_message(struct spi_controller *ctlr,
{
struct spi_device *spi = msg->spi;
struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
struct bcm2835_spidev *slv = spi_get_ctldata(spi);
struct bcm2835_spidev *target = spi_get_ctldata(spi);
int ret;
if (ctlr->can_dma) {
@ -1131,7 +1131,7 @@ static int bcm2835_spi_prepare_message(struct spi_controller *ctlr,
* Set up clock polarity before spi_transfer_one_message() asserts
* chip select to avoid a gratuitous clock signal edge.
*/
bcm2835_wr(bs, BCM2835_SPI_CS, slv->prepare_cs);
bcm2835_wr(bs, BCM2835_SPI_CS, target->prepare_cs);
return 0;
}
@ -1163,51 +1163,51 @@ static int chip_match_name(struct gpio_chip *chip, void *data)
static void bcm2835_spi_cleanup(struct spi_device *spi)
{
struct bcm2835_spidev *slv = spi_get_ctldata(spi);
struct bcm2835_spidev *target = spi_get_ctldata(spi);
struct spi_controller *ctlr = spi->controller;
if (slv->clear_rx_desc)
dmaengine_desc_free(slv->clear_rx_desc);
if (target->clear_rx_desc)
dmaengine_desc_free(target->clear_rx_desc);
if (slv->clear_rx_addr)
if (target->clear_rx_addr)
dma_unmap_single(ctlr->dma_rx->device->dev,
slv->clear_rx_addr,
target->clear_rx_addr,
sizeof(u32),
DMA_TO_DEVICE);
kfree(slv);
kfree(target);
}
static int bcm2835_spi_setup_dma(struct spi_controller *ctlr,
struct spi_device *spi,
struct bcm2835_spi *bs,
struct bcm2835_spidev *slv)
struct bcm2835_spidev *target)
{
int ret;
if (!ctlr->dma_rx)
return 0;
slv->clear_rx_addr = dma_map_single(ctlr->dma_rx->device->dev,
&slv->clear_rx_cs,
sizeof(u32),
DMA_TO_DEVICE);
if (dma_mapping_error(ctlr->dma_rx->device->dev, slv->clear_rx_addr)) {
target->clear_rx_addr = dma_map_single(ctlr->dma_rx->device->dev,
&target->clear_rx_cs,
sizeof(u32),
DMA_TO_DEVICE);
if (dma_mapping_error(ctlr->dma_rx->device->dev, target->clear_rx_addr)) {
dev_err(&spi->dev, "cannot map clear_rx_cs\n");
slv->clear_rx_addr = 0;
target->clear_rx_addr = 0;
return -ENOMEM;
}
slv->clear_rx_desc = dmaengine_prep_dma_cyclic(ctlr->dma_rx,
slv->clear_rx_addr,
sizeof(u32), 0,
DMA_MEM_TO_DEV, 0);
if (!slv->clear_rx_desc) {
target->clear_rx_desc = dmaengine_prep_dma_cyclic(ctlr->dma_rx,
target->clear_rx_addr,
sizeof(u32), 0,
DMA_MEM_TO_DEV, 0);
if (!target->clear_rx_desc) {
dev_err(&spi->dev, "cannot prepare clear_rx_desc\n");
return -ENOMEM;
}
ret = dmaengine_desc_set_reuse(slv->clear_rx_desc);
ret = dmaengine_desc_set_reuse(target->clear_rx_desc);
if (ret) {
dev_err(&spi->dev, "cannot reuse clear_rx_desc\n");
return ret;
@ -1220,26 +1220,26 @@ static int bcm2835_spi_setup(struct spi_device *spi)
{
struct spi_controller *ctlr = spi->controller;
struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
struct bcm2835_spidev *slv = spi_get_ctldata(spi);
struct bcm2835_spidev *target = spi_get_ctldata(spi);
struct gpio_chip *chip;
int ret;
u32 cs;
if (!slv) {
slv = kzalloc(ALIGN(sizeof(*slv), dma_get_cache_alignment()),
if (!target) {
target = kzalloc(ALIGN(sizeof(*target), dma_get_cache_alignment()),
GFP_KERNEL);
if (!slv)
if (!target)
return -ENOMEM;
spi_set_ctldata(spi, slv);
spi_set_ctldata(spi, target);
ret = bcm2835_spi_setup_dma(ctlr, spi, bs, slv);
ret = bcm2835_spi_setup_dma(ctlr, spi, bs, target);
if (ret)
goto err_cleanup;
}
/*
* Precalculate SPI slave's CS register value for ->prepare_message():
* Precalculate SPI target's CS register value for ->prepare_message():
* The driver always uses software-controlled GPIO chip select, hence
* set the hardware-controlled native chip select to an invalid value
* to prevent it from interfering.
@ -1249,18 +1249,18 @@ static int bcm2835_spi_setup(struct spi_device *spi)
cs |= BCM2835_SPI_CS_CPOL;
if (spi->mode & SPI_CPHA)
cs |= BCM2835_SPI_CS_CPHA;
slv->prepare_cs = cs;
target->prepare_cs = cs;
/*
* Precalculate SPI slave's CS register value to clear RX FIFO
* Precalculate SPI target's CS register value to clear RX FIFO
* in case of a TX-only DMA transfer.
*/
if (ctlr->dma_rx) {
slv->clear_rx_cs = cs | BCM2835_SPI_CS_TA |
target->clear_rx_cs = cs | BCM2835_SPI_CS_TA |
BCM2835_SPI_CS_DMAEN |
BCM2835_SPI_CS_CLEAR_RX;
dma_sync_single_for_device(ctlr->dma_rx->device->dev,
slv->clear_rx_addr,
target->clear_rx_addr,
sizeof(u32),
DMA_TO_DEVICE);
}
@ -1328,7 +1328,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
struct bcm2835_spi *bs;
int err;
ctlr = devm_spi_alloc_master(&pdev->dev, sizeof(*bs));
ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(*bs));
if (!ctlr)
return -ENOMEM;
@ -1360,10 +1360,12 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
ctlr->max_speed_hz = clk_get_rate(bs->clk) / 2;
bs->irq = platform_get_irq(pdev, 0);
if (bs->irq <= 0)
return bs->irq ? bs->irq : -ENODEV;
if (bs->irq < 0)
return bs->irq;
clk_prepare_enable(bs->clk);
err = clk_prepare_enable(bs->clk);
if (err)
return err;
bs->clk_hz = clk_get_rate(bs->clk);
err = bcm2835_dma_init(ctlr, &pdev->dev, bs);

Просмотреть файл

@ -20,9 +20,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/spi/spi.h>
#include <linux/spinlock.h>
@ -233,8 +231,8 @@ static void bcm2835aux_spi_transfer_helper(struct bcm2835aux_spi *bs)
static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
{
struct spi_master *master = dev_id;
struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
struct spi_controller *host = dev_id;
struct bcm2835aux_spi *bs = spi_controller_get_devdata(host);
/* IRQ may be shared, so return if our interrupts are disabled */
if (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_CNTL1) &
@ -253,17 +251,17 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
/* and if rx_len is 0 then disable interrupts and wake up completion */
if (!bs->rx_len) {
bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]);
spi_finalize_current_transfer(master);
spi_finalize_current_transfer(host);
}
return IRQ_HANDLED;
}
static int __bcm2835aux_spi_transfer_one_irq(struct spi_master *master,
static int __bcm2835aux_spi_transfer_one_irq(struct spi_controller *host,
struct spi_device *spi,
struct spi_transfer *tfr)
{
struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
struct bcm2835aux_spi *bs = spi_controller_get_devdata(host);
/* enable interrupts */
bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1] |
@ -274,11 +272,11 @@ static int __bcm2835aux_spi_transfer_one_irq(struct spi_master *master,
return 1;
}
static int bcm2835aux_spi_transfer_one_irq(struct spi_master *master,
static int bcm2835aux_spi_transfer_one_irq(struct spi_controller *host,
struct spi_device *spi,
struct spi_transfer *tfr)
{
struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
struct bcm2835aux_spi *bs = spi_controller_get_devdata(host);
/* update statistics */
bs->count_transfer_irq++;
@ -296,14 +294,14 @@ static int bcm2835aux_spi_transfer_one_irq(struct spi_master *master,
}
/* now run the interrupt mode */
return __bcm2835aux_spi_transfer_one_irq(master, spi, tfr);
return __bcm2835aux_spi_transfer_one_irq(host, spi, tfr);
}
static int bcm2835aux_spi_transfer_one_poll(struct spi_master *master,
static int bcm2835aux_spi_transfer_one_poll(struct spi_controller *host,
struct spi_device *spi,
struct spi_transfer *tfr)
{
struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
struct bcm2835aux_spi *bs = spi_controller_get_devdata(host);
unsigned long timeout;
/* update statistics */
@ -330,7 +328,7 @@ static int bcm2835aux_spi_transfer_one_poll(struct spi_master *master,
bs->tx_len, bs->rx_len);
/* forward to interrupt handler */
bs->count_transfer_irq_after_poll++;
return __bcm2835aux_spi_transfer_one_irq(master,
return __bcm2835aux_spi_transfer_one_irq(host,
spi, tfr);
}
}
@ -339,11 +337,11 @@ static int bcm2835aux_spi_transfer_one_poll(struct spi_master *master,
return 0;
}
static int bcm2835aux_spi_transfer_one(struct spi_master *master,
static int bcm2835aux_spi_transfer_one(struct spi_controller *host,
struct spi_device *spi,
struct spi_transfer *tfr)
{
struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
struct bcm2835aux_spi *bs = spi_controller_get_devdata(host);
unsigned long spi_hz, clk_hz, speed;
unsigned long hz_per_byte, byte_limit;
@ -394,17 +392,17 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master,
/* run in polling mode for short transfers */
if (tfr->len < byte_limit)
return bcm2835aux_spi_transfer_one_poll(master, spi, tfr);
return bcm2835aux_spi_transfer_one_poll(host, spi, tfr);
/* run in interrupt mode for all others */
return bcm2835aux_spi_transfer_one_irq(master, spi, tfr);
return bcm2835aux_spi_transfer_one_irq(host, spi, tfr);
}
static int bcm2835aux_spi_prepare_message(struct spi_master *master,
static int bcm2835aux_spi_prepare_message(struct spi_controller *host,
struct spi_message *msg)
{
struct spi_device *spi = msg->spi;
struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
struct bcm2835aux_spi *bs = spi_controller_get_devdata(host);
bs->cntl[0] = BCM2835_AUX_SPI_CNTL0_ENABLE |
BCM2835_AUX_SPI_CNTL0_VAR_WIDTH |
@ -424,20 +422,20 @@ static int bcm2835aux_spi_prepare_message(struct spi_master *master,
return 0;
}
static int bcm2835aux_spi_unprepare_message(struct spi_master *master,
static int bcm2835aux_spi_unprepare_message(struct spi_controller *host,
struct spi_message *msg)
{
struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
struct bcm2835aux_spi *bs = spi_controller_get_devdata(host);
bcm2835aux_spi_reset_hw(bs);
return 0;
}
static void bcm2835aux_spi_handle_err(struct spi_master *master,
static void bcm2835aux_spi_handle_err(struct spi_controller *host,
struct spi_message *msg)
{
struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
struct bcm2835aux_spi *bs = spi_controller_get_devdata(host);
bcm2835aux_spi_reset_hw(bs);
}
@ -475,18 +473,18 @@ static int bcm2835aux_spi_setup(struct spi_device *spi)
static int bcm2835aux_spi_probe(struct platform_device *pdev)
{
struct spi_master *master;
struct spi_controller *host;
struct bcm2835aux_spi *bs;
unsigned long clk_hz;
int err;
master = devm_spi_alloc_master(&pdev->dev, sizeof(*bs));
if (!master)
host = devm_spi_alloc_host(&pdev->dev, sizeof(*bs));
if (!host)
return -ENOMEM;
platform_set_drvdata(pdev, master);
master->mode_bits = (SPI_CPOL | SPI_CS_HIGH | SPI_NO_CS);
master->bits_per_word_mask = SPI_BPW_MASK(8);
platform_set_drvdata(pdev, host);
host->mode_bits = (SPI_CPOL | SPI_CS_HIGH | SPI_NO_CS);
host->bits_per_word_mask = SPI_BPW_MASK(8);
/* even though the driver never officially supported native CS
* allow a single native CS for legacy DT support purposes when
* no cs-gpio is configured.
@ -498,16 +496,16 @@ static int bcm2835aux_spi_probe(struct platform_device *pdev)
* * cs_delay_usec: cs is always deasserted one SCK cycle after
* a spi_transfer
*/
master->num_chipselect = 1;
master->setup = bcm2835aux_spi_setup;
master->transfer_one = bcm2835aux_spi_transfer_one;
master->handle_err = bcm2835aux_spi_handle_err;
master->prepare_message = bcm2835aux_spi_prepare_message;
master->unprepare_message = bcm2835aux_spi_unprepare_message;
master->dev.of_node = pdev->dev.of_node;
master->use_gpio_descriptors = true;
host->num_chipselect = 1;
host->setup = bcm2835aux_spi_setup;
host->transfer_one = bcm2835aux_spi_transfer_one;
host->handle_err = bcm2835aux_spi_handle_err;
host->prepare_message = bcm2835aux_spi_prepare_message;
host->unprepare_message = bcm2835aux_spi_unprepare_message;
host->dev.of_node = pdev->dev.of_node;
host->use_gpio_descriptors = true;
bs = spi_master_get_devdata(master);
bs = spi_controller_get_devdata(host);
/* the main area */
bs->regs = devm_platform_ioremap_resource(pdev, 0);
@ -522,8 +520,8 @@ static int bcm2835aux_spi_probe(struct platform_device *pdev)
}
bs->irq = platform_get_irq(pdev, 0);
if (bs->irq <= 0)
return bs->irq ? bs->irq : -ENODEV;
if (bs->irq < 0)
return bs->irq;
/* this also enables the HW block */
err = clk_prepare_enable(bs->clk);
@ -546,15 +544,15 @@ static int bcm2835aux_spi_probe(struct platform_device *pdev)
err = devm_request_irq(&pdev->dev, bs->irq,
bcm2835aux_spi_interrupt,
IRQF_SHARED,
dev_name(&pdev->dev), master);
dev_name(&pdev->dev), host);
if (err) {
dev_err(&pdev->dev, "could not request IRQ: %d\n", err);
goto out_clk_disable;
}
err = spi_register_master(master);
err = spi_register_controller(host);
if (err) {
dev_err(&pdev->dev, "could not register SPI master: %d\n", err);
dev_err(&pdev->dev, "could not register SPI host: %d\n", err);
goto out_clk_disable;
}
@ -569,12 +567,12 @@ out_clk_disable:
static void bcm2835aux_spi_remove(struct platform_device *pdev)
{
struct spi_master *master = platform_get_drvdata(pdev);
struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
struct spi_controller *host = platform_get_drvdata(pdev);
struct bcm2835aux_spi *bs = spi_controller_get_devdata(host);
bcm2835aux_debugfs_remove(bs);
spi_unregister_master(master);
spi_unregister_controller(host);
bcm2835aux_spi_reset_hw(bs);

Просмотреть файл

@ -149,7 +149,7 @@ static ssize_t wait_mode_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct spi_controller *ctrl = dev_get_drvdata(dev);
struct bcm63xx_hsspi *bs = spi_master_get_devdata(ctrl);
struct bcm63xx_hsspi *bs = spi_controller_get_devdata(ctrl);
return sprintf(buf, "%d\n", bs->wait_mode);
}
@ -158,7 +158,7 @@ static ssize_t wait_mode_store(struct device *dev, struct device_attribute *attr
const char *buf, size_t count)
{
struct spi_controller *ctrl = dev_get_drvdata(dev);
struct bcm63xx_hsspi *bs = spi_master_get_devdata(ctrl);
struct bcm63xx_hsspi *bs = spi_controller_get_devdata(ctrl);
u32 val;
if (kstrtou32(buf, 10, &val))
@ -185,7 +185,7 @@ static ssize_t xfer_mode_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct spi_controller *ctrl = dev_get_drvdata(dev);
struct bcm63xx_hsspi *bs = spi_master_get_devdata(ctrl);
struct bcm63xx_hsspi *bs = spi_controller_get_devdata(ctrl);
return sprintf(buf, "%d\n", bs->xfer_mode);
}
@ -194,7 +194,7 @@ static ssize_t xfer_mode_store(struct device *dev, struct device_attribute *attr
const char *buf, size_t count)
{
struct spi_controller *ctrl = dev_get_drvdata(dev);
struct bcm63xx_hsspi *bs = spi_master_get_devdata(ctrl);
struct bcm63xx_hsspi *bs = spi_controller_get_devdata(ctrl);
u32 val;
if (kstrtou32(buf, 10, &val))
@ -262,12 +262,12 @@ static int bcm63xx_hsspi_wait_cmd(struct bcm63xx_hsspi *bs)
return rc;
}
static bool bcm63xx_prepare_prepend_transfer(struct spi_master *master,
static bool bcm63xx_prepare_prepend_transfer(struct spi_controller *host,
struct spi_message *msg,
struct spi_transfer *t_prepend)
{
struct bcm63xx_hsspi *bs = spi_master_get_devdata(master);
struct bcm63xx_hsspi *bs = spi_controller_get_devdata(host);
bool tx_only = false;
struct spi_transfer *t;
@ -348,7 +348,7 @@ static bool bcm63xx_prepare_prepend_transfer(struct spi_master *master,
static int bcm63xx_hsspi_do_prepend_txrx(struct spi_device *spi,
struct spi_transfer *t)
{
struct bcm63xx_hsspi *bs = spi_master_get_devdata(spi->master);
struct bcm63xx_hsspi *bs = spi_controller_get_devdata(spi->controller);
unsigned int chip_select = spi_get_chipselect(spi, 0);
u16 opcode = 0, val;
const u8 *tx = t->tx_buf;
@ -467,7 +467,7 @@ static void bcm63xx_hsspi_set_clk(struct bcm63xx_hsspi *bs,
static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t)
{
struct bcm63xx_hsspi *bs = spi_master_get_devdata(spi->master);
struct bcm63xx_hsspi *bs = spi_controller_get_devdata(spi->controller);
unsigned int chip_select = spi_get_chipselect(spi, 0);
u16 opcode = 0, val;
int pending = t->len;
@ -541,7 +541,7 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t)
static int bcm63xx_hsspi_setup(struct spi_device *spi)
{
struct bcm63xx_hsspi *bs = spi_master_get_devdata(spi->master);
struct bcm63xx_hsspi *bs = spi_controller_get_devdata(spi->controller);
u32 reg;
reg = __raw_readl(bs->regs +
@ -579,7 +579,7 @@ static int bcm63xx_hsspi_setup(struct spi_device *spi)
static int bcm63xx_hsspi_do_dummy_cs_txrx(struct spi_device *spi,
struct spi_message *msg)
{
struct bcm63xx_hsspi *bs = spi_master_get_devdata(spi->master);
struct bcm63xx_hsspi *bs = spi_controller_get_devdata(spi->controller);
int status = -EINVAL;
int dummy_cs;
bool keep_cs = false;
@ -653,10 +653,10 @@ static int bcm63xx_hsspi_do_dummy_cs_txrx(struct spi_device *spi,
return status;
}
static int bcm63xx_hsspi_transfer_one(struct spi_master *master,
static int bcm63xx_hsspi_transfer_one(struct spi_controller *host,
struct spi_message *msg)
{
struct bcm63xx_hsspi *bs = spi_master_get_devdata(master);
struct bcm63xx_hsspi *bs = spi_controller_get_devdata(host);
struct spi_device *spi = msg->spi;
int status = -EINVAL;
bool prependable = false;
@ -665,7 +665,7 @@ static int bcm63xx_hsspi_transfer_one(struct spi_master *master,
mutex_lock(&bs->msg_mutex);
if (bs->xfer_mode != HSSPI_XFER_MODE_DUMMYCS)
prependable = bcm63xx_prepare_prepend_transfer(master, msg, &t_prepend);
prependable = bcm63xx_prepare_prepend_transfer(host, msg, &t_prepend);
if (prependable) {
status = bcm63xx_hsspi_do_prepend_txrx(spi, &t_prepend);
@ -681,7 +681,7 @@ static int bcm63xx_hsspi_transfer_one(struct spi_master *master,
mutex_unlock(&bs->msg_mutex);
msg->status = status;
spi_finalize_current_message(master);
spi_finalize_current_message(host);
return 0;
}
@ -723,7 +723,7 @@ static irqreturn_t bcm63xx_hsspi_interrupt(int irq, void *dev_id)
static int bcm63xx_hsspi_probe(struct platform_device *pdev)
{
struct spi_master *master;
struct spi_controller *host;
struct bcm63xx_hsspi *bs;
void __iomem *regs;
struct device *dev = &pdev->dev;
@ -779,13 +779,13 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev)
}
}
master = spi_alloc_master(&pdev->dev, sizeof(*bs));
if (!master) {
host = spi_alloc_host(&pdev->dev, sizeof(*bs));
if (!host) {
ret = -ENOMEM;
goto out_disable_pll_clk;
}
bs = spi_master_get_devdata(master);
bs = spi_controller_get_devdata(host);
bs->pdev = pdev;
bs->clk = clk;
bs->pll_clk = pll_clk;
@ -796,17 +796,17 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev)
bs->prepend_buf = devm_kzalloc(dev, HSSPI_BUFFER_LEN, GFP_KERNEL);
if (!bs->prepend_buf) {
ret = -ENOMEM;
goto out_put_master;
goto out_put_host;
}
mutex_init(&bs->bus_mutex);
mutex_init(&bs->msg_mutex);
init_completion(&bs->done);
master->mem_ops = &bcm63xx_hsspi_mem_ops;
master->dev.of_node = dev->of_node;
host->mem_ops = &bcm63xx_hsspi_mem_ops;
host->dev.of_node = dev->of_node;
if (!dev->of_node)
master->bus_num = HSSPI_BUS_NUM;
host->bus_num = HSSPI_BUS_NUM;
of_property_read_u32(dev->of_node, "num-cs", &num_cs);
if (num_cs > 8) {
@ -814,18 +814,18 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev)
num_cs);
num_cs = HSSPI_SPI_MAX_CS;
}
master->num_chipselect = num_cs;
master->setup = bcm63xx_hsspi_setup;
master->transfer_one_message = bcm63xx_hsspi_transfer_one;
master->max_transfer_size = bcm63xx_hsspi_max_message_size;
master->max_message_size = bcm63xx_hsspi_max_message_size;
host->num_chipselect = num_cs;
host->setup = bcm63xx_hsspi_setup;
host->transfer_one_message = bcm63xx_hsspi_transfer_one;
host->max_transfer_size = bcm63xx_hsspi_max_message_size;
host->max_message_size = bcm63xx_hsspi_max_message_size;
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH |
host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH |
SPI_RX_DUAL | SPI_TX_DUAL;
master->bits_per_word_mask = SPI_BPW_MASK(8);
master->auto_runtime_pm = true;
host->bits_per_word_mask = SPI_BPW_MASK(8);
host->auto_runtime_pm = true;
platform_set_drvdata(pdev, master);
platform_set_drvdata(pdev, host);
/* Initialize the hardware */
__raw_writel(0, bs->regs + HSSPI_INT_MASK_REG);
@ -844,7 +844,7 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev)
pdev->name, bs);
if (ret)
goto out_put_master;
goto out_put_host;
}
pm_runtime_enable(&pdev->dev);
@ -856,7 +856,7 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev)
}
/* register and we are done */
ret = devm_spi_register_master(dev, master);
ret = devm_spi_register_controller(dev, host);
if (ret)
goto out_sysgroup_disable;
@ -868,8 +868,8 @@ out_sysgroup_disable:
sysfs_remove_group(&pdev->dev.kobj, &bcm63xx_hsspi_group);
out_pm_disable:
pm_runtime_disable(&pdev->dev);
out_put_master:
spi_master_put(master);
out_put_host:
spi_controller_put(host);
out_disable_pll_clk:
clk_disable_unprepare(pll_clk);
out_disable_clk:
@ -880,8 +880,8 @@ out_disable_clk:
static void bcm63xx_hsspi_remove(struct platform_device *pdev)
{
struct spi_master *master = platform_get_drvdata(pdev);
struct bcm63xx_hsspi *bs = spi_master_get_devdata(master);
struct spi_controller *host = platform_get_drvdata(pdev);
struct bcm63xx_hsspi *bs = spi_controller_get_devdata(host);
/* reset the hardware and block queue progress */
__raw_writel(0, bs->regs + HSSPI_INT_MASK_REG);
@ -893,10 +893,10 @@ static void bcm63xx_hsspi_remove(struct platform_device *pdev)
#ifdef CONFIG_PM_SLEEP
static int bcm63xx_hsspi_suspend(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct bcm63xx_hsspi *bs = spi_master_get_devdata(master);
struct spi_controller *host = dev_get_drvdata(dev);
struct bcm63xx_hsspi *bs = spi_controller_get_devdata(host);
spi_master_suspend(master);
spi_controller_suspend(host);
clk_disable_unprepare(bs->pll_clk);
clk_disable_unprepare(bs->clk);
@ -905,8 +905,8 @@ static int bcm63xx_hsspi_suspend(struct device *dev)
static int bcm63xx_hsspi_resume(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct bcm63xx_hsspi *bs = spi_master_get_devdata(master);
struct spi_controller *host = dev_get_drvdata(dev);
struct bcm63xx_hsspi *bs = spi_controller_get_devdata(host);
int ret;
ret = clk_prepare_enable(bs->clk);
@ -921,7 +921,7 @@ static int bcm63xx_hsspi_resume(struct device *dev)
}
}
spi_master_resume(master);
spi_controller_resume(host);
return 0;
}

Просмотреть файл

@ -186,7 +186,7 @@ static const unsigned int bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = {
static void bcm63xx_spi_setup_transfer(struct spi_device *spi,
struct spi_transfer *t)
{
struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
struct bcm63xx_spi *bs = spi_controller_get_devdata(spi->controller);
u8 clk_cfg, reg;
int i;
@ -217,7 +217,7 @@ static void bcm63xx_spi_setup_transfer(struct spi_device *spi,
static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
unsigned int num_transfers)
{
struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
struct bcm63xx_spi *bs = spi_controller_get_devdata(spi->controller);
u16 msg_ctl;
u16 cmd;
unsigned int i, timeout = 0, prepend_len = 0, len = 0;
@ -312,10 +312,10 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
return 0;
}
static int bcm63xx_spi_transfer_one(struct spi_master *master,
static int bcm63xx_spi_transfer_one(struct spi_controller *host,
struct spi_message *m)
{
struct bcm63xx_spi *bs = spi_master_get_devdata(master);
struct bcm63xx_spi *bs = spi_controller_get_devdata(host);
struct spi_transfer *t, *first = NULL;
struct spi_device *spi = m->spi;
int status = 0;
@ -385,18 +385,18 @@ static int bcm63xx_spi_transfer_one(struct spi_master *master,
}
exit:
m->status = status;
spi_finalize_current_message(master);
spi_finalize_current_message(host);
return 0;
}
/* This driver supports single master mode only. Hence
/* This driver supports single host mode only. Hence
* CMD_DONE is the only interrupt we care about
*/
static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id)
{
struct spi_master *master = (struct spi_master *)dev_id;
struct bcm63xx_spi *bs = spi_master_get_devdata(master);
struct spi_controller *host = (struct spi_controller *)dev_id;
struct bcm63xx_spi *bs = spi_controller_get_devdata(host);
u8 intr;
/* Read interupts and clear them immediately */
@ -413,7 +413,7 @@ static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id)
static size_t bcm63xx_spi_max_length(struct spi_device *spi)
{
struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
struct bcm63xx_spi *bs = spi_controller_get_devdata(spi->controller);
return bs->fifo_size;
}
@ -479,7 +479,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
const unsigned long *bcm63xx_spireg;
struct device *dev = &pdev->dev;
int irq, bus_num;
struct spi_master *master;
struct spi_controller *host;
struct clk *clk;
struct bcm63xx_spi *bs;
int ret;
@ -525,16 +525,16 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
if (IS_ERR(reset))
return PTR_ERR(reset);
master = spi_alloc_master(dev, sizeof(*bs));
if (!master) {
host = spi_alloc_host(dev, sizeof(*bs));
if (!host) {
dev_err(dev, "out of memory\n");
return -ENOMEM;
}
bs = spi_master_get_devdata(master);
bs = spi_controller_get_devdata(host);
init_completion(&bs->done);
platform_set_drvdata(pdev, master);
platform_set_drvdata(pdev, host);
bs->pdev = pdev;
bs->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &r);
@ -549,21 +549,21 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
bs->fifo_size = bs->reg_offsets[SPI_MSG_DATA_SIZE];
ret = devm_request_irq(&pdev->dev, irq, bcm63xx_spi_interrupt, 0,
pdev->name, master);
pdev->name, host);
if (ret) {
dev_err(dev, "unable to request irq\n");
goto out_err;
}
master->dev.of_node = dev->of_node;
master->bus_num = bus_num;
master->num_chipselect = num_cs;
master->transfer_one_message = bcm63xx_spi_transfer_one;
master->mode_bits = MODEBITS;
master->bits_per_word_mask = SPI_BPW_MASK(8);
master->max_transfer_size = bcm63xx_spi_max_length;
master->max_message_size = bcm63xx_spi_max_length;
master->auto_runtime_pm = true;
host->dev.of_node = dev->of_node;
host->bus_num = bus_num;
host->num_chipselect = num_cs;
host->transfer_one_message = bcm63xx_spi_transfer_one;
host->mode_bits = MODEBITS;
host->bits_per_word_mask = SPI_BPW_MASK(8);
host->max_transfer_size = bcm63xx_spi_max_length;
host->max_message_size = bcm63xx_spi_max_length;
host->auto_runtime_pm = true;
bs->msg_type_shift = bs->reg_offsets[SPI_MSG_TYPE_SHIFT];
bs->msg_ctl_width = bs->reg_offsets[SPI_MSG_CTL_WIDTH];
bs->tx_io = (u8 *)(bs->regs + bs->reg_offsets[SPI_MSG_DATA]);
@ -585,7 +585,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
/* register and we are done */
ret = devm_spi_register_master(dev, master);
ret = devm_spi_register_controller(dev, host);
if (ret) {
dev_err(dev, "spi register failed\n");
goto out_pm_disable;
@ -601,14 +601,14 @@ out_pm_disable:
out_clk_disable:
clk_disable_unprepare(clk);
out_err:
spi_master_put(master);
spi_controller_put(host);
return ret;
}
static void bcm63xx_spi_remove(struct platform_device *pdev)
{
struct spi_master *master = platform_get_drvdata(pdev);
struct bcm63xx_spi *bs = spi_master_get_devdata(master);
struct spi_controller *host = platform_get_drvdata(pdev);
struct bcm63xx_spi *bs = spi_controller_get_devdata(host);
/* reset spi block */
bcm_spi_writeb(bs, 0, SPI_INT_MASK);
@ -619,10 +619,10 @@ static void bcm63xx_spi_remove(struct platform_device *pdev)
static int bcm63xx_spi_suspend(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct bcm63xx_spi *bs = spi_master_get_devdata(master);
struct spi_controller *host = dev_get_drvdata(dev);
struct bcm63xx_spi *bs = spi_controller_get_devdata(host);
spi_master_suspend(master);
spi_controller_suspend(host);
clk_disable_unprepare(bs->clk);
@ -631,15 +631,15 @@ static int bcm63xx_spi_suspend(struct device *dev)
static int bcm63xx_spi_resume(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct bcm63xx_spi *bs = spi_master_get_devdata(master);
struct spi_controller *host = dev_get_drvdata(dev);
struct bcm63xx_spi *bs = spi_controller_get_devdata(host);
int ret;
ret = clk_prepare_enable(bs->clk);
if (ret)
return ret;
spi_master_resume(master);
spi_controller_resume(host);
return 0;
}

Просмотреть файл

@ -127,7 +127,7 @@ static ssize_t wait_mode_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct spi_controller *ctrl = dev_get_drvdata(dev);
struct bcmbca_hsspi *bs = spi_master_get_devdata(ctrl);
struct bcmbca_hsspi *bs = spi_controller_get_devdata(ctrl);
return sprintf(buf, "%d\n", bs->wait_mode);
}
@ -136,7 +136,7 @@ static ssize_t wait_mode_store(struct device *dev, struct device_attribute *attr
const char *buf, size_t count)
{
struct spi_controller *ctrl = dev_get_drvdata(dev);
struct bcmbca_hsspi *bs = spi_master_get_devdata(ctrl);
struct bcmbca_hsspi *bs = spi_controller_get_devdata(ctrl);
u32 val;
if (kstrtou32(buf, 10, &val))
@ -250,7 +250,7 @@ static int bcmbca_hsspi_wait_cmd(struct bcmbca_hsspi *bs, unsigned int cs)
static int bcmbca_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t,
struct spi_message *msg)
{
struct bcmbca_hsspi *bs = spi_master_get_devdata(spi->master);
struct bcmbca_hsspi *bs = spi_controller_get_devdata(spi->controller);
unsigned int chip_select = spi_get_chipselect(spi, 0);
u16 opcode = 0, val;
int pending = t->len;
@ -328,7 +328,7 @@ static int bcmbca_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t,
static int bcmbca_hsspi_setup(struct spi_device *spi)
{
struct bcmbca_hsspi *bs = spi_master_get_devdata(spi->master);
struct bcmbca_hsspi *bs = spi_controller_get_devdata(spi->controller);
u32 reg;
reg = __raw_readl(bs->regs +
@ -366,10 +366,10 @@ static int bcmbca_hsspi_setup(struct spi_device *spi)
return 0;
}
static int bcmbca_hsspi_transfer_one(struct spi_master *master,
static int bcmbca_hsspi_transfer_one(struct spi_controller *host,
struct spi_message *msg)
{
struct bcmbca_hsspi *bs = spi_master_get_devdata(master);
struct bcmbca_hsspi *bs = spi_controller_get_devdata(host);
struct spi_transfer *t;
struct spi_device *spi = msg->spi;
int status = -EINVAL;
@ -409,7 +409,7 @@ static int bcmbca_hsspi_transfer_one(struct spi_master *master,
bcmbca_hsspi_set_cs(bs, spi_get_chipselect(spi, 0), false);
msg->status = status;
spi_finalize_current_message(master);
spi_finalize_current_message(host);
return 0;
}
@ -431,7 +431,7 @@ static irqreturn_t bcmbca_hsspi_interrupt(int irq, void *dev_id)
static int bcmbca_hsspi_probe(struct platform_device *pdev)
{
struct spi_master *master;
struct spi_controller *host;
struct bcmbca_hsspi *bs;
struct resource *res_mem;
void __iomem *spim_ctrl;
@ -487,13 +487,13 @@ static int bcmbca_hsspi_probe(struct platform_device *pdev)
}
}
master = spi_alloc_master(&pdev->dev, sizeof(*bs));
if (!master) {
host = spi_alloc_host(&pdev->dev, sizeof(*bs));
if (!host) {
ret = -ENOMEM;
goto out_disable_pll_clk;
}
bs = spi_master_get_devdata(master);
bs = spi_controller_get_devdata(host);
bs->pdev = pdev;
bs->clk = clk;
bs->pll_clk = pll_clk;
@ -507,9 +507,9 @@ static int bcmbca_hsspi_probe(struct platform_device *pdev)
mutex_init(&bs->msg_mutex);
init_completion(&bs->done);
master->dev.of_node = dev->of_node;
host->dev.of_node = dev->of_node;
if (!dev->of_node)
master->bus_num = HSSPI_BUS_NUM;
host->bus_num = HSSPI_BUS_NUM;
of_property_read_u32(dev->of_node, "num-cs", &num_cs);
if (num_cs > 8) {
@ -517,15 +517,15 @@ static int bcmbca_hsspi_probe(struct platform_device *pdev)
num_cs);
num_cs = HSSPI_SPI_MAX_CS;
}
master->num_chipselect = num_cs;
master->setup = bcmbca_hsspi_setup;
master->transfer_one_message = bcmbca_hsspi_transfer_one;
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH |
SPI_RX_DUAL | SPI_TX_DUAL;
master->bits_per_word_mask = SPI_BPW_MASK(8);
master->auto_runtime_pm = true;
host->num_chipselect = num_cs;
host->setup = bcmbca_hsspi_setup;
host->transfer_one_message = bcmbca_hsspi_transfer_one;
host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH |
SPI_RX_DUAL | SPI_TX_DUAL;
host->bits_per_word_mask = SPI_BPW_MASK(8);
host->auto_runtime_pm = true;
platform_set_drvdata(pdev, master);
platform_set_drvdata(pdev, host);
/* Initialize the hardware */
__raw_writel(0, bs->regs + HSSPI_INT_MASK_REG);
@ -543,7 +543,7 @@ static int bcmbca_hsspi_probe(struct platform_device *pdev)
ret = devm_request_irq(dev, irq, bcmbca_hsspi_interrupt, IRQF_SHARED,
pdev->name, bs);
if (ret)
goto out_put_master;
goto out_put_host;
}
pm_runtime_enable(&pdev->dev);
@ -555,7 +555,7 @@ static int bcmbca_hsspi_probe(struct platform_device *pdev)
}
/* register and we are done */
ret = devm_spi_register_master(dev, master);
ret = devm_spi_register_controller(dev, host);
if (ret)
goto out_sysgroup_disable;
@ -567,8 +567,8 @@ out_sysgroup_disable:
sysfs_remove_group(&pdev->dev.kobj, &bcmbca_hsspi_group);
out_pm_disable:
pm_runtime_disable(&pdev->dev);
out_put_master:
spi_master_put(master);
out_put_host:
spi_controller_put(host);
out_disable_pll_clk:
clk_disable_unprepare(pll_clk);
out_disable_clk:
@ -578,8 +578,8 @@ out_disable_clk:
static void bcmbca_hsspi_remove(struct platform_device *pdev)
{
struct spi_master *master = platform_get_drvdata(pdev);
struct bcmbca_hsspi *bs = spi_master_get_devdata(master);
struct spi_controller *host = platform_get_drvdata(pdev);
struct bcmbca_hsspi *bs = spi_controller_get_devdata(host);
/* reset the hardware and block queue progress */
__raw_writel(0, bs->regs + HSSPI_INT_MASK_REG);
@ -591,10 +591,10 @@ static void bcmbca_hsspi_remove(struct platform_device *pdev)
#ifdef CONFIG_PM_SLEEP
static int bcmbca_hsspi_suspend(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct bcmbca_hsspi *bs = spi_master_get_devdata(master);
struct spi_controller *host = dev_get_drvdata(dev);
struct bcmbca_hsspi *bs = spi_controller_get_devdata(host);
spi_master_suspend(master);
spi_controller_suspend(host);
clk_disable_unprepare(bs->pll_clk);
clk_disable_unprepare(bs->clk);
@ -603,8 +603,8 @@ static int bcmbca_hsspi_suspend(struct device *dev)
static int bcmbca_hsspi_resume(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct bcmbca_hsspi *bs = spi_master_get_devdata(master);
struct spi_controller *host = dev_get_drvdata(dev);
struct bcmbca_hsspi *bs = spi_controller_get_devdata(host);
int ret;
ret = clk_prepare_enable(bs->clk);
@ -619,7 +619,7 @@ static int bcmbca_hsspi_resume(struct device *dev)
}
}
spi_master_resume(master);
spi_controller_resume(host);
return 0;
}

Просмотреть файл

@ -57,7 +57,7 @@ bitbang_txrx_be_cpha0(struct spi_device *spi,
for (word <<= (32 - bits); likely(bits); bits--) {
/* setup MSB (to slave) on trailing edge */
if ((flags & SPI_MASTER_NO_TX) == 0) {
if ((flags & SPI_CONTROLLER_NO_TX) == 0) {
if ((word & (1 << 31)) != oldbit) {
setmosi(spi, word & (1 << 31));
oldbit = word & (1 << 31);
@ -70,7 +70,7 @@ bitbang_txrx_be_cpha0(struct spi_device *spi,
/* sample MSB (from slave) on leading edge */
word <<= 1;
if ((flags & SPI_MASTER_NO_RX) == 0)
if ((flags & SPI_CONTROLLER_NO_RX) == 0)
word |= getmiso(spi);
setsck(spi, cpol);
}
@ -90,7 +90,7 @@ bitbang_txrx_be_cpha1(struct spi_device *spi,
/* setup MSB (to slave) on leading edge */
setsck(spi, !cpol);
if ((flags & SPI_MASTER_NO_TX) == 0) {
if ((flags & SPI_CONTROLLER_NO_TX) == 0) {
if ((word & (1 << 31)) != oldbit) {
setmosi(spi, word & (1 << 31));
oldbit = word & (1 << 31);
@ -103,7 +103,7 @@ bitbang_txrx_be_cpha1(struct spi_device *spi,
/* sample MSB (from slave) on trailing edge */
word <<= 1;
if ((flags & SPI_MASTER_NO_RX) == 0)
if ((flags & SPI_CONTROLLER_NO_RX) == 0)
word |= getmiso(spi);
}
return word;
@ -122,7 +122,7 @@ bitbang_txrx_le_cpha0(struct spi_device *spi,
for (; likely(bits); bits--) {
/* setup LSB (to slave) on trailing edge */
if ((flags & SPI_MASTER_NO_TX) == 0) {
if ((flags & SPI_CONTROLLER_NO_TX) == 0) {
if ((word & 1) != oldbit) {
setmosi(spi, word & 1);
oldbit = word & 1;
@ -135,7 +135,7 @@ bitbang_txrx_le_cpha0(struct spi_device *spi,
/* sample LSB (from slave) on leading edge */
word >>= 1;
if ((flags & SPI_MASTER_NO_RX) == 0)
if ((flags & SPI_CONTROLLER_NO_RX) == 0)
word |= getmiso(spi) << rxbit;
setsck(spi, cpol);
}
@ -156,7 +156,7 @@ bitbang_txrx_le_cpha1(struct spi_device *spi,
/* setup LSB (to slave) on leading edge */
setsck(spi, !cpol);
if ((flags & SPI_MASTER_NO_TX) == 0) {
if ((flags & SPI_CONTROLLER_NO_TX) == 0) {
if ((word & 1) != oldbit) {
setmosi(spi, word & 1);
oldbit = word & 1;
@ -169,7 +169,7 @@ bitbang_txrx_le_cpha1(struct spi_device *spi,
/* sample LSB (from slave) on trailing edge */
word >>= 1;
if ((flags & SPI_MASTER_NO_RX) == 0)
if ((flags & SPI_CONTROLLER_NO_RX) == 0)
word |= getmiso(spi) << rxbit;
}
return word;

Просмотреть файл

@ -248,7 +248,7 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t)
if (spi->mode & SPI_3WIRE) {
unsigned flags;
flags = t->tx_buf ? SPI_MASTER_NO_RX : SPI_MASTER_NO_TX;
flags = t->tx_buf ? SPI_CONTROLLER_NO_RX : SPI_CONTROLLER_NO_TX;
return cs->txrx_bufs(spi, cs->txrx_word, nsecs, t, flags);
}
return cs->txrx_bufs(spi, cs->txrx_word, nsecs, t, 0);
@ -349,11 +349,11 @@ int spi_bitbang_init(struct spi_bitbang *bitbang)
/*
* 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
* SPI_CONTROLLER_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));
(master->flags & SPI_CONTROLLER_GPIO_SS));
if (custom_cs && !bitbang->chipselect)
return -EINVAL;
@ -371,7 +371,7 @@ int spi_bitbang_init(struct spi_bitbang *bitbang)
master->transfer_one = spi_bitbang_transfer_one;
/*
* When using GPIO descriptors, the ->set_cs() callback doesn't even
* get called unless SPI_MASTER_GPIO_SS is set.
* get called unless SPI_CONTROLLER_GPIO_SS is set.
*/
if (custom_cs)
master->set_cs = spi_bitbang_set_cs;

Просмотреть файл

@ -178,7 +178,7 @@ static void butterfly_attach(struct parport *p)
struct pardevice *pd;
int status;
struct butterfly *pp;
struct spi_master *master;
struct spi_controller *host;
struct device *dev = p->physport->dev;
struct pardev_cb butterfly_cb;
@ -189,12 +189,12 @@ static void butterfly_attach(struct parport *p)
* and no way to be selective about what it binds to.
*/
master = spi_alloc_master(dev, sizeof(*pp));
if (!master) {
host = spi_alloc_host(dev, sizeof(*pp));
if (!host) {
status = -ENOMEM;
goto done;
}
pp = spi_master_get_devdata(master);
pp = spi_controller_get_devdata(host);
/*
* SPI and bitbang hookup
@ -202,10 +202,10 @@ static void butterfly_attach(struct parport *p)
* use default setup(), cleanup(), and transfer() methods; and
* only bother implementing mode 0. Start it later.
*/
master->bus_num = 42;
master->num_chipselect = 2;
host->bus_num = 42;
host->num_chipselect = 2;
pp->bitbang.master = master;
pp->bitbang.master = host;
pp->bitbang.chipselect = butterfly_chipselect;
pp->bitbang.txrx_word[SPI_MODE_0] = butterfly_txrx_word_mode0;
@ -280,7 +280,7 @@ clean2:
clean1:
parport_unregister_device(pd);
clean0:
spi_master_put(pp->bitbang.master);
spi_controller_put(host);
done:
pr_debug("%s: butterfly probe, fail %d\n", p->name, status);
}
@ -308,7 +308,7 @@ static void butterfly_detach(struct parport *p)
parport_release(pp->pd);
parport_unregister_device(pp->pd);
spi_master_put(pp->bitbang.master);
spi_controller_put(pp->bitbang.master);
}
static struct parport_driver butterfly_driver = {

Просмотреть файл

@ -21,7 +21,6 @@
#include <linux/kernel.h>
#include <linux/log2.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
@ -47,6 +46,12 @@
#define CQSPI_OP_WIDTH(part) ((part).nbytes ? ilog2((part).buswidth) : 0)
enum {
CLK_QSPI_APB = 0,
CLK_QSPI_AHB,
CLK_QSPI_NUM,
};
struct cqspi_st;
struct cqspi_flash_pdata {
@ -62,8 +67,9 @@ struct cqspi_flash_pdata {
struct cqspi_st {
struct platform_device *pdev;
struct spi_master *master;
struct spi_controller *host;
struct clk *clk;
struct clk *clks[CLK_QSPI_NUM];
unsigned int sclk;
void __iomem *iobase;
@ -92,6 +98,8 @@ struct cqspi_st {
bool wr_completion;
bool slow_sram;
bool apb_ahb_hazard;
bool is_jh7110; /* Flag for StarFive JH7110 SoC */
};
struct cqspi_driver_platdata {
@ -100,6 +108,8 @@ struct cqspi_driver_platdata {
int (*indirect_read_dma)(struct cqspi_flash_pdata *f_pdata,
u_char *rxbuf, loff_t from_addr, size_t n_rx);
u32 (*get_dma_status)(struct cqspi_st *cqspi);
int (*jh7110_clk_init)(struct platform_device *pdev,
struct cqspi_st *cqspi);
};
/* Operation timeout value */
@ -1369,7 +1379,7 @@ static ssize_t cqspi_read(struct cqspi_flash_pdata *f_pdata,
static int cqspi_mem_process(struct spi_mem *mem, const struct spi_mem_op *op)
{
struct cqspi_st *cqspi = spi_master_get_devdata(mem->spi->master);
struct cqspi_st *cqspi = spi_controller_get_devdata(mem->spi->controller);
struct cqspi_flash_pdata *f_pdata;
f_pdata = &cqspi->f_pdata[spi_get_chipselect(mem->spi, 0)];
@ -1575,7 +1585,7 @@ static int cqspi_request_mmap_dma(struct cqspi_st *cqspi)
static const char *cqspi_get_name(struct spi_mem *mem)
{
struct cqspi_st *cqspi = spi_master_get_devdata(mem->spi->master);
struct cqspi_st *cqspi = spi_controller_get_devdata(mem->spi->controller);
struct device *dev = &cqspi->pdev->dev;
return devm_kasprintf(dev, GFP_KERNEL, "%s.%d", dev_name(dev),
@ -1630,31 +1640,77 @@ static int cqspi_setup_flash(struct cqspi_st *cqspi)
return 0;
}
static int cqspi_jh7110_clk_init(struct platform_device *pdev, struct cqspi_st *cqspi)
{
static struct clk_bulk_data qspiclk[] = {
{ .id = "apb" },
{ .id = "ahb" },
};
int ret = 0;
ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(qspiclk), qspiclk);
if (ret) {
dev_err(&pdev->dev, "%s: failed to get qspi clocks\n", __func__);
return ret;
}
cqspi->clks[CLK_QSPI_APB] = qspiclk[0].clk;
cqspi->clks[CLK_QSPI_AHB] = qspiclk[1].clk;
ret = clk_prepare_enable(cqspi->clks[CLK_QSPI_APB]);
if (ret) {
dev_err(&pdev->dev, "%s: failed to enable CLK_QSPI_APB\n", __func__);
return ret;
}
ret = clk_prepare_enable(cqspi->clks[CLK_QSPI_AHB]);
if (ret) {
dev_err(&pdev->dev, "%s: failed to enable CLK_QSPI_AHB\n", __func__);
goto disable_apb_clk;
}
cqspi->is_jh7110 = true;
return 0;
disable_apb_clk:
clk_disable_unprepare(cqspi->clks[CLK_QSPI_APB]);
return ret;
}
static void cqspi_jh7110_disable_clk(struct platform_device *pdev, struct cqspi_st *cqspi)
{
clk_disable_unprepare(cqspi->clks[CLK_QSPI_AHB]);
clk_disable_unprepare(cqspi->clks[CLK_QSPI_APB]);
}
static int cqspi_probe(struct platform_device *pdev)
{
const struct cqspi_driver_platdata *ddata;
struct reset_control *rstc, *rstc_ocp, *rstc_ref;
struct device *dev = &pdev->dev;
struct spi_master *master;
struct spi_controller *host;
struct resource *res_ahb;
struct cqspi_st *cqspi;
int ret;
int irq;
master = devm_spi_alloc_master(&pdev->dev, sizeof(*cqspi));
if (!master) {
dev_err(&pdev->dev, "spi_alloc_master failed\n");
host = devm_spi_alloc_host(&pdev->dev, sizeof(*cqspi));
if (!host) {
dev_err(&pdev->dev, "devm_spi_alloc_host failed\n");
return -ENOMEM;
}
master->mode_bits = SPI_RX_QUAD | SPI_RX_DUAL;
master->mem_ops = &cqspi_mem_ops;
master->mem_caps = &cqspi_mem_caps;
master->dev.of_node = pdev->dev.of_node;
host->mode_bits = SPI_RX_QUAD | SPI_RX_DUAL;
host->mem_ops = &cqspi_mem_ops;
host->mem_caps = &cqspi_mem_caps;
host->dev.of_node = pdev->dev.of_node;
cqspi = spi_master_get_devdata(master);
cqspi = spi_controller_get_devdata(host);
cqspi->pdev = pdev;
cqspi->master = master;
cqspi->host = host;
cqspi->is_jh7110 = false;
platform_set_drvdata(pdev, cqspi);
/* Obtain configuration from OF. */
@ -1741,7 +1797,7 @@ static int cqspi_probe(struct platform_device *pdev)
reset_control_deassert(rstc_ocp);
cqspi->master_ref_clk_hz = clk_get_rate(cqspi->clk);
master->max_speed_hz = cqspi->master_ref_clk_hz;
host->max_speed_hz = cqspi->master_ref_clk_hz;
/* write completion is supported by default */
cqspi->wr_completion = true;
@ -1752,7 +1808,7 @@ static int cqspi_probe(struct platform_device *pdev)
cqspi->wr_delay = 50 * DIV_ROUND_UP(NSEC_PER_SEC,
cqspi->master_ref_clk_hz);
if (ddata->hwcaps_mask & CQSPI_SUPPORTS_OCTAL)
master->mode_bits |= SPI_RX_OCTAL | SPI_TX_OCTAL;
host->mode_bits |= SPI_RX_OCTAL | SPI_TX_OCTAL;
if (!(ddata->quirks & CQSPI_DISABLE_DAC_MODE)) {
cqspi->use_direct_mode = true;
cqspi->use_direct_mode_wr = true;
@ -1766,6 +1822,12 @@ static int cqspi_probe(struct platform_device *pdev)
if (ddata->quirks & CQSPI_NEEDS_APB_AHB_HAZARD_WAR)
cqspi->apb_ahb_hazard = true;
if (ddata->jh7110_clk_init) {
ret = cqspi_jh7110_clk_init(pdev, cqspi);
if (ret)
goto probe_clk_failed;
}
if (of_device_is_compatible(pdev->dev.of_node,
"xlnx,versal-ospi-1.0")) {
ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
@ -1786,7 +1848,7 @@ static int cqspi_probe(struct platform_device *pdev)
cqspi->current_cs = -1;
cqspi->sclk = 0;
master->num_chipselect = cqspi->num_chipselect;
host->num_chipselect = cqspi->num_chipselect;
ret = cqspi_setup_flash(cqspi);
if (ret) {
@ -1800,7 +1862,7 @@ static int cqspi_probe(struct platform_device *pdev)
goto probe_setup_failed;
}
ret = spi_register_master(master);
ret = spi_register_controller(host);
if (ret) {
dev_err(&pdev->dev, "failed to register SPI ctlr %d\n", ret);
goto probe_setup_failed;
@ -1822,7 +1884,7 @@ static void cqspi_remove(struct platform_device *pdev)
{
struct cqspi_st *cqspi = platform_get_drvdata(pdev);
spi_unregister_master(cqspi->master);
spi_unregister_controller(cqspi->host);
cqspi_controller_enable(cqspi, 0);
if (cqspi->rx_chan)
@ -1830,6 +1892,9 @@ static void cqspi_remove(struct platform_device *pdev)
clk_disable_unprepare(cqspi->clk);
if (cqspi->is_jh7110)
cqspi_jh7110_disable_clk(pdev, cqspi);
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
}
@ -1837,10 +1902,10 @@ static void cqspi_remove(struct platform_device *pdev)
static int cqspi_suspend(struct device *dev)
{
struct cqspi_st *cqspi = dev_get_drvdata(dev);
struct spi_master *master = dev_get_drvdata(dev);
struct spi_controller *host = dev_get_drvdata(dev);
int ret;
ret = spi_master_suspend(master);
ret = spi_controller_suspend(host);
cqspi_controller_enable(cqspi, 0);
clk_disable_unprepare(cqspi->clk);
@ -1851,7 +1916,7 @@ static int cqspi_suspend(struct device *dev)
static int cqspi_resume(struct device *dev)
{
struct cqspi_st *cqspi = dev_get_drvdata(dev);
struct spi_master *master = dev_get_drvdata(dev);
struct spi_controller *host = dev_get_drvdata(dev);
clk_prepare_enable(cqspi->clk);
cqspi_wait_idle(cqspi);
@ -1860,7 +1925,7 @@ static int cqspi_resume(struct device *dev)
cqspi->current_cs = -1;
cqspi->sclk = 0;
return spi_master_resume(master);
return spi_controller_resume(host);
}
static DEFINE_SIMPLE_DEV_PM_OPS(cqspi_dev_pm_ops, cqspi_suspend, cqspi_resume);
@ -1897,6 +1962,7 @@ static const struct cqspi_driver_platdata versal_ospi = {
static const struct cqspi_driver_platdata jh7110_qspi = {
.quirks = CQSPI_DISABLE_DAC_MODE,
.jh7110_clk_init = cqspi_jh7110_clk_init,
};
static const struct cqspi_driver_platdata pensando_cdns_qspi = {

Просмотреть файл

@ -11,7 +11,6 @@
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
@ -420,7 +419,7 @@ static int cdns_xspi_mem_op_execute(struct spi_mem *mem,
const struct spi_mem_op *op)
{
struct cdns_xspi_dev *cdns_xspi =
spi_master_get_devdata(mem->spi->master);
spi_controller_get_devdata(mem->spi->controller);
int ret = 0;
ret = cdns_xspi_mem_op(cdns_xspi, mem, op);
@ -431,7 +430,7 @@ static int cdns_xspi_mem_op_execute(struct spi_mem *mem,
static int cdns_xspi_adjust_mem_op_size(struct spi_mem *mem, struct spi_mem_op *op)
{
struct cdns_xspi_dev *cdns_xspi =
spi_master_get_devdata(mem->spi->master);
spi_controller_get_devdata(mem->spi->controller);
op->data.nbytes = clamp_val(op->data.nbytes, 0, cdns_xspi->sdmasize);
@ -528,26 +527,26 @@ static void cdns_xspi_print_phy_config(struct cdns_xspi_dev *cdns_xspi)
static int cdns_xspi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct spi_master *master = NULL;
struct spi_controller *host = NULL;
struct cdns_xspi_dev *cdns_xspi = NULL;
struct resource *res;
int ret;
master = devm_spi_alloc_master(dev, sizeof(*cdns_xspi));
if (!master)
host = devm_spi_alloc_host(dev, sizeof(*cdns_xspi));
if (!host)
return -ENOMEM;
master->mode_bits = SPI_3WIRE | SPI_TX_DUAL | SPI_TX_QUAD |
host->mode_bits = SPI_3WIRE | SPI_TX_DUAL | SPI_TX_QUAD |
SPI_RX_DUAL | SPI_RX_QUAD | SPI_TX_OCTAL | SPI_RX_OCTAL |
SPI_MODE_0 | SPI_MODE_3;
master->mem_ops = &cadence_xspi_mem_ops;
master->dev.of_node = pdev->dev.of_node;
master->bus_num = -1;
host->mem_ops = &cadence_xspi_mem_ops;
host->dev.of_node = pdev->dev.of_node;
host->bus_num = -1;
platform_set_drvdata(pdev, master);
platform_set_drvdata(pdev, host);
cdns_xspi = spi_master_get_devdata(master);
cdns_xspi = spi_controller_get_devdata(host);
cdns_xspi->pdev = pdev;
cdns_xspi->dev = &pdev->dev;
cdns_xspi->cur_cs = 0;
@ -597,15 +596,15 @@ static int cdns_xspi_probe(struct platform_device *pdev)
return ret;
}
master->num_chipselect = 1 << cdns_xspi->hw_num_banks;
host->num_chipselect = 1 << cdns_xspi->hw_num_banks;
ret = devm_spi_register_master(dev, master);
ret = devm_spi_register_controller(dev, host);
if (ret) {
dev_err(dev, "Failed to register SPI master\n");
dev_err(dev, "Failed to register SPI host\n");
return ret;
}
dev_info(dev, "Successfully registered SPI master\n");
dev_info(dev, "Successfully registered SPI host\n");
return 0;
}

Просмотреть файл

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Cadence SPI controller driver (master and slave mode)
* Cadence SPI controller driver (host and target mode)
*
* Copyright (C) 2008 - 2014 Xilinx, Inc.
*
@ -59,10 +59,10 @@
CDNS_SPI_CR_BAUD_DIV_4)
/*
* SPI Configuration Register - Baud rate and slave select
* SPI Configuration Register - Baud rate and target select
*
* These are the values used in the calculation of baud rate divisor and
* setting the slave select.
* setting the target select.
*/
#define CDNS_SPI_BAUD_DIV_MAX 7 /* Baud rate divisor maximum */
@ -141,20 +141,20 @@ static inline void cdns_spi_write(struct cdns_spi *xspi, u32 offset, u32 val)
/**
* cdns_spi_init_hw - Initialize the hardware and configure the SPI controller
* @xspi: Pointer to the cdns_spi structure
* @is_slave: Flag to indicate slave or master mode
* * On reset the SPI controller is configured to slave or master mode.
* In master mode baud rate divisor is set to 4, threshold value for TX FIFO
* @is_target: Flag to indicate target or host mode
* * On reset the SPI controller is configured to target or host mode.
* In host mode baud rate divisor is set to 4, threshold value for TX FIFO
* not full interrupt is set to 1 and size of the word to be transferred as 8 bit.
*
* This function initializes the SPI controller to disable and clear all the
* interrupts, enable manual slave select and manual start, deselect all the
* interrupts, enable manual target select and manual start, deselect all the
* chip select lines, and enable the SPI controller.
*/
static void cdns_spi_init_hw(struct cdns_spi *xspi, bool is_slave)
static void cdns_spi_init_hw(struct cdns_spi *xspi, bool is_target)
{
u32 ctrl_reg = 0;
if (!is_slave)
if (!is_target)
ctrl_reg |= CDNS_SPI_CR_DEFAULT;
if (xspi->is_decoded_cs)
@ -185,10 +185,10 @@ static void cdns_spi_chipselect(struct spi_device *spi, bool is_high)
ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR);
if (is_high) {
/* Deselect the slave */
/* Deselect the target */
ctrl_reg |= CDNS_SPI_CR_SSCTRL;
} else {
/* Select the slave */
/* Select the target */
ctrl_reg &= ~CDNS_SPI_CR_SSCTRL;
if (!(xspi->is_decoded_cs))
ctrl_reg |= ((~(CDNS_SPI_SS0 << spi_get_chipselect(spi, 0))) <<
@ -227,7 +227,7 @@ static void cdns_spi_config_clock_mode(struct spi_device *spi)
/*
* Just writing the CR register does not seem to apply the clock
* setting changes. This is problematic when changing the clock
* polarity as it will cause the SPI slave to see spurious clock
* polarity as it will cause the SPI target to see spurious clock
* transitions. To workaround the issue toggle the ER register.
*/
cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE);
@ -405,7 +405,7 @@ static irqreturn_t cdns_spi_irq(int irq, void *dev_id)
static int cdns_prepare_message(struct spi_controller *ctlr,
struct spi_message *msg)
{
if (!spi_controller_is_slave(ctlr))
if (!spi_controller_is_target(ctlr))
cdns_spi_config_clock_mode(msg->spi);
return 0;
}
@ -417,9 +417,9 @@ static int cdns_prepare_message(struct spi_controller *ctlr,
* @transfer: Pointer to the spi_transfer structure which provides
* information about next transfer parameters
*
* This function in master mode fills the TX FIFO, starts the SPI transfer and
* This function in host mode fills the TX FIFO, starts the SPI transfer and
* returns a positive transfer count so that core will wait for completion.
* This function in slave mode fills the TX FIFO and wait for transfer trigger.
* This function in target mode fills the TX FIFO and wait for transfer trigger.
*
* Return: Number of bytes transferred in the last transfer
*/
@ -434,7 +434,7 @@ static int cdns_transfer_one(struct spi_controller *ctlr,
xspi->tx_bytes = transfer->len;
xspi->rx_bytes = transfer->len;
if (!spi_controller_is_slave(ctlr)) {
if (!spi_controller_is_target(ctlr)) {
cdns_spi_setup_transfer(spi, transfer);
} else {
/* Set TX empty threshold to half of FIFO depth
@ -462,7 +462,7 @@ static int cdns_transfer_one(struct spi_controller *ctlr,
* @ctlr: Pointer to the spi_controller structure which provides
* information about the controller.
*
* This function enables SPI master controller.
* This function enables SPI host controller.
*
* Return: 0 always
*/
@ -480,7 +480,7 @@ static int cdns_prepare_transfer_hardware(struct spi_controller *ctlr)
* @ctlr: Pointer to the spi_controller structure which provides
* information about the controller.
*
* This function disables the SPI master controller when no slave selected.
* This function disables the SPI host controller when no target selected.
* This function flush out if any pending data in FIFO.
*
* Return: 0 always
@ -491,15 +491,15 @@ static int cdns_unprepare_transfer_hardware(struct spi_controller *ctlr)
u32 ctrl_reg;
unsigned int cnt = xspi->tx_fifo_depth;
if (spi_controller_is_slave(ctlr)) {
if (spi_controller_is_target(ctlr)) {
while (cnt--)
cdns_spi_read(xspi, CDNS_SPI_RXD);
}
/* Disable the SPI if slave is deselected */
/* Disable the SPI if target is deselected */
ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR);
ctrl_reg = (ctrl_reg & CDNS_SPI_CR_SSCTRL) >> CDNS_SPI_SS_SHIFT;
if (ctrl_reg == CDNS_SPI_NOSS || spi_controller_is_slave(ctlr))
if (ctrl_reg == CDNS_SPI_NOSS || spi_controller_is_target(ctlr))
cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE);
/* Reset to default */
@ -526,14 +526,14 @@ static void cdns_spi_detect_fifo_depth(struct cdns_spi *xspi)
}
/**
* cdns_slave_abort - Abort slave transfer
* cdns_target_abort - Abort target transfer
* @ctlr: Pointer to the spi_controller structure
*
* This function abort slave transfer if there any transfer timeout.
* This function abort target transfer if there any transfer timeout.
*
* Return: 0 always
*/
static int cdns_slave_abort(struct spi_controller *ctlr)
static int cdns_target_abort(struct spi_controller *ctlr)
{
struct cdns_spi *xspi = spi_controller_get_devdata(ctlr);
u32 intr_status;
@ -560,13 +560,13 @@ static int cdns_spi_probe(struct platform_device *pdev)
struct spi_controller *ctlr;
struct cdns_spi *xspi;
u32 num_cs;
bool slave;
bool target;
slave = of_property_read_bool(pdev->dev.of_node, "spi-slave");
if (slave)
ctlr = spi_alloc_slave(&pdev->dev, sizeof(*xspi));
target = of_property_read_bool(pdev->dev.of_node, "spi-slave");
if (target)
ctlr = spi_alloc_target(&pdev->dev, sizeof(*xspi));
else
ctlr = spi_alloc_master(&pdev->dev, sizeof(*xspi));
ctlr = spi_alloc_host(&pdev->dev, sizeof(*xspi));
if (!ctlr)
return -ENOMEM;
@ -594,7 +594,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
goto remove_ctlr;
}
if (!spi_controller_is_slave(ctlr)) {
if (!spi_controller_is_target(ctlr)) {
xspi->ref_clk = devm_clk_get(&pdev->dev, "ref_clk");
if (IS_ERR(xspi->ref_clk)) {
dev_err(&pdev->dev, "ref_clk clock not found.\n");
@ -629,11 +629,11 @@ static int cdns_spi_probe(struct platform_device *pdev)
cdns_spi_detect_fifo_depth(xspi);
/* SPI controller initializations */
cdns_spi_init_hw(xspi, spi_controller_is_slave(ctlr));
cdns_spi_init_hw(xspi, spi_controller_is_target(ctlr));
irq = platform_get_irq(pdev, 0);
if (irq <= 0) {
ret = -ENXIO;
if (irq < 0) {
ret = irq;
goto clk_dis_all;
}
@ -653,7 +653,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
ctlr->mode_bits = SPI_CPOL | SPI_CPHA;
ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
if (!spi_controller_is_slave(ctlr)) {
if (!spi_controller_is_target(ctlr)) {
ctlr->mode_bits |= SPI_CS_HIGH;
ctlr->set_cs = cdns_spi_chipselect;
ctlr->auto_runtime_pm = true;
@ -665,7 +665,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
pm_runtime_put_autosuspend(&pdev->dev);
} else {
ctlr->mode_bits |= SPI_NO_CS;
ctlr->slave_abort = cdns_slave_abort;
ctlr->target_abort = cdns_target_abort;
}
ret = spi_register_controller(ctlr);
if (ret) {
@ -676,7 +676,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
return ret;
clk_dis_all:
if (!spi_controller_is_slave(ctlr)) {
if (!spi_controller_is_target(ctlr)) {
pm_runtime_set_suspended(&pdev->dev);
pm_runtime_disable(&pdev->dev);
clk_disable_unprepare(xspi->ref_clk);
@ -695,8 +695,6 @@ remove_ctlr:
* This function is called if a device is physically removed from the system or
* if the driver module is being unloaded. It frees all resources allocated to
* the device.
*
* Return: 0 on success and error value on error
*/
static void cdns_spi_remove(struct platform_device *pdev)
{
@ -742,7 +740,7 @@ static int __maybe_unused cdns_spi_resume(struct device *dev)
struct spi_controller *ctlr = dev_get_drvdata(dev);
struct cdns_spi *xspi = spi_controller_get_devdata(ctlr);
cdns_spi_init_hw(xspi, spi_controller_is_slave(ctlr));
cdns_spi_init_hw(xspi, spi_controller_is_target(ctlr));
return spi_controller_resume(ctlr);
}

Просмотреть файл

@ -19,15 +19,15 @@
static int octeon_spi_probe(struct platform_device *pdev)
{
void __iomem *reg_base;
struct spi_master *master;
struct spi_controller *host;
struct octeon_spi *p;
int err = -ENOENT;
master = spi_alloc_master(&pdev->dev, sizeof(struct octeon_spi));
if (!master)
host = spi_alloc_host(&pdev->dev, sizeof(struct octeon_spi));
if (!host)
return -ENOMEM;
p = spi_master_get_devdata(master);
platform_set_drvdata(pdev, master);
p = spi_controller_get_devdata(host);
platform_set_drvdata(pdev, host);
reg_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(reg_base)) {
@ -43,21 +43,21 @@ static int octeon_spi_probe(struct platform_device *pdev)
p->regs.tx = 0x10;
p->regs.data = 0x80;
master->num_chipselect = 4;
master->mode_bits = SPI_CPHA |
host->num_chipselect = 4;
host->mode_bits = SPI_CPHA |
SPI_CPOL |
SPI_CS_HIGH |
SPI_LSB_FIRST |
SPI_3WIRE;
master->transfer_one_message = octeon_spi_transfer_one_message;
master->bits_per_word_mask = SPI_BPW_MASK(8);
master->max_speed_hz = OCTEON_SPI_MAX_CLOCK_HZ;
host->transfer_one_message = octeon_spi_transfer_one_message;
host->bits_per_word_mask = SPI_BPW_MASK(8);
host->max_speed_hz = OCTEON_SPI_MAX_CLOCK_HZ;
master->dev.of_node = pdev->dev.of_node;
err = devm_spi_register_master(&pdev->dev, master);
host->dev.of_node = pdev->dev.of_node;
err = devm_spi_register_controller(&pdev->dev, host);
if (err) {
dev_err(&pdev->dev, "register master failed: %d\n", err);
dev_err(&pdev->dev, "register host failed: %d\n", err);
goto fail;
}
@ -65,14 +65,14 @@ static int octeon_spi_probe(struct platform_device *pdev)
return 0;
fail:
spi_master_put(master);
spi_controller_put(host);
return err;
}
static void octeon_spi_remove(struct platform_device *pdev)
{
struct spi_master *master = platform_get_drvdata(pdev);
struct octeon_spi *p = spi_master_get_devdata(master);
struct spi_controller *host = platform_get_drvdata(pdev);
struct octeon_spi *p = spi_controller_get_devdata(host);
/* Clear the CSENA* and put everything in a known state. */
writeq(0, p->register_base + OCTEON_SPI_CFG(p));

Просмотреть файл

@ -20,15 +20,15 @@ static int thunderx_spi_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct device *dev = &pdev->dev;
struct spi_master *master;
struct spi_controller *host;
struct octeon_spi *p;
int ret;
master = spi_alloc_master(dev, sizeof(struct octeon_spi));
if (!master)
host = spi_alloc_host(dev, sizeof(struct octeon_spi));
if (!host)
return -ENOMEM;
p = spi_master_get_devdata(master);
p = spi_controller_get_devdata(host);
ret = pcim_enable_device(pdev);
if (ret)
@ -64,18 +64,18 @@ static int thunderx_spi_probe(struct pci_dev *pdev,
p->sys_freq = SYS_FREQ_DEFAULT;
dev_info(dev, "Set system clock to %u\n", p->sys_freq);
master->flags = SPI_MASTER_HALF_DUPLEX;
master->num_chipselect = 4;
master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_CS_HIGH |
host->flags = SPI_CONTROLLER_HALF_DUPLEX;
host->num_chipselect = 4;
host->mode_bits = SPI_CPHA | SPI_CPOL | SPI_CS_HIGH |
SPI_LSB_FIRST | SPI_3WIRE;
master->transfer_one_message = octeon_spi_transfer_one_message;
master->bits_per_word_mask = SPI_BPW_MASK(8);
master->max_speed_hz = OCTEON_SPI_MAX_CLOCK_HZ;
master->dev.of_node = pdev->dev.of_node;
host->transfer_one_message = octeon_spi_transfer_one_message;
host->bits_per_word_mask = SPI_BPW_MASK(8);
host->max_speed_hz = OCTEON_SPI_MAX_CLOCK_HZ;
host->dev.of_node = pdev->dev.of_node;
pci_set_drvdata(pdev, master);
pci_set_drvdata(pdev, host);
ret = devm_spi_register_master(dev, master);
ret = devm_spi_register_controller(dev, host);
if (ret)
goto error;
@ -84,16 +84,16 @@ static int thunderx_spi_probe(struct pci_dev *pdev,
error:
clk_disable_unprepare(p->clk);
pci_release_regions(pdev);
spi_master_put(master);
spi_controller_put(host);
return ret;
}
static void thunderx_spi_remove(struct pci_dev *pdev)
{
struct spi_master *master = pci_get_drvdata(pdev);
struct spi_controller *host = pci_get_drvdata(pdev);
struct octeon_spi *p;
p = spi_master_get_devdata(master);
p = spi_controller_get_devdata(host);
if (!p)
return;

Просмотреть файл

@ -33,10 +33,10 @@ struct spi_clps711x_data {
int len;
};
static int spi_clps711x_prepare_message(struct spi_master *master,
static int spi_clps711x_prepare_message(struct spi_controller *host,
struct spi_message *msg)
{
struct spi_clps711x_data *hw = spi_master_get_devdata(master);
struct spi_clps711x_data *hw = spi_controller_get_devdata(host);
struct spi_device *spi = msg->spi;
/* Setup mode for transfer */
@ -45,11 +45,11 @@ static int spi_clps711x_prepare_message(struct spi_master *master,
SYSCON3_ADCCKNSEN : 0);
}
static int spi_clps711x_transfer_one(struct spi_master *master,
static int spi_clps711x_transfer_one(struct spi_controller *host,
struct spi_device *spi,
struct spi_transfer *xfer)
{
struct spi_clps711x_data *hw = spi_master_get_devdata(master);
struct spi_clps711x_data *hw = spi_controller_get_devdata(host);
u8 data;
clk_set_rate(hw->spi_clk, xfer->speed_hz ? : spi->max_speed_hz);
@ -68,8 +68,8 @@ static int spi_clps711x_transfer_one(struct spi_master *master,
static irqreturn_t spi_clps711x_isr(int irq, void *dev_id)
{
struct spi_master *master = dev_id;
struct spi_clps711x_data *hw = spi_master_get_devdata(master);
struct spi_controller *host = dev_id;
struct spi_clps711x_data *hw = spi_controller_get_devdata(host);
u8 data;
/* Handle RX */
@ -83,7 +83,7 @@ static irqreturn_t spi_clps711x_isr(int irq, void *dev_id)
writel(data | SYNCIO_FRMLEN(hw->bpw) | SYNCIO_TXFRMEN,
hw->syncio);
} else
spi_finalize_current_transfer(master);
spi_finalize_current_transfer(host);
return IRQ_HANDLED;
}
@ -92,26 +92,26 @@ static int spi_clps711x_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct spi_clps711x_data *hw;
struct spi_master *master;
struct spi_controller *host;
int irq, ret;
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
master = spi_alloc_master(&pdev->dev, sizeof(*hw));
if (!master)
host = spi_alloc_host(&pdev->dev, sizeof(*hw));
if (!host)
return -ENOMEM;
master->use_gpio_descriptors = true;
master->bus_num = -1;
master->mode_bits = SPI_CPHA | SPI_CS_HIGH;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 8);
master->dev.of_node = pdev->dev.of_node;
master->prepare_message = spi_clps711x_prepare_message;
master->transfer_one = spi_clps711x_transfer_one;
host->use_gpio_descriptors = true;
host->bus_num = -1;
host->mode_bits = SPI_CPHA | SPI_CS_HIGH;
host->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 8);
host->dev.of_node = pdev->dev.of_node;
host->prepare_message = spi_clps711x_prepare_message;
host->transfer_one = spi_clps711x_transfer_one;
hw = spi_master_get_devdata(master);
hw = spi_controller_get_devdata(host);
hw->spi_clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(hw->spi_clk)) {
@ -138,16 +138,16 @@ static int spi_clps711x_probe(struct platform_device *pdev)
readl(hw->syncio);
ret = devm_request_irq(&pdev->dev, irq, spi_clps711x_isr, 0,
dev_name(&pdev->dev), master);
dev_name(&pdev->dev), host);
if (ret)
goto err_out;
ret = devm_spi_register_master(&pdev->dev, master);
ret = devm_spi_register_controller(&pdev->dev, host);
if (!ret)
return 0;
err_out:
spi_master_put(master);
spi_controller_put(host);
return ret;
}

Просмотреть файл

@ -286,7 +286,7 @@ static void mcfqspi_transfer_msg16(struct mcfqspi *mcfqspi, unsigned count,
static void mcfqspi_set_cs(struct spi_device *spi, bool enable)
{
struct mcfqspi *mcfqspi = spi_master_get_devdata(spi->master);
struct mcfqspi *mcfqspi = spi_controller_get_devdata(spi->controller);
bool cs_high = spi->mode & SPI_CS_HIGH;
if (enable)
@ -295,11 +295,11 @@ static void mcfqspi_set_cs(struct spi_device *spi, bool enable)
mcfqspi_cs_deselect(mcfqspi, spi_get_chipselect(spi, 0), cs_high);
}
static int mcfqspi_transfer_one(struct spi_master *master,
static int mcfqspi_transfer_one(struct spi_controller *host,
struct spi_device *spi,
struct spi_transfer *t)
{
struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
struct mcfqspi *mcfqspi = spi_controller_get_devdata(host);
u16 qmr = MCFQSPI_QMR_MSTR;
qmr |= t->bits_per_word << 10;
@ -323,7 +323,7 @@ static int mcfqspi_transfer_one(struct spi_master *master,
static int mcfqspi_setup(struct spi_device *spi)
{
mcfqspi_cs_deselect(spi_master_get_devdata(spi->master),
mcfqspi_cs_deselect(spi_controller_get_devdata(spi->controller),
spi_get_chipselect(spi, 0), spi->mode & SPI_CS_HIGH);
dev_dbg(&spi->dev,
@ -337,7 +337,7 @@ static int mcfqspi_setup(struct spi_device *spi)
static int mcfqspi_probe(struct platform_device *pdev)
{
struct spi_master *master;
struct spi_controller *host;
struct mcfqspi *mcfqspi;
struct mcfqspi_platform_data *pdata;
int status;
@ -353,13 +353,13 @@ static int mcfqspi_probe(struct platform_device *pdev)
return -EINVAL;
}
master = spi_alloc_master(&pdev->dev, sizeof(*mcfqspi));
if (master == NULL) {
dev_dbg(&pdev->dev, "spi_alloc_master failed\n");
host = spi_alloc_host(&pdev->dev, sizeof(*mcfqspi));
if (host == NULL) {
dev_dbg(&pdev->dev, "spi_alloc_host failed\n");
return -ENOMEM;
}
mcfqspi = spi_master_get_devdata(master);
mcfqspi = spi_controller_get_devdata(host);
mcfqspi->iobase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(mcfqspi->iobase)) {
@ -381,53 +381,50 @@ static int mcfqspi_probe(struct platform_device *pdev)
goto fail0;
}
mcfqspi->clk = devm_clk_get(&pdev->dev, "qspi_clk");
mcfqspi->clk = devm_clk_get_enabled(&pdev->dev, "qspi_clk");
if (IS_ERR(mcfqspi->clk)) {
dev_dbg(&pdev->dev, "clk_get failed\n");
status = PTR_ERR(mcfqspi->clk);
goto fail0;
}
clk_prepare_enable(mcfqspi->clk);
master->bus_num = pdata->bus_num;
master->num_chipselect = pdata->num_chipselect;
host->bus_num = pdata->bus_num;
host->num_chipselect = pdata->num_chipselect;
mcfqspi->cs_control = pdata->cs_control;
status = mcfqspi_cs_setup(mcfqspi);
if (status) {
dev_dbg(&pdev->dev, "error initializing cs_control\n");
goto fail1;
goto fail0;
}
init_waitqueue_head(&mcfqspi->waitq);
master->mode_bits = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 16);
master->setup = mcfqspi_setup;
master->set_cs = mcfqspi_set_cs;
master->transfer_one = mcfqspi_transfer_one;
master->auto_runtime_pm = true;
host->mode_bits = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA;
host->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 16);
host->setup = mcfqspi_setup;
host->set_cs = mcfqspi_set_cs;
host->transfer_one = mcfqspi_transfer_one;
host->auto_runtime_pm = true;
platform_set_drvdata(pdev, master);
platform_set_drvdata(pdev, host);
pm_runtime_enable(&pdev->dev);
status = devm_spi_register_master(&pdev->dev, master);
status = devm_spi_register_controller(&pdev->dev, host);
if (status) {
dev_dbg(&pdev->dev, "spi_register_master failed\n");
goto fail2;
dev_dbg(&pdev->dev, "devm_spi_register_controller failed\n");
goto fail1;
}
dev_info(&pdev->dev, "Coldfire QSPI bus driver\n");
return 0;
fail2:
fail1:
pm_runtime_disable(&pdev->dev);
mcfqspi_cs_teardown(mcfqspi);
fail1:
clk_disable_unprepare(mcfqspi->clk);
fail0:
spi_master_put(master);
spi_controller_put(host);
dev_dbg(&pdev->dev, "Coldfire QSPI probe failed\n");
@ -436,8 +433,8 @@ fail0:
static void mcfqspi_remove(struct platform_device *pdev)
{
struct spi_master *master = platform_get_drvdata(pdev);
struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
struct spi_controller *host = platform_get_drvdata(pdev);
struct mcfqspi *mcfqspi = spi_controller_get_devdata(host);
pm_runtime_disable(&pdev->dev);
/* disable the hardware (set the baud rate to 0) */
@ -450,11 +447,11 @@ static void mcfqspi_remove(struct platform_device *pdev)
#ifdef CONFIG_PM_SLEEP
static int mcfqspi_suspend(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
struct spi_controller *host = dev_get_drvdata(dev);
struct mcfqspi *mcfqspi = spi_controller_get_devdata(host);
int ret;
ret = spi_master_suspend(master);
ret = spi_controller_suspend(host);
if (ret)
return ret;
@ -465,20 +462,20 @@ static int mcfqspi_suspend(struct device *dev)
static int mcfqspi_resume(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
struct spi_controller *host = dev_get_drvdata(dev);
struct mcfqspi *mcfqspi = spi_controller_get_devdata(host);
clk_enable(mcfqspi->clk);
return spi_master_resume(master);
return spi_controller_resume(host);
}
#endif
#ifdef CONFIG_PM
static int mcfqspi_runtime_suspend(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
struct spi_controller *host = dev_get_drvdata(dev);
struct mcfqspi *mcfqspi = spi_controller_get_devdata(host);
clk_disable(mcfqspi->clk);
@ -487,8 +484,8 @@ static int mcfqspi_runtime_suspend(struct device *dev)
static int mcfqspi_runtime_resume(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
struct spi_controller *host = dev_get_drvdata(dev);
struct mcfqspi *mcfqspi = spi_controller_get_devdata(host);
clk_enable(mcfqspi->clk);

284
drivers/spi/spi-cs42l43.c Normal file
Просмотреть файл

@ -0,0 +1,284 @@
// SPDX-License-Identifier: GPL-2.0
//
// CS42L43 SPI Controller Driver
//
// Copyright (C) 2022-2023 Cirrus Logic, Inc. and
// Cirrus Logic International Semiconductor Ltd.
#include <linux/bits.h>
#include <linux/bitfield.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/mfd/cs42l43.h>
#include <linux/mfd/cs42l43-regs.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/spi/spi.h>
#include <linux/units.h>
#define CS42L43_FIFO_SIZE 16
#define CS42L43_SPI_ROOT_HZ (40 * HZ_PER_MHZ)
#define CS42L43_SPI_MAX_LENGTH 65532
enum cs42l43_spi_cmd {
CS42L43_WRITE,
CS42L43_READ
};
struct cs42l43_spi {
struct device *dev;
struct regmap *regmap;
struct spi_controller *ctlr;
};
static const unsigned int cs42l43_clock_divs[] = {
2, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30
};
static int cs42l43_spi_tx(struct regmap *regmap, const u8 *buf, unsigned int len)
{
const u8 *end = buf + len;
u32 val = 0;
int ret;
while (buf < end) {
const u8 *block = min(buf + CS42L43_FIFO_SIZE, end);
while (buf < block) {
const u8 *word = min(buf + sizeof(u32), block);
int pad = (buf + sizeof(u32)) - word;
while (buf < word) {
val >>= BITS_PER_BYTE;
val |= FIELD_PREP(GENMASK(31, 24), *buf);
buf++;
}
val >>= pad * BITS_PER_BYTE;
regmap_write(regmap, CS42L43_TX_DATA, val);
}
regmap_write(regmap, CS42L43_TRAN_CONFIG8, CS42L43_SPI_TX_DONE_MASK);
ret = regmap_read_poll_timeout(regmap, CS42L43_TRAN_STATUS1,
val, (val & CS42L43_SPI_TX_REQUEST_MASK),
1000, 5000);
if (ret)
return ret;
}
return 0;
}
static int cs42l43_spi_rx(struct regmap *regmap, u8 *buf, unsigned int len)
{
u8 *end = buf + len;
u32 val;
int ret;
while (buf < end) {
u8 *block = min(buf + CS42L43_FIFO_SIZE, end);
ret = regmap_read_poll_timeout(regmap, CS42L43_TRAN_STATUS1,
val, (val & CS42L43_SPI_RX_REQUEST_MASK),
1000, 5000);
if (ret)
return ret;
while (buf < block) {
u8 *word = min(buf + sizeof(u32), block);
ret = regmap_read(regmap, CS42L43_RX_DATA, &val);
if (ret)
return ret;
while (buf < word) {
*buf = FIELD_GET(GENMASK(7, 0), val);
val >>= BITS_PER_BYTE;
buf++;
}
}
regmap_write(regmap, CS42L43_TRAN_CONFIG8, CS42L43_SPI_RX_DONE_MASK);
}
return 0;
}
static int cs42l43_transfer_one(struct spi_controller *ctlr, struct spi_device *spi,
struct spi_transfer *tfr)
{
struct cs42l43_spi *priv = spi_controller_get_devdata(spi->controller);
int i, ret = -EINVAL;
for (i = 0; i < ARRAY_SIZE(cs42l43_clock_divs); i++) {
if (CS42L43_SPI_ROOT_HZ / cs42l43_clock_divs[i] <= tfr->speed_hz)
break;
}
if (i == ARRAY_SIZE(cs42l43_clock_divs))
return -EINVAL;
regmap_write(priv->regmap, CS42L43_SPI_CLK_CONFIG1, i);
if (tfr->tx_buf) {
regmap_write(priv->regmap, CS42L43_TRAN_CONFIG3, CS42L43_WRITE);
regmap_write(priv->regmap, CS42L43_TRAN_CONFIG4, tfr->len - 1);
} else if (tfr->rx_buf) {
regmap_write(priv->regmap, CS42L43_TRAN_CONFIG3, CS42L43_READ);
regmap_write(priv->regmap, CS42L43_TRAN_CONFIG5, tfr->len - 1);
}
regmap_write(priv->regmap, CS42L43_TRAN_CONFIG1, CS42L43_SPI_START_MASK);
if (tfr->tx_buf)
ret = cs42l43_spi_tx(priv->regmap, (const u8 *)tfr->tx_buf, tfr->len);
else if (tfr->rx_buf)
ret = cs42l43_spi_rx(priv->regmap, (u8 *)tfr->rx_buf, tfr->len);
return ret;
}
static void cs42l43_set_cs(struct spi_device *spi, bool is_high)
{
struct cs42l43_spi *priv = spi_controller_get_devdata(spi->controller);
if (spi_get_chipselect(spi, 0) == 0)
regmap_write(priv->regmap, CS42L43_SPI_CONFIG2, !is_high);
}
static int cs42l43_prepare_message(struct spi_controller *ctlr, struct spi_message *msg)
{
struct cs42l43_spi *priv = spi_controller_get_devdata(ctlr);
struct spi_device *spi = msg->spi;
unsigned int spi_config1 = 0;
/* select another internal CS, which doesn't exist, so CS 0 is not used */
if (spi_get_csgpiod(spi, 0))
spi_config1 |= 1 << CS42L43_SPI_SS_SEL_SHIFT;
if (spi->mode & SPI_CPOL)
spi_config1 |= CS42L43_SPI_CPOL_MASK;
if (spi->mode & SPI_CPHA)
spi_config1 |= CS42L43_SPI_CPHA_MASK;
if (spi->mode & SPI_3WIRE)
spi_config1 |= CS42L43_SPI_THREE_WIRE_MASK;
regmap_write(priv->regmap, CS42L43_SPI_CONFIG1, spi_config1);
return 0;
}
static int cs42l43_prepare_transfer_hardware(struct spi_controller *ctlr)
{
struct cs42l43_spi *priv = spi_controller_get_devdata(ctlr);
int ret;
ret = regmap_write(priv->regmap, CS42L43_BLOCK_EN2, CS42L43_SPI_MSTR_EN_MASK);
if (ret)
dev_err(priv->dev, "Failed to enable SPI controller: %d\n", ret);
return ret;
}
static int cs42l43_unprepare_transfer_hardware(struct spi_controller *ctlr)
{
struct cs42l43_spi *priv = spi_controller_get_devdata(ctlr);
int ret;
ret = regmap_write(priv->regmap, CS42L43_BLOCK_EN2, 0);
if (ret)
dev_err(priv->dev, "Failed to disable SPI controller: %d\n", ret);
return ret;
}
static size_t cs42l43_spi_max_length(struct spi_device *spi)
{
return CS42L43_SPI_MAX_LENGTH;
}
static int cs42l43_spi_probe(struct platform_device *pdev)
{
struct cs42l43 *cs42l43 = dev_get_drvdata(pdev->dev.parent);
struct cs42l43_spi *priv;
struct fwnode_handle *fwnode = dev_fwnode(cs42l43->dev);
int ret;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->ctlr = devm_spi_alloc_master(&pdev->dev, sizeof(*priv->ctlr));
if (!priv->ctlr)
return -ENOMEM;
spi_controller_set_devdata(priv->ctlr, priv);
priv->dev = &pdev->dev;
priv->regmap = cs42l43->regmap;
priv->ctlr->prepare_message = cs42l43_prepare_message;
priv->ctlr->prepare_transfer_hardware = cs42l43_prepare_transfer_hardware;
priv->ctlr->unprepare_transfer_hardware = cs42l43_unprepare_transfer_hardware;
priv->ctlr->transfer_one = cs42l43_transfer_one;
priv->ctlr->set_cs = cs42l43_set_cs;
priv->ctlr->max_transfer_size = cs42l43_spi_max_length;
if (is_of_node(fwnode))
fwnode = fwnode_get_named_child_node(fwnode, "spi");
device_set_node(&priv->ctlr->dev, fwnode);
priv->ctlr->mode_bits = SPI_3WIRE | SPI_MODE_X_MASK;
priv->ctlr->flags = SPI_CONTROLLER_HALF_DUPLEX;
priv->ctlr->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16) |
SPI_BPW_MASK(32);
priv->ctlr->min_speed_hz = CS42L43_SPI_ROOT_HZ /
cs42l43_clock_divs[ARRAY_SIZE(cs42l43_clock_divs) - 1];
priv->ctlr->max_speed_hz = CS42L43_SPI_ROOT_HZ / cs42l43_clock_divs[0];
priv->ctlr->use_gpio_descriptors = true;
priv->ctlr->auto_runtime_pm = true;
devm_pm_runtime_enable(priv->dev);
pm_runtime_idle(priv->dev);
regmap_write(priv->regmap, CS42L43_TRAN_CONFIG6, CS42L43_FIFO_SIZE - 1);
regmap_write(priv->regmap, CS42L43_TRAN_CONFIG7, CS42L43_FIFO_SIZE - 1);
// Disable Watchdog timer and enable stall
regmap_write(priv->regmap, CS42L43_SPI_CONFIG3, 0);
regmap_write(priv->regmap, CS42L43_SPI_CONFIG4, CS42L43_SPI_STALL_ENA_MASK);
ret = devm_spi_register_controller(priv->dev, priv->ctlr);
if (ret) {
pm_runtime_disable(priv->dev);
dev_err(priv->dev, "Failed to register SPI controller: %d\n", ret);
}
return ret;
}
static const struct platform_device_id cs42l43_spi_id_table[] = {
{ "cs42l43-spi", },
{}
};
MODULE_DEVICE_TABLE(platform, cs42l43_spi_id_table);
static struct platform_driver cs42l43_spi_driver = {
.driver = {
.name = "cs42l43-spi",
},
.probe = cs42l43_spi_probe,
.id_table = cs42l43_spi_id_table,
};
module_platform_driver(cs42l43_spi_driver);
MODULE_DESCRIPTION("CS42L43 SPI Driver");
MODULE_AUTHOR("Lucas Tanure <tanureal@opensource.cirrus.com>");
MODULE_AUTHOR("Maciej Strozek <mstrozek@opensource.cirrus.com>");
MODULE_LICENSE("GPL");

Просмотреть файл

@ -15,7 +15,6 @@
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <linux/slab.h>
@ -202,7 +201,7 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)
u8 chip_sel = spi_get_chipselect(spi, 0);
u16 spidat1 = CS_DEFAULT;
dspi = spi_master_get_devdata(spi->master);
dspi = spi_controller_get_devdata(spi->controller);
/* program delay transfers if tx_delay is non zero */
if (spicfg && spicfg->wdelay)
@ -272,7 +271,7 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
u32 hz = 0, spifmt = 0;
int prescale;
dspi = spi_master_get_devdata(spi->master);
dspi = spi_controller_get_devdata(spi->controller);
spicfg = spi->controller_data;
if (!spicfg)
spicfg = &davinci_spi_default_cfg;
@ -380,7 +379,7 @@ static int davinci_spi_of_setup(struct spi_device *spi)
{
struct davinci_spi_config *spicfg = spi->controller_data;
struct device_node *np = spi->dev.of_node;
struct davinci_spi *dspi = spi_master_get_devdata(spi->master);
struct davinci_spi *dspi = spi_controller_get_devdata(spi->controller);
u32 prop;
if (spicfg == NULL && np) {
@ -412,7 +411,7 @@ static int davinci_spi_setup(struct spi_device *spi)
struct device_node *np = spi->dev.of_node;
bool internal_cs = true;
dspi = spi_master_get_devdata(spi->master);
dspi = spi_controller_get_devdata(spi->controller);
if (!(spi->mode & SPI_NO_CS)) {
if (np && spi_get_csgpiod(spi, 0))
@ -442,7 +441,7 @@ static void davinci_spi_cleanup(struct spi_device *spi)
kfree(spicfg);
}
static bool davinci_spi_can_dma(struct spi_master *master,
static bool davinci_spi_can_dma(struct spi_controller *host,
struct spi_device *spi,
struct spi_transfer *xfer)
{
@ -572,7 +571,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
struct davinci_spi_config *spicfg;
struct davinci_spi_platform_data *pdata;
dspi = spi_master_get_devdata(spi->master);
dspi = spi_controller_get_devdata(spi->controller);
pdata = &dspi->pdata;
spicfg = (struct davinci_spi_config *)spi->controller_data;
if (!spicfg)
@ -593,7 +592,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
reinit_completion(&dspi->done);
if (!davinci_spi_can_dma(spi->master, spi, t)) {
if (!davinci_spi_can_dma(spi->controller, spi, t)) {
if (spicfg->io_type != SPI_IO_TYPE_POLL)
set_io_bits(dspi->base + SPIINT, SPIINT_MASKINT);
/* start the transfer */
@ -674,7 +673,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
}
clear_io_bits(dspi->base + SPIINT, SPIINT_MASKALL);
if (davinci_spi_can_dma(spi->master, spi, t))
if (davinci_spi_can_dma(spi->controller, spi, t))
clear_io_bits(dspi->base + SPIINT, SPIINT_DMA_REQ_EN);
clear_io_bits(dspi->base + SPIGCR1, SPIGCR1_SPIENA_MASK);
@ -856,22 +855,22 @@ static int spi_davinci_get_pdata(struct platform_device *pdev,
*/
static int davinci_spi_probe(struct platform_device *pdev)
{
struct spi_master *master;
struct spi_controller *host;
struct davinci_spi *dspi;
struct davinci_spi_platform_data *pdata;
struct resource *r;
int ret = 0;
u32 spipc0;
master = spi_alloc_master(&pdev->dev, sizeof(struct davinci_spi));
if (master == NULL) {
host = spi_alloc_host(&pdev->dev, sizeof(struct davinci_spi));
if (host == NULL) {
ret = -ENOMEM;
goto err;
}
platform_set_drvdata(pdev, master);
platform_set_drvdata(pdev, host);
dspi = spi_master_get_devdata(master);
dspi = spi_controller_get_devdata(host);
if (dev_get_platdata(&pdev->dev)) {
pdata = dev_get_platdata(&pdev->dev);
@ -880,7 +879,7 @@ static int davinci_spi_probe(struct platform_device *pdev)
/* update dspi pdata with that from the DT */
ret = spi_davinci_get_pdata(pdev, dspi);
if (ret < 0)
goto free_master;
goto free_host;
}
/* pdata in dspi is now updated and point pdata to that */
@ -892,57 +891,48 @@ static int davinci_spi_probe(struct platform_device *pdev)
GFP_KERNEL);
if (dspi->bytes_per_word == NULL) {
ret = -ENOMEM;
goto free_master;
goto free_host;
}
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (r == NULL) {
ret = -ENOENT;
goto free_master;
}
dspi->pbase = r->start;
dspi->base = devm_ioremap_resource(&pdev->dev, r);
dspi->base = devm_platform_get_and_ioremap_resource(pdev, 0, &r);
if (IS_ERR(dspi->base)) {
ret = PTR_ERR(dspi->base);
goto free_master;
goto free_host;
}
dspi->pbase = r->start;
init_completion(&dspi->done);
ret = platform_get_irq(pdev, 0);
if (ret == 0)
ret = -EINVAL;
if (ret < 0)
goto free_master;
goto free_host;
dspi->irq = ret;
ret = devm_request_threaded_irq(&pdev->dev, dspi->irq, davinci_spi_irq,
dummy_thread_fn, 0, dev_name(&pdev->dev), dspi);
if (ret)
goto free_master;
goto free_host;
dspi->bitbang.master = master;
dspi->bitbang.master = host;
dspi->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(dspi->clk)) {
ret = -ENODEV;
goto free_master;
goto free_host;
}
ret = clk_prepare_enable(dspi->clk);
if (ret)
goto free_master;
goto free_host;
master->use_gpio_descriptors = true;
master->dev.of_node = pdev->dev.of_node;
master->bus_num = pdev->id;
master->num_chipselect = pdata->num_chipselect;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 16);
master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_GPIO_SS;
master->setup = davinci_spi_setup;
master->cleanup = davinci_spi_cleanup;
master->can_dma = davinci_spi_can_dma;
host->use_gpio_descriptors = true;
host->dev.of_node = pdev->dev.of_node;
host->bus_num = pdev->id;
host->num_chipselect = pdata->num_chipselect;
host->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 16);
host->flags = SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_GPIO_SS;
host->setup = davinci_spi_setup;
host->cleanup = davinci_spi_cleanup;
host->can_dma = davinci_spi_can_dma;
dspi->bitbang.chipselect = davinci_spi_chipselect;
dspi->bitbang.setup_transfer = davinci_spi_setup_transfer;
@ -983,7 +973,7 @@ static int davinci_spi_probe(struct platform_device *pdev)
iowrite32(CS_DEFAULT, dspi->base + SPIDEF);
/* master mode default */
/* host mode default */
set_io_bits(dspi->base + SPIGCR1, SPIGCR1_CLKMOD_MASK);
set_io_bits(dspi->base + SPIGCR1, SPIGCR1_MASTER_MASK);
set_io_bits(dspi->base + SPIGCR1, SPIGCR1_POWERDOWN_MASK);
@ -1003,8 +993,8 @@ free_dma:
}
free_clk:
clk_disable_unprepare(dspi->clk);
free_master:
spi_master_put(master);
free_host:
spi_controller_put(host);
err:
return ret;
}
@ -1021,10 +1011,10 @@ err:
static void davinci_spi_remove(struct platform_device *pdev)
{
struct davinci_spi *dspi;
struct spi_master *master;
struct spi_controller *host;
master = platform_get_drvdata(pdev);
dspi = spi_master_get_devdata(master);
host = platform_get_drvdata(pdev);
dspi = spi_controller_get_devdata(host);
spi_bitbang_stop(&dspi->bitbang);
@ -1035,7 +1025,7 @@ static void davinci_spi_remove(struct platform_device *pdev)
dma_release_channel(dspi->dma_tx);
}
spi_master_put(master);
spi_controller_put(host);
}
static struct platform_driver davinci_spi_driver = {

Просмотреть файл

@ -79,7 +79,7 @@
struct dln2_spi {
struct platform_device *pdev;
struct spi_master *master;
struct spi_controller *host;
u8 port;
/*
@ -176,7 +176,7 @@ static int dln2_spi_cs_enable(struct dln2_spi *dln2, u8 cs_mask, bool enable)
static int dln2_spi_cs_enable_all(struct dln2_spi *dln2, bool enable)
{
u8 cs_mask = GENMASK(dln2->master->num_chipselect - 1, 0);
u8 cs_mask = GENMASK(dln2->host->num_chipselect - 1, 0);
return dln2_spi_cs_enable(dln2, cs_mask, enable);
}
@ -589,11 +589,11 @@ static int dln2_spi_rdwr(struct dln2_spi *dln2, const u8 *tx_data,
return 0;
}
static int dln2_spi_prepare_message(struct spi_master *master,
static int dln2_spi_prepare_message(struct spi_controller *host,
struct spi_message *message)
{
int ret;
struct dln2_spi *dln2 = spi_master_get_devdata(master);
struct dln2_spi *dln2 = spi_controller_get_devdata(host);
struct spi_device *spi = message->spi;
if (dln2->cs != spi_get_chipselect(spi, 0)) {
@ -650,11 +650,11 @@ static int dln2_spi_transfer_setup(struct dln2_spi *dln2, u32 speed,
return dln2_spi_enable(dln2, true);
}
static int dln2_spi_transfer_one(struct spi_master *master,
static int dln2_spi_transfer_one(struct spi_controller *host,
struct spi_device *spi,
struct spi_transfer *xfer)
{
struct dln2_spi *dln2 = spi_master_get_devdata(master);
struct dln2_spi *dln2 = spi_controller_get_devdata(host);
int status;
u8 attr = 0;
@ -666,7 +666,7 @@ static int dln2_spi_transfer_one(struct spi_master *master,
return status;
}
if (!xfer->cs_change && !spi_transfer_is_last(master, xfer))
if (!xfer->cs_change && !spi_transfer_is_last(host, xfer))
attr = DLN2_SPI_ATTR_LEAVE_SS_LOW;
status = dln2_spi_rdwr(dln2, xfer->tx_buf, xfer->rx_buf,
@ -679,29 +679,29 @@ static int dln2_spi_transfer_one(struct spi_master *master,
static int dln2_spi_probe(struct platform_device *pdev)
{
struct spi_master *master;
struct spi_controller *host;
struct dln2_spi *dln2;
struct dln2_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct device *dev = &pdev->dev;
int ret;
master = spi_alloc_master(&pdev->dev, sizeof(*dln2));
if (!master)
host = spi_alloc_host(&pdev->dev, sizeof(*dln2));
if (!host)
return -ENOMEM;
device_set_node(&master->dev, dev_fwnode(dev));
device_set_node(&host->dev, dev_fwnode(dev));
platform_set_drvdata(pdev, master);
platform_set_drvdata(pdev, host);
dln2 = spi_master_get_devdata(master);
dln2 = spi_controller_get_devdata(host);
dln2->buf = devm_kmalloc(&pdev->dev, DLN2_SPI_BUF_SIZE, GFP_KERNEL);
if (!dln2->buf) {
ret = -ENOMEM;
goto exit_free_master;
goto exit_free_host;
}
dln2->master = master;
dln2->host = host;
dln2->pdev = pdev;
dln2->port = pdata->port;
/* cs/mode can never be 0xff, so the first transfer will set them */
@ -712,47 +712,47 @@ static int dln2_spi_probe(struct platform_device *pdev)
ret = dln2_spi_enable(dln2, false);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to disable SPI module\n");
goto exit_free_master;
goto exit_free_host;
}
ret = dln2_spi_get_cs_num(dln2, &master->num_chipselect);
ret = dln2_spi_get_cs_num(dln2, &host->num_chipselect);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get number of CS pins\n");
goto exit_free_master;
goto exit_free_host;
}
ret = dln2_spi_get_speed_range(dln2,
&master->min_speed_hz,
&master->max_speed_hz);
&host->min_speed_hz,
&host->max_speed_hz);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to read bus min/max freqs\n");
goto exit_free_master;
goto exit_free_host;
}
ret = dln2_spi_get_supported_frame_sizes(dln2,
&master->bits_per_word_mask);
&host->bits_per_word_mask);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to read supported frame sizes\n");
goto exit_free_master;
goto exit_free_host;
}
ret = dln2_spi_cs_enable_all(dln2, true);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to enable CS pins\n");
goto exit_free_master;
goto exit_free_host;
}
master->bus_num = -1;
master->mode_bits = SPI_CPOL | SPI_CPHA;
master->prepare_message = dln2_spi_prepare_message;
master->transfer_one = dln2_spi_transfer_one;
master->auto_runtime_pm = true;
host->bus_num = -1;
host->mode_bits = SPI_CPOL | SPI_CPHA;
host->prepare_message = dln2_spi_prepare_message;
host->transfer_one = dln2_spi_transfer_one;
host->auto_runtime_pm = true;
/* enable SPI module, we're good to go */
ret = dln2_spi_enable(dln2, true);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to enable SPI module\n");
goto exit_free_master;
goto exit_free_host;
}
pm_runtime_set_autosuspend_delay(&pdev->dev,
@ -761,9 +761,9 @@ static int dln2_spi_probe(struct platform_device *pdev)
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
ret = devm_spi_register_master(&pdev->dev, master);
ret = devm_spi_register_controller(&pdev->dev, host);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to register master\n");
dev_err(&pdev->dev, "Failed to register host\n");
goto exit_register;
}
@ -775,16 +775,16 @@ exit_register:
if (dln2_spi_enable(dln2, false) < 0)
dev_err(&pdev->dev, "Failed to disable SPI module\n");
exit_free_master:
spi_master_put(master);
exit_free_host:
spi_controller_put(host);
return ret;
}
static void dln2_spi_remove(struct platform_device *pdev)
{
struct spi_master *master = platform_get_drvdata(pdev);
struct dln2_spi *dln2 = spi_master_get_devdata(master);
struct spi_controller *host = platform_get_drvdata(pdev);
struct dln2_spi *dln2 = spi_controller_get_devdata(host);
pm_runtime_disable(&pdev->dev);
@ -796,10 +796,10 @@ static void dln2_spi_remove(struct platform_device *pdev)
static int dln2_spi_suspend(struct device *dev)
{
int ret;
struct spi_master *master = dev_get_drvdata(dev);
struct dln2_spi *dln2 = spi_master_get_devdata(master);
struct spi_controller *host = dev_get_drvdata(dev);
struct dln2_spi *dln2 = spi_controller_get_devdata(host);
ret = spi_master_suspend(master);
ret = spi_controller_suspend(host);
if (ret < 0)
return ret;
@ -824,8 +824,8 @@ static int dln2_spi_suspend(struct device *dev)
static int dln2_spi_resume(struct device *dev)
{
int ret;
struct spi_master *master = dev_get_drvdata(dev);
struct dln2_spi *dln2 = spi_master_get_devdata(master);
struct spi_controller *host = dev_get_drvdata(dev);
struct dln2_spi *dln2 = spi_controller_get_devdata(host);
if (!pm_runtime_suspended(dev)) {
ret = dln2_spi_cs_enable_all(dln2, true);
@ -837,23 +837,23 @@ static int dln2_spi_resume(struct device *dev)
return ret;
}
return spi_master_resume(master);
return spi_controller_resume(host);
}
#endif /* CONFIG_PM_SLEEP */
#ifdef CONFIG_PM
static int dln2_spi_runtime_suspend(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct dln2_spi *dln2 = spi_master_get_devdata(master);
struct spi_controller *host = dev_get_drvdata(dev);
struct dln2_spi *dln2 = spi_controller_get_devdata(host);
return dln2_spi_enable(dln2, false);
}
static int dln2_spi_runtime_resume(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct dln2_spi *dln2 = spi_master_get_devdata(master);
struct spi_controller *host = dev_get_drvdata(dev);
struct dln2_spi *dln2 = spi_controller_get_devdata(host);
return dln2_spi_enable(dln2, true);
}
@ -875,7 +875,7 @@ static struct platform_driver spi_dln2_driver = {
};
module_platform_driver(spi_dln2_driver);
MODULE_DESCRIPTION("Driver for the Diolan DLN2 SPI master interface");
MODULE_DESCRIPTION("Driver for the Diolan DLN2 SPI host interface");
MODULE_AUTHOR("Laurentiu Palcu <laurentiu.palcu@intel.com>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:dln2-spi");

Просмотреть файл

@ -61,7 +61,7 @@ static void dw_spi_debugfs_init(struct dw_spi *dws)
{
char name[32];
snprintf(name, 32, "dw_spi%d", dws->master->bus_num);
snprintf(name, 32, "dw_spi%d", dws->host->bus_num);
dws->debugfs = debugfs_create_dir(name, NULL);
dws->regset.regs = dw_spi_dbgfs_regs;
@ -183,25 +183,25 @@ int dw_spi_check_status(struct dw_spi *dws, bool raw)
irq_status = dw_readl(dws, DW_SPI_ISR);
if (irq_status & DW_SPI_INT_RXOI) {
dev_err(&dws->master->dev, "RX FIFO overflow detected\n");
dev_err(&dws->host->dev, "RX FIFO overflow detected\n");
ret = -EIO;
}
if (irq_status & DW_SPI_INT_RXUI) {
dev_err(&dws->master->dev, "RX FIFO underflow detected\n");
dev_err(&dws->host->dev, "RX FIFO underflow detected\n");
ret = -EIO;
}
if (irq_status & DW_SPI_INT_TXOI) {
dev_err(&dws->master->dev, "TX FIFO overflow detected\n");
dev_err(&dws->host->dev, "TX FIFO overflow detected\n");
ret = -EIO;
}
/* Generically handle the erroneous situation */
if (ret) {
dw_spi_reset_chip(dws);
if (dws->master->cur_msg)
dws->master->cur_msg->status = ret;
if (dws->host->cur_msg)
dws->host->cur_msg->status = ret;
}
return ret;
@ -213,7 +213,7 @@ static irqreturn_t dw_spi_transfer_handler(struct dw_spi *dws)
u16 irq_status = dw_readl(dws, DW_SPI_ISR);
if (dw_spi_check_status(dws, false)) {
spi_finalize_current_transfer(dws->master);
spi_finalize_current_transfer(dws->host);
return IRQ_HANDLED;
}
@ -227,7 +227,7 @@ static irqreturn_t dw_spi_transfer_handler(struct dw_spi *dws)
dw_reader(dws);
if (!dws->rx_len) {
dw_spi_mask_intr(dws, 0xff);
spi_finalize_current_transfer(dws->master);
spi_finalize_current_transfer(dws->host);
} else if (dws->rx_len <= dw_readl(dws, DW_SPI_RXFTLR)) {
dw_writel(dws, DW_SPI_RXFTLR, dws->rx_len - 1);
}
@ -248,14 +248,14 @@ static irqreturn_t dw_spi_transfer_handler(struct dw_spi *dws)
static irqreturn_t dw_spi_irq(int irq, void *dev_id)
{
struct spi_controller *master = dev_id;
struct dw_spi *dws = spi_controller_get_devdata(master);
struct spi_controller *host = dev_id;
struct dw_spi *dws = spi_controller_get_devdata(host);
u16 irq_status = dw_readl(dws, DW_SPI_ISR) & DW_SPI_INT_MASK;
if (!irq_status)
return IRQ_NONE;
if (!master->cur_msg) {
if (!host->cur_msg) {
dw_spi_mask_intr(dws, 0xff);
return IRQ_HANDLED;
}
@ -408,11 +408,11 @@ static int dw_spi_poll_transfer(struct dw_spi *dws,
return 0;
}
static int dw_spi_transfer_one(struct spi_controller *master,
static int dw_spi_transfer_one(struct spi_controller *host,
struct spi_device *spi,
struct spi_transfer *transfer)
{
struct dw_spi *dws = spi_controller_get_devdata(master);
struct dw_spi *dws = spi_controller_get_devdata(host);
struct dw_spi_cfg cfg = {
.tmode = DW_SPI_CTRLR0_TMOD_TR,
.dfs = transfer->bits_per_word,
@ -440,8 +440,8 @@ static int dw_spi_transfer_one(struct spi_controller *master,
transfer->effective_speed_hz = dws->current_freq;
/* Check if current transfer is a DMA transaction */
if (master->can_dma && master->can_dma(master, spi, transfer))
dws->dma_mapped = master->cur_msg_mapped;
if (host->can_dma && host->can_dma(host, spi, transfer))
dws->dma_mapped = host->cur_msg_mapped;
/* For poll mode just disable all interrupts */
dw_spi_mask_intr(dws, 0xff);
@ -464,10 +464,10 @@ static int dw_spi_transfer_one(struct spi_controller *master,
return 1;
}
static void dw_spi_handle_err(struct spi_controller *master,
static void dw_spi_handle_err(struct spi_controller *host,
struct spi_message *msg)
{
struct dw_spi *dws = spi_controller_get_devdata(master);
struct dw_spi *dws = spi_controller_get_devdata(host);
if (dws->dma_mapped)
dws->dma_ops->dma_stop(dws);
@ -576,7 +576,7 @@ static int dw_spi_write_then_read(struct dw_spi *dws, struct spi_device *spi)
while (len) {
entries = readl_relaxed(dws->regs + DW_SPI_TXFLR);
if (!entries) {
dev_err(&dws->master->dev, "CS de-assertion on Tx\n");
dev_err(&dws->host->dev, "CS de-assertion on Tx\n");
return -EIO;
}
room = min(dws->fifo_len - entries, len);
@ -596,7 +596,7 @@ static int dw_spi_write_then_read(struct dw_spi *dws, struct spi_device *spi)
if (!entries) {
sts = readl_relaxed(dws->regs + DW_SPI_RISR);
if (sts & DW_SPI_INT_RXOI) {
dev_err(&dws->master->dev, "FIFO overflow on Rx\n");
dev_err(&dws->host->dev, "FIFO overflow on Rx\n");
return -EIO;
}
continue;
@ -637,7 +637,7 @@ static int dw_spi_wait_mem_op_done(struct dw_spi *dws)
spi_delay_exec(&delay, NULL);
if (retry < 0) {
dev_err(&dws->master->dev, "Mem op hanged up\n");
dev_err(&dws->host->dev, "Mem op hanged up\n");
return -EIO;
}
@ -884,56 +884,56 @@ static void dw_spi_hw_init(struct device *dev, struct dw_spi *dws)
int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
{
struct spi_controller *master;
struct spi_controller *host;
int ret;
if (!dws)
return -EINVAL;
master = spi_alloc_master(dev, 0);
if (!master)
host = spi_alloc_host(dev, 0);
if (!host)
return -ENOMEM;
device_set_node(&master->dev, dev_fwnode(dev));
device_set_node(&host->dev, dev_fwnode(dev));
dws->master = master;
dws->host = host;
dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR);
spi_controller_set_devdata(master, dws);
spi_controller_set_devdata(host, dws);
/* Basic HW init */
dw_spi_hw_init(dev, dws);
ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dev_name(dev),
master);
host);
if (ret < 0 && ret != -ENOTCONN) {
dev_err(dev, "can not get IRQ\n");
goto err_free_master;
goto err_free_host;
}
dw_spi_init_mem_ops(dws);
master->use_gpio_descriptors = true;
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP;
host->use_gpio_descriptors = true;
host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP;
if (dws->caps & DW_SPI_CAP_DFS32)
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
host->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
else
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);
master->bus_num = dws->bus_num;
master->num_chipselect = dws->num_cs;
master->setup = dw_spi_setup;
master->cleanup = dw_spi_cleanup;
host->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);
host->bus_num = dws->bus_num;
host->num_chipselect = dws->num_cs;
host->setup = dw_spi_setup;
host->cleanup = dw_spi_cleanup;
if (dws->set_cs)
master->set_cs = dws->set_cs;
host->set_cs = dws->set_cs;
else
master->set_cs = dw_spi_set_cs;
master->transfer_one = dw_spi_transfer_one;
master->handle_err = dw_spi_handle_err;
host->set_cs = dw_spi_set_cs;
host->transfer_one = dw_spi_transfer_one;
host->handle_err = dw_spi_handle_err;
if (dws->mem_ops.exec_op)
master->mem_ops = &dws->mem_ops;
master->max_speed_hz = dws->max_freq;
master->flags = SPI_MASTER_GPIO_SS;
master->auto_runtime_pm = true;
host->mem_ops = &dws->mem_ops;
host->max_speed_hz = dws->max_freq;
host->flags = SPI_CONTROLLER_GPIO_SS;
host->auto_runtime_pm = true;
/* Get default rx sample delay */
device_property_read_u32(dev, "rx-sample-delay-ns",
@ -946,14 +946,14 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
} else if (ret) {
dev_warn(dev, "DMA init failed\n");
} else {
master->can_dma = dws->dma_ops->can_dma;
master->flags |= SPI_CONTROLLER_MUST_TX;
host->can_dma = dws->dma_ops->can_dma;
host->flags |= SPI_CONTROLLER_MUST_TX;
}
}
ret = spi_register_controller(master);
ret = spi_register_controller(host);
if (ret) {
dev_err_probe(dev, ret, "problem registering spi master\n");
dev_err_probe(dev, ret, "problem registering spi host\n");
goto err_dma_exit;
}
@ -965,9 +965,9 @@ err_dma_exit:
dws->dma_ops->dma_exit(dws);
dw_spi_enable_chip(dws, 0);
err_free_irq:
free_irq(dws->irq, master);
err_free_master:
spi_controller_put(master);
free_irq(dws->irq, host);
err_free_host:
spi_controller_put(host);
return ret;
}
EXPORT_SYMBOL_NS_GPL(dw_spi_add_host, SPI_DW_CORE);
@ -976,14 +976,14 @@ void dw_spi_remove_host(struct dw_spi *dws)
{
dw_spi_debugfs_remove(dws);
spi_unregister_controller(dws->master);
spi_unregister_controller(dws->host);
if (dws->dma_ops && dws->dma_ops->dma_exit)
dws->dma_ops->dma_exit(dws);
dw_spi_shutdown_chip(dws);
free_irq(dws->irq, dws->master);
free_irq(dws->irq, dws->host);
}
EXPORT_SYMBOL_NS_GPL(dw_spi_remove_host, SPI_DW_CORE);
@ -991,7 +991,7 @@ int dw_spi_suspend_host(struct dw_spi *dws)
{
int ret;
ret = spi_controller_suspend(dws->master);
ret = spi_controller_suspend(dws->host);
if (ret)
return ret;
@ -1002,8 +1002,8 @@ EXPORT_SYMBOL_NS_GPL(dw_spi_suspend_host, SPI_DW_CORE);
int dw_spi_resume_host(struct dw_spi *dws)
{
dw_spi_hw_init(&dws->master->dev, dws);
return spi_controller_resume(dws->master);
dw_spi_hw_init(&dws->host->dev, dws);
return spi_controller_resume(dws->host);
}
EXPORT_SYMBOL_NS_GPL(dw_spi_resume_host, SPI_DW_CORE);

Просмотреть файл

@ -139,8 +139,8 @@ static int dw_spi_dma_init_mfld(struct device *dev, struct dw_spi *dws)
if (!dws->txchan)
goto free_rxchan;
dws->master->dma_rx = dws->rxchan;
dws->master->dma_tx = dws->txchan;
dws->host->dma_rx = dws->rxchan;
dws->host->dma_tx = dws->txchan;
init_completion(&dws->dma_completion);
@ -183,8 +183,8 @@ static int dw_spi_dma_init_generic(struct device *dev, struct dw_spi *dws)
goto free_rxchan;
}
dws->master->dma_rx = dws->rxchan;
dws->master->dma_tx = dws->txchan;
dws->host->dma_rx = dws->rxchan;
dws->host->dma_tx = dws->txchan;
init_completion(&dws->dma_completion);
@ -242,10 +242,10 @@ static enum dma_slave_buswidth dw_spi_dma_convert_width(u8 n_bytes)
}
}
static bool dw_spi_can_dma(struct spi_controller *master,
static bool dw_spi_can_dma(struct spi_controller *host,
struct spi_device *spi, struct spi_transfer *xfer)
{
struct dw_spi *dws = spi_controller_get_devdata(master);
struct dw_spi *dws = spi_controller_get_devdata(host);
enum dma_slave_buswidth dma_bus_width;
if (xfer->len <= dws->fifo_len)
@ -271,7 +271,7 @@ static int dw_spi_dma_wait(struct dw_spi *dws, unsigned int len, u32 speed)
msecs_to_jiffies(ms));
if (ms == 0) {
dev_err(&dws->master->cur_msg->spi->dev,
dev_err(&dws->host->cur_msg->spi->dev,
"DMA transaction timed out\n");
return -ETIMEDOUT;
}
@ -299,7 +299,7 @@ static int dw_spi_dma_wait_tx_done(struct dw_spi *dws,
spi_delay_exec(&delay, xfer);
if (retry < 0) {
dev_err(&dws->master->dev, "Tx hanged up\n");
dev_err(&dws->host->dev, "Tx hanged up\n");
return -EIO;
}
@ -400,7 +400,7 @@ static int dw_spi_dma_wait_rx_done(struct dw_spi *dws)
spi_delay_exec(&delay, NULL);
if (retry < 0) {
dev_err(&dws->master->dev, "Rx hanged up\n");
dev_err(&dws->host->dev, "Rx hanged up\n");
return -EIO;
}
@ -656,13 +656,13 @@ static int dw_spi_dma_transfer(struct dw_spi *dws, struct spi_transfer *xfer)
if (ret)
return ret;
if (dws->master->cur_msg->status == -EINPROGRESS) {
if (dws->host->cur_msg->status == -EINPROGRESS) {
ret = dw_spi_dma_wait_tx_done(dws, xfer);
if (ret)
return ret;
}
if (xfer->rx_buf && dws->master->cur_msg->status == -EINPROGRESS)
if (xfer->rx_buf && dws->host->cur_msg->status == -EINPROGRESS)
ret = dw_spi_dma_wait_rx_done(dws);
return ret;

Просмотреть файл

@ -76,7 +76,7 @@ struct dw_spi_mscc {
*/
static void dw_spi_mscc_set_cs(struct spi_device *spi, bool enable)
{
struct dw_spi *dws = spi_master_get_devdata(spi->master);
struct dw_spi *dws = spi_controller_get_devdata(spi->controller);
struct dw_spi_mmio *dwsmmio = container_of(dws, struct dw_spi_mmio, dws);
struct dw_spi_mscc *dwsmscc = dwsmmio->priv;
u32 cs = spi_get_chipselect(spi, 0);
@ -149,7 +149,7 @@ static int dw_spi_mscc_jaguar2_init(struct platform_device *pdev,
*/
static void dw_spi_sparx5_set_cs(struct spi_device *spi, bool enable)
{
struct dw_spi *dws = spi_master_get_devdata(spi->master);
struct dw_spi *dws = spi_controller_get_devdata(spi->controller);
struct dw_spi_mmio *dwsmmio = container_of(dws, struct dw_spi_mmio, dws);
struct dw_spi_mscc *dwsmscc = dwsmmio->priv;
u8 cs = spi_get_chipselect(spi, 0);
@ -277,7 +277,7 @@ static void dw_spi_elba_override_cs(struct regmap *syscon, int cs, int enable)
static void dw_spi_elba_set_cs(struct spi_device *spi, bool enable)
{
struct dw_spi *dws = spi_master_get_devdata(spi->master);
struct dw_spi *dws = spi_controller_get_devdata(spi->controller);
struct dw_spi_mmio *dwsmmio = container_of(dws, struct dw_spi_mmio, dws);
struct regmap *syscon = dwsmmio->priv;
u8 cs;
@ -369,7 +369,9 @@ static int dw_spi_mmio_probe(struct platform_device *pdev)
dws->max_freq = clk_get_rate(dwsmmio->clk);
device_property_read_u32(&pdev->dev, "reg-io-width", &dws->reg_io_width);
if (device_property_read_u32(&pdev->dev, "reg-io-width",
&dws->reg_io_width))
dws->reg_io_width = 4;
num_cs = 4;

Просмотреть файл

@ -142,14 +142,14 @@ struct dw_spi_dma_ops {
int (*dma_init)(struct device *dev, struct dw_spi *dws);
void (*dma_exit)(struct dw_spi *dws);
int (*dma_setup)(struct dw_spi *dws, struct spi_transfer *xfer);
bool (*can_dma)(struct spi_controller *master, struct spi_device *spi,
bool (*can_dma)(struct spi_controller *host, struct spi_device *spi,
struct spi_transfer *xfer);
int (*dma_transfer)(struct dw_spi *dws, struct spi_transfer *xfer);
void (*dma_stop)(struct dw_spi *dws);
};
struct dw_spi {
struct spi_controller *master;
struct spi_controller *host;
u32 ip; /* Synopsys DW SSI IP-core ID */
u32 ver; /* Synopsys component version */

Просмотреть файл

@ -104,15 +104,15 @@ struct ep93xx_spi {
/**
* ep93xx_spi_calc_divisors() - calculates SPI clock divisors
* @master: SPI master
* @host: SPI host
* @rate: desired SPI output clock rate
* @div_cpsr: pointer to return the cpsr (pre-scaler) divider
* @div_scr: pointer to return the scr divider
*/
static int ep93xx_spi_calc_divisors(struct spi_master *master,
static int ep93xx_spi_calc_divisors(struct spi_controller *host,
u32 rate, u8 *div_cpsr, u8 *div_scr)
{
struct ep93xx_spi *espi = spi_master_get_devdata(master);
struct ep93xx_spi *espi = spi_controller_get_devdata(host);
unsigned long spi_clk_rate = clk_get_rate(espi->clk);
int cpsr, scr;
@ -120,7 +120,7 @@ static int ep93xx_spi_calc_divisors(struct spi_master *master,
* Make sure that max value is between values supported by the
* controller.
*/
rate = clamp(rate, master->min_speed_hz, master->max_speed_hz);
rate = clamp(rate, host->min_speed_hz, host->max_speed_hz);
/*
* Calculate divisors so that we can get speed according the
@ -143,18 +143,18 @@ static int ep93xx_spi_calc_divisors(struct spi_master *master,
return -EINVAL;
}
static int ep93xx_spi_chip_setup(struct spi_master *master,
static int ep93xx_spi_chip_setup(struct spi_controller *host,
struct spi_device *spi,
struct spi_transfer *xfer)
{
struct ep93xx_spi *espi = spi_master_get_devdata(master);
struct ep93xx_spi *espi = spi_controller_get_devdata(host);
u8 dss = bits_per_word_to_dss(xfer->bits_per_word);
u8 div_cpsr = 0;
u8 div_scr = 0;
u16 cr0;
int err;
err = ep93xx_spi_calc_divisors(master, xfer->speed_hz,
err = ep93xx_spi_calc_divisors(host, xfer->speed_hz,
&div_cpsr, &div_scr);
if (err)
return err;
@ -166,9 +166,9 @@ static int ep93xx_spi_chip_setup(struct spi_master *master,
cr0 |= SSPCR0_SPH;
cr0 |= dss;
dev_dbg(&master->dev, "setup: mode %d, cpsr %d, scr %d, dss %d\n",
dev_dbg(&host->dev, "setup: mode %d, cpsr %d, scr %d, dss %d\n",
spi->mode, div_cpsr, div_scr, dss);
dev_dbg(&master->dev, "setup: cr0 %#x\n", cr0);
dev_dbg(&host->dev, "setup: cr0 %#x\n", cr0);
writel(div_cpsr, espi->mmio + SSPCPSR);
writel(cr0, espi->mmio + SSPCR0);
@ -176,10 +176,10 @@ static int ep93xx_spi_chip_setup(struct spi_master *master,
return 0;
}
static void ep93xx_do_write(struct spi_master *master)
static void ep93xx_do_write(struct spi_controller *host)
{
struct ep93xx_spi *espi = spi_master_get_devdata(master);
struct spi_transfer *xfer = master->cur_msg->state;
struct ep93xx_spi *espi = spi_controller_get_devdata(host);
struct spi_transfer *xfer = host->cur_msg->state;
u32 val = 0;
if (xfer->bits_per_word > 8) {
@ -194,10 +194,10 @@ static void ep93xx_do_write(struct spi_master *master)
writel(val, espi->mmio + SSPDR);
}
static void ep93xx_do_read(struct spi_master *master)
static void ep93xx_do_read(struct spi_controller *host)
{
struct ep93xx_spi *espi = spi_master_get_devdata(master);
struct spi_transfer *xfer = master->cur_msg->state;
struct ep93xx_spi *espi = spi_controller_get_devdata(host);
struct spi_transfer *xfer = host->cur_msg->state;
u32 val;
val = readl(espi->mmio + SSPDR);
@ -214,7 +214,7 @@ static void ep93xx_do_read(struct spi_master *master)
/**
* ep93xx_spi_read_write() - perform next RX/TX transfer
* @master: SPI master
* @host: SPI host
*
* This function transfers next bytes (or half-words) to/from RX/TX FIFOs. If
* called several times, the whole transfer will be completed. Returns
@ -223,20 +223,20 @@ static void ep93xx_do_read(struct spi_master *master)
* When this function is finished, RX FIFO should be empty and TX FIFO should be
* full.
*/
static int ep93xx_spi_read_write(struct spi_master *master)
static int ep93xx_spi_read_write(struct spi_controller *host)
{
struct ep93xx_spi *espi = spi_master_get_devdata(master);
struct spi_transfer *xfer = master->cur_msg->state;
struct ep93xx_spi *espi = spi_controller_get_devdata(host);
struct spi_transfer *xfer = host->cur_msg->state;
/* read as long as RX FIFO has frames in it */
while ((readl(espi->mmio + SSPSR) & SSPSR_RNE)) {
ep93xx_do_read(master);
ep93xx_do_read(host);
espi->fifo_level--;
}
/* write as long as TX FIFO has room */
while (espi->fifo_level < SPI_FIFO_SIZE && espi->tx < xfer->len) {
ep93xx_do_write(master);
ep93xx_do_write(host);
espi->fifo_level++;
}
@ -261,7 +261,7 @@ ep93xx_dma_data_to_trans_dir(enum dma_data_direction dir)
/**
* ep93xx_spi_dma_prepare() - prepares a DMA transfer
* @master: SPI master
* @host: SPI host
* @dir: DMA transfer direction
*
* Function configures the DMA, maps the buffer and prepares the DMA
@ -269,11 +269,11 @@ ep93xx_dma_data_to_trans_dir(enum dma_data_direction dir)
* in case of failure.
*/
static struct dma_async_tx_descriptor *
ep93xx_spi_dma_prepare(struct spi_master *master,
ep93xx_spi_dma_prepare(struct spi_controller *host,
enum dma_data_direction dir)
{
struct ep93xx_spi *espi = spi_master_get_devdata(master);
struct spi_transfer *xfer = master->cur_msg->state;
struct ep93xx_spi *espi = spi_controller_get_devdata(host);
struct spi_transfer *xfer = host->cur_msg->state;
struct dma_async_tx_descriptor *txd;
enum dma_slave_buswidth buswidth;
struct dma_slave_config conf;
@ -348,7 +348,7 @@ ep93xx_spi_dma_prepare(struct spi_master *master,
}
if (WARN_ON(len)) {
dev_warn(&master->dev, "len = %zu expected 0!\n", len);
dev_warn(&host->dev, "len = %zu expected 0!\n", len);
return ERR_PTR(-EINVAL);
}
@ -367,16 +367,16 @@ ep93xx_spi_dma_prepare(struct spi_master *master,
/**
* ep93xx_spi_dma_finish() - finishes with a DMA transfer
* @master: SPI master
* @host: SPI host
* @dir: DMA transfer direction
*
* Function finishes with the DMA transfer. After this, the DMA buffer is
* unmapped.
*/
static void ep93xx_spi_dma_finish(struct spi_master *master,
static void ep93xx_spi_dma_finish(struct spi_controller *host,
enum dma_data_direction dir)
{
struct ep93xx_spi *espi = spi_master_get_devdata(master);
struct ep93xx_spi *espi = spi_controller_get_devdata(host);
struct dma_chan *chan;
struct sg_table *sgt;
@ -393,35 +393,35 @@ static void ep93xx_spi_dma_finish(struct spi_master *master,
static void ep93xx_spi_dma_callback(void *callback_param)
{
struct spi_master *master = callback_param;
struct spi_controller *host = callback_param;
ep93xx_spi_dma_finish(master, DMA_TO_DEVICE);
ep93xx_spi_dma_finish(master, DMA_FROM_DEVICE);
ep93xx_spi_dma_finish(host, DMA_TO_DEVICE);
ep93xx_spi_dma_finish(host, DMA_FROM_DEVICE);
spi_finalize_current_transfer(master);
spi_finalize_current_transfer(host);
}
static int ep93xx_spi_dma_transfer(struct spi_master *master)
static int ep93xx_spi_dma_transfer(struct spi_controller *host)
{
struct ep93xx_spi *espi = spi_master_get_devdata(master);
struct ep93xx_spi *espi = spi_controller_get_devdata(host);
struct dma_async_tx_descriptor *rxd, *txd;
rxd = ep93xx_spi_dma_prepare(master, DMA_FROM_DEVICE);
rxd = ep93xx_spi_dma_prepare(host, DMA_FROM_DEVICE);
if (IS_ERR(rxd)) {
dev_err(&master->dev, "DMA RX failed: %ld\n", PTR_ERR(rxd));
dev_err(&host->dev, "DMA RX failed: %ld\n", PTR_ERR(rxd));
return PTR_ERR(rxd);
}
txd = ep93xx_spi_dma_prepare(master, DMA_TO_DEVICE);
txd = ep93xx_spi_dma_prepare(host, DMA_TO_DEVICE);
if (IS_ERR(txd)) {
ep93xx_spi_dma_finish(master, DMA_FROM_DEVICE);
dev_err(&master->dev, "DMA TX failed: %ld\n", PTR_ERR(txd));
ep93xx_spi_dma_finish(host, DMA_FROM_DEVICE);
dev_err(&host->dev, "DMA TX failed: %ld\n", PTR_ERR(txd));
return PTR_ERR(txd);
}
/* We are ready when RX is done */
rxd->callback = ep93xx_spi_dma_callback;
rxd->callback_param = master;
rxd->callback_param = host;
/* Now submit both descriptors and start DMA */
dmaengine_submit(rxd);
@ -436,8 +436,8 @@ static int ep93xx_spi_dma_transfer(struct spi_master *master)
static irqreturn_t ep93xx_spi_interrupt(int irq, void *dev_id)
{
struct spi_master *master = dev_id;
struct ep93xx_spi *espi = spi_master_get_devdata(master);
struct spi_controller *host = dev_id;
struct ep93xx_spi *espi = spi_controller_get_devdata(host);
u32 val;
/*
@ -447,15 +447,15 @@ static irqreturn_t ep93xx_spi_interrupt(int irq, void *dev_id)
if (readl(espi->mmio + SSPIIR) & SSPIIR_RORIS) {
/* clear the overrun interrupt */
writel(0, espi->mmio + SSPICR);
dev_warn(&master->dev,
dev_warn(&host->dev,
"receive overrun, aborting the message\n");
master->cur_msg->status = -EIO;
host->cur_msg->status = -EIO;
} else {
/*
* Interrupt is either RX (RIS) or TX (TIS). For both cases we
* simply execute next data transfer.
*/
if (ep93xx_spi_read_write(master)) {
if (ep93xx_spi_read_write(host)) {
/*
* In normal case, there still is some processing left
* for current transfer. Let's wait for the next
@ -474,26 +474,26 @@ static irqreturn_t ep93xx_spi_interrupt(int irq, void *dev_id)
val &= ~(SSPCR1_RORIE | SSPCR1_TIE | SSPCR1_RIE);
writel(val, espi->mmio + SSPCR1);
spi_finalize_current_transfer(master);
spi_finalize_current_transfer(host);
return IRQ_HANDLED;
}
static int ep93xx_spi_transfer_one(struct spi_master *master,
static int ep93xx_spi_transfer_one(struct spi_controller *host,
struct spi_device *spi,
struct spi_transfer *xfer)
{
struct ep93xx_spi *espi = spi_master_get_devdata(master);
struct ep93xx_spi *espi = spi_controller_get_devdata(host);
u32 val;
int ret;
ret = ep93xx_spi_chip_setup(master, spi, xfer);
ret = ep93xx_spi_chip_setup(host, spi, xfer);
if (ret) {
dev_err(&master->dev, "failed to setup chip for transfer\n");
dev_err(&host->dev, "failed to setup chip for transfer\n");
return ret;
}
master->cur_msg->state = xfer;
host->cur_msg->state = xfer;
espi->rx = 0;
espi->tx = 0;
@ -503,10 +503,10 @@ static int ep93xx_spi_transfer_one(struct spi_master *master,
* So in these cases we will be using PIO and don't bother for DMA.
*/
if (espi->dma_rx && xfer->len > SPI_FIFO_SIZE)
return ep93xx_spi_dma_transfer(master);
return ep93xx_spi_dma_transfer(host);
/* Using PIO so prime the TX FIFO and enable interrupts */
ep93xx_spi_read_write(master);
ep93xx_spi_read_write(host);
val = readl(espi->mmio + SSPCR1);
val |= (SSPCR1_RORIE | SSPCR1_TIE | SSPCR1_RIE);
@ -516,10 +516,10 @@ static int ep93xx_spi_transfer_one(struct spi_master *master,
return 1;
}
static int ep93xx_spi_prepare_message(struct spi_master *master,
static int ep93xx_spi_prepare_message(struct spi_controller *host,
struct spi_message *msg)
{
struct ep93xx_spi *espi = spi_master_get_devdata(master);
struct ep93xx_spi *espi = spi_controller_get_devdata(host);
unsigned long timeout;
/*
@ -528,7 +528,7 @@ static int ep93xx_spi_prepare_message(struct spi_master *master,
timeout = jiffies + msecs_to_jiffies(SPI_TIMEOUT);
while (readl(espi->mmio + SSPSR) & SSPSR_RNE) {
if (time_after(jiffies, timeout)) {
dev_warn(&master->dev,
dev_warn(&host->dev,
"timeout while flushing RX FIFO\n");
return -ETIMEDOUT;
}
@ -544,9 +544,9 @@ static int ep93xx_spi_prepare_message(struct spi_master *master,
return 0;
}
static int ep93xx_spi_prepare_hardware(struct spi_master *master)
static int ep93xx_spi_prepare_hardware(struct spi_controller *host)
{
struct ep93xx_spi *espi = spi_master_get_devdata(master);
struct ep93xx_spi *espi = spi_controller_get_devdata(host);
u32 val;
int ret;
@ -561,9 +561,9 @@ static int ep93xx_spi_prepare_hardware(struct spi_master *master)
return 0;
}
static int ep93xx_spi_unprepare_hardware(struct spi_master *master)
static int ep93xx_spi_unprepare_hardware(struct spi_controller *host)
{
struct ep93xx_spi *espi = spi_master_get_devdata(master);
struct ep93xx_spi *espi = spi_controller_get_devdata(host);
u32 val;
val = readl(espi->mmio + SSPCR1);
@ -646,7 +646,7 @@ static void ep93xx_spi_release_dma(struct ep93xx_spi *espi)
static int ep93xx_spi_probe(struct platform_device *pdev)
{
struct spi_master *master;
struct spi_controller *host;
struct ep93xx_spi_info *info;
struct ep93xx_spi *espi;
struct resource *res;
@ -661,63 +661,56 @@ static int ep93xx_spi_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return -EBUSY;
return irq;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "unable to get iomem resource\n");
return -ENODEV;
}
master = spi_alloc_master(&pdev->dev, sizeof(*espi));
if (!master)
host = spi_alloc_host(&pdev->dev, sizeof(*espi));
if (!host)
return -ENOMEM;
master->use_gpio_descriptors = true;
master->prepare_transfer_hardware = ep93xx_spi_prepare_hardware;
master->unprepare_transfer_hardware = ep93xx_spi_unprepare_hardware;
master->prepare_message = ep93xx_spi_prepare_message;
master->transfer_one = ep93xx_spi_transfer_one;
master->bus_num = pdev->id;
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);
host->use_gpio_descriptors = true;
host->prepare_transfer_hardware = ep93xx_spi_prepare_hardware;
host->unprepare_transfer_hardware = ep93xx_spi_unprepare_hardware;
host->prepare_message = ep93xx_spi_prepare_message;
host->transfer_one = ep93xx_spi_transfer_one;
host->bus_num = pdev->id;
host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
host->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);
/*
* The SPI core will count the number of GPIO descriptors to figure
* out the number of chip selects available on the platform.
*/
master->num_chipselect = 0;
host->num_chipselect = 0;
platform_set_drvdata(pdev, master);
platform_set_drvdata(pdev, host);
espi = spi_master_get_devdata(master);
espi = spi_controller_get_devdata(host);
espi->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(espi->clk)) {
dev_err(&pdev->dev, "unable to get spi clock\n");
error = PTR_ERR(espi->clk);
goto fail_release_master;
goto fail_release_host;
}
/*
* Calculate maximum and minimum supported clock rates
* for the controller.
*/
master->max_speed_hz = clk_get_rate(espi->clk) / 2;
master->min_speed_hz = clk_get_rate(espi->clk) / (254 * 256);
host->max_speed_hz = clk_get_rate(espi->clk) / 2;
host->min_speed_hz = clk_get_rate(espi->clk) / (254 * 256);
espi->sspdr_phys = res->start + SSPDR;
espi->mmio = devm_ioremap_resource(&pdev->dev, res);
espi->mmio = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(espi->mmio)) {
error = PTR_ERR(espi->mmio);
goto fail_release_master;
goto fail_release_host;
}
espi->sspdr_phys = res->start + SSPDR;
error = devm_request_irq(&pdev->dev, irq, ep93xx_spi_interrupt,
0, "ep93xx-spi", master);
0, "ep93xx-spi", host);
if (error) {
dev_err(&pdev->dev, "failed to request irq\n");
goto fail_release_master;
goto fail_release_host;
}
if (info->use_dma && ep93xx_spi_setup_dma(espi))
@ -726,9 +719,9 @@ static int ep93xx_spi_probe(struct platform_device *pdev)
/* make sure that the hardware is disabled */
writel(0, espi->mmio + SSPCR1);
error = devm_spi_register_master(&pdev->dev, master);
error = devm_spi_register_controller(&pdev->dev, host);
if (error) {
dev_err(&pdev->dev, "failed to register SPI master\n");
dev_err(&pdev->dev, "failed to register SPI host\n");
goto fail_free_dma;
}
@ -739,16 +732,16 @@ static int ep93xx_spi_probe(struct platform_device *pdev)
fail_free_dma:
ep93xx_spi_release_dma(espi);
fail_release_master:
spi_master_put(master);
fail_release_host:
spi_controller_put(host);
return error;
}
static void ep93xx_spi_remove(struct platform_device *pdev)
{
struct spi_master *master = platform_get_drvdata(pdev);
struct ep93xx_spi *espi = spi_master_get_devdata(master);
struct spi_controller *host = platform_get_drvdata(pdev);
struct ep93xx_spi *espi = spi_controller_get_devdata(host);
ep93xx_spi_release_dma(espi);
}

Просмотреть файл

@ -91,14 +91,14 @@
struct falcon_sflash {
u32 sfcmd; /* for caching of opcode, direction, ... */
struct spi_master *master;
struct spi_controller *host;
};
int falcon_sflash_xfer(struct spi_device *spi, struct spi_transfer *t,
unsigned long flags)
{
struct device *dev = &spi->dev;
struct falcon_sflash *priv = spi_master_get_devdata(spi->master);
struct falcon_sflash *priv = spi_controller_get_devdata(spi->controller);
const u8 *txp = t->tx_buf;
u8 *rxp = t->rx_buf;
unsigned int bytelen = ((8 * t->len + 7) / 8);
@ -351,10 +351,10 @@ static int falcon_sflash_setup(struct spi_device *spi)
return 0;
}
static int falcon_sflash_xfer_one(struct spi_master *master,
static int falcon_sflash_xfer_one(struct spi_controller *host,
struct spi_message *m)
{
struct falcon_sflash *priv = spi_master_get_devdata(master);
struct falcon_sflash *priv = spi_controller_get_devdata(host);
struct spi_transfer *t;
unsigned long spi_flags;
unsigned long flags;
@ -382,7 +382,7 @@ static int falcon_sflash_xfer_one(struct spi_master *master,
}
m->status = ret;
spi_finalize_current_message(master);
spi_finalize_current_message(host);
return 0;
}
@ -390,25 +390,25 @@ static int falcon_sflash_xfer_one(struct spi_master *master,
static int falcon_sflash_probe(struct platform_device *pdev)
{
struct falcon_sflash *priv;
struct spi_master *master;
struct spi_controller *host;
int ret;
master = spi_alloc_master(&pdev->dev, sizeof(*priv));
if (!master)
host = spi_alloc_host(&pdev->dev, sizeof(*priv));
if (!host)
return -ENOMEM;
priv = spi_master_get_devdata(master);
priv->master = master;
priv = spi_controller_get_devdata(host);
priv->host = host;
master->mode_bits = SPI_MODE_3;
master->flags = SPI_MASTER_HALF_DUPLEX;
master->setup = falcon_sflash_setup;
master->transfer_one_message = falcon_sflash_xfer_one;
master->dev.of_node = pdev->dev.of_node;
host->mode_bits = SPI_MODE_3;
host->flags = SPI_CONTROLLER_HALF_DUPLEX;
host->setup = falcon_sflash_setup;
host->transfer_one_message = falcon_sflash_xfer_one;
host->dev.of_node = pdev->dev.of_node;
ret = devm_spi_register_master(&pdev->dev, master);
ret = devm_spi_register_controller(&pdev->dev, host);
if (ret)
spi_master_put(master);
spi_controller_put(host);
return ret;
}

Просмотреть файл

@ -542,7 +542,7 @@ static int fsi_spi_probe(struct device *dev)
if (of_property_read_u32(np, "reg", &base))
continue;
ctlr = spi_alloc_master(dev, sizeof(*ctx));
ctlr = spi_alloc_host(dev, sizeof(*ctx));
if (!ctlr) {
of_node_put(np);
break;

Просмотреть файл

@ -56,12 +56,12 @@ void fsl_spi_cpm_reinit_txrx(struct mpc8xxx_spi *mspi)
QE_CR_PROTOCOL_UNSPECIFIED, 0);
} else {
if (mspi->flags & SPI_CPM1) {
out_be32(&mspi->pram->rstate, 0);
out_be16(&mspi->pram->rbptr,
in_be16(&mspi->pram->rbase));
out_be32(&mspi->pram->tstate, 0);
out_be16(&mspi->pram->tbptr,
in_be16(&mspi->pram->tbase));
iowrite32be(0, &mspi->pram->rstate);
iowrite16be(ioread16be(&mspi->pram->rbase),
&mspi->pram->rbptr);
iowrite32be(0, &mspi->pram->tstate);
iowrite16be(ioread16be(&mspi->pram->tbase),
&mspi->pram->tbptr);
} else {
cpm_command(CPM_SPI_CMD, CPM_CR_INIT_TRX);
}
@ -75,24 +75,24 @@ static void fsl_spi_cpm_bufs_start(struct mpc8xxx_spi *mspi)
struct cpm_buf_desc __iomem *rx_bd = mspi->rx_bd;
unsigned int xfer_len = min(mspi->count, SPI_MRBLR);
unsigned int xfer_ofs;
struct fsl_spi_reg *reg_base = mspi->reg_base;
struct fsl_spi_reg __iomem *reg_base = mspi->reg_base;
xfer_ofs = mspi->xfer_in_progress->len - mspi->count;
if (mspi->rx_dma == mspi->dma_dummy_rx)
out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma);
iowrite32be(mspi->rx_dma, &rx_bd->cbd_bufaddr);
else
out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma + xfer_ofs);
out_be16(&rx_bd->cbd_datlen, 0);
out_be16(&rx_bd->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT | BD_SC_WRAP);
iowrite32be(mspi->rx_dma + xfer_ofs, &rx_bd->cbd_bufaddr);
iowrite16be(0, &rx_bd->cbd_datlen);
iowrite16be(BD_SC_EMPTY | BD_SC_INTRPT | BD_SC_WRAP, &rx_bd->cbd_sc);
if (mspi->tx_dma == mspi->dma_dummy_tx)
out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma);
iowrite32be(mspi->tx_dma, &tx_bd->cbd_bufaddr);
else
out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma + xfer_ofs);
out_be16(&tx_bd->cbd_datlen, xfer_len);
out_be16(&tx_bd->cbd_sc, BD_SC_READY | BD_SC_INTRPT | BD_SC_WRAP |
BD_SC_LAST);
iowrite32be(mspi->tx_dma + xfer_ofs, &tx_bd->cbd_bufaddr);
iowrite16be(xfer_len, &tx_bd->cbd_datlen);
iowrite16be(BD_SC_READY | BD_SC_INTRPT | BD_SC_WRAP | BD_SC_LAST,
&tx_bd->cbd_sc);
/* start transfer */
mpc8xxx_spi_write_reg(&reg_base->command, SPCOM_STR);
@ -102,7 +102,7 @@ int fsl_spi_cpm_bufs(struct mpc8xxx_spi *mspi,
struct spi_transfer *t, bool is_dma_mapped)
{
struct device *dev = mspi->dev;
struct fsl_spi_reg *reg_base = mspi->reg_base;
struct fsl_spi_reg __iomem *reg_base = mspi->reg_base;
if (is_dma_mapped) {
mspi->map_tx_dma = 0;
@ -123,7 +123,7 @@ int fsl_spi_cpm_bufs(struct mpc8xxx_spi *mspi,
}
if (t->bits_per_word == 16 && t->tx_buf) {
const u16 *src = t->tx_buf;
u16 *dst;
__le16 *dst;
int i;
dst = kmalloc(t->len, GFP_KERNEL);
@ -202,12 +202,12 @@ EXPORT_SYMBOL_GPL(fsl_spi_cpm_bufs_complete);
void fsl_spi_cpm_irq(struct mpc8xxx_spi *mspi, u32 events)
{
u16 len;
struct fsl_spi_reg *reg_base = mspi->reg_base;
struct fsl_spi_reg __iomem *reg_base = mspi->reg_base;
dev_dbg(mspi->dev, "%s: bd datlen %d, count %d\n", __func__,
in_be16(&mspi->rx_bd->cbd_datlen), mspi->count);
ioread16be(&mspi->rx_bd->cbd_datlen), mspi->count);
len = in_be16(&mspi->rx_bd->cbd_datlen);
len = ioread16be(&mspi->rx_bd->cbd_datlen);
if (len > mspi->count) {
WARN_ON(1);
len = mspi->count;
@ -328,7 +328,7 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi)
}
if (mspi->flags & SPI_CPM1) {
void *pram;
void __iomem *pram;
pram = devm_platform_ioremap_resource(to_platform_device(dev),
1);
@ -374,21 +374,21 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi)
mspi->rx_bd = cpm_muram_addr(bds_ofs + sizeof(*mspi->tx_bd));
/* Initialize parameter ram. */
out_be16(&mspi->pram->tbase, cpm_muram_offset(mspi->tx_bd));
out_be16(&mspi->pram->rbase, cpm_muram_offset(mspi->rx_bd));
out_8(&mspi->pram->tfcr, CPMFCR_EB | CPMFCR_GBL);
out_8(&mspi->pram->rfcr, CPMFCR_EB | CPMFCR_GBL);
out_be16(&mspi->pram->mrblr, SPI_MRBLR);
out_be32(&mspi->pram->rstate, 0);
out_be32(&mspi->pram->rdp, 0);
out_be16(&mspi->pram->rbptr, 0);
out_be16(&mspi->pram->rbc, 0);
out_be32(&mspi->pram->rxtmp, 0);
out_be32(&mspi->pram->tstate, 0);
out_be32(&mspi->pram->tdp, 0);
out_be16(&mspi->pram->tbptr, 0);
out_be16(&mspi->pram->tbc, 0);
out_be32(&mspi->pram->txtmp, 0);
iowrite16be(cpm_muram_offset(mspi->tx_bd), &mspi->pram->tbase);
iowrite16be(cpm_muram_offset(mspi->rx_bd), &mspi->pram->rbase);
iowrite8(CPMFCR_EB | CPMFCR_GBL, &mspi->pram->tfcr);
iowrite8(CPMFCR_EB | CPMFCR_GBL, &mspi->pram->rfcr);
iowrite16be(SPI_MRBLR, &mspi->pram->mrblr);
iowrite32be(0, &mspi->pram->rstate);
iowrite32be(0, &mspi->pram->rdp);
iowrite16be(0, &mspi->pram->rbptr);
iowrite16be(0, &mspi->pram->rbc);
iowrite32be(0, &mspi->pram->rxtmp);
iowrite32be(0, &mspi->pram->tstate);
iowrite32be(0, &mspi->pram->tdp);
iowrite16be(0, &mspi->pram->tbptr);
iowrite16be(0, &mspi->pram->tbc);
iowrite32be(0, &mspi->pram->txtmp);
return 0;

Просмотреть файл

@ -13,7 +13,8 @@
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/regmap.h>
#include <linux/spi/spi.h>
@ -22,7 +23,7 @@
#define DRIVER_NAME "fsl-dspi"
#define SPI_MCR 0x00
#define SPI_MCR_MASTER BIT(31)
#define SPI_MCR_HOST BIT(31)
#define SPI_MCR_PCSIS(x) ((x) << 16)
#define SPI_MCR_CLR_TXF BIT(11)
#define SPI_MCR_CLR_RXF BIT(10)
@ -339,7 +340,7 @@ static u32 dspi_pop_tx_pushr(struct fsl_dspi *dspi)
{
u16 cmd = dspi->tx_cmd, data = dspi_pop_tx(dspi);
if (spi_controller_is_slave(dspi->ctlr))
if (spi_controller_is_target(dspi->ctlr))
return data;
if (dspi->len > 0)
@ -429,7 +430,7 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
dma_async_issue_pending(dma->chan_rx);
dma_async_issue_pending(dma->chan_tx);
if (spi_controller_is_slave(dspi->ctlr)) {
if (spi_controller_is_target(dspi->ctlr)) {
wait_for_completion_interruptible(&dspi->dma->cmd_rx_complete);
return 0;
}
@ -502,15 +503,14 @@ static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr)
dma->chan_rx = dma_request_chan(dev, "rx");
if (IS_ERR(dma->chan_rx)) {
dev_err(dev, "rx dma channel not available\n");
ret = PTR_ERR(dma->chan_rx);
return ret;
return dev_err_probe(dev, PTR_ERR(dma->chan_rx),
"rx dma channel not available\n");
}
dma->chan_tx = dma_request_chan(dev, "tx");
if (IS_ERR(dma->chan_tx)) {
dev_err(dev, "tx dma channel not available\n");
ret = PTR_ERR(dma->chan_tx);
dev_err_probe(dev, ret, "tx dma channel not available\n");
goto err_tx_channel;
}
@ -1061,7 +1061,7 @@ static int dspi_setup(struct spi_device *spi)
if (spi->mode & SPI_CPHA)
chip->ctar_val |= SPI_CTAR_CPHA;
if (!spi_controller_is_slave(dspi->ctlr)) {
if (!spi_controller_is_target(dspi->ctlr)) {
chip->ctar_val |= SPI_CTAR_PCSSCK(pcssck) |
SPI_CTAR_CSSCK(cssck) |
SPI_CTAR_PASC(pasc) |
@ -1216,8 +1216,8 @@ static int dspi_init(struct fsl_dspi *dspi)
if (dspi->devtype_data->trans_mode == DSPI_XSPI_MODE)
mcr |= SPI_MCR_XSPI;
if (!spi_controller_is_slave(dspi->ctlr))
mcr |= SPI_MCR_MASTER;
if (!spi_controller_is_target(dspi->ctlr))
mcr |= SPI_MCR_HOST;
regmap_write(dspi->regmap, SPI_MCR, mcr);
regmap_write(dspi->regmap, SPI_SR, SPI_SR_CLEAR);
@ -1240,13 +1240,13 @@ static int dspi_init(struct fsl_dspi *dspi)
return 0;
}
static int dspi_slave_abort(struct spi_master *master)
static int dspi_target_abort(struct spi_controller *host)
{
struct fsl_dspi *dspi = spi_master_get_devdata(master);
struct fsl_dspi *dspi = spi_controller_get_devdata(host);
/*
* Terminate all pending DMA transactions for the SPI working
* in SLAVE mode.
* in TARGET mode.
*/
if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) {
dmaengine_terminate_sync(dspi->dma->chan_rx);
@ -1277,7 +1277,7 @@ static int dspi_probe(struct platform_device *pdev)
if (!dspi)
return -ENOMEM;
ctlr = spi_alloc_master(&pdev->dev, 0);
ctlr = spi_alloc_host(&pdev->dev, 0);
if (!ctlr)
return -ENOMEM;
@ -1292,7 +1292,7 @@ static int dspi_probe(struct platform_device *pdev)
ctlr->dev.of_node = pdev->dev.of_node;
ctlr->cleanup = dspi_cleanup;
ctlr->slave_abort = dspi_slave_abort;
ctlr->target_abort = dspi_target_abort;
ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
ctlr->use_gpio_descriptors = true;
@ -1317,7 +1317,7 @@ static int dspi_probe(struct platform_device *pdev)
ctlr->bus_num = bus_num;
if (of_property_read_bool(np, "spi-slave"))
ctlr->slave = true;
ctlr->target = true;
dspi->devtype_data = of_device_get_match_data(&pdev->dev);
if (!dspi->devtype_data) {

Просмотреть файл

@ -148,7 +148,7 @@ static inline void fsl_espi_write_reg8(struct fsl_espi *espi, int offset,
static int fsl_espi_check_message(struct spi_message *m)
{
struct fsl_espi *espi = spi_master_get_devdata(m->spi->master);
struct fsl_espi *espi = spi_controller_get_devdata(m->spi->controller);
struct spi_transfer *t, *first;
if (m->frame_length > SPCOM_TRANLEN_MAX) {
@ -323,7 +323,7 @@ start:
static void fsl_espi_setup_transfer(struct spi_device *spi,
struct spi_transfer *t)
{
struct fsl_espi *espi = spi_master_get_devdata(spi->master);
struct fsl_espi *espi = spi_controller_get_devdata(spi->controller);
int bits_per_word = t ? t->bits_per_word : spi->bits_per_word;
u32 pm, hz = t ? t->speed_hz : spi->max_speed_hz;
struct fsl_espi_cs *cs = spi_get_ctldata(spi);
@ -351,7 +351,7 @@ static void fsl_espi_setup_transfer(struct spi_device *spi,
static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
{
struct fsl_espi *espi = spi_master_get_devdata(spi->master);
struct fsl_espi *espi = spi_controller_get_devdata(spi->controller);
unsigned int rx_len = t->len;
u32 mask, spcom;
int ret;
@ -396,7 +396,7 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
static int fsl_espi_trans(struct spi_message *m, struct spi_transfer *trans)
{
struct fsl_espi *espi = spi_master_get_devdata(m->spi->master);
struct fsl_espi *espi = spi_controller_get_devdata(m->spi->controller);
struct spi_device *spi = m->spi;
int ret;
@ -432,7 +432,7 @@ static int fsl_espi_trans(struct spi_message *m, struct spi_transfer *trans)
return ret;
}
static int fsl_espi_do_one_msg(struct spi_master *master,
static int fsl_espi_do_one_msg(struct spi_controller *host,
struct spi_message *m)
{
unsigned int rx_nbits = 0, delay_nsecs = 0;
@ -470,7 +470,7 @@ out:
if (m->status == -EINPROGRESS)
m->status = ret;
spi_finalize_current_message(master);
spi_finalize_current_message(host);
return ret;
}
@ -488,7 +488,7 @@ static int fsl_espi_setup(struct spi_device *spi)
spi_set_ctldata(spi, cs);
}
espi = spi_master_get_devdata(spi->master);
espi = spi_controller_get_devdata(spi->controller);
pm_runtime_get_sync(espi->dev);
@ -584,8 +584,8 @@ static irqreturn_t fsl_espi_irq(s32 irq, void *context_data)
#ifdef CONFIG_PM
static int fsl_espi_runtime_suspend(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct fsl_espi *espi = spi_master_get_devdata(master);
struct spi_controller *host = dev_get_drvdata(dev);
struct fsl_espi *espi = spi_controller_get_devdata(host);
u32 regval;
regval = fsl_espi_read_reg(espi, ESPI_SPMODE);
@ -597,8 +597,8 @@ static int fsl_espi_runtime_suspend(struct device *dev)
static int fsl_espi_runtime_resume(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct fsl_espi *espi = spi_master_get_devdata(master);
struct spi_controller *host = dev_get_drvdata(dev);
struct fsl_espi *espi = spi_controller_get_devdata(host);
u32 regval;
regval = fsl_espi_read_reg(espi, ESPI_SPMODE);
@ -616,8 +616,8 @@ static size_t fsl_espi_max_message_size(struct spi_device *spi)
static void fsl_espi_init_regs(struct device *dev, bool initial)
{
struct spi_master *master = dev_get_drvdata(dev);
struct fsl_espi *espi = spi_master_get_devdata(master);
struct spi_controller *host = dev_get_drvdata(dev);
struct fsl_espi *espi = spi_controller_get_devdata(host);
struct device_node *nc;
u32 csmode, cs, prop;
int ret;
@ -629,10 +629,10 @@ static void fsl_espi_init_regs(struct device *dev, bool initial)
fsl_espi_write_reg(espi, ESPI_SPIE, 0xffffffff);
/* Init eSPI CS mode register */
for_each_available_child_of_node(master->dev.of_node, nc) {
for_each_available_child_of_node(host->dev.of_node, nc) {
/* get chip select */
ret = of_property_read_u32(nc, "reg", &cs);
if (ret || cs >= master->num_chipselect)
if (ret || cs >= host->num_chipselect)
continue;
csmode = CSMODE_INIT_VAL;
@ -664,28 +664,28 @@ static void fsl_espi_init_regs(struct device *dev, bool initial)
static int fsl_espi_probe(struct device *dev, struct resource *mem,
unsigned int irq, unsigned int num_cs)
{
struct spi_master *master;
struct spi_controller *host;
struct fsl_espi *espi;
int ret;
master = spi_alloc_master(dev, sizeof(struct fsl_espi));
if (!master)
host = spi_alloc_host(dev, sizeof(struct fsl_espi));
if (!host)
return -ENOMEM;
dev_set_drvdata(dev, master);
dev_set_drvdata(dev, host);
master->mode_bits = SPI_RX_DUAL | SPI_CPOL | SPI_CPHA | SPI_CS_HIGH |
SPI_LSB_FIRST | SPI_LOOP;
master->dev.of_node = dev->of_node;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);
master->setup = fsl_espi_setup;
master->cleanup = fsl_espi_cleanup;
master->transfer_one_message = fsl_espi_do_one_msg;
master->auto_runtime_pm = true;
master->max_message_size = fsl_espi_max_message_size;
master->num_chipselect = num_cs;
host->mode_bits = SPI_RX_DUAL | SPI_CPOL | SPI_CPHA | SPI_CS_HIGH |
SPI_LSB_FIRST | SPI_LOOP;
host->dev.of_node = dev->of_node;
host->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);
host->setup = fsl_espi_setup;
host->cleanup = fsl_espi_cleanup;
host->transfer_one_message = fsl_espi_do_one_msg;
host->auto_runtime_pm = true;
host->max_message_size = fsl_espi_max_message_size;
host->num_chipselect = num_cs;
espi = spi_master_get_devdata(master);
espi = spi_controller_get_devdata(host);
spin_lock_init(&espi->lock);
espi->dev = dev;
@ -696,8 +696,8 @@ static int fsl_espi_probe(struct device *dev, struct resource *mem,
goto err_probe;
}
/* determined by clock divider fields DIV16/PM in register SPMODEx */
master->min_speed_hz = DIV_ROUND_UP(espi->spibrg, 4 * 16 * 16);
master->max_speed_hz = DIV_ROUND_UP(espi->spibrg, 4);
host->min_speed_hz = DIV_ROUND_UP(espi->spibrg, 4 * 16 * 16);
host->max_speed_hz = DIV_ROUND_UP(espi->spibrg, 4);
init_completion(&espi->done);
@ -720,7 +720,7 @@ static int fsl_espi_probe(struct device *dev, struct resource *mem,
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
ret = devm_spi_register_master(dev, master);
ret = devm_spi_register_controller(dev, host);
if (ret < 0)
goto err_pm;
@ -736,7 +736,7 @@ err_pm:
pm_runtime_disable(dev);
pm_runtime_set_suspended(dev);
err_probe:
spi_master_put(master);
spi_controller_put(host);
return ret;
}
@ -791,10 +791,10 @@ static void of_fsl_espi_remove(struct platform_device *dev)
#ifdef CONFIG_PM_SLEEP
static int of_fsl_espi_suspend(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct spi_controller *host = dev_get_drvdata(dev);
int ret;
ret = spi_master_suspend(master);
ret = spi_controller_suspend(host);
if (ret)
return ret;
@ -803,7 +803,7 @@ static int of_fsl_espi_suspend(struct device *dev)
static int of_fsl_espi_resume(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct spi_controller *host = dev_get_drvdata(dev);
int ret;
fsl_espi_init_regs(dev, false);
@ -812,7 +812,7 @@ static int of_fsl_espi_resume(struct device *dev)
if (ret < 0)
return ret;
return spi_master_resume(master);
return spi_controller_resume(host);
}
#endif /* CONFIG_PM_SLEEP */

Просмотреть файл

@ -18,7 +18,8 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#ifdef CONFIG_FSL_SOC
#include <sysdev/fsl_soc.h>

Просмотреть файл

@ -103,12 +103,9 @@ extern void mpc8xxx_spi_rx_buf_u32(u32 data, struct mpc8xxx_spi *mpc8xxx_spi);
extern struct mpc8xxx_spi_probe_info *to_of_pinfo(
struct fsl_spi_platform_data *pdata);
extern int mpc8xxx_spi_bufs(struct mpc8xxx_spi *mspi,
struct spi_transfer *t, unsigned int len);
extern const char *mpc8xxx_spi_strmode(unsigned int flags);
extern void mpc8xxx_spi_probe(struct device *dev, struct resource *mem,
unsigned int irq);
extern int mpc8xxx_spi_remove(struct device *dev);
extern int of_mpc8xxx_spi_probe(struct platform_device *ofdev);
#endif /* __SPI_FSL_LIB_H__ */

Просмотреть файл

@ -17,7 +17,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/dma/imx-dma.h>
@ -73,7 +72,7 @@
#define CFGR1_PINCFG (BIT(24)|BIT(25))
#define CFGR1_PCSPOL BIT(8)
#define CFGR1_NOSTALL BIT(3)
#define CFGR1_MASTER BIT(0)
#define CFGR1_HOST BIT(0)
#define FSR_TXCOUNT (0xFF)
#define RSR_RXEMPTY BIT(1)
#define TCR_CPOL BIT(31)
@ -97,8 +96,7 @@ struct fsl_lpspi_data {
unsigned long base_phys;
struct clk *clk_ipg;
struct clk *clk_per;
bool is_slave;
u32 num_cs;
bool is_target;
bool is_only_cs1;
bool is_first_byte;
@ -115,7 +113,7 @@ struct fsl_lpspi_data {
struct lpspi_config config;
struct completion xfer_done;
bool slave_aborted;
bool target_aborted;
/* DMA */
bool usedma;
@ -236,7 +234,7 @@ static void fsl_lpspi_write_tx_fifo(struct fsl_lpspi_data *fsl_lpspi)
}
if (txfifo_cnt < fsl_lpspi->txfifosize) {
if (!fsl_lpspi->is_slave) {
if (!fsl_lpspi->is_target) {
temp = readl(fsl_lpspi->base + IMX7ULP_TCR);
temp &= ~TCR_CONTC;
writel(temp, fsl_lpspi->base + IMX7ULP_TCR);
@ -260,7 +258,7 @@ static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi)
temp |= fsl_lpspi->config.bpw - 1;
temp |= (fsl_lpspi->config.mode & 0x3) << 30;
temp |= (fsl_lpspi->config.chip_select & 0x3) << 24;
if (!fsl_lpspi->is_slave) {
if (!fsl_lpspi->is_target) {
temp |= fsl_lpspi->config.prescale << 27;
/*
* Set TCR_CONT will keep SS asserted after current transfer.
@ -387,7 +385,7 @@ static int fsl_lpspi_config(struct fsl_lpspi_data *fsl_lpspi)
u32 temp;
int ret;
if (!fsl_lpspi->is_slave) {
if (!fsl_lpspi->is_target) {
ret = fsl_lpspi_set_bitrate(fsl_lpspi);
if (ret)
return ret;
@ -395,8 +393,8 @@ static int fsl_lpspi_config(struct fsl_lpspi_data *fsl_lpspi)
fsl_lpspi_set_watermark(fsl_lpspi);
if (!fsl_lpspi->is_slave)
temp = CFGR1_MASTER;
if (!fsl_lpspi->is_target)
temp = CFGR1_HOST;
else
temp = CFGR1_PINCFG;
if (fsl_lpspi->config.mode & SPI_CS_HIGH)
@ -463,12 +461,12 @@ static int fsl_lpspi_setup_transfer(struct spi_controller *controller,
return fsl_lpspi_config(fsl_lpspi);
}
static int fsl_lpspi_slave_abort(struct spi_controller *controller)
static int fsl_lpspi_target_abort(struct spi_controller *controller)
{
struct fsl_lpspi_data *fsl_lpspi =
spi_controller_get_devdata(controller);
fsl_lpspi->slave_aborted = true;
fsl_lpspi->target_aborted = true;
if (!fsl_lpspi->usedma)
complete(&fsl_lpspi->xfer_done);
else {
@ -484,9 +482,9 @@ static int fsl_lpspi_wait_for_completion(struct spi_controller *controller)
struct fsl_lpspi_data *fsl_lpspi =
spi_controller_get_devdata(controller);
if (fsl_lpspi->is_slave) {
if (fsl_lpspi->is_target) {
if (wait_for_completion_interruptible(&fsl_lpspi->xfer_done) ||
fsl_lpspi->slave_aborted) {
fsl_lpspi->target_aborted) {
dev_dbg(fsl_lpspi->dev, "interrupted\n");
return -EINTR;
}
@ -589,9 +587,9 @@ static int fsl_lpspi_dma_transfer(struct spi_controller *controller,
reinit_completion(&fsl_lpspi->dma_tx_completion);
dma_async_issue_pending(controller->dma_tx);
fsl_lpspi->slave_aborted = false;
fsl_lpspi->target_aborted = false;
if (!fsl_lpspi->is_slave) {
if (!fsl_lpspi->is_target) {
transfer_timeout = fsl_lpspi_calculate_timeout(fsl_lpspi,
transfer->len);
@ -617,7 +615,7 @@ static int fsl_lpspi_dma_transfer(struct spi_controller *controller,
}
} else {
if (wait_for_completion_interruptible(&fsl_lpspi->dma_tx_completion) ||
fsl_lpspi->slave_aborted) {
fsl_lpspi->target_aborted) {
dev_dbg(fsl_lpspi->dev,
"I/O Error in DMA TX interrupted\n");
dmaengine_terminate_all(controller->dma_tx);
@ -627,7 +625,7 @@ static int fsl_lpspi_dma_transfer(struct spi_controller *controller,
}
if (wait_for_completion_interruptible(&fsl_lpspi->dma_rx_completion) ||
fsl_lpspi->slave_aborted) {
fsl_lpspi->target_aborted) {
dev_dbg(fsl_lpspi->dev,
"I/O Error in DMA RX interrupted\n");
dmaengine_terminate_all(controller->dma_tx);
@ -702,7 +700,7 @@ static int fsl_lpspi_pio_transfer(struct spi_controller *controller,
fsl_lpspi->remain = t->len;
reinit_completion(&fsl_lpspi->xfer_done);
fsl_lpspi->slave_aborted = false;
fsl_lpspi->target_aborted = false;
fsl_lpspi_write_tx_fifo(fsl_lpspi);
@ -826,16 +824,17 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
struct spi_controller *controller;
struct resource *res;
int ret, irq;
u32 num_cs;
u32 temp;
bool is_slave;
bool is_target;
is_slave = of_property_read_bool((&pdev->dev)->of_node, "spi-slave");
if (is_slave)
controller = spi_alloc_slave(&pdev->dev,
sizeof(struct fsl_lpspi_data));
is_target = of_property_read_bool((&pdev->dev)->of_node, "spi-slave");
if (is_target)
controller = spi_alloc_target(&pdev->dev,
sizeof(struct fsl_lpspi_data));
else
controller = spi_alloc_master(&pdev->dev,
sizeof(struct fsl_lpspi_data));
controller = spi_alloc_host(&pdev->dev,
sizeof(struct fsl_lpspi_data));
if (!controller)
return -ENOMEM;
@ -844,25 +843,9 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
fsl_lpspi = spi_controller_get_devdata(controller);
fsl_lpspi->dev = &pdev->dev;
fsl_lpspi->is_slave = is_slave;
fsl_lpspi->is_target = is_target;
fsl_lpspi->is_only_cs1 = of_property_read_bool((&pdev->dev)->of_node,
"fsl,spi-only-use-cs1-sel");
if (of_property_read_u32((&pdev->dev)->of_node, "num-cs",
&fsl_lpspi->num_cs))
fsl_lpspi->num_cs = 1;
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->num_chipselect = fsl_lpspi->num_cs;
controller->slave_abort = fsl_lpspi_slave_abort;
if (!fsl_lpspi->is_slave)
controller->use_gpio_descriptors = true;
init_completion(&fsl_lpspi->xfer_done);
@ -912,6 +895,26 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
temp = readl(fsl_lpspi->base + IMX7ULP_PARAM);
fsl_lpspi->txfifosize = 1 << (temp & 0x0f);
fsl_lpspi->rxfifosize = 1 << ((temp >> 8) & 0x0f);
if (of_property_read_u32((&pdev->dev)->of_node, "num-cs",
&num_cs)) {
if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx93-spi"))
num_cs = ((temp >> 16) & 0xf);
else
num_cs = 1;
}
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_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX;
controller->dev.of_node = pdev->dev.of_node;
controller->bus_num = pdev->id;
controller->num_chipselect = num_cs;
controller->target_abort = fsl_lpspi_target_abort;
if (!fsl_lpspi->is_target)
controller->use_gpio_descriptors = true;
ret = fsl_lpspi_dma_init(&pdev->dev, fsl_lpspi, controller);
if (ret == -EPROBE_DEFER)

Просмотреть файл

@ -34,7 +34,6 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_qos.h>
#include <linux/sizes.h>
@ -368,7 +367,7 @@ static int fsl_qspi_check_buswidth(struct fsl_qspi *q, u8 width)
static bool fsl_qspi_supports_op(struct spi_mem *mem,
const struct spi_mem_op *op)
{
struct fsl_qspi *q = spi_controller_get_devdata(mem->spi->master);
struct fsl_qspi *q = spi_controller_get_devdata(mem->spi->controller);
int ret;
ret = fsl_qspi_check_buswidth(q, op->cmd.buswidth);
@ -641,7 +640,7 @@ static int fsl_qspi_readl_poll_tout(struct fsl_qspi *q, void __iomem *base,
static int fsl_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
{
struct fsl_qspi *q = spi_controller_get_devdata(mem->spi->master);
struct fsl_qspi *q = spi_controller_get_devdata(mem->spi->controller);
void __iomem *base = q->iobase;
u32 addr_offset = 0;
int err = 0;
@ -703,7 +702,7 @@ static int fsl_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
static int fsl_qspi_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
{
struct fsl_qspi *q = spi_controller_get_devdata(mem->spi->master);
struct fsl_qspi *q = spi_controller_get_devdata(mem->spi->controller);
if (op->data.dir == SPI_MEM_DATA_OUT) {
if (op->data.nbytes > q->devtype_data->txfifo)
@ -809,7 +808,7 @@ static int fsl_qspi_default_setup(struct fsl_qspi *q)
static const char *fsl_qspi_get_name(struct spi_mem *mem)
{
struct fsl_qspi *q = spi_controller_get_devdata(mem->spi->master);
struct fsl_qspi *q = spi_controller_get_devdata(mem->spi->controller);
struct device *dev = &mem->spi->dev;
const char *name;
@ -849,7 +848,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
struct fsl_qspi *q;
int ret;
ctlr = spi_alloc_master(&pdev->dev, sizeof(*q));
ctlr = spi_alloc_host(&pdev->dev, sizeof(*q));
if (!ctlr)
return -ENOMEM;

Просмотреть файл

@ -88,7 +88,7 @@ static int fsl_spi_get_type(struct device *dev)
static void fsl_spi_change_mode(struct spi_device *spi)
{
struct mpc8xxx_spi *mspi = spi_master_get_devdata(spi->master);
struct mpc8xxx_spi *mspi = spi_controller_get_devdata(spi->controller);
struct spi_mpc8xxx_cs *cs = spi->controller_state;
struct fsl_spi_reg __iomem *reg_base = mspi->reg_base;
__be32 __iomem *mode = &reg_base->mode;
@ -183,7 +183,7 @@ static int fsl_spi_setup_transfer(struct spi_device *spi,
u32 hz = 0;
struct spi_mpc8xxx_cs *cs = spi->controller_state;
mpc8xxx_spi = spi_master_get_devdata(spi->master);
mpc8xxx_spi = spi_controller_get_devdata(spi->controller);
if (t) {
bits_per_word = t->bits_per_word;
@ -252,7 +252,7 @@ static int fsl_spi_cpu_bufs(struct mpc8xxx_spi *mspi,
static int fsl_spi_bufs(struct spi_device *spi, struct spi_transfer *t,
bool is_dma_mapped)
{
struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
struct mpc8xxx_spi *mpc8xxx_spi = spi_controller_get_devdata(spi->controller);
struct fsl_spi_reg __iomem *reg_base;
unsigned int len = t->len;
u8 bits_per_word;
@ -385,7 +385,7 @@ static int fsl_spi_setup(struct spi_device *spi)
spi_set_ctldata(spi, cs);
initial_setup = true;
}
mpc8xxx_spi = spi_master_get_devdata(spi->master);
mpc8xxx_spi = spi_controller_get_devdata(spi->controller);
reg_base = mpc8xxx_spi->reg_base;
@ -479,7 +479,7 @@ static irqreturn_t fsl_spi_irq(s32 irq, void *context_data)
static void fsl_spi_grlib_cs_control(struct spi_device *spi, bool on)
{
struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
struct mpc8xxx_spi *mpc8xxx_spi = spi_controller_get_devdata(spi->controller);
struct fsl_spi_reg __iomem *reg_base = mpc8xxx_spi->reg_base;
u32 slvsel;
u16 cs = spi_get_chipselect(spi, 0);
@ -493,8 +493,8 @@ static void fsl_spi_grlib_cs_control(struct spi_device *spi, bool on)
static void fsl_spi_grlib_probe(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master);
struct spi_controller *host = dev_get_drvdata(dev);
struct mpc8xxx_spi *mpc8xxx_spi = spi_controller_get_devdata(host);
struct fsl_spi_reg __iomem *reg_base = mpc8xxx_spi->reg_base;
int mbits;
u32 capabilities;
@ -511,8 +511,8 @@ static void fsl_spi_grlib_probe(struct device *dev)
mpc8xxx_spi->native_chipselects = SPCAP_SSSZ(capabilities);
mpc8xxx_spi_write_reg(&reg_base->slvsel, 0xffffffff);
}
master->num_chipselect = mpc8xxx_spi->native_chipselects;
master->set_cs = fsl_spi_grlib_cs_control;
host->num_chipselect = mpc8xxx_spi->native_chipselects;
host->set_cs = fsl_spi_grlib_cs_control;
}
static void fsl_spi_cs_control(struct spi_device *spi, bool on)
@ -526,35 +526,35 @@ static void fsl_spi_cs_control(struct spi_device *spi, bool on)
iowrite32be(on ? 0 : SPI_BOOT_SEL_BIT, pinfo->immr_spi_cs);
}
static struct spi_master *fsl_spi_probe(struct device *dev,
static struct spi_controller *fsl_spi_probe(struct device *dev,
struct resource *mem, unsigned int irq)
{
struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
struct spi_master *master;
struct spi_controller *host;
struct mpc8xxx_spi *mpc8xxx_spi;
struct fsl_spi_reg __iomem *reg_base;
u32 regval;
int ret = 0;
master = spi_alloc_master(dev, sizeof(struct mpc8xxx_spi));
if (master == NULL) {
host = spi_alloc_host(dev, sizeof(struct mpc8xxx_spi));
if (host == NULL) {
ret = -ENOMEM;
goto err;
}
dev_set_drvdata(dev, master);
dev_set_drvdata(dev, host);
mpc8xxx_spi_probe(dev, mem, irq);
master->setup = fsl_spi_setup;
master->cleanup = fsl_spi_cleanup;
master->prepare_message = fsl_spi_prepare_message;
master->transfer_one = fsl_spi_transfer_one;
master->unprepare_message = fsl_spi_unprepare_message;
master->use_gpio_descriptors = true;
master->set_cs = fsl_spi_cs_control;
host->setup = fsl_spi_setup;
host->cleanup = fsl_spi_cleanup;
host->prepare_message = fsl_spi_prepare_message;
host->transfer_one = fsl_spi_transfer_one;
host->unprepare_message = fsl_spi_unprepare_message;
host->use_gpio_descriptors = true;
host->set_cs = fsl_spi_cs_control;
mpc8xxx_spi = spi_master_get_devdata(master);
mpc8xxx_spi = spi_controller_get_devdata(host);
mpc8xxx_spi->max_bits_per_word = 32;
mpc8xxx_spi->type = fsl_spi_get_type(dev);
@ -572,13 +572,13 @@ static struct spi_master *fsl_spi_probe(struct device *dev,
fsl_spi_grlib_probe(dev);
if (mpc8xxx_spi->flags & SPI_CPM_MODE)
master->bits_per_word_mask =
host->bits_per_word_mask =
(SPI_BPW_RANGE_MASK(4, 8) | SPI_BPW_MASK(16) | SPI_BPW_MASK(32));
else
master->bits_per_word_mask =
host->bits_per_word_mask =
(SPI_BPW_RANGE_MASK(4, 16) | SPI_BPW_MASK(32));
master->bits_per_word_mask &=
host->bits_per_word_mask &=
SPI_BPW_RANGE_MASK(1, mpc8xxx_spi->max_bits_per_word);
if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE)
@ -615,19 +615,19 @@ static struct spi_master *fsl_spi_probe(struct device *dev,
mpc8xxx_spi_write_reg(&reg_base->mode, regval);
ret = devm_spi_register_master(dev, master);
ret = devm_spi_register_controller(dev, host);
if (ret < 0)
goto err_probe;
dev_info(dev, "at 0x%p (irq = %d), %s mode\n", reg_base,
mpc8xxx_spi->irq, mpc8xxx_spi_strmode(mpc8xxx_spi->flags));
return master;
return host;
err_probe:
fsl_spi_cpm_free(mpc8xxx_spi);
err_cpm_init:
spi_master_put(master);
spi_controller_put(host);
err:
return ERR_PTR(ret);
}
@ -636,7 +636,7 @@ static int of_fsl_spi_probe(struct platform_device *ofdev)
{
struct device *dev = &ofdev->dev;
struct device_node *np = ofdev->dev.of_node;
struct spi_master *master;
struct spi_controller *host;
struct resource mem;
int irq, type;
int ret;
@ -689,9 +689,9 @@ static int of_fsl_spi_probe(struct platform_device *ofdev)
goto unmap_out;
}
master = fsl_spi_probe(dev, &mem, irq);
host = fsl_spi_probe(dev, &mem, irq);
return PTR_ERR_OR_ZERO(master);
return PTR_ERR_OR_ZERO(host);
unmap_out:
#if IS_ENABLED(CONFIG_FSL_SOC)
@ -703,8 +703,8 @@ unmap_out:
static void of_fsl_spi_remove(struct platform_device *ofdev)
{
struct spi_master *master = platform_get_drvdata(ofdev);
struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master);
struct spi_controller *host = platform_get_drvdata(ofdev);
struct mpc8xxx_spi *mpc8xxx_spi = spi_controller_get_devdata(host);
fsl_spi_cpm_free(mpc8xxx_spi);
}
@ -730,7 +730,7 @@ static int plat_mpc8xxx_spi_probe(struct platform_device *pdev)
{
struct resource *mem;
int irq;
struct spi_master *master;
struct spi_controller *host;
if (!dev_get_platdata(&pdev->dev))
return -EINVAL;
@ -740,17 +740,17 @@ static int plat_mpc8xxx_spi_probe(struct platform_device *pdev)
return -EINVAL;
irq = platform_get_irq(pdev, 0);
if (irq <= 0)
return -EINVAL;
if (irq < 0)
return irq;
master = fsl_spi_probe(&pdev->dev, mem, irq);
return PTR_ERR_OR_ZERO(master);
host = fsl_spi_probe(&pdev->dev, mem, irq);
return PTR_ERR_OR_ZERO(host);
}
static void plat_mpc8xxx_spi_remove(struct platform_device *pdev)
{
struct spi_master *master = platform_get_drvdata(pdev);
struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master);
struct spi_controller *host = platform_get_drvdata(pdev);
struct mpc8xxx_spi *mpc8xxx_spi = spi_controller_get_devdata(host);
fsl_spi_cpm_free(mpc8xxx_spi);
}

Просмотреть файл

@ -12,6 +12,7 @@
#include <linux/platform_device.h>
#include <linux/pm_opp.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include <linux/soc/qcom/geni-se.h>
#include <linux/spi/spi.h>
#include <linux/spinlock.h>
@ -52,6 +53,9 @@
#define SPI_CS_CLK_DELAY_MSK GENMASK(19, 10)
#define SPI_CS_CLK_DELAY_SHFT 10
#define SE_SPI_SLAVE_EN (0x2BC)
#define SPI_SLAVE_EN BIT(0)
/* M_CMD OP codes for SPI */
#define SPI_TX_ONLY 1
#define SPI_RX_ONLY 2
@ -99,6 +103,16 @@ struct spi_geni_master {
int cur_xfer_mode;
};
static void spi_slv_setup(struct spi_geni_master *mas)
{
struct geni_se *se = &mas->se;
writel(SPI_SLAVE_EN, se->base + SE_SPI_SLAVE_EN);
writel(GENI_IO_MUX_0_EN, se->base + GENI_OUTPUT_CTRL);
writel(START_TRIGGER, se->base + SE_GENI_CFG_SEQ_START);
dev_dbg(mas->dev, "spi slave setup done\n");
}
static int get_spi_clk_cfg(unsigned int speed_hz,
struct spi_geni_master *mas,
unsigned int *clk_idx,
@ -140,12 +154,22 @@ static void handle_se_timeout(struct spi_master *spi,
const struct spi_transfer *xfer;
spin_lock_irq(&mas->lock);
reinit_completion(&mas->cancel_done);
if (mas->cur_xfer_mode == GENI_SE_FIFO)
writel(0, se->base + SE_GENI_TX_WATERMARK_REG);
xfer = mas->cur_xfer;
mas->cur_xfer = NULL;
if (spi->slave) {
/*
* skip CMD Cancel sequnece since spi slave
* doesn`t support CMD Cancel sequnece
*/
spin_unlock_irq(&mas->lock);
goto unmap_if_dma;
}
reinit_completion(&mas->cancel_done);
geni_se_cancel_m_cmd(se);
spin_unlock_irq(&mas->lock);
@ -542,6 +566,10 @@ static bool geni_can_dma(struct spi_controller *ctlr,
if (mas->cur_xfer_mode == GENI_GPI_DMA)
return true;
/* Set SE DMA mode for SPI slave. */
if (ctlr->slave)
return true;
len = get_xfer_len_in_words(xfer, mas);
fifo_size = mas->tx_fifo_depth * mas->fifo_width_bits / mas->cur_bits_per_word;
@ -619,6 +647,7 @@ static void spi_geni_release_dma_chan(struct spi_geni_master *mas)
static int spi_geni_init(struct spi_geni_master *mas)
{
struct spi_master *spi = dev_get_drvdata(mas->dev);
struct geni_se *se = &mas->se;
unsigned int proto, major, minor, ver;
u32 spi_tx_cfg, fifo_disable;
@ -627,7 +656,14 @@ static int spi_geni_init(struct spi_geni_master *mas)
pm_runtime_get_sync(mas->dev);
proto = geni_se_read_proto(se);
if (proto != GENI_SE_SPI) {
if (spi->slave) {
if (proto != GENI_SE_SPI_SLAVE) {
dev_err(mas->dev, "Invalid proto %d\n", proto);
goto out_pm;
}
spi_slv_setup(mas);
} else if (proto != GENI_SE_SPI) {
dev_err(mas->dev, "Invalid proto %d\n", proto);
goto out_pm;
}
@ -679,9 +715,11 @@ static int spi_geni_init(struct spi_geni_master *mas)
}
/* We always control CS manually */
spi_tx_cfg = readl(se->base + SE_SPI_TRANS_CFG);
spi_tx_cfg &= ~CS_TOGGLE;
writel(spi_tx_cfg, se->base + SE_SPI_TRANS_CFG);
if (!spi->slave) {
spi_tx_cfg = readl(se->base + SE_SPI_TRANS_CFG);
spi_tx_cfg &= ~CS_TOGGLE;
writel(spi_tx_cfg, se->base + SE_SPI_TRANS_CFG);
}
out_pm:
pm_runtime_put(mas->dev);
@ -1074,6 +1112,9 @@ static int spi_geni_probe(struct platform_device *pdev)
pm_runtime_set_autosuspend_delay(&pdev->dev, 250);
pm_runtime_enable(dev);
if (device_property_read_bool(&pdev->dev, "spi-slave"))
spi->slave = true;
ret = geni_icc_get(&mas->se, NULL);
if (ret)
goto spi_geni_probe_runtime_disable;
@ -1094,7 +1135,7 @@ static int spi_geni_probe(struct platform_device *pdev)
* for dma (gsi) mode, the gsi will set cs based on params passed in
* TRE
*/
if (mas->cur_xfer_mode == GENI_SE_FIFO)
if (!spi->slave && mas->cur_xfer_mode == GENI_SE_FIFO)
spi->set_cs = spi_geni_set_cs;
/*

Просмотреть файл

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* SPI master driver using generic bitbanged GPIO
* SPI host driver using generic bitbanged GPIO
*
* Copyright (C) 2006,2008 David Brownell
* Copyright (C) 2017 Linus Walleij
@ -10,7 +10,6 @@
#include <linux/platform_device.h>
#include <linux/gpio/consumer.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
@ -18,7 +17,7 @@
/*
* This bitbanging SPI master driver should help make systems usable
* This bitbanging SPI host driver should help make systems usable
* when a native hardware SPI engine is not available, perhaps because
* its driver isn't yet working or because the I/O pins it requires
* are used for other purposes.
@ -27,7 +26,7 @@
*
* spi->controller_state ... reserved for bitbang framework code
*
* spi->master->dev.driver_data ... points to spi_gpio->bitbang
* spi->controller->dev.driver_data ... points to spi_gpio->bitbang
*/
struct spi_gpio {
@ -78,7 +77,7 @@ spi_to_spi_gpio(const struct spi_device *spi)
const struct spi_bitbang *bang;
struct spi_gpio *spi_gpio;
bang = spi_master_get_devdata(spi->master);
bang = spi_controller_get_devdata(spi->controller);
spi_gpio = container_of(bang, struct spi_gpio, bitbang);
return spi_gpio;
}
@ -170,7 +169,7 @@ static u32 spi_gpio_txrx_word_mode3(struct spi_device *spi,
/*
* These functions do not call setmosi or getmiso if respective flag
* (SPI_MASTER_NO_RX or SPI_MASTER_NO_TX) is set, so they are safe to
* (SPI_CONTROLLER_NO_RX or SPI_CONTROLLER_NO_TX) is set, so they are safe to
* call when such pin is not present or defined in the controller.
* A separate set of callbacks is defined to get highest possible
* speed in the generic case (when both MISO and MOSI lines are
@ -181,7 +180,7 @@ static u32 spi_gpio_txrx_word_mode3(struct spi_device *spi,
static u32 spi_gpio_spec_txrx_word_mode0(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits, unsigned flags)
{
flags = spi->master->flags;
flags = spi->controller->flags;
if (unlikely(spi->mode & SPI_LSB_FIRST))
return bitbang_txrx_le_cpha0(spi, nsecs, 0, flags, word, bits);
else
@ -191,7 +190,7 @@ static u32 spi_gpio_spec_txrx_word_mode0(struct spi_device *spi,
static u32 spi_gpio_spec_txrx_word_mode1(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits, unsigned flags)
{
flags = spi->master->flags;
flags = spi->controller->flags;
if (unlikely(spi->mode & SPI_LSB_FIRST))
return bitbang_txrx_le_cpha1(spi, nsecs, 0, flags, word, bits);
else
@ -201,7 +200,7 @@ static u32 spi_gpio_spec_txrx_word_mode1(struct spi_device *spi,
static u32 spi_gpio_spec_txrx_word_mode2(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits, unsigned flags)
{
flags = spi->master->flags;
flags = spi->controller->flags;
if (unlikely(spi->mode & SPI_LSB_FIRST))
return bitbang_txrx_le_cpha0(spi, nsecs, 1, flags, word, bits);
else
@ -211,7 +210,7 @@ static u32 spi_gpio_spec_txrx_word_mode2(struct spi_device *spi,
static u32 spi_gpio_spec_txrx_word_mode3(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits, unsigned flags)
{
flags = spi->master->flags;
flags = spi->controller->flags;
if (unlikely(spi->mode & SPI_LSB_FIRST))
return bitbang_txrx_le_cpha1(spi, nsecs, 1, flags, word, bits);
else
@ -311,7 +310,7 @@ static void spi_gpio_cleanup(struct spi_device *spi)
* On platforms which can do so, configure MISO with a weak pullup unless
* there's an external pullup on that signal. That saves power by avoiding
* floating signals. (A weak pulldown would save power too, but many
* drivers expect to see all-ones data as the no slave "response".)
* drivers expect to see all-ones data as the no target "response".)
*/
static int spi_gpio_request(struct device *dev, struct spi_gpio *spi_gpio)
{
@ -335,27 +334,27 @@ static const struct of_device_id spi_gpio_dt_ids[] = {
MODULE_DEVICE_TABLE(of, spi_gpio_dt_ids);
static int spi_gpio_probe_dt(struct platform_device *pdev,
struct spi_master *master)
struct spi_controller *host)
{
master->dev.of_node = pdev->dev.of_node;
master->use_gpio_descriptors = true;
host->dev.of_node = pdev->dev.of_node;
host->use_gpio_descriptors = true;
return 0;
}
#else
static inline int spi_gpio_probe_dt(struct platform_device *pdev,
struct spi_master *master)
struct spi_controller *host)
{
return 0;
}
#endif
static int spi_gpio_probe_pdata(struct platform_device *pdev,
struct spi_master *master)
struct spi_controller *host)
{
struct device *dev = &pdev->dev;
struct spi_gpio_platform_data *pdata = dev_get_platdata(dev);
struct spi_gpio *spi_gpio = spi_master_get_devdata(master);
struct spi_gpio *spi_gpio = spi_controller_get_devdata(host);
int i;
#ifdef GENERIC_BITBANG
@ -363,18 +362,18 @@ static int spi_gpio_probe_pdata(struct platform_device *pdev,
return -ENODEV;
#endif
/*
* The master needs to think there is a chipselect even if not
* The host needs to think there is a chipselect even if not
* connected
*/
master->num_chipselect = pdata->num_chipselect ?: 1;
host->num_chipselect = pdata->num_chipselect ?: 1;
spi_gpio->cs_gpios = devm_kcalloc(dev, master->num_chipselect,
spi_gpio->cs_gpios = devm_kcalloc(dev, host->num_chipselect,
sizeof(*spi_gpio->cs_gpios),
GFP_KERNEL);
if (!spi_gpio->cs_gpios)
return -ENOMEM;
for (i = 0; i < master->num_chipselect; i++) {
for (i = 0; i < host->num_chipselect; i++) {
spi_gpio->cs_gpios[i] = devm_gpiod_get_index(dev, "cs", i,
GPIOD_OUT_HIGH);
if (IS_ERR(spi_gpio->cs_gpios[i]))
@ -387,58 +386,58 @@ static int spi_gpio_probe_pdata(struct platform_device *pdev,
static int spi_gpio_probe(struct platform_device *pdev)
{
int status;
struct spi_master *master;
struct spi_controller *host;
struct spi_gpio *spi_gpio;
struct device *dev = &pdev->dev;
struct spi_bitbang *bb;
master = devm_spi_alloc_master(dev, sizeof(*spi_gpio));
if (!master)
host = devm_spi_alloc_host(dev, sizeof(*spi_gpio));
if (!host)
return -ENOMEM;
if (pdev->dev.of_node)
status = spi_gpio_probe_dt(pdev, master);
status = spi_gpio_probe_dt(pdev, host);
else
status = spi_gpio_probe_pdata(pdev, master);
status = spi_gpio_probe_pdata(pdev, host);
if (status)
return status;
spi_gpio = spi_master_get_devdata(master);
spi_gpio = spi_controller_get_devdata(host);
status = spi_gpio_request(dev, spi_gpio);
if (status)
return status;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
master->mode_bits = SPI_3WIRE | SPI_3WIRE_HIZ | SPI_CPHA | SPI_CPOL |
host->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
host->mode_bits = SPI_3WIRE | SPI_3WIRE_HIZ | SPI_CPHA | SPI_CPOL |
SPI_CS_HIGH | SPI_LSB_FIRST;
if (!spi_gpio->mosi) {
/* HW configuration without MOSI pin
*
* No setting SPI_MASTER_NO_RX here - if there is only
* No setting SPI_CONTROLLER_NO_RX here - if there is only
* a MOSI pin connected the host can still do RX by
* changing the direction of the line.
*/
master->flags = SPI_MASTER_NO_TX;
host->flags = SPI_CONTROLLER_NO_TX;
}
master->bus_num = pdev->id;
master->setup = spi_gpio_setup;
master->cleanup = spi_gpio_cleanup;
host->bus_num = pdev->id;
host->setup = spi_gpio_setup;
host->cleanup = spi_gpio_cleanup;
bb = &spi_gpio->bitbang;
bb->master = master;
bb->master = host;
/*
* There is some additional business, apart from driving the CS GPIO
* line, that we need to do on selection. This makes the local
* callback for chipselect always get called.
*/
master->flags |= SPI_MASTER_GPIO_SS;
host->flags |= SPI_CONTROLLER_GPIO_SS;
bb->chipselect = spi_gpio_chipselect;
bb->set_line_direction = spi_gpio_set_direction;
if (master->flags & SPI_MASTER_NO_TX) {
if (host->flags & SPI_CONTROLLER_NO_TX) {
bb->txrx_word[SPI_MODE_0] = spi_gpio_spec_txrx_word_mode0;
bb->txrx_word[SPI_MODE_1] = spi_gpio_spec_txrx_word_mode1;
bb->txrx_word[SPI_MODE_2] = spi_gpio_spec_txrx_word_mode2;
@ -455,7 +454,7 @@ static int spi_gpio_probe(struct platform_device *pdev)
if (status)
return status;
return devm_spi_register_master(&pdev->dev, master);
return devm_spi_register_controller(&pdev->dev, host);
}
MODULE_ALIAS("platform:" DRIVER_NAME);
@ -469,6 +468,6 @@ static struct platform_driver spi_gpio_driver = {
};
module_platform_driver(spi_gpio_driver);
MODULE_DESCRIPTION("SPI master driver using generic bitbanged GPIO ");
MODULE_DESCRIPTION("SPI host driver using generic bitbanged GPIO ");
MODULE_AUTHOR("David Brownell");
MODULE_LICENSE("GPL");

Просмотреть файл

@ -3,7 +3,6 @@
#include <linux/iopoll.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi-mem.h>
@ -200,7 +199,7 @@ static ssize_t gxp_spi_write(struct gxp_spi_chip *chip, const struct spi_mem_op
static int do_gxp_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
{
struct gxp_spi *spifi = spi_controller_get_devdata(mem->spi->master);
struct gxp_spi *spifi = spi_controller_get_devdata(mem->spi->controller);
struct gxp_spi_chip *chip = &spifi->chips[spi_get_chipselect(mem->spi, 0)];
int ret;
@ -236,7 +235,7 @@ static const struct spi_controller_mem_ops gxp_spi_mem_ops = {
static int gxp_spi_setup(struct spi_device *spi)
{
struct gxp_spi *spifi = spi_controller_get_devdata(spi->master);
struct gxp_spi *spifi = spi_controller_get_devdata(spi->controller);
unsigned int cs = spi_get_chipselect(spi, 0);
struct gxp_spi_chip *chip = &spifi->chips[cs];
@ -258,7 +257,7 @@ static int gxp_spifi_probe(struct platform_device *pdev)
data = of_device_get_match_data(&pdev->dev);
ctlr = devm_spi_alloc_master(dev, sizeof(*spifi));
ctlr = devm_spi_alloc_host(dev, sizeof(*spifi));
if (!ctlr)
return -ENOMEM;

Просмотреть файл

@ -164,10 +164,10 @@ static int hisi_spi_debugfs_init(struct hisi_spi *hs)
{
char name[32];
struct spi_controller *master;
struct spi_controller *host;
master = container_of(hs->dev, struct spi_controller, dev);
snprintf(name, 32, "hisi_spi%d", master->bus_num);
host = container_of(hs->dev, struct spi_controller, dev);
snprintf(name, 32, "hisi_spi%d", host->bus_num);
hs->debugfs = debugfs_create_dir(name, NULL);
if (IS_ERR(hs->debugfs))
return -ENOMEM;
@ -291,18 +291,18 @@ static void __hisi_calc_div_reg(struct hisi_chip_data *chip)
chip->div_post = (chip->clk_div / chip->div_pre) - 1;
}
static u32 hisi_calc_effective_speed(struct spi_controller *master,
static u32 hisi_calc_effective_speed(struct spi_controller *host,
struct hisi_chip_data *chip, u32 speed_hz)
{
u32 effective_speed;
/* Note clock divider doesn't support odd numbers */
chip->clk_div = DIV_ROUND_UP(master->max_speed_hz, speed_hz) + 1;
chip->clk_div = DIV_ROUND_UP(host->max_speed_hz, speed_hz) + 1;
chip->clk_div &= 0xfffe;
if (chip->clk_div > CLK_DIV_MAX)
chip->clk_div = CLK_DIV_MAX;
effective_speed = master->max_speed_hz / chip->clk_div;
effective_speed = host->max_speed_hz / chip->clk_div;
if (chip->speed_hz != effective_speed) {
__hisi_calc_div_reg(chip);
chip->speed_hz = effective_speed;
@ -336,20 +336,20 @@ static void hisi_spi_hw_init(struct hisi_spi *hs)
static irqreturn_t hisi_spi_irq(int irq, void *dev_id)
{
struct spi_controller *master = dev_id;
struct hisi_spi *hs = spi_controller_get_devdata(master);
struct spi_controller *host = dev_id;
struct hisi_spi *hs = spi_controller_get_devdata(host);
u32 irq_status = readl(hs->regs + HISI_SPI_ISR) & ISR_MASK;
if (!irq_status)
return IRQ_NONE;
if (!master->cur_msg)
if (!host->cur_msg)
return IRQ_HANDLED;
/* Error handling */
if (irq_status & ISR_RXOF) {
dev_err(hs->dev, "interrupt_transfer: fifo overflow\n");
master->cur_msg->status = -EIO;
host->cur_msg->status = -EIO;
goto finalize_transfer;
}
@ -369,20 +369,20 @@ static irqreturn_t hisi_spi_irq(int irq, void *dev_id)
finalize_transfer:
hisi_spi_disable(hs);
spi_finalize_current_transfer(master);
spi_finalize_current_transfer(host);
return IRQ_HANDLED;
}
static int hisi_spi_transfer_one(struct spi_controller *master,
static int hisi_spi_transfer_one(struct spi_controller *host,
struct spi_device *spi, struct spi_transfer *transfer)
{
struct hisi_spi *hs = spi_controller_get_devdata(master);
struct hisi_spi *hs = spi_controller_get_devdata(host);
struct hisi_chip_data *chip = spi_get_ctldata(spi);
u32 cr = chip->cr;
/* Update per transfer options for speed and bpw */
transfer->effective_speed_hz =
hisi_calc_effective_speed(master, chip, transfer->speed_hz);
hisi_calc_effective_speed(host, chip, transfer->speed_hz);
cr |= FIELD_PREP(CR_DIV_PRE_MASK, chip->div_pre);
cr |= FIELD_PREP(CR_DIV_POST_MASK, chip->div_post);
cr |= FIELD_PREP(CR_BPW_MASK, transfer->bits_per_word - 1);
@ -409,10 +409,10 @@ static int hisi_spi_transfer_one(struct spi_controller *master,
return 1;
}
static void hisi_spi_handle_err(struct spi_controller *master,
static void hisi_spi_handle_err(struct spi_controller *host,
struct spi_message *msg)
{
struct hisi_spi *hs = spi_controller_get_devdata(master);
struct hisi_spi *hs = spi_controller_get_devdata(host);
hisi_spi_disable(hs);
@ -452,7 +452,7 @@ static void hisi_spi_cleanup(struct spi_device *spi)
static int hisi_spi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct spi_controller *master;
struct spi_controller *host;
struct hisi_spi *hs;
int ret, irq;
@ -460,13 +460,13 @@ static int hisi_spi_probe(struct platform_device *pdev)
if (irq < 0)
return irq;
master = devm_spi_alloc_master(dev, sizeof(*hs));
if (!master)
host = devm_spi_alloc_host(dev, sizeof(*hs));
if (!host)
return -ENOMEM;
platform_set_drvdata(pdev, master);
platform_set_drvdata(pdev, host);
hs = spi_controller_get_devdata(master);
hs = spi_controller_get_devdata(host);
hs->dev = dev;
hs->irq = irq;
@ -474,9 +474,9 @@ static int hisi_spi_probe(struct platform_device *pdev)
if (IS_ERR(hs->regs))
return PTR_ERR(hs->regs);
/* Specify maximum SPI clocking speed (master only) by firmware */
/* Specify maximum SPI clocking speed (host only) by firmware */
ret = device_property_read_u32(dev, "spi-max-frequency",
&master->max_speed_hz);
&host->max_speed_hz);
if (ret) {
dev_err(dev, "failed to get max SPI clocking speed, ret=%d\n",
ret);
@ -484,32 +484,32 @@ static int hisi_spi_probe(struct platform_device *pdev)
}
ret = device_property_read_u16(dev, "num-cs",
&master->num_chipselect);
&host->num_chipselect);
if (ret)
master->num_chipselect = DEFAULT_NUM_CS;
host->num_chipselect = DEFAULT_NUM_CS;
master->use_gpio_descriptors = true;
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
master->bus_num = pdev->id;
master->setup = hisi_spi_setup;
master->cleanup = hisi_spi_cleanup;
master->transfer_one = hisi_spi_transfer_one;
master->handle_err = hisi_spi_handle_err;
master->dev.fwnode = dev->fwnode;
host->use_gpio_descriptors = true;
host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
host->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
host->bus_num = pdev->id;
host->setup = hisi_spi_setup;
host->cleanup = hisi_spi_cleanup;
host->transfer_one = hisi_spi_transfer_one;
host->handle_err = hisi_spi_handle_err;
host->dev.fwnode = dev->fwnode;
hisi_spi_hw_init(hs);
ret = devm_request_irq(dev, hs->irq, hisi_spi_irq, 0, dev_name(dev),
master);
host);
if (ret < 0) {
dev_err(dev, "failed to get IRQ=%d, ret=%d\n", hs->irq, ret);
return ret;
}
ret = spi_register_controller(master);
ret = spi_register_controller(host);
if (ret) {
dev_err(dev, "failed to register spi master, ret=%d\n", ret);
dev_err(dev, "failed to register spi host, ret=%d\n", ret);
return ret;
}
@ -518,18 +518,18 @@ static int hisi_spi_probe(struct platform_device *pdev)
dev_info(dev, "hw version:0x%x max-freq:%u kHz\n",
readl(hs->regs + HISI_SPI_VERSION),
master->max_speed_hz / 1000);
host->max_speed_hz / 1000);
return 0;
}
static void hisi_spi_remove(struct platform_device *pdev)
{
struct spi_controller *master = platform_get_drvdata(pdev);
struct hisi_spi *hs = spi_controller_get_devdata(master);
struct spi_controller *host = platform_get_drvdata(pdev);
struct hisi_spi *hs = spi_controller_get_devdata(host);
debugfs_remove_recursive(hs->debugfs);
spi_unregister_controller(master);
spi_unregister_controller(host);
}
static const struct acpi_device_id hisi_spi_acpi_match[] = {

Просмотреть файл

@ -152,7 +152,7 @@ static int hisi_sfc_v3xx_adjust_op_size(struct spi_mem *mem,
uintptr_t addr = (uintptr_t)op->data.buf.in;
int max_byte_count;
host = spi_controller_get_devdata(spi->master);
host = spi_controller_get_devdata(spi->controller);
max_byte_count = host->max_cmd_dword * 4;
@ -174,7 +174,7 @@ static bool hisi_sfc_v3xx_supports_op(struct spi_mem *mem,
struct spi_device *spi = mem->spi;
struct hisi_sfc_v3xx_host *host;
host = spi_controller_get_devdata(spi->master);
host = spi_controller_get_devdata(spi->controller);
if (op->data.buswidth > 4 || op->dummy.buswidth > 4 ||
op->addr.buswidth > 4 || op->cmd.buswidth > 4)
@ -363,7 +363,7 @@ static int hisi_sfc_v3xx_exec_op(struct spi_mem *mem,
struct spi_device *spi = mem->spi;
u8 chip_select = spi_get_chipselect(spi, 0);
host = spi_controller_get_devdata(spi->master);
host = spi_controller_get_devdata(spi->controller);
return hisi_sfc_v3xx_generic_exec_op(host, op, chip_select);
}
@ -431,7 +431,7 @@ static int hisi_sfc_v3xx_probe(struct platform_device *pdev)
u32 version, glb_config;
int ret;
ctlr = spi_alloc_master(&pdev->dev, sizeof(*host));
ctlr = spi_alloc_host(&pdev->dev, sizeof(*host));
if (!ctlr)
return -ENOMEM;
@ -448,13 +448,13 @@ static int hisi_sfc_v3xx_probe(struct platform_device *pdev)
host->regbase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(host->regbase)) {
ret = PTR_ERR(host->regbase);
goto err_put_master;
goto err_put_host;
}
host->irq = platform_get_irq_optional(pdev, 0);
if (host->irq == -EPROBE_DEFER) {
ret = -EPROBE_DEFER;
goto err_put_master;
goto err_put_host;
}
hisi_sfc_v3xx_disable_int(host);
@ -496,15 +496,15 @@ static int hisi_sfc_v3xx_probe(struct platform_device *pdev)
ret = devm_spi_register_controller(dev, ctlr);
if (ret)
goto err_put_master;
goto err_put_host;
dev_info(&pdev->dev, "hw version 0x%x, %s mode.\n",
version, host->irq ? "irq" : "polling");
return 0;
err_put_master:
spi_master_put(ctlr);
err_put_host:
spi_controller_put(ctlr);
return ret;
}

Просмотреть файл

@ -86,7 +86,7 @@
struct img_spfi {
struct device *dev;
struct spi_master *master;
struct spi_controller *host;
spinlock_t lock;
void __iomem *regs;
@ -221,11 +221,11 @@ static unsigned int spfi_pio_read8(struct img_spfi *spfi, u8 *buf,
return count;
}
static int img_spfi_start_pio(struct spi_master *master,
static int img_spfi_start_pio(struct spi_controller *host,
struct spi_device *spi,
struct spi_transfer *xfer)
{
struct img_spfi *spfi = spi_master_get_devdata(spi->master);
struct img_spfi *spfi = spi_controller_get_devdata(spi->controller);
unsigned int tx_bytes = 0, rx_bytes = 0;
const void *tx_buf = xfer->tx_buf;
void *rx_buf = xfer->rx_buf;
@ -285,7 +285,7 @@ static void img_spfi_dma_rx_cb(void *data)
spin_lock_irqsave(&spfi->lock, flags);
spfi->rx_dma_busy = false;
if (!spfi->tx_dma_busy)
spi_finalize_current_transfer(spfi->master);
spi_finalize_current_transfer(spfi->host);
spin_unlock_irqrestore(&spfi->lock, flags);
}
@ -299,15 +299,15 @@ static void img_spfi_dma_tx_cb(void *data)
spin_lock_irqsave(&spfi->lock, flags);
spfi->tx_dma_busy = false;
if (!spfi->rx_dma_busy)
spi_finalize_current_transfer(spfi->master);
spi_finalize_current_transfer(spfi->host);
spin_unlock_irqrestore(&spfi->lock, flags);
}
static int img_spfi_start_dma(struct spi_master *master,
static int img_spfi_start_dma(struct spi_controller *host,
struct spi_device *spi,
struct spi_transfer *xfer)
{
struct img_spfi *spfi = spi_master_get_devdata(spi->master);
struct img_spfi *spfi = spi_controller_get_devdata(spi->controller);
struct dma_async_tx_descriptor *rxdesc = NULL, *txdesc = NULL;
struct dma_slave_config rxconf, txconf;
@ -384,10 +384,10 @@ stop_dma:
return -EIO;
}
static void img_spfi_handle_err(struct spi_master *master,
static void img_spfi_handle_err(struct spi_controller *host,
struct spi_message *msg)
{
struct img_spfi *spfi = spi_master_get_devdata(master);
struct img_spfi *spfi = spi_controller_get_devdata(host);
unsigned long flags;
/*
@ -405,9 +405,9 @@ static void img_spfi_handle_err(struct spi_master *master,
spin_unlock_irqrestore(&spfi->lock, flags);
}
static int img_spfi_prepare(struct spi_master *master, struct spi_message *msg)
static int img_spfi_prepare(struct spi_controller *host, struct spi_message *msg)
{
struct img_spfi *spfi = spi_master_get_devdata(master);
struct img_spfi *spfi = spi_controller_get_devdata(host);
u32 val;
val = spfi_readl(spfi, SPFI_PORT_STATE);
@ -427,20 +427,20 @@ static int img_spfi_prepare(struct spi_master *master, struct spi_message *msg)
return 0;
}
static int img_spfi_unprepare(struct spi_master *master,
static int img_spfi_unprepare(struct spi_controller *host,
struct spi_message *msg)
{
struct img_spfi *spfi = spi_master_get_devdata(master);
struct img_spfi *spfi = spi_controller_get_devdata(host);
spfi_reset(spfi);
return 0;
}
static void img_spfi_config(struct spi_master *master, struct spi_device *spi,
static void img_spfi_config(struct spi_controller *host, struct spi_device *spi,
struct spi_transfer *xfer)
{
struct img_spfi *spfi = spi_master_get_devdata(spi->master);
struct img_spfi *spfi = spi_controller_get_devdata(spi->controller);
u32 val, div;
/*
@ -476,11 +476,11 @@ static void img_spfi_config(struct spi_master *master, struct spi_device *spi,
spfi_writel(spfi, val, SPFI_CONTROL);
}
static int img_spfi_transfer_one(struct spi_master *master,
static int img_spfi_transfer_one(struct spi_controller *host,
struct spi_device *spi,
struct spi_transfer *xfer)
{
struct img_spfi *spfi = spi_master_get_devdata(spi->master);
struct img_spfi *spfi = spi_controller_get_devdata(spi->controller);
int ret;
if (xfer->len > SPFI_TRANSACTION_TSIZE_MASK) {
@ -490,16 +490,16 @@ static int img_spfi_transfer_one(struct spi_master *master,
return -EINVAL;
}
img_spfi_config(master, spi, xfer);
if (master->can_dma && master->can_dma(master, spi, xfer))
ret = img_spfi_start_dma(master, spi, xfer);
img_spfi_config(host, spi, xfer);
if (host->can_dma && host->can_dma(host, spi, xfer))
ret = img_spfi_start_dma(host, spi, xfer);
else
ret = img_spfi_start_pio(master, spi, xfer);
ret = img_spfi_start_pio(host, spi, xfer);
return ret;
}
static bool img_spfi_can_dma(struct spi_master *master, struct spi_device *spi,
static bool img_spfi_can_dma(struct spi_controller *host, struct spi_device *spi,
struct spi_transfer *xfer)
{
if (xfer->len > SPFI_32BIT_FIFO_SIZE)
@ -524,20 +524,20 @@ static irqreturn_t img_spfi_irq(int irq, void *dev_id)
static int img_spfi_probe(struct platform_device *pdev)
{
struct spi_master *master;
struct spi_controller *host;
struct img_spfi *spfi;
struct resource *res;
int ret;
u32 max_speed_hz;
master = spi_alloc_master(&pdev->dev, sizeof(*spfi));
if (!master)
host = spi_alloc_host(&pdev->dev, sizeof(*spfi));
if (!host)
return -ENOMEM;
platform_set_drvdata(pdev, master);
platform_set_drvdata(pdev, host);
spfi = spi_master_get_devdata(master);
spfi = spi_controller_get_devdata(host);
spfi->dev = &pdev->dev;
spfi->master = master;
spfi->host = host;
spin_lock_init(&spfi->lock);
spfi->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
@ -582,15 +582,15 @@ static int img_spfi_probe(struct platform_device *pdev)
*/
spfi_writel(spfi, SPFI_INTERRUPT_IACCESS, SPFI_INTERRUPT_ENABLE);
master->auto_runtime_pm = true;
master->bus_num = pdev->id;
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_TX_DUAL | SPI_RX_DUAL;
host->auto_runtime_pm = true;
host->bus_num = pdev->id;
host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_TX_DUAL | SPI_RX_DUAL;
if (of_property_read_bool(spfi->dev->of_node, "img,supports-quad-mode"))
master->mode_bits |= SPI_TX_QUAD | SPI_RX_QUAD;
master->dev.of_node = pdev->dev.of_node;
master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(8);
master->max_speed_hz = clk_get_rate(spfi->spfi_clk) / 4;
master->min_speed_hz = clk_get_rate(spfi->spfi_clk) / 512;
host->mode_bits |= SPI_TX_QUAD | SPI_RX_QUAD;
host->dev.of_node = pdev->dev.of_node;
host->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(8);
host->max_speed_hz = clk_get_rate(spfi->spfi_clk) / 4;
host->min_speed_hz = clk_get_rate(spfi->spfi_clk) / 512;
/*
* Maximum speed supported by spfi is limited to the lower value
@ -601,15 +601,15 @@ static int img_spfi_probe(struct platform_device *pdev)
*/
if (!of_property_read_u32(spfi->dev->of_node, "spfi-max-frequency",
&max_speed_hz)) {
if (master->max_speed_hz > max_speed_hz)
master->max_speed_hz = max_speed_hz;
if (host->max_speed_hz > max_speed_hz)
host->max_speed_hz = max_speed_hz;
}
master->transfer_one = img_spfi_transfer_one;
master->prepare_message = img_spfi_prepare;
master->unprepare_message = img_spfi_unprepare;
master->handle_err = img_spfi_handle_err;
master->use_gpio_descriptors = true;
host->transfer_one = img_spfi_transfer_one;
host->prepare_message = img_spfi_prepare;
host->unprepare_message = img_spfi_unprepare;
host->handle_err = img_spfi_handle_err;
host->use_gpio_descriptors = true;
spfi->tx_ch = dma_request_chan(spfi->dev, "tx");
if (IS_ERR(spfi->tx_ch)) {
@ -636,15 +636,15 @@ static int img_spfi_probe(struct platform_device *pdev)
spfi->rx_ch = NULL;
dev_warn(spfi->dev, "Failed to get DMA channels, falling back to PIO mode\n");
} else {
master->dma_tx = spfi->tx_ch;
master->dma_rx = spfi->rx_ch;
master->can_dma = img_spfi_can_dma;
host->dma_tx = spfi->tx_ch;
host->dma_rx = spfi->rx_ch;
host->can_dma = img_spfi_can_dma;
}
pm_runtime_set_active(spfi->dev);
pm_runtime_enable(spfi->dev);
ret = devm_spi_register_master(spfi->dev, master);
ret = devm_spi_register_controller(spfi->dev, host);
if (ret)
goto disable_pm;
@ -660,15 +660,15 @@ disable_pm:
disable_pclk:
clk_disable_unprepare(spfi->sys_clk);
put_spi:
spi_master_put(master);
spi_controller_put(host);
return ret;
}
static void img_spfi_remove(struct platform_device *pdev)
{
struct spi_master *master = platform_get_drvdata(pdev);
struct img_spfi *spfi = spi_master_get_devdata(master);
struct spi_controller *host = platform_get_drvdata(pdev);
struct img_spfi *spfi = spi_controller_get_devdata(host);
if (spfi->tx_ch)
dma_release_channel(spfi->tx_ch);
@ -685,8 +685,8 @@ static void img_spfi_remove(struct platform_device *pdev)
#ifdef CONFIG_PM
static int img_spfi_runtime_suspend(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct img_spfi *spfi = spi_master_get_devdata(master);
struct spi_controller *host = dev_get_drvdata(dev);
struct img_spfi *spfi = spi_controller_get_devdata(host);
clk_disable_unprepare(spfi->spfi_clk);
clk_disable_unprepare(spfi->sys_clk);
@ -696,8 +696,8 @@ static int img_spfi_runtime_suspend(struct device *dev)
static int img_spfi_runtime_resume(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct img_spfi *spfi = spi_master_get_devdata(master);
struct spi_controller *host = dev_get_drvdata(dev);
struct img_spfi *spfi = spi_controller_get_devdata(host);
int ret;
ret = clk_prepare_enable(spfi->sys_clk);
@ -716,15 +716,15 @@ static int img_spfi_runtime_resume(struct device *dev)
#ifdef CONFIG_PM_SLEEP
static int img_spfi_suspend(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct spi_controller *host = dev_get_drvdata(dev);
return spi_master_suspend(master);
return spi_controller_suspend(host);
}
static int img_spfi_resume(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct img_spfi *spfi = spi_master_get_devdata(master);
struct spi_controller *host = dev_get_drvdata(dev);
struct img_spfi *spfi = spi_controller_get_devdata(host);
int ret;
ret = pm_runtime_resume_and_get(dev);
@ -733,7 +733,7 @@ static int img_spfi_resume(struct device *dev)
spfi_reset(spfi);
pm_runtime_put(dev);
return spi_master_resume(master);
return spi_controller_resume(host);
}
#endif /* CONFIG_PM_SLEEP */

Просмотреть файл

@ -20,7 +20,6 @@
#include <linux/spi/spi.h>
#include <linux/types.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/property.h>
#include <linux/dma/imx-dma.h>
@ -53,7 +52,7 @@ MODULE_PARM_DESC(polling_limit_us,
/* The maximum bytes that a sdma BD can transfer. */
#define MAX_SDMA_BD_BYTES (1 << 15)
#define MX51_ECSPI_CTRL_MAX_BURST 512
/* The maximum bytes that IMX53_ECSPI can transfer in slave mode.*/
/* The maximum bytes that IMX53_ECSPI can transfer in target mode.*/
#define MX53_MAX_TRANSFER_BYTES 512
enum spi_imx_devtype {
@ -78,7 +77,7 @@ struct spi_imx_devtype_data {
void (*setup_wml)(struct spi_imx_data *spi_imx);
void (*disable)(struct spi_imx_data *spi_imx);
bool has_dmamode;
bool has_slavemode;
bool has_targetmode;
unsigned int fifo_size;
bool dynamic_burst;
/*
@ -114,10 +113,10 @@ struct spi_imx_data {
unsigned int dynamic_burst;
bool rx_only;
/* Slave mode */
bool slave_mode;
bool slave_aborted;
unsigned int slave_burst;
/* Target mode */
bool target_mode;
bool target_aborted;
unsigned int target_burst;
/* DMA */
bool usedma;
@ -241,7 +240,7 @@ static bool spi_imx_can_dma(struct spi_controller *controller, struct spi_device
if (!controller->dma_rx)
return false;
if (spi_imx->slave_mode)
if (spi_imx->target_mode)
return false;
if (transfer->len < spi_imx->devtype_data->fifo_size)
@ -405,12 +404,12 @@ static void spi_imx_buf_tx_swap(struct spi_imx_data *spi_imx)
writel(val, spi_imx->base + MXC_CSPITXDATA);
}
static void mx53_ecspi_rx_slave(struct spi_imx_data *spi_imx)
static void mx53_ecspi_rx_target(struct spi_imx_data *spi_imx)
{
u32 val = be32_to_cpu(readl(spi_imx->base + MXC_CSPIRXDATA));
if (spi_imx->rx_buf) {
int n_bytes = spi_imx->slave_burst % sizeof(val);
int n_bytes = spi_imx->target_burst % sizeof(val);
if (!n_bytes)
n_bytes = sizeof(val);
@ -419,13 +418,13 @@ static void mx53_ecspi_rx_slave(struct spi_imx_data *spi_imx)
((u8 *)&val) + sizeof(val) - n_bytes, n_bytes);
spi_imx->rx_buf += n_bytes;
spi_imx->slave_burst -= n_bytes;
spi_imx->target_burst -= n_bytes;
}
spi_imx->remainder -= sizeof(u32);
}
static void mx53_ecspi_tx_slave(struct spi_imx_data *spi_imx)
static void mx53_ecspi_tx_target(struct spi_imx_data *spi_imx)
{
u32 val = 0;
int n_bytes = spi_imx->count % sizeof(val);
@ -536,8 +535,8 @@ static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx,
u32 current_cfg = cfg;
int channel = mx51_ecspi_channel(spi);
/* set Master or Slave mode */
if (spi_imx->slave_mode)
/* set Host or Target mode */
if (spi_imx->target_mode)
ctrl &= ~MX51_ECSPI_CTRL_MODE_MASK;
else
ctrl |= MX51_ECSPI_CTRL_MODE_MASK;
@ -565,11 +564,11 @@ static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx,
writel(testreg, spi_imx->base + MX51_ECSPI_TESTREG);
/*
* eCSPI burst completion by Chip Select signal in Slave mode
* eCSPI burst completion by Chip Select signal in Target mode
* is not functional for imx53 Soc, config SPI burst completed when
* BURST_LENGTH + 1 bits are received
*/
if (spi_imx->slave_mode && is_imx53_ecspi(spi_imx))
if (spi_imx->target_mode && is_imx53_ecspi(spi_imx))
cfg &= ~MX51_ECSPI_CONFIG_SBBCTRL(channel);
else
cfg |= MX51_ECSPI_CONFIG_SBBCTRL(channel);
@ -656,12 +655,16 @@ static int mx51_ecspi_prepare_transfer(struct spi_imx_data *spi_imx,
/* Clear BL field and set the right value */
ctrl &= ~MX51_ECSPI_CTRL_BL_MASK;
if (spi_imx->slave_mode && is_imx53_ecspi(spi_imx))
ctrl |= (spi_imx->slave_burst * 8 - 1)
<< MX51_ECSPI_CTRL_BL_OFFSET;
else
ctrl |= (spi_imx->bits_per_word - 1)
if (spi_imx->target_mode && is_imx53_ecspi(spi_imx))
ctrl |= (spi_imx->target_burst * 8 - 1)
<< MX51_ECSPI_CTRL_BL_OFFSET;
else {
if (spi_imx->count >= 512)
ctrl |= 0xFFF << MX51_ECSPI_CTRL_BL_OFFSET;
else
ctrl |= (spi_imx->count*8 - 1)
<< MX51_ECSPI_CTRL_BL_OFFSET;
}
/* set clock speed */
ctrl &= ~(0xf << MX51_ECSPI_CTRL_POSTDIV_OFFSET |
@ -718,7 +721,7 @@ static void mx51_ecspi_reset(struct spi_imx_data *spi_imx)
#define MX31_INTREG_RREN (1 << 3)
#define MX31_CSPICTRL_ENABLE (1 << 0)
#define MX31_CSPICTRL_MASTER (1 << 1)
#define MX31_CSPICTRL_HOST (1 << 1)
#define MX31_CSPICTRL_XCH (1 << 2)
#define MX31_CSPICTRL_SMC (1 << 3)
#define MX31_CSPICTRL_POL (1 << 4)
@ -775,7 +778,7 @@ static int mx31_prepare_message(struct spi_imx_data *spi_imx,
static int mx31_prepare_transfer(struct spi_imx_data *spi_imx,
struct spi_device *spi)
{
unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER;
unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_HOST;
unsigned int clk;
reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, spi_imx->spi_bus_clk, &clk) <<
@ -845,7 +848,7 @@ static void mx31_reset(struct spi_imx_data *spi_imx)
#define MX21_CSPICTRL_SSPOL (1 << 8)
#define MX21_CSPICTRL_XCH (1 << 9)
#define MX21_CSPICTRL_ENABLE (1 << 10)
#define MX21_CSPICTRL_MASTER (1 << 11)
#define MX21_CSPICTRL_HOST (1 << 11)
#define MX21_CSPICTRL_DR_SHIFT 14
#define MX21_CSPICTRL_CS_SHIFT 19
@ -879,7 +882,7 @@ static int mx21_prepare_message(struct spi_imx_data *spi_imx,
static int mx21_prepare_transfer(struct spi_imx_data *spi_imx,
struct spi_device *spi)
{
unsigned int reg = MX21_CSPICTRL_ENABLE | MX21_CSPICTRL_MASTER;
unsigned int reg = MX21_CSPICTRL_ENABLE | MX21_CSPICTRL_HOST;
unsigned int max = is_imx27_cspi(spi_imx) ? 16 : 18;
unsigned int clk;
@ -921,7 +924,7 @@ static void mx21_reset(struct spi_imx_data *spi_imx)
#define MX1_CSPICTRL_PHA (1 << 5)
#define MX1_CSPICTRL_XCH (1 << 8)
#define MX1_CSPICTRL_ENABLE (1 << 9)
#define MX1_CSPICTRL_MASTER (1 << 10)
#define MX1_CSPICTRL_HOST (1 << 10)
#define MX1_CSPICTRL_DR_SHIFT 13
static void mx1_intctrl(struct spi_imx_data *spi_imx, int enable)
@ -954,7 +957,7 @@ static int mx1_prepare_message(struct spi_imx_data *spi_imx,
static int mx1_prepare_transfer(struct spi_imx_data *spi_imx,
struct spi_device *spi)
{
unsigned int reg = MX1_CSPICTRL_ENABLE | MX1_CSPICTRL_MASTER;
unsigned int reg = MX1_CSPICTRL_ENABLE | MX1_CSPICTRL_HOST;
unsigned int clk;
reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, spi_imx->spi_bus_clk, &clk) <<
@ -993,7 +996,7 @@ static struct spi_imx_devtype_data imx1_cspi_devtype_data = {
.fifo_size = 8,
.has_dmamode = false,
.dynamic_burst = false,
.has_slavemode = false,
.has_targetmode = false,
.devtype = IMX1_CSPI,
};
@ -1007,7 +1010,7 @@ static struct spi_imx_devtype_data imx21_cspi_devtype_data = {
.fifo_size = 8,
.has_dmamode = false,
.dynamic_burst = false,
.has_slavemode = false,
.has_targetmode = false,
.devtype = IMX21_CSPI,
};
@ -1022,7 +1025,7 @@ static struct spi_imx_devtype_data imx27_cspi_devtype_data = {
.fifo_size = 8,
.has_dmamode = false,
.dynamic_burst = false,
.has_slavemode = false,
.has_targetmode = false,
.devtype = IMX27_CSPI,
};
@ -1036,7 +1039,7 @@ static struct spi_imx_devtype_data imx31_cspi_devtype_data = {
.fifo_size = 8,
.has_dmamode = false,
.dynamic_burst = false,
.has_slavemode = false,
.has_targetmode = false,
.devtype = IMX31_CSPI,
};
@ -1051,7 +1054,7 @@ static struct spi_imx_devtype_data imx35_cspi_devtype_data = {
.fifo_size = 8,
.has_dmamode = true,
.dynamic_burst = false,
.has_slavemode = false,
.has_targetmode = false,
.devtype = IMX35_CSPI,
};
@ -1066,7 +1069,7 @@ static struct spi_imx_devtype_data imx51_ecspi_devtype_data = {
.fifo_size = 64,
.has_dmamode = true,
.dynamic_burst = true,
.has_slavemode = true,
.has_targetmode = true,
.disable = mx51_ecspi_disable,
.devtype = IMX51_ECSPI,
};
@ -1080,7 +1083,7 @@ static struct spi_imx_devtype_data imx53_ecspi_devtype_data = {
.reset = mx51_ecspi_reset,
.fifo_size = 64,
.has_dmamode = true,
.has_slavemode = true,
.has_targetmode = true,
.disable = mx51_ecspi_disable,
.devtype = IMX53_ECSPI,
};
@ -1096,7 +1099,7 @@ static struct spi_imx_devtype_data imx6ul_ecspi_devtype_data = {
.fifo_size = 64,
.has_dmamode = true,
.dynamic_burst = true,
.has_slavemode = true,
.has_targetmode = true,
.tx_glitch_fixed = true,
.disable = mx51_ecspi_disable,
.devtype = IMX51_ECSPI,
@ -1161,7 +1164,7 @@ static void spi_imx_push(struct spi_imx_data *spi_imx)
spi_imx->txfifo++;
}
if (!spi_imx->slave_mode)
if (!spi_imx->target_mode)
spi_imx->devtype_data->trigger(spi_imx);
}
@ -1258,13 +1261,14 @@ static int spi_imx_setupxfer(struct spi_device *spi,
spi_imx->spi_bus_clk = t->speed_hz;
spi_imx->bits_per_word = t->bits_per_word;
spi_imx->count = t->len;
/*
* Initialize the functions for transfer. To transfer non byte-aligned
* words, we have to use multiple word-size bursts, we can't use
* dynamic_burst in that case.
*/
if (spi_imx->devtype_data->dynamic_burst && !spi_imx->slave_mode &&
if (spi_imx->devtype_data->dynamic_burst && !spi_imx->target_mode &&
!(spi->mode & SPI_CS_WORD) &&
(spi_imx->bits_per_word == 8 ||
spi_imx->bits_per_word == 16 ||
@ -1296,10 +1300,10 @@ static int spi_imx_setupxfer(struct spi_device *spi,
spi_imx->rx_only = ((t->tx_buf == NULL)
|| (t->tx_buf == spi->controller->dummy_tx));
if (is_imx53_ecspi(spi_imx) && spi_imx->slave_mode) {
spi_imx->rx = mx53_ecspi_rx_slave;
spi_imx->tx = mx53_ecspi_tx_slave;
spi_imx->slave_burst = t->len;
if (is_imx53_ecspi(spi_imx) && spi_imx->target_mode) {
spi_imx->rx = mx53_ecspi_rx_target;
spi_imx->tx = mx53_ecspi_tx_target;
spi_imx->target_burst = t->len;
}
spi_imx->devtype_data->prepare_transfer(spi_imx, spi);
@ -1564,8 +1568,8 @@ static int spi_imx_poll_transfer(struct spi_device *spi,
return 0;
}
static int spi_imx_pio_transfer_slave(struct spi_device *spi,
struct spi_transfer *transfer)
static int spi_imx_pio_transfer_target(struct spi_device *spi,
struct spi_transfer *transfer)
{
struct spi_imx_data *spi_imx = spi_controller_get_devdata(spi->controller);
int ret = 0;
@ -1584,22 +1588,22 @@ static int spi_imx_pio_transfer_slave(struct spi_device *spi,
spi_imx->remainder = 0;
reinit_completion(&spi_imx->xfer_done);
spi_imx->slave_aborted = false;
spi_imx->target_aborted = false;
spi_imx_push(spi_imx);
spi_imx->devtype_data->intctrl(spi_imx, MXC_INT_TE | MXC_INT_RDR);
if (wait_for_completion_interruptible(&spi_imx->xfer_done) ||
spi_imx->slave_aborted) {
spi_imx->target_aborted) {
dev_dbg(&spi->dev, "interrupted\n");
ret = -EINTR;
}
/* ecspi has a HW issue when works in Slave mode,
/* ecspi has a HW issue when works in Target mode,
* after 64 words writtern to TXFIFO, even TXFIFO becomes empty,
* ECSPI_TXDATA keeps shift out the last word data,
* so we have to disable ECSPI when in slave mode after the
* so we have to disable ECSPI when in target mode after the
* transfer completes
*/
if (spi_imx->devtype_data->disable)
@ -1622,8 +1626,8 @@ static int spi_imx_transfer_one(struct spi_controller *controller,
while (spi_imx->devtype_data->rx_available(spi_imx))
readl(spi_imx->base + MXC_CSPIRXDATA);
if (spi_imx->slave_mode)
return spi_imx_pio_transfer_slave(spi, transfer);
if (spi_imx->target_mode)
return spi_imx_pio_transfer_target(spi, transfer);
/*
* If we decided in spi_imx_can_dma() that we want to do a DMA
@ -1689,11 +1693,11 @@ spi_imx_unprepare_message(struct spi_controller *controller, struct spi_message
return 0;
}
static int spi_imx_slave_abort(struct spi_controller *controller)
static int spi_imx_target_abort(struct spi_controller *controller)
{
struct spi_imx_data *spi_imx = spi_controller_get_devdata(controller);
spi_imx->slave_aborted = true;
spi_imx->target_aborted = true;
complete(&spi_imx->xfer_done);
return 0;
@ -1708,17 +1712,17 @@ static int spi_imx_probe(struct platform_device *pdev)
int ret, irq, spi_drctl;
const struct spi_imx_devtype_data *devtype_data =
of_device_get_match_data(&pdev->dev);
bool slave_mode;
bool target_mode;
u32 val;
slave_mode = devtype_data->has_slavemode &&
of_property_read_bool(np, "spi-slave");
if (slave_mode)
controller = spi_alloc_slave(&pdev->dev,
sizeof(struct spi_imx_data));
else
controller = spi_alloc_master(&pdev->dev,
target_mode = devtype_data->has_targetmode &&
of_property_read_bool(np, "spi-slave");
if (target_mode)
controller = spi_alloc_target(&pdev->dev,
sizeof(struct spi_imx_data));
else
controller = spi_alloc_host(&pdev->dev,
sizeof(struct spi_imx_data));
if (!controller)
return -ENOMEM;
@ -1737,7 +1741,7 @@ static int spi_imx_probe(struct platform_device *pdev)
spi_imx = spi_controller_get_devdata(controller);
spi_imx->controller = controller;
spi_imx->dev = &pdev->dev;
spi_imx->slave_mode = slave_mode;
spi_imx->target_mode = target_mode;
spi_imx->devtype_data = devtype_data;
@ -1757,7 +1761,7 @@ static int spi_imx_probe(struct platform_device *pdev)
controller->cleanup = spi_imx_cleanup;
controller->prepare_message = spi_imx_prepare_message;
controller->unprepare_message = spi_imx_unprepare_message;
controller->slave_abort = spi_imx_slave_abort;
controller->target_abort = spi_imx_target_abort;
controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_NO_CS |
SPI_MOSI_IDLE_LOW;
@ -1779,7 +1783,7 @@ static int spi_imx_probe(struct platform_device *pdev)
if (is_imx51_ecspi(spi_imx) || is_imx53_ecspi(spi_imx)) {
controller->max_native_cs = 4;
controller->flags |= SPI_MASTER_GPIO_SS;
controller->flags |= SPI_CONTROLLER_GPIO_SS;
}
spi_imx->spi_drctl = spi_drctl;

Просмотреть файл

@ -12,7 +12,7 @@
#include <linux/dma-mapping.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/spi/spi.h>
@ -392,7 +392,7 @@ static int spi_ingenic_probe(struct platform_device *pdev)
return -EINVAL;
}
ctlr = devm_spi_alloc_master(dev, sizeof(*priv));
ctlr = devm_spi_alloc_host(dev, sizeof(*priv));
if (!ctlr) {
dev_err(dev, "Unable to allocate SPI controller.\n");
return -ENOMEM;

Просмотреть файл

@ -143,7 +143,7 @@
* @base: Beginning of MMIO space
* @pregs: Start of protection registers
* @sregs: Start of software sequencer registers
* @master: Pointer to the SPI controller structure
* @host: Pointer to the SPI controller structure
* @nregions: Maximum number of regions
* @pr_num: Maximum number of protected range registers
* @chip0_size: Size of the first flash chip in bytes
@ -161,7 +161,7 @@ struct intel_spi {
void __iomem *base;
void __iomem *pregs;
void __iomem *sregs;
struct spi_controller *master;
struct spi_controller *host;
size_t nregions;
size_t pr_num;
size_t chip0_size;
@ -747,7 +747,7 @@ intel_spi_match_mem_op(struct intel_spi *ispi, const struct spi_mem_op *op)
static bool intel_spi_supports_mem_op(struct spi_mem *mem,
const struct spi_mem_op *op)
{
struct intel_spi *ispi = spi_master_get_devdata(mem->spi->master);
struct intel_spi *ispi = spi_controller_get_devdata(mem->spi->controller);
const struct intel_spi_mem_op *iop;
iop = intel_spi_match_mem_op(ispi, op);
@ -778,7 +778,7 @@ static bool intel_spi_supports_mem_op(struct spi_mem *mem,
static int intel_spi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
{
struct intel_spi *ispi = spi_master_get_devdata(mem->spi->master);
struct intel_spi *ispi = spi_controller_get_devdata(mem->spi->controller);
const struct intel_spi_mem_op *iop;
iop = intel_spi_match_mem_op(ispi, op);
@ -790,7 +790,7 @@ static int intel_spi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *o
static const char *intel_spi_get_name(struct spi_mem *mem)
{
const struct intel_spi *ispi = spi_master_get_devdata(mem->spi->master);
const struct intel_spi *ispi = spi_controller_get_devdata(mem->spi->controller);
/*
* Return name of the flash controller device to be compatible
@ -801,7 +801,7 @@ static const char *intel_spi_get_name(struct spi_mem *mem)
static int intel_spi_dirmap_create(struct spi_mem_dirmap_desc *desc)
{
struct intel_spi *ispi = spi_master_get_devdata(desc->mem->spi->master);
struct intel_spi *ispi = spi_controller_get_devdata(desc->mem->spi->controller);
const struct intel_spi_mem_op *iop;
iop = intel_spi_match_mem_op(ispi, &desc->info.op_tmpl);
@ -815,7 +815,7 @@ static int intel_spi_dirmap_create(struct spi_mem_dirmap_desc *desc)
static ssize_t intel_spi_dirmap_read(struct spi_mem_dirmap_desc *desc, u64 offs,
size_t len, void *buf)
{
struct intel_spi *ispi = spi_master_get_devdata(desc->mem->spi->master);
struct intel_spi *ispi = spi_controller_get_devdata(desc->mem->spi->controller);
const struct intel_spi_mem_op *iop = desc->priv;
struct spi_mem_op op = desc->info.op_tmpl;
int ret;
@ -832,7 +832,7 @@ static ssize_t intel_spi_dirmap_read(struct spi_mem_dirmap_desc *desc, u64 offs,
static ssize_t intel_spi_dirmap_write(struct spi_mem_dirmap_desc *desc, u64 offs,
size_t len, const void *buf)
{
struct intel_spi *ispi = spi_master_get_devdata(desc->mem->spi->master);
struct intel_spi *ispi = spi_controller_get_devdata(desc->mem->spi->controller);
const struct intel_spi_mem_op *iop = desc->priv;
struct spi_mem_op op = desc->info.op_tmpl;
int ret;
@ -1332,14 +1332,14 @@ static int intel_spi_read_desc(struct intel_spi *ispi)
nc = (buf[1] & FLMAP0_NC_MASK) >> FLMAP0_NC_SHIFT;
if (!nc)
ispi->master->num_chipselect = 1;
ispi->host->num_chipselect = 1;
else if (nc == 1)
ispi->master->num_chipselect = 2;
ispi->host->num_chipselect = 2;
else
return -EINVAL;
dev_dbg(ispi->dev, "%u flash components found\n",
ispi->master->num_chipselect);
ispi->host->num_chipselect);
return 0;
}
@ -1365,7 +1365,7 @@ static int intel_spi_populate_chip(struct intel_spi *ispi)
snprintf(chip.modalias, 8, "spi-nor");
chip.platform_data = pdata;
if (!spi_new_device(ispi->master, &chip))
if (!spi_new_device(ispi->host, &chip))
return -ENODEV;
ret = intel_spi_read_desc(ispi);
@ -1373,13 +1373,13 @@ static int intel_spi_populate_chip(struct intel_spi *ispi)
return ret;
/* Add the second chip if present */
if (ispi->master->num_chipselect < 2)
if (ispi->host->num_chipselect < 2)
return 0;
chip.platform_data = NULL;
chip.chip_select = 1;
if (!spi_new_device(ispi->master, &chip))
if (!spi_new_device(ispi->host, &chip))
return -ENODEV;
return 0;
}
@ -1396,31 +1396,31 @@ static int intel_spi_populate_chip(struct intel_spi *ispi)
int intel_spi_probe(struct device *dev, struct resource *mem,
const struct intel_spi_boardinfo *info)
{
struct spi_controller *master;
struct spi_controller *host;
struct intel_spi *ispi;
int ret;
master = devm_spi_alloc_master(dev, sizeof(*ispi));
if (!master)
host = devm_spi_alloc_host(dev, sizeof(*ispi));
if (!host)
return -ENOMEM;
master->mem_ops = &intel_spi_mem_ops;
host->mem_ops = &intel_spi_mem_ops;
ispi = spi_master_get_devdata(master);
ispi = spi_controller_get_devdata(host);
ispi->base = devm_ioremap_resource(dev, mem);
if (IS_ERR(ispi->base))
return PTR_ERR(ispi->base);
ispi->dev = dev;
ispi->master = master;
ispi->host = host;
ispi->info = info;
ret = intel_spi_init(ispi);
if (ret)
return ret;
ret = devm_spi_register_master(dev, master);
ret = devm_spi_register_controller(dev, host);
if (ret)
return ret;

Просмотреть файл

@ -94,7 +94,6 @@ static int bcm_iproc_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct bcm_iproc_intc *priv;
struct bcm_qspi_soc_intc *soc_intc;
struct resource *res;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
@ -104,14 +103,12 @@ static int bcm_iproc_probe(struct platform_device *pdev)
spin_lock_init(&priv->soclock);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr_regs");
priv->int_reg = devm_ioremap_resource(dev, res);
priv->int_reg = devm_platform_ioremap_resource_byname(pdev, "intr_regs");
if (IS_ERR(priv->int_reg))
return PTR_ERR(priv->int_reg);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"intr_status_reg");
priv->int_status_reg = devm_ioremap_resource(dev, res);
priv->int_status_reg = devm_platform_ioremap_resource_byname(pdev,
"intr_status_reg");
if (IS_ERR(priv->int_status_reg))
return PTR_ERR(priv->int_status_reg);

Просмотреть файл

@ -33,7 +33,7 @@
#define JCORE_SPI_WAIT_RDY_MAX_LOOP 2000000
struct jcore_spi {
struct spi_master *master;
struct spi_controller *host;
void __iomem *base;
unsigned int cs_reg;
unsigned int speed_reg;
@ -59,7 +59,7 @@ static void jcore_spi_program(struct jcore_spi *hw)
void __iomem *ctrl_reg = hw->base + CTRL_REG;
if (jcore_spi_wait(ctrl_reg))
dev_err(hw->master->dev.parent,
dev_err(hw->host->dev.parent,
"timeout waiting to program ctrl reg.\n");
writel(hw->cs_reg | hw->speed_reg, ctrl_reg);
@ -67,10 +67,10 @@ static void jcore_spi_program(struct jcore_spi *hw)
static void jcore_spi_chipsel(struct spi_device *spi, bool value)
{
struct jcore_spi *hw = spi_master_get_devdata(spi->master);
struct jcore_spi *hw = spi_controller_get_devdata(spi->controller);
u32 csbit = 1U << (2 * spi_get_chipselect(spi, 0));
dev_dbg(hw->master->dev.parent, "chipselect %d\n", spi_get_chipselect(spi, 0));
dev_dbg(hw->host->dev.parent, "chipselect %d\n", spi_get_chipselect(spi, 0));
if (value)
hw->cs_reg |= csbit;
@ -90,14 +90,14 @@ static void jcore_spi_baudrate(struct jcore_spi *hw, int speed)
else
hw->speed_reg = ((hw->clock_freq / 2 / speed) - 1) << 27;
jcore_spi_program(hw);
dev_dbg(hw->master->dev.parent, "speed=%d reg=0x%x\n",
dev_dbg(hw->host->dev.parent, "speed=%d reg=0x%x\n",
speed, hw->speed_reg);
}
static int jcore_spi_txrx(struct spi_master *master, struct spi_device *spi,
static int jcore_spi_txrx(struct spi_controller *host, struct spi_device *spi,
struct spi_transfer *t)
{
struct jcore_spi *hw = spi_master_get_devdata(master);
struct jcore_spi *hw = spi_controller_get_devdata(host);
void __iomem *ctrl_reg = hw->base + CTRL_REG;
void __iomem *data_reg = hw->base + DATA_REG;
@ -130,7 +130,7 @@ static int jcore_spi_txrx(struct spi_master *master, struct spi_device *spi,
*rx++ = readl(data_reg);
}
spi_finalize_current_transfer(master);
spi_finalize_current_transfer(host);
if (count < len)
return -EREMOTEIO;
@ -142,26 +142,26 @@ static int jcore_spi_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
struct jcore_spi *hw;
struct spi_master *master;
struct spi_controller *host;
struct resource *res;
u32 clock_freq;
struct clk *clk;
int err = -ENODEV;
master = spi_alloc_master(&pdev->dev, sizeof(struct jcore_spi));
if (!master)
host = spi_alloc_host(&pdev->dev, sizeof(struct jcore_spi));
if (!host)
return err;
/* Setup the master state. */
master->num_chipselect = 3;
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
master->transfer_one = jcore_spi_txrx;
master->set_cs = jcore_spi_chipsel;
master->dev.of_node = node;
master->bus_num = pdev->id;
/* Setup the host state. */
host->num_chipselect = 3;
host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
host->transfer_one = jcore_spi_txrx;
host->set_cs = jcore_spi_chipsel;
host->dev.of_node = node;
host->bus_num = pdev->id;
hw = spi_master_get_devdata(master);
hw->master = master;
hw = spi_controller_get_devdata(host);
hw->host = host;
platform_set_drvdata(pdev, hw);
/* Find and map our resources */
@ -200,7 +200,7 @@ static int jcore_spi_probe(struct platform_device *pdev)
jcore_spi_baudrate(hw, 400000);
/* Register our spi controller */
err = devm_spi_register_master(&pdev->dev, master);
err = devm_spi_register_controller(&pdev->dev, host);
if (err)
goto exit;
@ -209,7 +209,7 @@ static int jcore_spi_probe(struct platform_device *pdev)
exit_busy:
err = -EBUSY;
exit:
spi_master_put(master);
spi_controller_put(host);
return err;
}

Просмотреть файл

@ -6,7 +6,8 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/delay.h>
@ -91,7 +92,7 @@
#define LTQ_SPI_STAT_RE BIT(9) /* Receive error flag */
#define LTQ_SPI_STAT_TE BIT(8) /* Transmit error flag */
#define LTQ_SPI_STAT_ME BIT(7) /* Mode error flag */
#define LTQ_SPI_STAT_MS BIT(1) /* Master/slave select bit */
#define LTQ_SPI_STAT_MS BIT(1) /* Host/target select bit */
#define LTQ_SPI_STAT_EN BIT(0) /* Enable bit */
#define LTQ_SPI_STAT_ERRORS (LTQ_SPI_STAT_ME | LTQ_SPI_STAT_TE | \
LTQ_SPI_STAT_RE | LTQ_SPI_STAT_AE | \
@ -109,8 +110,8 @@
#define LTQ_SPI_WHBSTATE_CLRME BIT(6) /* Clear mode error flag */
#define LTQ_SPI_WHBSTATE_SETRUE BIT(5) /* Set receive underflow error flag */
#define LTQ_SPI_WHBSTATE_CLRRUE BIT(4) /* Clear receive underflow error flag */
#define LTQ_SPI_WHBSTATE_SETMS BIT(3) /* Set master select bit */
#define LTQ_SPI_WHBSTATE_CLRMS BIT(2) /* Clear master select bit */
#define LTQ_SPI_WHBSTATE_SETMS BIT(3) /* Set host select bit */
#define LTQ_SPI_WHBSTATE_CLRMS BIT(2) /* Clear host select bit */
#define LTQ_SPI_WHBSTATE_SETEN BIT(1) /* Set enable bit (operational mode) */
#define LTQ_SPI_WHBSTATE_CLREN BIT(0) /* Clear enable bit (config mode */
#define LTQ_SPI_WHBSTATE_CLR_ERRORS (LTQ_SPI_WHBSTATE_CLRRUE | \
@ -162,7 +163,7 @@ struct lantiq_ssc_hwcfg {
};
struct lantiq_ssc_spi {
struct spi_master *master;
struct spi_controller *host;
struct device *dev;
void __iomem *regbase;
struct clk *spi_clk;
@ -366,7 +367,7 @@ static void lantiq_ssc_hw_init(const struct lantiq_ssc_spi *spi)
hw_setup_bits_per_word(spi, spi->bits_per_word);
hw_setup_clock_mode(spi, SPI_MODE_0);
/* Enable master mode and clear error flags */
/* Enable host mode and clear error flags */
lantiq_ssc_writel(spi, LTQ_SPI_WHBSTATE_SETMS |
LTQ_SPI_WHBSTATE_CLR_ERRORS,
LTQ_SPI_WHBSTATE);
@ -386,8 +387,8 @@ static void lantiq_ssc_hw_init(const struct lantiq_ssc_spi *spi)
static int lantiq_ssc_setup(struct spi_device *spidev)
{
struct spi_master *master = spidev->master;
struct lantiq_ssc_spi *spi = spi_master_get_devdata(master);
struct spi_controller *host = spidev->controller;
struct lantiq_ssc_spi *spi = spi_controller_get_devdata(host);
unsigned int cs = spi_get_chipselect(spidev, 0);
u32 gpocon;
@ -415,10 +416,10 @@ static int lantiq_ssc_setup(struct spi_device *spidev)
return 0;
}
static int lantiq_ssc_prepare_message(struct spi_master *master,
static int lantiq_ssc_prepare_message(struct spi_controller *host,
struct spi_message *message)
{
struct lantiq_ssc_spi *spi = spi_master_get_devdata(master);
struct lantiq_ssc_spi *spi = spi_controller_get_devdata(host);
hw_enter_config_mode(spi);
hw_setup_clock_mode(spi, message->spi->mode);
@ -460,10 +461,10 @@ static void hw_setup_transfer(struct lantiq_ssc_spi *spi,
lantiq_ssc_writel(spi, con, LTQ_SPI_CON);
}
static int lantiq_ssc_unprepare_message(struct spi_master *master,
static int lantiq_ssc_unprepare_message(struct spi_controller *host,
struct spi_message *message)
{
struct lantiq_ssc_spi *spi = spi_master_get_devdata(master);
struct lantiq_ssc_spi *spi = spi_controller_get_devdata(host);
flush_workqueue(spi->wq);
@ -692,8 +693,8 @@ static irqreturn_t lantiq_ssc_err_interrupt(int irq, void *data)
lantiq_ssc_maskl(spi, 0, LTQ_SPI_WHBSTATE_CLR_ERRORS, LTQ_SPI_WHBSTATE);
/* set bad status so it can be retried */
if (spi->master->cur_msg)
spi->master->cur_msg->status = -EIO;
if (spi->host->cur_msg)
spi->host->cur_msg->status = -EIO;
queue_work(spi->wq, &spi->work);
spin_unlock(&spi->lock);
@ -771,22 +772,22 @@ static void lantiq_ssc_bussy_work(struct work_struct *work)
u32 stat = lantiq_ssc_readl(spi, LTQ_SPI_STAT);
if (!(stat & LTQ_SPI_STAT_BSY)) {
spi_finalize_current_transfer(spi->master);
spi_finalize_current_transfer(spi->host);
return;
}
cond_resched();
} while (!time_after_eq(jiffies, end));
if (spi->master->cur_msg)
spi->master->cur_msg->status = -EIO;
spi_finalize_current_transfer(spi->master);
if (spi->host->cur_msg)
spi->host->cur_msg->status = -EIO;
spi_finalize_current_transfer(spi->host);
}
static void lantiq_ssc_handle_err(struct spi_master *master,
static void lantiq_ssc_handle_err(struct spi_controller *host,
struct spi_message *message)
{
struct lantiq_ssc_spi *spi = spi_master_get_devdata(master);
struct lantiq_ssc_spi *spi = spi_controller_get_devdata(host);
/* flush FIFOs on timeout */
rx_fifo_flush(spi);
@ -795,7 +796,7 @@ static void lantiq_ssc_handle_err(struct spi_master *master,
static void lantiq_ssc_set_cs(struct spi_device *spidev, bool enable)
{
struct lantiq_ssc_spi *spi = spi_master_get_devdata(spidev->master);
struct lantiq_ssc_spi *spi = spi_controller_get_devdata(spidev->controller);
unsigned int cs = spi_get_chipselect(spidev, 0);
u32 fgpo;
@ -807,11 +808,11 @@ static void lantiq_ssc_set_cs(struct spi_device *spidev, bool enable)
lantiq_ssc_writel(spi, fgpo, LTQ_SPI_FPGO);
}
static int lantiq_ssc_transfer_one(struct spi_master *master,
static int lantiq_ssc_transfer_one(struct spi_controller *host,
struct spi_device *spidev,
struct spi_transfer *t)
{
struct lantiq_ssc_spi *spi = spi_master_get_devdata(master);
struct lantiq_ssc_spi *spi = spi_controller_get_devdata(host);
hw_setup_transfer(spi, spidev, t);
@ -903,7 +904,7 @@ MODULE_DEVICE_TABLE(of, lantiq_ssc_match);
static int lantiq_ssc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct spi_master *master;
struct spi_controller *host;
struct lantiq_ssc_spi *spi;
const struct lantiq_ssc_hwcfg *hwcfg;
u32 id, supports_dma, revision;
@ -912,33 +913,33 @@ static int lantiq_ssc_probe(struct platform_device *pdev)
hwcfg = of_device_get_match_data(dev);
master = spi_alloc_master(dev, sizeof(struct lantiq_ssc_spi));
if (!master)
host = spi_alloc_host(dev, sizeof(struct lantiq_ssc_spi));
if (!host)
return -ENOMEM;
spi = spi_master_get_devdata(master);
spi->master = master;
spi = spi_controller_get_devdata(host);
spi->host = host;
spi->dev = dev;
spi->hwcfg = hwcfg;
platform_set_drvdata(pdev, spi);
spi->regbase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(spi->regbase)) {
err = PTR_ERR(spi->regbase);
goto err_master_put;
goto err_host_put;
}
err = hwcfg->cfg_irq(pdev, spi);
if (err)
goto err_master_put;
goto err_host_put;
spi->spi_clk = devm_clk_get(dev, "gate");
if (IS_ERR(spi->spi_clk)) {
err = PTR_ERR(spi->spi_clk);
goto err_master_put;
goto err_host_put;
}
err = clk_prepare_enable(spi->spi_clk);
if (err)
goto err_master_put;
goto err_host_put;
/*
* Use the old clk_get_fpi() function on Lantiq platform, till it
@ -964,19 +965,19 @@ static int lantiq_ssc_probe(struct platform_device *pdev)
spi->bits_per_word = 8;
spi->speed_hz = 0;
master->dev.of_node = pdev->dev.of_node;
master->num_chipselect = num_cs;
master->use_gpio_descriptors = true;
master->setup = lantiq_ssc_setup;
master->set_cs = lantiq_ssc_set_cs;
master->handle_err = lantiq_ssc_handle_err;
master->prepare_message = lantiq_ssc_prepare_message;
master->unprepare_message = lantiq_ssc_unprepare_message;
master->transfer_one = lantiq_ssc_transfer_one;
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_CS_HIGH |
SPI_LOOP;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 8) |
SPI_BPW_MASK(16) | SPI_BPW_MASK(32);
host->dev.of_node = pdev->dev.of_node;
host->num_chipselect = num_cs;
host->use_gpio_descriptors = true;
host->setup = lantiq_ssc_setup;
host->set_cs = lantiq_ssc_set_cs;
host->handle_err = lantiq_ssc_handle_err;
host->prepare_message = lantiq_ssc_prepare_message;
host->unprepare_message = lantiq_ssc_unprepare_message;
host->transfer_one = lantiq_ssc_transfer_one;
host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_CS_HIGH |
SPI_LOOP;
host->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 8) |
SPI_BPW_MASK(16) | SPI_BPW_MASK(32);
spi->wq = alloc_ordered_workqueue(dev_name(dev), WQ_MEM_RECLAIM);
if (!spi->wq) {
@ -997,9 +998,9 @@ static int lantiq_ssc_probe(struct platform_device *pdev)
"Lantiq SSC SPI controller (Rev %i, TXFS %u, RXFS %u, DMA %u)\n",
revision, spi->tx_fifo_size, spi->rx_fifo_size, supports_dma);
err = devm_spi_register_master(dev, master);
err = devm_spi_register_controller(dev, host);
if (err) {
dev_err(dev, "failed to register spi_master\n");
dev_err(dev, "failed to register spi host\n");
goto err_wq_destroy;
}
@ -1011,8 +1012,8 @@ err_clk_put:
clk_put(spi->fpi_clk);
err_clk_disable:
clk_disable_unprepare(spi->spi_clk);
err_master_put:
spi_master_put(master);
err_host_put:
spi_controller_put(host);
return err;
}

Просмотреть файл

@ -0,0 +1,279 @@
// SPDX-License-Identifier: GPL-2.0+
// Loongson SPI Support
// Copyright (C) 2023 Loongson Technology Corporation Limited
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/spi/spi.h>
#include "spi-loongson.h"
static inline void loongson_spi_write_reg(struct loongson_spi *spi, unsigned char reg,
unsigned char data)
{
writeb(data, spi->base + reg);
}
static inline char loongson_spi_read_reg(struct loongson_spi *spi, unsigned char reg)
{
return readb(spi->base + reg);
}
static void loongson_spi_set_cs(struct spi_device *spi, bool en)
{
int cs;
unsigned char mask = (BIT(4) | BIT(0)) << spi_get_chipselect(spi, 0);
unsigned char val = en ? mask : (BIT(0) << spi_get_chipselect(spi, 0));
struct loongson_spi *loongson_spi = spi_controller_get_devdata(spi->controller);
cs = loongson_spi_read_reg(loongson_spi, LOONGSON_SPI_SFCS_REG) & ~mask;
loongson_spi_write_reg(loongson_spi, LOONGSON_SPI_SFCS_REG, val | cs);
}
static void loongson_spi_set_clk(struct loongson_spi *loongson_spi, unsigned int hz)
{
unsigned char val;
unsigned int div, div_tmp;
static const char rdiv[12] = {0, 1, 4, 2, 3, 5, 6, 7, 8, 9, 10, 11};
div = clamp_val(DIV_ROUND_UP_ULL(loongson_spi->clk_rate, hz), 2, 4096);
div_tmp = rdiv[fls(div - 1)];
loongson_spi->spcr = (div_tmp & GENMASK(1, 0)) >> 0;
loongson_spi->sper = (div_tmp & GENMASK(3, 2)) >> 2;
val = loongson_spi_read_reg(loongson_spi, LOONGSON_SPI_SPCR_REG);
val &= ~GENMASK(1, 0);
loongson_spi_write_reg(loongson_spi, LOONGSON_SPI_SPCR_REG, val |
loongson_spi->spcr);
val = loongson_spi_read_reg(loongson_spi, LOONGSON_SPI_SPER_REG);
val &= ~GENMASK(1, 0);
loongson_spi_write_reg(loongson_spi, LOONGSON_SPI_SPER_REG, val |
loongson_spi->sper);
loongson_spi->hz = hz;
}
static void loongson_spi_set_mode(struct loongson_spi *loongson_spi,
struct spi_device *spi)
{
unsigned char val;
val = loongson_spi_read_reg(loongson_spi, LOONGSON_SPI_SPCR_REG);
val &= ~(LOONGSON_SPI_SPCR_CPOL | LOONGSON_SPI_SPCR_CPHA);
if (spi->mode & SPI_CPOL)
val |= LOONGSON_SPI_SPCR_CPOL;
if (spi->mode & SPI_CPHA)
val |= LOONGSON_SPI_SPCR_CPHA;
loongson_spi_write_reg(loongson_spi, LOONGSON_SPI_SPCR_REG, val);
loongson_spi->mode |= spi->mode;
}
static int loongson_spi_update_state(struct loongson_spi *loongson_spi,
struct spi_device *spi, struct spi_transfer *t)
{
if (t && loongson_spi->hz != t->speed_hz)
loongson_spi_set_clk(loongson_spi, t->speed_hz);
if ((spi->mode ^ loongson_spi->mode) & SPI_MODE_X_MASK)
loongson_spi_set_mode(loongson_spi, spi);
return 0;
}
static int loongson_spi_setup(struct spi_device *spi)
{
struct loongson_spi *loongson_spi;
loongson_spi = spi_controller_get_devdata(spi->controller);
if (spi->bits_per_word % 8)
return -EINVAL;
if (spi_get_chipselect(spi, 0) >= spi->controller->num_chipselect)
return -EINVAL;
loongson_spi->hz = 0;
loongson_spi_set_cs(spi, true);
return 0;
}
static int loongson_spi_write_read_8bit(struct spi_device *spi, const u8 **tx_buf,
u8 **rx_buf, unsigned int num)
{
int ret;
struct loongson_spi *loongson_spi = spi_controller_get_devdata(spi->controller);
if (tx_buf && *tx_buf)
loongson_spi_write_reg(loongson_spi, LOONGSON_SPI_FIFO_REG, *((*tx_buf)++));
else
loongson_spi_write_reg(loongson_spi, LOONGSON_SPI_FIFO_REG, 0);
ret = readb_poll_timeout(loongson_spi->base + LOONGSON_SPI_SPSR_REG,
loongson_spi->spsr, (loongson_spi->spsr &
LOONGSON_SPI_SPSR_RFEMPTY) != LOONGSON_SPI_SPSR_RFEMPTY,
1, USEC_PER_MSEC);
if (rx_buf && *rx_buf)
*(*rx_buf)++ = loongson_spi_read_reg(loongson_spi, LOONGSON_SPI_FIFO_REG);
else
loongson_spi_read_reg(loongson_spi, LOONGSON_SPI_FIFO_REG);
return ret;
}
static int loongson_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
{
int ret;
unsigned int count;
const u8 *tx = xfer->tx_buf;
u8 *rx = xfer->rx_buf;
count = xfer->len;
do {
ret = loongson_spi_write_read_8bit(spi, &tx, &rx, count);
if (ret)
break;
} while (--count);
return ret;
}
static int loongson_spi_prepare_message(struct spi_controller *ctlr, struct spi_message *m)
{
struct loongson_spi *loongson_spi = spi_controller_get_devdata(ctlr);
loongson_spi->para = loongson_spi_read_reg(loongson_spi, LOONGSON_SPI_PARA_REG);
loongson_spi_write_reg(loongson_spi, LOONGSON_SPI_PARA_REG, loongson_spi->para &
~LOONGSON_SPI_PARA_MEM_EN);
return 0;
}
static int loongson_spi_transfer_one(struct spi_controller *ctrl, struct spi_device *spi,
struct spi_transfer *xfer)
{
struct loongson_spi *loongson_spi = spi_controller_get_devdata(spi->controller);
loongson_spi_update_state(loongson_spi, spi, xfer);
if (xfer->len)
return loongson_spi_write_read(spi, xfer);
return 0;
}
static int loongson_spi_unprepare_message(struct spi_controller *ctrl, struct spi_message *m)
{
struct loongson_spi *loongson_spi = spi_controller_get_devdata(ctrl);
loongson_spi_write_reg(loongson_spi, LOONGSON_SPI_PARA_REG, loongson_spi->para);
return 0;
}
static void loongson_spi_reginit(struct loongson_spi *loongson_spi_dev)
{
unsigned char val;
val = loongson_spi_read_reg(loongson_spi_dev, LOONGSON_SPI_SPCR_REG);
val &= ~LOONGSON_SPI_SPCR_SPE;
loongson_spi_write_reg(loongson_spi_dev, LOONGSON_SPI_SPCR_REG, val);
loongson_spi_write_reg(loongson_spi_dev, LOONGSON_SPI_SPSR_REG,
(LOONGSON_SPI_SPSR_SPIF | LOONGSON_SPI_SPSR_WCOL));
val = loongson_spi_read_reg(loongson_spi_dev, LOONGSON_SPI_SPCR_REG);
val |= LOONGSON_SPI_SPCR_SPE;
loongson_spi_write_reg(loongson_spi_dev, LOONGSON_SPI_SPCR_REG, val);
}
int loongson_spi_init_controller(struct device *dev, void __iomem *regs)
{
struct spi_controller *controller;
struct loongson_spi *spi;
struct clk *clk;
controller = devm_spi_alloc_host(dev, sizeof(struct loongson_spi));
if (controller == NULL)
return -ENOMEM;
controller->mode_bits = SPI_MODE_X_MASK | SPI_CS_HIGH;
controller->setup = loongson_spi_setup;
controller->prepare_message = loongson_spi_prepare_message;
controller->transfer_one = loongson_spi_transfer_one;
controller->unprepare_message = loongson_spi_unprepare_message;
controller->set_cs = loongson_spi_set_cs;
controller->num_chipselect = 4;
device_set_node(&controller->dev, dev_fwnode(dev));
dev_set_drvdata(dev, controller);
spi = spi_controller_get_devdata(controller);
spi->base = regs;
spi->controller = controller;
clk = devm_clk_get_optional(dev, NULL);
if (IS_ERR(clk))
return dev_err_probe(dev, PTR_ERR(clk), "unable to get clock\n");
spi->clk_rate = clk_get_rate(clk);
loongson_spi_reginit(spi);
spi->mode = 0;
return devm_spi_register_controller(dev, controller);
}
EXPORT_SYMBOL_NS_GPL(loongson_spi_init_controller, SPI_LOONGSON_CORE);
static int __maybe_unused loongson_spi_suspend(struct device *dev)
{
struct loongson_spi *loongson_spi;
struct spi_controller *controller;
controller = dev_get_drvdata(dev);
spi_controller_suspend(controller);
loongson_spi = spi_controller_get_devdata(controller);
loongson_spi->spcr = loongson_spi_read_reg(loongson_spi, LOONGSON_SPI_SPCR_REG);
loongson_spi->sper = loongson_spi_read_reg(loongson_spi, LOONGSON_SPI_SPER_REG);
loongson_spi->spsr = loongson_spi_read_reg(loongson_spi, LOONGSON_SPI_SPSR_REG);
loongson_spi->para = loongson_spi_read_reg(loongson_spi, LOONGSON_SPI_PARA_REG);
loongson_spi->sfcs = loongson_spi_read_reg(loongson_spi, LOONGSON_SPI_SFCS_REG);
loongson_spi->timi = loongson_spi_read_reg(loongson_spi, LOONGSON_SPI_TIMI_REG);
return 0;
}
static int __maybe_unused loongson_spi_resume(struct device *dev)
{
struct loongson_spi *loongson_spi;
struct spi_controller *controller;
controller = dev_get_drvdata(dev);
loongson_spi = spi_controller_get_devdata(controller);
loongson_spi_write_reg(loongson_spi, LOONGSON_SPI_SPCR_REG, loongson_spi->spcr);
loongson_spi_write_reg(loongson_spi, LOONGSON_SPI_SPER_REG, loongson_spi->sper);
loongson_spi_write_reg(loongson_spi, LOONGSON_SPI_SPSR_REG, loongson_spi->spsr);
loongson_spi_write_reg(loongson_spi, LOONGSON_SPI_PARA_REG, loongson_spi->para);
loongson_spi_write_reg(loongson_spi, LOONGSON_SPI_SFCS_REG, loongson_spi->sfcs);
loongson_spi_write_reg(loongson_spi, LOONGSON_SPI_TIMI_REG, loongson_spi->timi);
spi_controller_resume(controller);
return 0;
}
const struct dev_pm_ops loongson_spi_dev_pm_ops = {
.suspend = loongson_spi_suspend,
.resume = loongson_spi_resume,
};
EXPORT_SYMBOL_NS_GPL(loongson_spi_dev_pm_ops, SPI_LOONGSON_CORE);
MODULE_DESCRIPTION("Loongson SPI core driver");
MODULE_LICENSE("GPL");

Просмотреть файл

@ -0,0 +1,55 @@
// SPDX-License-Identifier: GPL-2.0+
// PCI interface driver for Loongson SPI Support
// Copyright (C) 2023 Loongson Technology Corporation Limited
#include <linux/mod_devicetable.h>
#include <linux/pci.h>
#include "spi-loongson.h"
static int loongson_spi_pci_register(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
int ret;
void __iomem *reg_base;
struct device *dev = &pdev->dev;
int pci_bar = 0;
ret = pcim_enable_device(pdev);
if (ret < 0)
return dev_err_probe(dev, ret, "cannot enable pci device\n");
ret = pcim_iomap_regions(pdev, BIT(pci_bar), pci_name(pdev));
if (ret)
return dev_err_probe(dev, ret, "failed to request and remap memory\n");
reg_base = pcim_iomap_table(pdev)[pci_bar];
ret = loongson_spi_init_controller(dev, reg_base);
if (ret)
return dev_err_probe(dev, ret, "failed to initialize controller\n");
return 0;
}
static struct pci_device_id loongson_spi_devices[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_LOONGSON, 0x7a0b) },
{ PCI_DEVICE(PCI_VENDOR_ID_LOONGSON, 0x7a1b) },
{ }
};
MODULE_DEVICE_TABLE(pci, loongson_spi_devices);
static struct pci_driver loongson_spi_pci_driver = {
.name = "loongson-spi-pci",
.id_table = loongson_spi_devices,
.probe = loongson_spi_pci_register,
.driver = {
.bus = &pci_bus_type,
.pm = &loongson_spi_dev_pm_ops,
},
};
module_pci_driver(loongson_spi_pci_driver);
MODULE_DESCRIPTION("Loongson spi pci driver");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(SPI_LOONGSON_CORE);

Просмотреть файл

@ -0,0 +1,47 @@
// SPDX-License-Identifier: GPL-2.0+
// Platform driver for Loongson SPI Support
// Copyright (C) 2023 Loongson Technology Corporation Limited
#include <linux/err.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include "spi-loongson.h"
static int loongson_spi_platform_probe(struct platform_device *pdev)
{
int ret;
void __iomem *reg_base;
struct device *dev = &pdev->dev;
reg_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(reg_base))
return PTR_ERR(reg_base);
ret = loongson_spi_init_controller(dev, reg_base);
if (ret)
return dev_err_probe(dev, ret, "failed to initialize controller\n");
return 0;
}
static const struct of_device_id loongson_spi_id_table[] = {
{ .compatible = "loongson,ls2k1000-spi" },
{ }
};
MODULE_DEVICE_TABLE(of, loongson_spi_id_table);
static struct platform_driver loongson_spi_plat_driver = {
.probe = loongson_spi_platform_probe,
.driver = {
.name = "loongson-spi",
.bus = &platform_bus_type,
.pm = &loongson_spi_dev_pm_ops,
.of_match_table = loongson_spi_id_table,
},
};
module_platform_driver(loongson_spi_plat_driver);
MODULE_DESCRIPTION("Loongson spi platform driver");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(SPI_LOONGSON_CORE);

Просмотреть файл

@ -0,0 +1,49 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/* Header File for Loongson SPI Driver. */
/* Copyright (C) 2023 Loongson Technology Corporation Limited */
#ifndef __LINUX_SPI_LOONGSON_H
#define __LINUX_SPI_LOONGSON_H
#include <linux/bits.h>
#include <linux/pm.h>
#include <linux/types.h>
#define LOONGSON_SPI_SPCR_REG 0x00
#define LOONGSON_SPI_SPSR_REG 0x01
#define LOONGSON_SPI_FIFO_REG 0x02
#define LOONGSON_SPI_SPER_REG 0x03
#define LOONGSON_SPI_PARA_REG 0x04
#define LOONGSON_SPI_SFCS_REG 0x05
#define LOONGSON_SPI_TIMI_REG 0x06
/* Bits definition for Loongson SPI register */
#define LOONGSON_SPI_PARA_MEM_EN BIT(0)
#define LOONGSON_SPI_SPCR_CPHA BIT(2)
#define LOONGSON_SPI_SPCR_CPOL BIT(3)
#define LOONGSON_SPI_SPCR_SPE BIT(6)
#define LOONGSON_SPI_SPSR_RFEMPTY BIT(0)
#define LOONGSON_SPI_SPSR_WCOL BIT(6)
#define LOONGSON_SPI_SPSR_SPIF BIT(7)
struct device;
struct spi_controller;
struct loongson_spi {
struct spi_controller *controller;
void __iomem *base;
int cs_active;
unsigned int hz;
unsigned char spcr;
unsigned char sper;
unsigned char spsr;
unsigned char para;
unsigned char sfcs;
unsigned char timi;
unsigned int mode;
u64 clk_rate;
};
int loongson_spi_init_controller(struct device *dev, void __iomem *reg);
extern const struct dev_pm_ops loongson_spi_dev_pm_ops;
#endif /* __LINUX_SPI_LOONGSON_H */

Просмотреть файл

@ -14,8 +14,8 @@
#include <linux/ktime.h>
#include <linux/list.h>
#include <linux/list_sort.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/printk.h>
#include <linux/vmalloc.h>
#include <linux/spi/spi.h>

Просмотреть файл

@ -15,7 +15,6 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/spi/spi.h>
#define DRIVER_NAME "spi_lp8841_rtc"
@ -75,14 +74,14 @@ bitbang_txrx_be_cpha0_lsb(struct spi_lp8841_rtc *data,
for (; likely(bits); bits--) {
/* setup LSB (to slave) on leading edge */
if ((flags & SPI_MASTER_NO_TX) == 0)
if ((flags & SPI_CONTROLLER_NO_TX) == 0)
setmosi(data, (word & 1));
usleep_range(usecs, usecs + 1); /* T(setup) */
/* sample LSB (from slave) on trailing edge */
word >>= 1;
if ((flags & SPI_MASTER_NO_RX) == 0)
if ((flags & SPI_CONTROLLER_NO_RX) == 0)
word |= (getmiso(data) << 31);
setsck(data, !cpol);
@ -113,7 +112,7 @@ spi_lp8841_rtc_transfer_one(struct spi_master *master,
while (likely(count > 0)) {
word = *tx++;
bitbang_txrx_be_cpha0_lsb(data, 1, 0,
SPI_MASTER_NO_RX, word, 8);
SPI_CONTROLLER_NO_RX, word, 8);
count--;
}
} else if (rx) {
@ -121,7 +120,7 @@ spi_lp8841_rtc_transfer_one(struct spi_master *master,
writeb(data->state, data->iomem);
while (likely(count > 0)) {
word = bitbang_txrx_be_cpha0_lsb(data, 1, 0,
SPI_MASTER_NO_TX, word, 8);
SPI_CONTROLLER_NO_TX, word, 8);
*rx++ = word;
count--;
}
@ -191,7 +190,7 @@ spi_lp8841_rtc_probe(struct platform_device *pdev)
return -ENOMEM;
platform_set_drvdata(pdev, master);
master->flags = SPI_MASTER_HALF_DUPLEX;
master->flags = SPI_CONTROLLER_HALF_DUPLEX;
master->mode_bits = SPI_CS_HIGH | SPI_3WIRE | SPI_LSB_FIRST;
master->bus_num = pdev->id;

Просмотреть файл

@ -15,7 +15,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/types.h>
@ -864,7 +863,7 @@ static int meson_spicc_probe(struct platform_device *pdev)
SPI_BPW_MASK(24) |
SPI_BPW_MASK(16) |
SPI_BPW_MASK(8);
master->flags = (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX);
master->flags = (SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX);
master->min_speed_hz = spicc->data->min_speed_hz;
master->max_speed_hz = spicc->data->max_speed_hz;
master->setup = meson_spicc_setup;

Просмотреть файл

@ -530,10 +530,8 @@ static int mchp_corespi_probe(struct platform_device *pdev)
return PTR_ERR(spi->regs);
spi->irq = platform_get_irq(pdev, 0);
if (spi->irq <= 0)
return dev_err_probe(&pdev->dev, -ENXIO,
"invalid IRQ %d for SPI controller\n",
spi->irq);
if (spi->irq < 0)
return spi->irq;
ret = devm_request_irq(&pdev->dev, spi->irq, mchp_corespi_interrupt,
IRQF_SHARED, dev_name(&pdev->dev), master);

Просмотреть файл

@ -53,7 +53,7 @@ struct mpc512x_psc_spi {
int type;
void __iomem *psc;
struct mpc512x_psc_fifo __iomem *fifo;
unsigned int irq;
int irq;
u8 bits_per_word;
u32 mclk_rate;

Просмотреть файл

@ -29,7 +29,7 @@ struct mpc52xx_psc_spi {
/* driver internal data */
struct mpc52xx_psc __iomem *psc;
struct mpc52xx_psc_fifo __iomem *fifo;
unsigned int irq;
int irq;
u8 bits_per_word;
struct completion done;

Просмотреть файл

@ -1142,7 +1142,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
master->mode_bits |= SPI_CS_HIGH;
if (mdata->dev_comp->must_tx)
master->flags = SPI_MASTER_MUST_TX;
master->flags = SPI_CONTROLLER_MUST_TX;
if (mdata->dev_comp->ipm_design)
master->mode_bits |= SPI_LOOP | SPI_RX_DUAL | SPI_TX_DUAL |
SPI_RX_QUAD | SPI_TX_QUAD;

Просмотреть файл

@ -14,7 +14,9 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/spi/spi.h>

Просмотреть файл

@ -13,7 +13,8 @@
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi-mem.h>

Просмотреть файл

@ -76,7 +76,8 @@
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/iopoll.h>
#include <linux/of_platform.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/mtd/nand-ecc-mtk.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi-mem.h>

Просмотреть файл

@ -572,7 +572,7 @@ static int mxs_spi_probe(struct platform_device *pdev)
master->mode_bits = SPI_CPOL | SPI_CPHA;
master->num_chipselect = 3;
master->dev.of_node = np;
master->flags = SPI_MASTER_HALF_DUPLEX;
master->flags = SPI_CONTROLLER_HALF_DUPLEX;
master->auto_runtime_pm = true;
spi = spi_master_get_devdata(master);

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше