mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-27 22:24:11 +08:00
spi: Updates for v6.4
A fairly standard release for SPI with the exception of a change to the API for specifying chip selects done in preparation for supporting devices with more than one chip select, this required some mechanical changes throughout the tree which have been cooking in -next happily for a while. There's also a new API to allow us to TPM chips on half duplex controllers. There's three commits in here that were mangled by a bad interaction between the alsa-devel mailing list software and b4, I didn't notice until there were merges on top with it being SPI not ALSA. It seemed clear enough to not be worth going back and fixing. - Refactoring in preparation for supporting multiple chip selects for a single device, needed by some flash devices, which required a change in the SPI device API visible throughout the tree. - Support for hardware assisted interaction with SPI TPMs on half duplex controllers, implemented on nVidia Tedra210 QuadSPI. - Optimisation for large transfers on fsl-cpm devices. - Cleanups around device property use which fix some sisues with fwnode. - Use of both void remove() and devm_platform_.*ioremap_resource(). - Support for AMD Pensando Elba, Amlogic A1, Cadence device mode, Intel MetorLake-S and StarFive J7110 QuadSPI. The final commit converting to DEV_PM_OPS() was applied late to fix a warning that was introduced by some of the earlier work. -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmRIFQgACgkQJNaLcl1U h9BJOwf+JF2RySdn5g1LsyTndPZhLfw4iJgTHaMlnv5tiPHvYVYMM/mNMbMr5Znh Y2T0OUkzuRfOK273C+hItC1bTYFTa2cEbDb5dpmKBOZdQ3hjGsZQBvuH2bScUQ+a H7UgD3FYOJST6k6rRgZQxVMPePFrXAOaO1gmFWTR3v1EcEr2JeQnjZsmymFXcTnc CtPg9N3RvhVnq5aXuxSgQeyyKIjo4LJh/eZ2mexPIu0DeUq3MftaWwSwCXFIoeNC DMLA4mZWTgf/yt6JUALwLr+bIiJjb4qGjp3xGZ2wmX7zn73f9QQvuunKb1V4zbNF EdXLo2VjA9cZjsihenBaKeHnkfgNfA== =IRqY -----END PGP SIGNATURE----- Merge tag 'spi-v6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi Pull spi updates from Mark Brown: "A fairly standard release for SPI with the exception of a change to the API for specifying chip selects done in preparation for supporting devices with more than one chip select, this required some mechanical changes throughout the tree which have been cooking in -next happily for a while. There's also a new API to allow us to support TPM chips on half duplex controllers. Summary: - Refactoring in preparation for supporting multiple chip selects for a single device, needed by some flash devices, which required a change in the SPI device API visible throughout the tree - Support for hardware assisted interaction with SPI TPMs on half duplex controllers, implemented on nVidia Tedra210 QuadSPI - Optimisation for large transfers on fsl-cpm devices - Cleanups around device property use which fix some sisues with fwnode - Use of both void remove() and devm_platform_.*ioremap_resource() - Support for AMD Pensando Elba, Amlogic A1, Cadence device mode, Intel MetorLake-S and StarFive J7110 QuadSPI" * tag 'spi-v6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (185 commits) spi: bcm63xx: use macro DEFINE_SIMPLE_DEV_PM_OPS spi: tegra210-quad: Enable TPM wait polling spi: Add TPM HW flow flag spi: bcm63xx: remove PM_SLEEP based conditional compilation spi: cadence-quadspi: use macro DEFINE_SIMPLE_DEV_PM_OPS spi: spi-cadence: Add support for Slave mode spi: spi-cadence: Switch to spi_controller structure spi: cadence-quadspi: fix suspend-resume implementations spi: dw: Add support for AMD Pensando Elba SoC spi: dw: Add AMD Pensando Elba SoC SPI Controller spi: cadence-quadspi: Disable the SPI before reconfiguring spi: cadence-quadspi: Update the read timeout based on the length spi: spi-loopback-test: Add module param for iteration length spi: add support for Amlogic A1 SPI Flash Controller dt-bindings: spi: add Amlogic A1 SPI controller spi: fsl-spi: No need to check transfer length versus word size spi: fsl-spi: Change mspi_apply_cpu_mode_quirks() to void spi: fsl-cpm: Use 16 bit mode for large transfers with even size spi: fsl-spi: Re-organise transfer bits_per_word adaptation spi: fsl-spi: Fix CPM/QE mode Litte Endian ...
This commit is contained in:
commit
fc2e58b8b7
41
Documentation/devicetree/bindings/spi/amlogic,a1-spifc.yaml
Normal file
41
Documentation/devicetree/bindings/spi/amlogic,a1-spifc.yaml
Normal file
@ -0,0 +1,41 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/spi/amlogic,a1-spifc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Amlogic A1 SPI Flash Controller
|
||||
|
||||
maintainers:
|
||||
- Martin Kurbanov <mmkurbanov@sberdevices.ru>
|
||||
|
||||
allOf:
|
||||
- $ref: spi-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- amlogic,a1-spifc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
spi@fd000400 {
|
||||
compatible = "amlogic,a1-spifc";
|
||||
reg = <0xfd000400 0x290>;
|
||||
clocks = <&clkc_clkid_spifc>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
@ -19,6 +19,33 @@ allOf:
|
||||
then:
|
||||
required:
|
||||
- power-domains
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: starfive,jh7110-qspi
|
||||
then:
|
||||
properties:
|
||||
resets:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
|
||||
reset-names:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
items:
|
||||
enum: [ qspi, qspi-ocp, rstc_ref ]
|
||||
|
||||
else:
|
||||
properties:
|
||||
resets:
|
||||
maxItems: 2
|
||||
|
||||
reset-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
enum: [ qspi, qspi-ocp ]
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
@ -30,6 +57,7 @@ properties:
|
||||
- intel,lgm-qspi
|
||||
- xlnx,versal-ospi-1.0
|
||||
- intel,socfpga-qspi
|
||||
- starfive,jh7110-qspi
|
||||
- const: cdns,qspi-nor
|
||||
- const: cdns,qspi-nor
|
||||
|
||||
@ -79,13 +107,14 @@ properties:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 2
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
|
||||
reset-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
items:
|
||||
enum: [ qspi, qspi-ocp ]
|
||||
enum: [ qspi, qspi-ocp, rstc_ref ]
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
@ -149,23 +149,38 @@ required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- power-domains
|
||||
- '#address-cells'
|
||||
- '#size-cells'
|
||||
|
||||
if:
|
||||
not:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: renesas,sh-mobile-msiof
|
||||
then:
|
||||
required:
|
||||
- resets
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/r8a7791-clock.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/clock/r8a7791-cpg-mssr.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/r8a7791-sysc.h>
|
||||
|
||||
msiof0: spi@e6e20000 {
|
||||
compatible = "renesas,msiof-r8a7791", "renesas,rcar-gen2-msiof";
|
||||
reg = <0xe6e20000 0x0064>;
|
||||
interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&mstp0_clks R8A7791_CLK_MSIOF0>;
|
||||
interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cpg CPG_MOD 000>;
|
||||
dmas = <&dmac0 0x51>, <&dmac0 0x52>;
|
||||
dma-names = "tx", "rx";
|
||||
power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
|
||||
resets = <&cpg 0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
@ -37,6 +37,17 @@ allOf:
|
||||
else:
|
||||
required:
|
||||
- interrupts
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: amd,pensando-elba-spi
|
||||
then:
|
||||
required:
|
||||
- amd,pensando-elba-syscon
|
||||
else:
|
||||
properties:
|
||||
amd,pensando-elba-syscon: false
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
@ -63,6 +74,8 @@ properties:
|
||||
const: intel,keembay-ssi
|
||||
- description: Intel Thunder Bay SPI Controller
|
||||
const: intel,thunderbay-ssi
|
||||
- description: AMD Pensando Elba SoC SPI Controller
|
||||
const: amd,pensando-elba-spi
|
||||
- description: Baikal-T1 SPI Controller
|
||||
const: baikal,bt1-ssi
|
||||
- description: Baikal-T1 System Boot SPI Controller
|
||||
@ -136,6 +149,12 @@ properties:
|
||||
of the designware controller, and the upper limit is also subject to
|
||||
controller configuration.
|
||||
|
||||
amd,pensando-elba-syscon:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
description:
|
||||
Block address to control SPI chip-selects. The Elba SoC system controller
|
||||
provides an interface to override the native DWC SSI CS control.
|
||||
|
||||
patternProperties:
|
||||
"^.*@[0-9a-f]+$":
|
||||
type: object
|
||||
|
@ -178,10 +178,10 @@ shows up in sysfs in several locations::
|
||||
|
||||
/sys/bus/spi/drivers/D ... driver for one or more spi*.* devices
|
||||
|
||||
/sys/class/spi_master/spiB ... symlink (or actual device node) to
|
||||
a logical node which could hold class related state for the SPI
|
||||
master controller managing bus "B". All spiB.* devices share one
|
||||
physical SPI bus segment, with SCLK, MOSI, and MISO.
|
||||
/sys/class/spi_master/spiB ... symlink to a logical node which could hold
|
||||
class related state for the SPI master controller managing bus "B".
|
||||
All spiB.* devices share one physical SPI bus segment, with SCLK,
|
||||
MOSI, and MISO.
|
||||
|
||||
/sys/devices/.../CTLR/slave ... virtual file for (un)registering the
|
||||
slave device for an SPI slave controller.
|
||||
@ -191,16 +191,13 @@ shows up in sysfs in several locations::
|
||||
Reading from this file shows the name of the slave device ("(null)"
|
||||
if not registered).
|
||||
|
||||
/sys/class/spi_slave/spiB ... symlink (or actual device node) to
|
||||
a logical node which could hold class related state for the SPI
|
||||
slave controller on bus "B". When registered, a single spiB.*
|
||||
device is present here, possible sharing the physical SPI bus
|
||||
segment with other SPI slave devices.
|
||||
/sys/class/spi_slave/spiB ... symlink to a logical node which could hold
|
||||
class related state for the SPI slave controller on bus "B". When
|
||||
registered, a single spiB.* device is present here, possible sharing
|
||||
the physical SPI bus segment with other SPI slave devices.
|
||||
|
||||
Note that the actual location of the controller's class state depends
|
||||
on whether you enabled CONFIG_SYSFS_DEPRECATED or not. At this time,
|
||||
the only class-specific state is the bus number ("B" in "spiB"), so
|
||||
those /sys/class entries are only useful to quickly identify busses.
|
||||
At this time, the only class-specific state is the bus number ("B" in "spiB"),
|
||||
so those /sys/class entries are only useful to quickly identify busses.
|
||||
|
||||
|
||||
How does board-specific init code declare SPI devices?
|
||||
|
@ -18658,7 +18658,7 @@ F: include/linux/clk/samsung.h
|
||||
|
||||
SAMSUNG SPI DRIVERS
|
||||
M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
M: Andi Shyti <andi@etezian.org>
|
||||
M: Andi Shyti <andi.shyti@kernel.org>
|
||||
L: linux-spi@vger.kernel.org
|
||||
L: linux-samsung-soc@vger.kernel.org
|
||||
S: Maintained
|
||||
|
@ -144,7 +144,7 @@ static int __init fsl_spi_init(struct spi_board_info *board_infos,
|
||||
|
||||
static void mpc83xx_spi_cs_control(struct spi_device *spi, bool on)
|
||||
{
|
||||
pr_debug("%s %d %d\n", __func__, spi->chip_select, on);
|
||||
pr_debug("%s %d %d\n", __func__, spi_get_chipselect(spi, 0), on);
|
||||
par_io_data_set(3, 13, on);
|
||||
}
|
||||
|
||||
|
@ -466,7 +466,7 @@ static int adis16400_initial_setup(struct iio_dev *indio_dev)
|
||||
|
||||
dev_info(&indio_dev->dev, "%s: prod_id 0x%04x at CS%d (irq %d)\n",
|
||||
indio_dev->name, prod_id,
|
||||
st->adis.spi->chip_select, st->adis.spi->irq);
|
||||
spi_get_chipselect(st->adis.spi, 0), st->adis.spi->irq);
|
||||
}
|
||||
/* use high spi speed if possible */
|
||||
if (st->variant->flags & ADIS16400_HAS_SLOW_MODE) {
|
||||
|
@ -639,7 +639,7 @@ static int add_dataflash_otp(struct spi_device *spi, char *name, int nr_pages,
|
||||
|
||||
/* name must be usable with cmdlinepart */
|
||||
sprintf(priv->name, "spi%d.%d-%s",
|
||||
spi->master->bus_num, spi->chip_select,
|
||||
spi->master->bus_num, spi_get_chipselect(spi, 0),
|
||||
name);
|
||||
|
||||
device = &priv->mtd;
|
||||
|
@ -515,7 +515,7 @@ static int adin1110_register_mdiobus(struct adin1110_priv *priv,
|
||||
return -ENOMEM;
|
||||
|
||||
snprintf(priv->mii_bus_name, MII_BUS_ID_SIZE, "%s-%u",
|
||||
priv->cfg->name, priv->spidev->chip_select);
|
||||
priv->cfg->name, spi_get_chipselect(priv->spidev, 0));
|
||||
|
||||
mii_bus->name = priv->mii_bus_name;
|
||||
mii_bus->read = adin1110_mdio_read;
|
||||
|
@ -1006,7 +1006,7 @@ static int ax88796c_probe(struct spi_device *spi)
|
||||
ax_local->mdiobus->parent = &spi->dev;
|
||||
|
||||
snprintf(ax_local->mdiobus->id, MII_BUS_ID_SIZE,
|
||||
"ax88796c-%s.%u", dev_name(&spi->dev), spi->chip_select);
|
||||
"ax88796c-%s.%u", dev_name(&spi->dev), spi_get_chipselect(spi, 0));
|
||||
|
||||
ret = devm_mdiobus_register(&spi->dev, ax_local->mdiobus);
|
||||
if (ret < 0) {
|
||||
|
@ -1123,7 +1123,7 @@ static int dm9051_mdio_register(struct board_info *db)
|
||||
db->mdiobus->phy_mask = (u32)~BIT(1);
|
||||
db->mdiobus->parent = &spi->dev;
|
||||
snprintf(db->mdiobus->id, MII_BUS_ID_SIZE,
|
||||
"dm9051-%s.%u", dev_name(&spi->dev), spi->chip_select);
|
||||
"dm9051-%s.%u", dev_name(&spi->dev), spi_get_chipselect(spi, 0));
|
||||
|
||||
ret = devm_mdiobus_register(&spi->dev, db->mdiobus);
|
||||
if (ret)
|
||||
|
@ -119,7 +119,7 @@ qcaspi_info_show(struct seq_file *s, void *what)
|
||||
seq_printf(s, "SPI mode : %x\n",
|
||||
qca->spi_dev->mode);
|
||||
seq_printf(s, "SPI chip select : %u\n",
|
||||
(unsigned int)qca->spi_dev->chip_select);
|
||||
(unsigned int)spi_get_chipselect(qca->spi_dev, 0));
|
||||
seq_printf(s, "SPI legacy mode : %u\n",
|
||||
(unsigned int)qca->legacy_mode);
|
||||
seq_printf(s, "SPI burst length : %u\n",
|
||||
|
@ -2969,7 +2969,7 @@ static int ca8210_test_interface_init(struct ca8210_priv *priv)
|
||||
sizeof(node_name),
|
||||
"ca8210@%d_%d",
|
||||
priv->spi->master->bus_num,
|
||||
priv->spi->chip_select
|
||||
spi_get_chipselect(priv->spi, 0)
|
||||
);
|
||||
|
||||
test->ca8210_dfs_spi_int = debugfs_create_file(
|
||||
|
@ -211,7 +211,7 @@ static int slic_ds26522_probe(struct spi_device *spi)
|
||||
|
||||
ret = slic_ds26522_init_configure(spi);
|
||||
if (ret == 0)
|
||||
pr_info("DS26522 cs%d configured\n", spi->chip_select);
|
||||
pr_info("DS26522 cs%d configured\n", spi_get_chipselect(spi, 0));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1051,7 +1051,7 @@ static int if_spi_init_card(struct if_spi_card *card)
|
||||
"spi->max_speed_hz=%d\n",
|
||||
card->card_id, card->card_rev,
|
||||
card->spi->master->bus_num,
|
||||
card->spi->chip_select,
|
||||
spi_get_chipselect(card->spi, 0),
|
||||
card->spi->max_speed_hz);
|
||||
err = if_spi_prog_helper_firmware(card, helper);
|
||||
if (err)
|
||||
|
@ -208,7 +208,7 @@ static int wfx_spi_probe(struct spi_device *func)
|
||||
|
||||
/* Trace below is also displayed by spi_setup() if compiled with DEBUG */
|
||||
dev_dbg(&func->dev, "SPI params: CS=%d, mode=%d bits/word=%d speed=%d\n",
|
||||
func->chip_select, func->mode, func->bits_per_word, func->max_speed_hz);
|
||||
spi_get_chipselect(func, 0), func->mode, func->bits_per_word, func->max_speed_hz);
|
||||
if (func->bits_per_word != 16 && func->bits_per_word != 8)
|
||||
dev_warn(&func->dev, "unusual bits/word value: %d\n", func->bits_per_word);
|
||||
if (func->max_speed_hz > 50000000)
|
||||
|
@ -378,7 +378,7 @@ static int cw1200_spi_probe(struct spi_device *func)
|
||||
func->mode = SPI_MODE_0;
|
||||
|
||||
pr_info("cw1200_wlan_spi: Probe called (CS %d M %d BPW %d CLK %d)\n",
|
||||
func->chip_select, func->mode, func->bits_per_word,
|
||||
spi_get_chipselect(func, 0), func->mode, func->bits_per_word,
|
||||
func->max_speed_hz);
|
||||
|
||||
if (cw1200_spi_on(plat_data)) {
|
||||
|
@ -139,7 +139,8 @@ static int smi_spi_probe(struct platform_device *pdev, struct smi *smi,
|
||||
goto error;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "SPI device %s using chip select %u", name, spi_dev->chip_select);
|
||||
dev_dbg(dev, "SPI device %s using chip select %u", name,
|
||||
spi_get_chipselect(spi_dev, 0));
|
||||
|
||||
smi->spi_devs[i] = spi_dev;
|
||||
smi->spi_num++;
|
||||
|
@ -79,6 +79,13 @@ config SPI_ALTERA_DFL
|
||||
Altera SPI master controller. The SPI master is connected
|
||||
to a SPI slave to Avalon bridge in a Intel MAX BMC.
|
||||
|
||||
config SPI_AMLOGIC_SPIFC_A1
|
||||
tristate "Amlogic A1 SPIFC controller"
|
||||
depends on ARCH_MESON || COMPILE_TEST
|
||||
help
|
||||
This enables master mode support for the SPIFC (SPI flash
|
||||
controller) available in Amlogic A1 (A113L SoC).
|
||||
|
||||
config SPI_AR934X
|
||||
tristate "Qualcomm Atheros AR934X/QCA95XX SPI controller driver"
|
||||
depends on ATH79 || COMPILE_TEST
|
||||
@ -239,7 +246,7 @@ config SPI_CADENCE
|
||||
|
||||
config SPI_CADENCE_QUADSPI
|
||||
tristate "Cadence Quad SPI controller"
|
||||
depends on OF && (ARM || ARM64 || X86 || COMPILE_TEST)
|
||||
depends on OF && (ARM || ARM64 || X86 || RISCV || COMPILE_TEST)
|
||||
help
|
||||
Enable support for the Cadence Quad SPI Flash controller.
|
||||
|
||||
@ -276,7 +283,7 @@ config SPI_COLDFIRE_QSPI
|
||||
|
||||
config SPI_DAVINCI
|
||||
tristate "Texas Instruments DaVinci/DA8x/OMAP-L/AM1x SoC SPI controller"
|
||||
depends on ARCH_DAVINCI || ARCH_KEYSTONE
|
||||
depends on ARCH_DAVINCI || ARCH_KEYSTONE || COMPILE_TEST
|
||||
select SPI_BITBANG
|
||||
help
|
||||
SPI master controller for DaVinci/DA8x/OMAP-L/AM1x SPI modules.
|
||||
@ -406,7 +413,8 @@ config SPI_HISI_SFC_V3XX
|
||||
|
||||
config SPI_NXP_FLEXSPI
|
||||
tristate "NXP Flex SPI controller"
|
||||
depends on ARCH_LAYERSCAPE || HAS_IOMEM
|
||||
depends on ARCH_LAYERSCAPE || ARCH_MXC || COMPILE_TEST
|
||||
depends on HAS_IOMEM
|
||||
help
|
||||
This enables support for the Flex SPI controller in master mode.
|
||||
Up to four slave devices can be connected on two buses with two
|
||||
@ -777,6 +785,7 @@ config SPI_PXA2XX_PCI
|
||||
|
||||
config SPI_ROCKCHIP
|
||||
tristate "Rockchip SPI controller driver"
|
||||
depends on ARCH_ROCKCHIP || COMPILE_TEST
|
||||
help
|
||||
This selects a driver for Rockchip SPI controller.
|
||||
|
||||
@ -818,7 +827,7 @@ config SPI_RSPI
|
||||
|
||||
config SPI_QCOM_QSPI
|
||||
tristate "QTI QSPI controller"
|
||||
depends on ARCH_QCOM
|
||||
depends on ARCH_QCOM || COMPILE_TEST
|
||||
help
|
||||
QSPI(Quad SPI) driver for Qualcomm QSPI controller.
|
||||
|
||||
|
@ -17,6 +17,7 @@ obj-$(CONFIG_SPI_LOOPBACK_TEST) += spi-loopback-test.o
|
||||
obj-$(CONFIG_SPI_ALTERA) += spi-altera-platform.o
|
||||
obj-$(CONFIG_SPI_ALTERA_CORE) += spi-altera-core.o
|
||||
obj-$(CONFIG_SPI_ALTERA_DFL) += spi-altera-dfl.o
|
||||
obj-$(CONFIG_SPI_AMLOGIC_SPIFC_A1) += spi-amlogic-spifc-a1.o
|
||||
obj-$(CONFIG_SPI_AR934X) += spi-ar934x.o
|
||||
obj-$(CONFIG_SPI_ARMADA_3700) += spi-armada-3700.o
|
||||
obj-$(CONFIG_SPI_ASPEED_SMC) += spi-aspeed-smc.o
|
||||
|
@ -700,25 +700,33 @@ disable_pclk:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int atmel_qspi_remove(struct platform_device *pdev)
|
||||
static void atmel_qspi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_controller *ctrl = platform_get_drvdata(pdev);
|
||||
struct atmel_qspi *aq = spi_controller_get_devdata(ctrl);
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_resume_and_get(&pdev->dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
spi_unregister_controller(ctrl);
|
||||
atmel_qspi_write(QSPI_CR_QSPIDIS, aq, QSPI_CR);
|
||||
|
||||
ret = pm_runtime_get_sync(&pdev->dev);
|
||||
if (ret >= 0) {
|
||||
atmel_qspi_write(QSPI_CR_QSPIDIS, aq, QSPI_CR);
|
||||
clk_disable(aq->qspick);
|
||||
clk_disable(aq->pclk);
|
||||
} else {
|
||||
/*
|
||||
* atmel_qspi_runtime_{suspend,resume} just disable and enable
|
||||
* the two clks respectively. So after resume failed these are
|
||||
* off, and we skip hardware access and disabling these clks again.
|
||||
*/
|
||||
dev_warn(&pdev->dev, "Failed to resume device on remove\n");
|
||||
}
|
||||
|
||||
clk_unprepare(aq->qspick);
|
||||
clk_unprepare(aq->pclk);
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
pm_runtime_put_noidle(&pdev->dev);
|
||||
|
||||
clk_disable_unprepare(aq->qspick);
|
||||
clk_disable_unprepare(aq->pclk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused atmel_qspi_suspend(struct device *dev)
|
||||
@ -786,7 +794,11 @@ static int __maybe_unused atmel_qspi_runtime_resume(struct device *dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return clk_enable(aq->qspick);
|
||||
ret = clk_enable(aq->qspick);
|
||||
if (ret)
|
||||
clk_disable(aq->pclk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops __maybe_unused atmel_qspi_pm_ops = {
|
||||
@ -823,7 +835,7 @@ static struct platform_driver atmel_qspi_driver = {
|
||||
.pm = pm_ptr(&atmel_qspi_pm_ops),
|
||||
},
|
||||
.probe = atmel_qspi_probe,
|
||||
.remove = atmel_qspi_remove,
|
||||
.remove_new = atmel_qspi_remove,
|
||||
};
|
||||
module_platform_driver(atmel_qspi_driver);
|
||||
|
||||
|
@ -80,7 +80,7 @@ static void altera_spi_set_cs(struct spi_device *spi, bool is_high)
|
||||
altr_spi_writel(hw, ALTERA_SPI_TARGET_SEL, 0);
|
||||
} else {
|
||||
altr_spi_writel(hw, ALTERA_SPI_TARGET_SEL,
|
||||
BIT(spi->chip_select));
|
||||
BIT(spi_get_chipselect(spi, 0)));
|
||||
hw->imr |= ALTERA_SPI_CONTROL_SSO_MSK;
|
||||
altr_spi_writel(hw, ALTERA_SPI_CONTROL, hw->imr);
|
||||
}
|
||||
|
@ -347,7 +347,7 @@ fin_msg:
|
||||
case AMD_SPI_V1:
|
||||
break;
|
||||
case AMD_SPI_V2:
|
||||
amd_spi_clear_chip(amd_spi, message->spi->chip_select);
|
||||
amd_spi_clear_chip(amd_spi, spi_get_chipselect(message->spi, 0));
|
||||
break;
|
||||
default:
|
||||
return -ENODEV;
|
||||
@ -364,7 +364,7 @@ static int amd_spi_master_transfer(struct spi_master *master,
|
||||
struct amd_spi *amd_spi = spi_master_get_devdata(master);
|
||||
struct spi_device *spi = msg->spi;
|
||||
|
||||
amd_spi_select_chip(amd_spi, spi->chip_select);
|
||||
amd_spi_select_chip(amd_spi, spi_get_chipselect(spi, 0));
|
||||
|
||||
/*
|
||||
* Extract spi_transfers from the spi message and
|
||||
|
456
drivers/spi/spi-amlogic-spifc-a1.c
Normal file
456
drivers/spi/spi-amlogic-spifc-a1.c
Normal file
@ -0,0 +1,456 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Driver for Amlogic A1 SPI flash controller (SPIFC)
|
||||
*
|
||||
* Copyright (c) 2023, SberDevices. All Rights Reserved.
|
||||
*
|
||||
* Author: Martin Kurbanov <mmkurbanov@sberdevices.ru>
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.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>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define SPIFC_A1_AHB_CTRL_REG 0x0
|
||||
#define SPIFC_A1_AHB_BUS_EN BIT(31)
|
||||
|
||||
#define SPIFC_A1_USER_CTRL0_REG 0x200
|
||||
#define SPIFC_A1_USER_REQUEST_ENABLE BIT(31)
|
||||
#define SPIFC_A1_USER_REQUEST_FINISH BIT(30)
|
||||
#define SPIFC_A1_USER_DATA_UPDATED BIT(0)
|
||||
|
||||
#define SPIFC_A1_USER_CTRL1_REG 0x204
|
||||
#define SPIFC_A1_USER_CMD_ENABLE BIT(30)
|
||||
#define SPIFC_A1_USER_CMD_MODE GENMASK(29, 28)
|
||||
#define SPIFC_A1_USER_CMD_CODE GENMASK(27, 20)
|
||||
#define SPIFC_A1_USER_ADDR_ENABLE BIT(19)
|
||||
#define SPIFC_A1_USER_ADDR_MODE GENMASK(18, 17)
|
||||
#define SPIFC_A1_USER_ADDR_BYTES GENMASK(16, 15)
|
||||
#define SPIFC_A1_USER_DOUT_ENABLE BIT(14)
|
||||
#define SPIFC_A1_USER_DOUT_MODE GENMASK(11, 10)
|
||||
#define SPIFC_A1_USER_DOUT_BYTES GENMASK(9, 0)
|
||||
|
||||
#define SPIFC_A1_USER_CTRL2_REG 0x208
|
||||
#define SPIFC_A1_USER_DUMMY_ENABLE BIT(31)
|
||||
#define SPIFC_A1_USER_DUMMY_MODE GENMASK(30, 29)
|
||||
#define SPIFC_A1_USER_DUMMY_CLK_SYCLES GENMASK(28, 23)
|
||||
|
||||
#define SPIFC_A1_USER_CTRL3_REG 0x20c
|
||||
#define SPIFC_A1_USER_DIN_ENABLE BIT(31)
|
||||
#define SPIFC_A1_USER_DIN_MODE GENMASK(28, 27)
|
||||
#define SPIFC_A1_USER_DIN_BYTES GENMASK(25, 16)
|
||||
|
||||
#define SPIFC_A1_USER_ADDR_REG 0x210
|
||||
|
||||
#define SPIFC_A1_AHB_REQ_CTRL_REG 0x214
|
||||
#define SPIFC_A1_AHB_REQ_ENABLE BIT(31)
|
||||
|
||||
#define SPIFC_A1_ACTIMING0_REG (0x0088 << 2)
|
||||
#define SPIFC_A1_TSLCH GENMASK(31, 30)
|
||||
#define SPIFC_A1_TCLSH GENMASK(29, 28)
|
||||
#define SPIFC_A1_TSHWL GENMASK(20, 16)
|
||||
#define SPIFC_A1_TSHSL2 GENMASK(15, 12)
|
||||
#define SPIFC_A1_TSHSL1 GENMASK(11, 8)
|
||||
#define SPIFC_A1_TWHSL GENMASK(7, 0)
|
||||
|
||||
#define SPIFC_A1_DBUF_CTRL_REG 0x240
|
||||
#define SPIFC_A1_DBUF_DIR BIT(31)
|
||||
#define SPIFC_A1_DBUF_AUTO_UPDATE_ADDR BIT(30)
|
||||
#define SPIFC_A1_DBUF_ADDR GENMASK(7, 0)
|
||||
|
||||
#define SPIFC_A1_DBUF_DATA_REG 0x244
|
||||
|
||||
#define SPIFC_A1_USER_DBUF_ADDR_REG 0x248
|
||||
|
||||
#define SPIFC_A1_BUFFER_SIZE 512
|
||||
|
||||
#define SPIFC_A1_MAX_HZ 200000000
|
||||
#define SPIFC_A1_MIN_HZ 1000000
|
||||
|
||||
#define SPIFC_A1_USER_CMD(op) ( \
|
||||
SPIFC_A1_USER_CMD_ENABLE | \
|
||||
FIELD_PREP(SPIFC_A1_USER_CMD_CODE, (op)->cmd.opcode) | \
|
||||
FIELD_PREP(SPIFC_A1_USER_CMD_MODE, ilog2((op)->cmd.buswidth)))
|
||||
|
||||
#define SPIFC_A1_USER_ADDR(op) ( \
|
||||
SPIFC_A1_USER_ADDR_ENABLE | \
|
||||
FIELD_PREP(SPIFC_A1_USER_ADDR_MODE, ilog2((op)->addr.buswidth)) | \
|
||||
FIELD_PREP(SPIFC_A1_USER_ADDR_BYTES, (op)->addr.nbytes - 1))
|
||||
|
||||
#define SPIFC_A1_USER_DUMMY(op) ( \
|
||||
SPIFC_A1_USER_DUMMY_ENABLE | \
|
||||
FIELD_PREP(SPIFC_A1_USER_DUMMY_MODE, ilog2((op)->dummy.buswidth)) | \
|
||||
FIELD_PREP(SPIFC_A1_USER_DUMMY_CLK_SYCLES, (op)->dummy.nbytes << 3))
|
||||
|
||||
#define SPIFC_A1_TSLCH_VAL FIELD_PREP(SPIFC_A1_TSLCH, 1)
|
||||
#define SPIFC_A1_TCLSH_VAL FIELD_PREP(SPIFC_A1_TCLSH, 1)
|
||||
#define SPIFC_A1_TSHWL_VAL FIELD_PREP(SPIFC_A1_TSHWL, 7)
|
||||
#define SPIFC_A1_TSHSL2_VAL FIELD_PREP(SPIFC_A1_TSHSL2, 7)
|
||||
#define SPIFC_A1_TSHSL1_VAL FIELD_PREP(SPIFC_A1_TSHSL1, 7)
|
||||
#define SPIFC_A1_TWHSL_VAL FIELD_PREP(SPIFC_A1_TWHSL, 2)
|
||||
#define SPIFC_A1_ACTIMING0_VAL (SPIFC_A1_TSLCH_VAL | SPIFC_A1_TCLSH_VAL | \
|
||||
SPIFC_A1_TSHWL_VAL | SPIFC_A1_TSHSL2_VAL | \
|
||||
SPIFC_A1_TSHSL1_VAL | SPIFC_A1_TWHSL_VAL)
|
||||
|
||||
struct amlogic_spifc_a1 {
|
||||
struct spi_controller *ctrl;
|
||||
struct clk *clk;
|
||||
struct device *dev;
|
||||
void __iomem *base;
|
||||
};
|
||||
|
||||
static int amlogic_spifc_a1_request(struct amlogic_spifc_a1 *spifc, bool read)
|
||||
{
|
||||
u32 mask = SPIFC_A1_USER_REQUEST_FINISH |
|
||||
(read ? SPIFC_A1_USER_DATA_UPDATED : 0);
|
||||
u32 val;
|
||||
|
||||
writel(SPIFC_A1_USER_REQUEST_ENABLE,
|
||||
spifc->base + SPIFC_A1_USER_CTRL0_REG);
|
||||
|
||||
return readl_poll_timeout(spifc->base + SPIFC_A1_USER_CTRL0_REG,
|
||||
val, (val & mask) == mask, 0,
|
||||
200 * USEC_PER_MSEC);
|
||||
}
|
||||
|
||||
static void amlogic_spifc_a1_drain_buffer(struct amlogic_spifc_a1 *spifc,
|
||||
char *buf, u32 len)
|
||||
{
|
||||
u32 data;
|
||||
const u32 count = len / sizeof(data);
|
||||
const u32 pad = len % sizeof(data);
|
||||
|
||||
writel(SPIFC_A1_DBUF_AUTO_UPDATE_ADDR,
|
||||
spifc->base + SPIFC_A1_DBUF_CTRL_REG);
|
||||
ioread32_rep(spifc->base + SPIFC_A1_DBUF_DATA_REG, buf, count);
|
||||
|
||||
if (pad) {
|
||||
data = readl(spifc->base + SPIFC_A1_DBUF_DATA_REG);
|
||||
memcpy(buf + len - pad, &data, pad);
|
||||
}
|
||||
}
|
||||
|
||||
static void amlogic_spifc_a1_fill_buffer(struct amlogic_spifc_a1 *spifc,
|
||||
const char *buf, u32 len)
|
||||
{
|
||||
u32 data;
|
||||
const u32 count = len / sizeof(data);
|
||||
const u32 pad = len % sizeof(data);
|
||||
|
||||
writel(SPIFC_A1_DBUF_DIR | SPIFC_A1_DBUF_AUTO_UPDATE_ADDR,
|
||||
spifc->base + SPIFC_A1_DBUF_CTRL_REG);
|
||||
iowrite32_rep(spifc->base + SPIFC_A1_DBUF_DATA_REG, buf, count);
|
||||
|
||||
if (pad) {
|
||||
memcpy(&data, buf + len - pad, pad);
|
||||
writel(data, spifc->base + SPIFC_A1_DBUF_DATA_REG);
|
||||
}
|
||||
}
|
||||
|
||||
static void amlogic_spifc_a1_user_init(struct amlogic_spifc_a1 *spifc)
|
||||
{
|
||||
writel(0, spifc->base + SPIFC_A1_USER_CTRL0_REG);
|
||||
writel(0, spifc->base + SPIFC_A1_USER_CTRL1_REG);
|
||||
writel(0, spifc->base + SPIFC_A1_USER_CTRL2_REG);
|
||||
writel(0, spifc->base + SPIFC_A1_USER_CTRL3_REG);
|
||||
}
|
||||
|
||||
static void amlogic_spifc_a1_set_cmd(struct amlogic_spifc_a1 *spifc,
|
||||
u32 cmd_cfg)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl(spifc->base + SPIFC_A1_USER_CTRL1_REG);
|
||||
val &= ~(SPIFC_A1_USER_CMD_MODE | SPIFC_A1_USER_CMD_CODE);
|
||||
val |= cmd_cfg;
|
||||
writel(val, spifc->base + SPIFC_A1_USER_CTRL1_REG);
|
||||
}
|
||||
|
||||
static void amlogic_spifc_a1_set_addr(struct amlogic_spifc_a1 *spifc, u32 addr,
|
||||
u32 addr_cfg)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
writel(addr, spifc->base + SPIFC_A1_USER_ADDR_REG);
|
||||
|
||||
val = readl(spifc->base + SPIFC_A1_USER_CTRL1_REG);
|
||||
val &= ~(SPIFC_A1_USER_ADDR_MODE | SPIFC_A1_USER_ADDR_BYTES);
|
||||
val |= addr_cfg;
|
||||
writel(val, spifc->base + SPIFC_A1_USER_CTRL1_REG);
|
||||
}
|
||||
|
||||
static void amlogic_spifc_a1_set_dummy(struct amlogic_spifc_a1 *spifc,
|
||||
u32 dummy_cfg)
|
||||
{
|
||||
u32 val = readl(spifc->base + SPIFC_A1_USER_CTRL2_REG);
|
||||
|
||||
val &= ~(SPIFC_A1_USER_DUMMY_MODE | SPIFC_A1_USER_DUMMY_CLK_SYCLES);
|
||||
val |= dummy_cfg;
|
||||
writel(val, spifc->base + SPIFC_A1_USER_CTRL2_REG);
|
||||
}
|
||||
|
||||
static int amlogic_spifc_a1_read(struct amlogic_spifc_a1 *spifc, void *buf,
|
||||
u32 size, u32 mode)
|
||||
{
|
||||
u32 val = readl(spifc->base + SPIFC_A1_USER_CTRL3_REG);
|
||||
int ret;
|
||||
|
||||
val &= ~(SPIFC_A1_USER_DIN_MODE | SPIFC_A1_USER_DIN_BYTES);
|
||||
val |= SPIFC_A1_USER_DIN_ENABLE;
|
||||
val |= FIELD_PREP(SPIFC_A1_USER_DIN_MODE, mode);
|
||||
val |= FIELD_PREP(SPIFC_A1_USER_DIN_BYTES, size);
|
||||
writel(val, spifc->base + SPIFC_A1_USER_CTRL3_REG);
|
||||
|
||||
ret = amlogic_spifc_a1_request(spifc, true);
|
||||
if (!ret)
|
||||
amlogic_spifc_a1_drain_buffer(spifc, buf, size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int amlogic_spifc_a1_write(struct amlogic_spifc_a1 *spifc,
|
||||
const void *buf, u32 size, u32 mode)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
amlogic_spifc_a1_fill_buffer(spifc, buf, size);
|
||||
|
||||
val = readl(spifc->base + SPIFC_A1_USER_CTRL1_REG);
|
||||
val &= ~(SPIFC_A1_USER_DOUT_MODE | SPIFC_A1_USER_DOUT_BYTES);
|
||||
val |= FIELD_PREP(SPIFC_A1_USER_DOUT_MODE, mode);
|
||||
val |= FIELD_PREP(SPIFC_A1_USER_DOUT_BYTES, size);
|
||||
val |= SPIFC_A1_USER_DOUT_ENABLE;
|
||||
writel(val, spifc->base + SPIFC_A1_USER_CTRL1_REG);
|
||||
|
||||
return amlogic_spifc_a1_request(spifc, false);
|
||||
}
|
||||
|
||||
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;
|
||||
int ret;
|
||||
|
||||
amlogic_spifc_a1_user_init(spifc);
|
||||
|
||||
cmd_cfg = SPIFC_A1_USER_CMD(op);
|
||||
amlogic_spifc_a1_set_cmd(spifc, cmd_cfg);
|
||||
|
||||
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) {
|
||||
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);
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void amlogic_spifc_a1_hw_init(struct amlogic_spifc_a1 *spifc)
|
||||
{
|
||||
u32 regv;
|
||||
|
||||
regv = readl(spifc->base + SPIFC_A1_AHB_REQ_CTRL_REG);
|
||||
regv &= ~(SPIFC_A1_AHB_REQ_ENABLE);
|
||||
writel(regv, spifc->base + SPIFC_A1_AHB_REQ_CTRL_REG);
|
||||
|
||||
regv = readl(spifc->base + SPIFC_A1_AHB_CTRL_REG);
|
||||
regv &= ~(SPIFC_A1_AHB_BUS_EN);
|
||||
writel(regv, spifc->base + SPIFC_A1_AHB_CTRL_REG);
|
||||
|
||||
writel(SPIFC_A1_ACTIMING0_VAL, spifc->base + SPIFC_A1_ACTIMING0_REG);
|
||||
|
||||
writel(0, spifc->base + SPIFC_A1_USER_DBUF_ADDR_REG);
|
||||
}
|
||||
|
||||
static const struct spi_controller_mem_ops amlogic_spifc_a1_mem_ops = {
|
||||
.exec_op = amlogic_spifc_a1_exec_op,
|
||||
};
|
||||
|
||||
static int amlogic_spifc_a1_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_controller *ctrl;
|
||||
struct amlogic_spifc_a1 *spifc;
|
||||
int ret;
|
||||
|
||||
ctrl = devm_spi_alloc_master(&pdev->dev, sizeof(*spifc));
|
||||
if (!ctrl)
|
||||
return -ENOMEM;
|
||||
|
||||
spifc = spi_controller_get_devdata(ctrl);
|
||||
platform_set_drvdata(pdev, spifc);
|
||||
|
||||
spifc->dev = &pdev->dev;
|
||||
spifc->ctrl = ctrl;
|
||||
|
||||
spifc->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(spifc->base))
|
||||
return PTR_ERR(spifc->base);
|
||||
|
||||
spifc->clk = devm_clk_get_enabled(spifc->dev, NULL);
|
||||
if (IS_ERR(spifc->clk))
|
||||
return dev_err_probe(spifc->dev, PTR_ERR(spifc->clk),
|
||||
"unable to get clock\n");
|
||||
|
||||
amlogic_spifc_a1_hw_init(spifc);
|
||||
|
||||
pm_runtime_set_autosuspend_delay(spifc->dev, 500);
|
||||
pm_runtime_use_autosuspend(spifc->dev);
|
||||
devm_pm_runtime_enable(spifc->dev);
|
||||
|
||||
ctrl->num_chipselect = 1;
|
||||
ctrl->dev.of_node = pdev->dev.of_node;
|
||||
ctrl->bits_per_word_mask = SPI_BPW_MASK(8);
|
||||
ctrl->auto_runtime_pm = true;
|
||||
ctrl->mem_ops = &amlogic_spifc_a1_mem_ops;
|
||||
ctrl->min_speed_hz = SPIFC_A1_MIN_HZ;
|
||||
ctrl->max_speed_hz = SPIFC_A1_MAX_HZ;
|
||||
ctrl->mode_bits = (SPI_RX_DUAL | SPI_TX_DUAL |
|
||||
SPI_RX_QUAD | SPI_TX_QUAD);
|
||||
|
||||
ret = devm_spi_register_controller(spifc->dev, ctrl);
|
||||
if (ret)
|
||||
return dev_err_probe(spifc->dev, ret,
|
||||
"failed to register spi controller\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int amlogic_spifc_a1_suspend(struct device *dev)
|
||||
{
|
||||
struct amlogic_spifc_a1 *spifc = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = spi_controller_suspend(spifc->ctrl);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!pm_runtime_suspended(dev))
|
||||
clk_disable_unprepare(spifc->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amlogic_spifc_a1_resume(struct device *dev)
|
||||
{
|
||||
struct amlogic_spifc_a1 *spifc = dev_get_drvdata(dev);
|
||||
int ret = 0;
|
||||
|
||||
if (!pm_runtime_suspended(dev)) {
|
||||
ret = clk_prepare_enable(spifc->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
amlogic_spifc_a1_hw_init(spifc);
|
||||
|
||||
ret = spi_controller_resume(spifc->ctrl);
|
||||
if (ret)
|
||||
clk_disable_unprepare(spifc->clk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int amlogic_spifc_a1_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct amlogic_spifc_a1 *spifc = dev_get_drvdata(dev);
|
||||
|
||||
clk_disable_unprepare(spifc->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amlogic_spifc_a1_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct amlogic_spifc_a1 *spifc = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(spifc->clk);
|
||||
if (!ret)
|
||||
amlogic_spifc_a1_hw_init(spifc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static const struct dev_pm_ops amlogic_spifc_a1_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(amlogic_spifc_a1_suspend,
|
||||
amlogic_spifc_a1_resume)
|
||||
SET_RUNTIME_PM_OPS(amlogic_spifc_a1_runtime_suspend,
|
||||
amlogic_spifc_a1_runtime_resume,
|
||||
NULL)
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id amlogic_spifc_a1_dt_match[] = {
|
||||
{ .compatible = "amlogic,a1-spifc", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, amlogic_spifc_a1_dt_match);
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
static struct platform_driver amlogic_spifc_a1_driver = {
|
||||
.probe = amlogic_spifc_a1_probe,
|
||||
.driver = {
|
||||
.name = "amlogic-spifc-a1",
|
||||
.of_match_table = of_match_ptr(amlogic_spifc_a1_dt_match),
|
||||
.pm = &amlogic_spifc_a1_pm_ops,
|
||||
},
|
||||
};
|
||||
module_platform_driver(amlogic_spifc_a1_driver);
|
||||
|
||||
MODULE_AUTHOR("Martin Kurbanov <mmkurbanov@sberdevices.ru>");
|
||||
MODULE_DESCRIPTION("Amlogic A1 SPIFC driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -125,7 +125,7 @@ static int ar934x_spi_transfer_one_message(struct spi_controller *ctlr,
|
||||
iowrite32(reg, sp->base + AR934X_SPI_DATAOUT);
|
||||
}
|
||||
|
||||
reg = AR934X_SPI_SHIFT_VAL(spi->chip_select, term,
|
||||
reg = AR934X_SPI_SHIFT_VAL(spi_get_chipselect(spi, 0), term,
|
||||
trx_cur * 8);
|
||||
iowrite32(reg, sp->base + AR934X_SPI_REG_SHIFT_CTRL);
|
||||
stat = readl_poll_timeout(
|
||||
@ -220,7 +220,7 @@ err_clk_disable:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ar934x_spi_remove(struct platform_device *pdev)
|
||||
static void ar934x_spi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_controller *ctlr;
|
||||
struct ar934x_spi *sp;
|
||||
@ -230,8 +230,6 @@ static int ar934x_spi_remove(struct platform_device *pdev)
|
||||
|
||||
spi_unregister_controller(ctlr);
|
||||
clk_disable_unprepare(sp->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver ar934x_spi_driver = {
|
||||
@ -240,7 +238,7 @@ static struct platform_driver ar934x_spi_driver = {
|
||||
.of_match_table = ar934x_spi_match,
|
||||
},
|
||||
.probe = ar934x_spi_probe,
|
||||
.remove = ar934x_spi_remove,
|
||||
.remove_new = ar934x_spi_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(ar934x_spi_driver);
|
||||
|
@ -437,9 +437,9 @@ static void a3700_spi_set_cs(struct spi_device *spi, bool enable)
|
||||
struct a3700_spi *a3700_spi = spi_controller_get_devdata(spi->controller);
|
||||
|
||||
if (!enable)
|
||||
a3700_spi_activate_cs(a3700_spi, spi->chip_select);
|
||||
a3700_spi_activate_cs(a3700_spi, spi_get_chipselect(spi, 0));
|
||||
else
|
||||
a3700_spi_deactivate_cs(a3700_spi, spi->chip_select);
|
||||
a3700_spi_deactivate_cs(a3700_spi, spi_get_chipselect(spi, 0));
|
||||
}
|
||||
|
||||
static void a3700_spi_header_set(struct a3700_spi *a3700_spi)
|
||||
@ -908,14 +908,12 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int a3700_spi_remove(struct platform_device *pdev)
|
||||
static void a3700_spi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_controller *host = platform_get_drvdata(pdev);
|
||||
struct a3700_spi *spi = spi_controller_get_devdata(host);
|
||||
|
||||
clk_unprepare(spi->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver a3700_spi_driver = {
|
||||
@ -924,7 +922,7 @@ static struct platform_driver a3700_spi_driver = {
|
||||
.of_match_table = of_match_ptr(a3700_spi_dt_ids),
|
||||
},
|
||||
.probe = a3700_spi_probe,
|
||||
.remove = a3700_spi_remove,
|
||||
.remove_new = a3700_spi_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(a3700_spi_driver);
|
||||
|
@ -296,7 +296,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_chip *chip = &aspi->chips[mem->spi->chip_select];
|
||||
struct aspeed_spi_chip *chip = &aspi->chips[spi_get_chipselect(mem->spi, 0)];
|
||||
u32 addr_mode, addr_mode_backup;
|
||||
u32 ctl_val;
|
||||
int ret = 0;
|
||||
@ -377,7 +377,8 @@ static const char *aspeed_spi_get_name(struct spi_mem *mem)
|
||||
struct aspeed_spi *aspi = spi_controller_get_devdata(mem->spi->master);
|
||||
struct device *dev = aspi->dev;
|
||||
|
||||
return devm_kasprintf(dev, GFP_KERNEL, "%s.%d", dev_name(dev), mem->spi->chip_select);
|
||||
return devm_kasprintf(dev, GFP_KERNEL, "%s.%d", dev_name(dev),
|
||||
spi_get_chipselect(mem->spi, 0));
|
||||
}
|
||||
|
||||
struct aspeed_spi_window {
|
||||
@ -553,7 +554,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_chip *chip = &aspi->chips[desc->mem->spi->chip_select];
|
||||
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;
|
||||
int ret = 0;
|
||||
@ -620,7 +621,7 @@ 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_chip *chip = &aspi->chips[desc->mem->spi->chip_select];
|
||||
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 */
|
||||
if (chip->ahb_window_size < offset + len) {
|
||||
@ -670,7 +671,7 @@ static int aspeed_spi_setup(struct spi_device *spi)
|
||||
{
|
||||
struct aspeed_spi *aspi = spi_controller_get_devdata(spi->master);
|
||||
const struct aspeed_spi_data *data = aspi->data;
|
||||
unsigned int cs = spi->chip_select;
|
||||
unsigned int cs = spi_get_chipselect(spi, 0);
|
||||
struct aspeed_spi_chip *chip = &aspi->chips[cs];
|
||||
|
||||
chip->aspi = aspi;
|
||||
@ -697,7 +698,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);
|
||||
unsigned int cs = spi->chip_select;
|
||||
unsigned int cs = spi_get_chipselect(spi, 0);
|
||||
|
||||
aspeed_spi_chip_enable(aspi, cs, false);
|
||||
|
||||
@ -787,13 +788,12 @@ disable_clk:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aspeed_spi_remove(struct platform_device *pdev)
|
||||
static void aspeed_spi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct aspeed_spi *aspi = platform_get_drvdata(pdev);
|
||||
|
||||
aspeed_spi_enable(aspi, false);
|
||||
clk_disable_unprepare(aspi->clk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1201,7 +1201,7 @@ MODULE_DEVICE_TABLE(of, aspeed_spi_matches);
|
||||
|
||||
static struct platform_driver aspeed_spi_driver = {
|
||||
.probe = aspeed_spi_probe,
|
||||
.remove = aspeed_spi_remove,
|
||||
.remove_new = aspeed_spi_remove,
|
||||
.driver = {
|
||||
.name = DEVICE_NAME,
|
||||
.of_match_table = aspeed_spi_matches,
|
||||
|
@ -390,7 +390,7 @@ static int at91_usart_spi_setup(struct spi_device *spi)
|
||||
|
||||
dev_dbg(&spi->dev,
|
||||
"setup: bpw %u mode 0x%x -> mr %d %08x\n",
|
||||
spi->bits_per_word, spi->mode, spi->chip_select, mr);
|
||||
spi->bits_per_word, spi->mode, spi_get_chipselect(spi, 0), mr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -647,15 +647,13 @@ __maybe_unused static int at91_usart_spi_resume(struct device *dev)
|
||||
return spi_controller_resume(ctrl);
|
||||
}
|
||||
|
||||
static int at91_usart_spi_remove(struct platform_device *pdev)
|
||||
static void at91_usart_spi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_controller *ctlr = platform_get_drvdata(pdev);
|
||||
struct at91_usart_spi *aus = spi_controller_get_devdata(ctlr);
|
||||
|
||||
at91_usart_spi_release_dma(ctlr);
|
||||
clk_disable_unprepare(aus->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops at91_usart_spi_pm_ops = {
|
||||
@ -670,7 +668,7 @@ static struct platform_driver at91_usart_spi_driver = {
|
||||
.pm = &at91_usart_spi_pm_ops,
|
||||
},
|
||||
.probe = at91_usart_spi_probe,
|
||||
.remove = at91_usart_spi_remove,
|
||||
.remove_new = at91_usart_spi_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(at91_usart_spi_driver);
|
||||
|
@ -71,7 +71,7 @@ static void ath79_spi_chipselect(struct spi_device *spi, int is_active)
|
||||
{
|
||||
struct ath79_spi *sp = ath79_spidev_to_sp(spi);
|
||||
int cs_high = (spi->mode & SPI_CS_HIGH) ? is_active : !is_active;
|
||||
u32 cs_bit = AR71XX_SPI_IOC_CS(spi->chip_select);
|
||||
u32 cs_bit = AR71XX_SPI_IOC_CS(spi_get_chipselect(spi, 0));
|
||||
|
||||
if (cs_high)
|
||||
sp->ioc_base |= cs_bit;
|
||||
@ -140,7 +140,7 @@ static int ath79_exec_mem_op(struct spi_mem *mem,
|
||||
struct ath79_spi *sp = ath79_spidev_to_sp(mem->spi);
|
||||
|
||||
/* Ensures that reading is performed on device connected to hardware cs0 */
|
||||
if (mem->spi->chip_select || mem->spi->cs_gpiod)
|
||||
if (spi_get_chipselect(mem->spi, 0) || spi_get_csgpiod(mem->spi, 0))
|
||||
return -ENOTSUPP;
|
||||
|
||||
/* Only use for fast-read op. */
|
||||
@ -237,7 +237,7 @@ err_put_host:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath79_spi_remove(struct platform_device *pdev)
|
||||
static void ath79_spi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct ath79_spi *sp = platform_get_drvdata(pdev);
|
||||
|
||||
@ -245,8 +245,6 @@ static int ath79_spi_remove(struct platform_device *pdev)
|
||||
ath79_spi_disable(sp);
|
||||
clk_disable_unprepare(sp->clk);
|
||||
spi_controller_put(sp->bitbang.master);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ath79_spi_shutdown(struct platform_device *pdev)
|
||||
@ -262,7 +260,7 @@ MODULE_DEVICE_TABLE(of, ath79_spi_of_match);
|
||||
|
||||
static struct platform_driver ath79_spi_driver = {
|
||||
.probe = ath79_spi_probe,
|
||||
.remove = ath79_spi_remove,
|
||||
.remove_new = ath79_spi_remove,
|
||||
.shutdown = ath79_spi_shutdown,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
|
@ -327,10 +327,10 @@ static void cs_activate(struct atmel_spi *as, struct spi_device *spi)
|
||||
int chip_select;
|
||||
u32 mr;
|
||||
|
||||
if (spi->cs_gpiod)
|
||||
if (spi_get_csgpiod(spi, 0))
|
||||
chip_select = as->native_cs_for_gpio;
|
||||
else
|
||||
chip_select = spi->chip_select;
|
||||
chip_select = spi_get_chipselect(spi, 0);
|
||||
|
||||
if (atmel_spi_is_v2(as)) {
|
||||
spi_writel(as, CSR0 + 4 * chip_select, asd->csr);
|
||||
@ -378,10 +378,10 @@ static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi)
|
||||
int chip_select;
|
||||
u32 mr;
|
||||
|
||||
if (spi->cs_gpiod)
|
||||
if (spi_get_csgpiod(spi, 0))
|
||||
chip_select = as->native_cs_for_gpio;
|
||||
else
|
||||
chip_select = spi->chip_select;
|
||||
chip_select = spi_get_chipselect(spi, 0);
|
||||
|
||||
/* only deactivate *this* device; sometimes transfers to
|
||||
* another device may be active when this routine is called.
|
||||
@ -394,7 +394,7 @@ static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi)
|
||||
|
||||
dev_dbg(&spi->dev, "DEactivate NPCS, mr %08x\n", mr);
|
||||
|
||||
if (!spi->cs_gpiod)
|
||||
if (!spi_get_csgpiod(spi, 0))
|
||||
spi_writel(as, CR, SPI_BIT(LASTXFER));
|
||||
}
|
||||
|
||||
@ -800,10 +800,10 @@ static int atmel_spi_set_xfer_speed(struct atmel_spi *as,
|
||||
unsigned long bus_hz;
|
||||
int chip_select;
|
||||
|
||||
if (spi->cs_gpiod)
|
||||
if (spi_get_csgpiod(spi, 0))
|
||||
chip_select = as->native_cs_for_gpio;
|
||||
else
|
||||
chip_select = spi->chip_select;
|
||||
chip_select = spi_get_chipselect(spi, 0);
|
||||
|
||||
/* v1 chips start out at half the peripheral bus speed. */
|
||||
bus_hz = as->spi_clk;
|
||||
@ -1189,7 +1189,7 @@ static int atmel_spi_setup(struct spi_device *spi)
|
||||
as = spi_controller_get_devdata(spi->controller);
|
||||
|
||||
/* see notes above re chipselect */
|
||||
if (!spi->cs_gpiod && (spi->mode & SPI_CS_HIGH)) {
|
||||
if (!spi_get_csgpiod(spi, 0) && (spi->mode & SPI_CS_HIGH)) {
|
||||
dev_warn(&spi->dev, "setup: non GPIO CS can't be active-high\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -1201,16 +1201,16 @@ static int atmel_spi_setup(struct spi_device *spi)
|
||||
*/
|
||||
initialize_native_cs_for_gpio(as);
|
||||
|
||||
if (spi->cs_gpiod && as->native_cs_free) {
|
||||
if (spi_get_csgpiod(spi, 0) && as->native_cs_free) {
|
||||
dev_err(&spi->dev,
|
||||
"No native CS available to support this GPIO CS\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (spi->cs_gpiod)
|
||||
if (spi_get_csgpiod(spi, 0))
|
||||
chip_select = as->native_cs_for_gpio;
|
||||
else
|
||||
chip_select = spi->chip_select;
|
||||
chip_select = spi_get_chipselect(spi, 0);
|
||||
|
||||
csr = SPI_BF(BITS, bits - 8);
|
||||
if (spi->mode & SPI_CPOL)
|
||||
@ -1218,7 +1218,7 @@ static int atmel_spi_setup(struct spi_device *spi)
|
||||
if (!(spi->mode & SPI_CPHA))
|
||||
csr |= SPI_BIT(NCPHA);
|
||||
|
||||
if (!spi->cs_gpiod)
|
||||
if (!spi_get_csgpiod(spi, 0))
|
||||
csr |= SPI_BIT(CSAAT);
|
||||
csr |= SPI_BF(DLYBS, 0);
|
||||
|
||||
@ -1244,7 +1244,7 @@ static int atmel_spi_setup(struct spi_device *spi)
|
||||
|
||||
dev_dbg(&spi->dev,
|
||||
"setup: bpw %u mode 0x%x -> csr%d %08x\n",
|
||||
bits, spi->mode, spi->chip_select, csr);
|
||||
bits, spi->mode, spi_get_chipselect(spi, 0), csr);
|
||||
|
||||
if (!atmel_spi_is_v2(as))
|
||||
spi_writel(as, CSR0 + 4 * chip_select, csr);
|
||||
@ -1596,7 +1596,7 @@ out_unmap_regs:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int atmel_spi_remove(struct platform_device *pdev)
|
||||
static void atmel_spi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_controller *host = platform_get_drvdata(pdev);
|
||||
struct atmel_spi *as = spi_controller_get_devdata(host);
|
||||
@ -1627,8 +1627,6 @@ static int atmel_spi_remove(struct platform_device *pdev)
|
||||
|
||||
pm_runtime_put_noidle(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int atmel_spi_runtime_suspend(struct device *dev)
|
||||
@ -1712,7 +1710,7 @@ static struct platform_driver atmel_spi_driver = {
|
||||
.of_match_table = atmel_spi_dt_ids,
|
||||
},
|
||||
.probe = atmel_spi_probe,
|
||||
.remove = atmel_spi_remove,
|
||||
.remove_new = atmel_spi_remove,
|
||||
};
|
||||
module_platform_driver(atmel_spi_driver);
|
||||
|
||||
|
@ -166,7 +166,7 @@ static void au1550_spi_chipsel(struct spi_device *spi, int value)
|
||||
switch (value) {
|
||||
case BITBANG_CS_INACTIVE:
|
||||
if (hw->pdata->deactivate_cs)
|
||||
hw->pdata->deactivate_cs(hw->pdata, spi->chip_select,
|
||||
hw->pdata->deactivate_cs(hw->pdata, spi_get_chipselect(spi, 0),
|
||||
cspol);
|
||||
break;
|
||||
|
||||
@ -211,7 +211,7 @@ static void au1550_spi_chipsel(struct spi_device *spi, int value)
|
||||
} while ((stat & PSC_SPISTAT_DR) == 0);
|
||||
|
||||
if (hw->pdata->activate_cs)
|
||||
hw->pdata->activate_cs(hw->pdata, spi->chip_select,
|
||||
hw->pdata->activate_cs(hw->pdata, spi_get_chipselect(spi, 0),
|
||||
cspol);
|
||||
break;
|
||||
}
|
||||
@ -923,7 +923,7 @@ err_nomem:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int au1550_spi_remove(struct platform_device *pdev)
|
||||
static void au1550_spi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct au1550_spi *hw = platform_get_drvdata(pdev);
|
||||
|
||||
@ -942,7 +942,6 @@ static int au1550_spi_remove(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
spi_master_put(hw->master);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* work with hotplug and coldplug */
|
||||
@ -950,7 +949,7 @@ MODULE_ALIAS("platform:au1550-spi");
|
||||
|
||||
static struct platform_driver au1550_spi_drv = {
|
||||
.probe = au1550_spi_probe,
|
||||
.remove = au1550_spi_remove,
|
||||
.remove_new = au1550_spi_remove,
|
||||
.driver = {
|
||||
.name = "au1550-spi",
|
||||
},
|
||||
|
@ -193,7 +193,7 @@ static void spi_engine_gen_cs(struct spi_engine_program *p, bool dry,
|
||||
unsigned int mask = 0xff;
|
||||
|
||||
if (assert)
|
||||
mask ^= BIT(spi->chip_select);
|
||||
mask ^= BIT(spi_get_chipselect(spi, 0));
|
||||
|
||||
spi_engine_program_add_cmd(p, dry, SPI_ENGINE_CMD_ASSERT(1, mask));
|
||||
}
|
||||
@ -554,7 +554,7 @@ err_put_master:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int spi_engine_remove(struct platform_device *pdev)
|
||||
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);
|
||||
@ -572,8 +572,6 @@ static int spi_engine_remove(struct platform_device *pdev)
|
||||
|
||||
clk_disable_unprepare(spi_engine->ref_clk);
|
||||
clk_disable_unprepare(spi_engine->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id spi_engine_match_table[] = {
|
||||
@ -584,7 +582,7 @@ MODULE_DEVICE_TABLE(of, spi_engine_match_table);
|
||||
|
||||
static struct platform_driver spi_engine_driver = {
|
||||
.probe = spi_engine_probe,
|
||||
.remove = spi_engine_remove,
|
||||
.remove_new = spi_engine_remove,
|
||||
.driver = {
|
||||
.name = "spi-engine",
|
||||
.of_match_table = spi_engine_match_table,
|
||||
|
@ -986,7 +986,7 @@ static int write_to_hw(struct bcm_qspi *qspi, struct spi_device *spi)
|
||||
if (has_bspi(qspi))
|
||||
mspi_cdram &= ~1;
|
||||
else
|
||||
mspi_cdram |= (~(1 << spi->chip_select) &
|
||||
mspi_cdram |= (~(1 << spi_get_chipselect(spi, 0)) &
|
||||
MSPI_CDRAM_PCS);
|
||||
|
||||
write_cdram_slot(qspi, slot, mspi_cdram);
|
||||
@ -1046,8 +1046,8 @@ static int bcm_qspi_bspi_exec_mem_op(struct spi_device *spi,
|
||||
return -EIO;
|
||||
|
||||
from = op->addr.val;
|
||||
if (!spi->cs_gpiod)
|
||||
bcm_qspi_chip_select(qspi, spi->chip_select);
|
||||
if (!spi_get_csgpiod(spi, 0))
|
||||
bcm_qspi_chip_select(qspi, spi_get_chipselect(spi, 0));
|
||||
bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 0);
|
||||
|
||||
/*
|
||||
@ -1126,8 +1126,8 @@ static int bcm_qspi_transfer_one(struct spi_master *master,
|
||||
int slots;
|
||||
unsigned long timeo = msecs_to_jiffies(100);
|
||||
|
||||
if (!spi->cs_gpiod)
|
||||
bcm_qspi_chip_select(qspi, spi->chip_select);
|
||||
if (!spi_get_csgpiod(spi, 0))
|
||||
bcm_qspi_chip_select(qspi, spi_get_chipselect(spi, 0));
|
||||
qspi->trans_pos.trans = trans;
|
||||
qspi->trans_pos.byte = 0;
|
||||
|
||||
@ -1457,7 +1457,7 @@ static const struct bcm_qspi_data bcm_qspi_spcr3_data = {
|
||||
.has_spcr3_sysclk = true,
|
||||
};
|
||||
|
||||
static const struct of_device_id bcm_qspi_of_match[] = {
|
||||
static const struct of_device_id bcm_qspi_of_match[] __maybe_unused = {
|
||||
{
|
||||
.compatible = "brcm,spi-bcm7445-qspi",
|
||||
.data = &bcm_qspi_rev_data,
|
||||
|
@ -1274,9 +1274,9 @@ static int bcm2835_spi_setup(struct spi_device *spi)
|
||||
* The SPI core has successfully requested the CS GPIO line from the
|
||||
* device tree, so we are done.
|
||||
*/
|
||||
if (spi->cs_gpiod)
|
||||
if (spi_get_csgpiod(spi, 0))
|
||||
return 0;
|
||||
if (spi->chip_select > 1) {
|
||||
if (spi_get_chipselect(spi, 0) > 1) {
|
||||
/* error in the case of native CS requested with CS > 1
|
||||
* officially there is a CS2, but it is not documented
|
||||
* which GPIO is connected with that...
|
||||
@ -1301,18 +1301,19 @@ static int bcm2835_spi_setup(struct spi_device *spi)
|
||||
if (!chip)
|
||||
return 0;
|
||||
|
||||
spi->cs_gpiod = gpiochip_request_own_desc(chip, 8 - spi->chip_select,
|
||||
DRV_NAME,
|
||||
GPIO_LOOKUP_FLAGS_DEFAULT,
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(spi->cs_gpiod)) {
|
||||
ret = PTR_ERR(spi->cs_gpiod);
|
||||
spi_set_csgpiod(spi, 0, gpiochip_request_own_desc(chip,
|
||||
8 - (spi_get_chipselect(spi, 0)),
|
||||
DRV_NAME,
|
||||
GPIO_LOOKUP_FLAGS_DEFAULT,
|
||||
GPIOD_OUT_LOW));
|
||||
if (IS_ERR(spi_get_csgpiod(spi, 0))) {
|
||||
ret = PTR_ERR(spi_get_csgpiod(spi, 0));
|
||||
goto err_cleanup;
|
||||
}
|
||||
|
||||
/* and set up the "mode" and level */
|
||||
dev_info(&spi->dev, "setting up native-CS%i to use GPIO\n",
|
||||
spi->chip_select);
|
||||
spi_get_chipselect(spi, 0));
|
||||
|
||||
return 0;
|
||||
|
||||
@ -1398,7 +1399,7 @@ out_clk_disable:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int bcm2835_spi_remove(struct platform_device *pdev)
|
||||
static void bcm2835_spi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_controller *ctlr = platform_get_drvdata(pdev);
|
||||
struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
|
||||
@ -1414,17 +1415,6 @@ static int bcm2835_spi_remove(struct platform_device *pdev)
|
||||
BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX);
|
||||
|
||||
clk_disable_unprepare(bs->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bcm2835_spi_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bcm2835_spi_remove(pdev);
|
||||
if (ret)
|
||||
dev_err(&pdev->dev, "failed to shutdown\n");
|
||||
}
|
||||
|
||||
static const struct of_device_id bcm2835_spi_match[] = {
|
||||
@ -1439,8 +1429,8 @@ static struct platform_driver bcm2835_spi_driver = {
|
||||
.of_match_table = bcm2835_spi_match,
|
||||
},
|
||||
.probe = bcm2835_spi_probe,
|
||||
.remove = bcm2835_spi_remove,
|
||||
.shutdown = bcm2835_spi_shutdown,
|
||||
.remove_new = bcm2835_spi_remove,
|
||||
.shutdown = bcm2835_spi_remove,
|
||||
};
|
||||
module_platform_driver(bcm2835_spi_driver);
|
||||
|
||||
|
@ -448,7 +448,7 @@ static int bcm2835aux_spi_setup(struct spi_device *spi)
|
||||
if (spi->mode & SPI_NO_CS)
|
||||
return 0;
|
||||
|
||||
if (spi->cs_gpiod)
|
||||
if (spi_get_csgpiod(spi, 0))
|
||||
return 0;
|
||||
|
||||
/* for dt-backwards compatibility: only support native on CS0
|
||||
@ -465,7 +465,7 @@ static int bcm2835aux_spi_setup(struct spi_device *spi)
|
||||
dev_warn(&spi->dev,
|
||||
"Native CS is not supported - please configure cs-gpio in device-tree\n");
|
||||
|
||||
if (spi->chip_select == 0)
|
||||
if (spi_get_chipselect(spi, 0) == 0)
|
||||
return 0;
|
||||
|
||||
dev_warn(&spi->dev, "Native CS is not working for cs > 0\n");
|
||||
@ -567,7 +567,7 @@ out_clk_disable:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int bcm2835aux_spi_remove(struct platform_device *pdev)
|
||||
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);
|
||||
@ -580,8 +580,6 @@ static int bcm2835aux_spi_remove(struct platform_device *pdev)
|
||||
|
||||
/* disable the HW block by releasing the clock */
|
||||
clk_disable_unprepare(bs->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id bcm2835aux_spi_match[] = {
|
||||
@ -596,7 +594,7 @@ static struct platform_driver bcm2835aux_spi_driver = {
|
||||
.of_match_table = bcm2835aux_spi_match,
|
||||
},
|
||||
.probe = bcm2835aux_spi_probe,
|
||||
.remove = bcm2835aux_spi_remove,
|
||||
.remove_new = bcm2835aux_spi_remove,
|
||||
};
|
||||
module_platform_driver(bcm2835aux_spi_driver);
|
||||
|
||||
|
@ -349,7 +349,7 @@ 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);
|
||||
unsigned int chip_select = spi->chip_select;
|
||||
unsigned int chip_select = spi_get_chipselect(spi, 0);
|
||||
u16 opcode = 0, val;
|
||||
const u8 *tx = t->tx_buf;
|
||||
u8 *rx = t->rx_buf;
|
||||
@ -441,7 +441,7 @@ static void bcm63xx_hsspi_set_cs(struct bcm63xx_hsspi *bs, unsigned int cs,
|
||||
static void bcm63xx_hsspi_set_clk(struct bcm63xx_hsspi *bs,
|
||||
struct spi_device *spi, int hz)
|
||||
{
|
||||
unsigned int profile = spi->chip_select;
|
||||
unsigned int profile = spi_get_chipselect(spi, 0);
|
||||
u32 reg;
|
||||
|
||||
reg = DIV_ROUND_UP(2048, DIV_ROUND_UP(bs->speed_hz, hz));
|
||||
@ -468,7 +468,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);
|
||||
unsigned int chip_select = spi->chip_select;
|
||||
unsigned int chip_select = spi_get_chipselect(spi, 0);
|
||||
u16 opcode = 0, val;
|
||||
int pending = t->len;
|
||||
int step_size = HSSPI_BUFFER_LEN;
|
||||
@ -478,7 +478,7 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t)
|
||||
|
||||
bcm63xx_hsspi_set_clk(bs, spi, t->speed_hz);
|
||||
if (!t->cs_off)
|
||||
bcm63xx_hsspi_set_cs(bs, spi->chip_select, true);
|
||||
bcm63xx_hsspi_set_cs(bs, spi_get_chipselect(spi, 0), true);
|
||||
|
||||
if (tx && rx)
|
||||
opcode = HSSPI_OP_READ_WRITE;
|
||||
@ -545,14 +545,14 @@ static int bcm63xx_hsspi_setup(struct spi_device *spi)
|
||||
u32 reg;
|
||||
|
||||
reg = __raw_readl(bs->regs +
|
||||
HSSPI_PROFILE_SIGNAL_CTRL_REG(spi->chip_select));
|
||||
HSSPI_PROFILE_SIGNAL_CTRL_REG(spi_get_chipselect(spi, 0)));
|
||||
reg &= ~(SIGNAL_CTRL_LAUNCH_RISING | SIGNAL_CTRL_LATCH_RISING);
|
||||
if (spi->mode & SPI_CPHA)
|
||||
reg |= SIGNAL_CTRL_LAUNCH_RISING;
|
||||
else
|
||||
reg |= SIGNAL_CTRL_LATCH_RISING;
|
||||
__raw_writel(reg, bs->regs +
|
||||
HSSPI_PROFILE_SIGNAL_CTRL_REG(spi->chip_select));
|
||||
HSSPI_PROFILE_SIGNAL_CTRL_REG(spi_get_chipselect(spi, 0)));
|
||||
|
||||
mutex_lock(&bs->bus_mutex);
|
||||
reg = __raw_readl(bs->regs + HSSPI_GLOBAL_CTRL_REG);
|
||||
@ -560,16 +560,16 @@ static int bcm63xx_hsspi_setup(struct spi_device *spi)
|
||||
/* only change actual polarities if there is no transfer */
|
||||
if ((reg & GLOBAL_CTRL_CS_POLARITY_MASK) == bs->cs_polarity) {
|
||||
if (spi->mode & SPI_CS_HIGH)
|
||||
reg |= BIT(spi->chip_select);
|
||||
reg |= BIT(spi_get_chipselect(spi, 0));
|
||||
else
|
||||
reg &= ~BIT(spi->chip_select);
|
||||
reg &= ~BIT(spi_get_chipselect(spi, 0));
|
||||
__raw_writel(reg, bs->regs + HSSPI_GLOBAL_CTRL_REG);
|
||||
}
|
||||
|
||||
if (spi->mode & SPI_CS_HIGH)
|
||||
bs->cs_polarity |= BIT(spi->chip_select);
|
||||
bs->cs_polarity |= BIT(spi_get_chipselect(spi, 0));
|
||||
else
|
||||
bs->cs_polarity &= ~BIT(spi->chip_select);
|
||||
bs->cs_polarity &= ~BIT(spi_get_chipselect(spi, 0));
|
||||
|
||||
mutex_unlock(&bs->bus_mutex);
|
||||
|
||||
@ -600,7 +600,7 @@ static int bcm63xx_hsspi_do_dummy_cs_txrx(struct spi_device *spi,
|
||||
* e. At the end restore the polarities again to their default values.
|
||||
*/
|
||||
|
||||
dummy_cs = !spi->chip_select;
|
||||
dummy_cs = !spi_get_chipselect(spi, 0);
|
||||
bcm63xx_hsspi_set_cs(bs, dummy_cs, true);
|
||||
|
||||
list_for_each_entry(t, &msg->transfers, transfer_list) {
|
||||
@ -633,22 +633,22 @@ static int bcm63xx_hsspi_do_dummy_cs_txrx(struct spi_device *spi,
|
||||
keep_cs = true;
|
||||
} else {
|
||||
if (!t->cs_off)
|
||||
bcm63xx_hsspi_set_cs(bs, spi->chip_select, false);
|
||||
bcm63xx_hsspi_set_cs(bs, spi_get_chipselect(spi, 0), false);
|
||||
|
||||
spi_transfer_cs_change_delay_exec(msg, t);
|
||||
|
||||
if (!list_next_entry(t, transfer_list)->cs_off)
|
||||
bcm63xx_hsspi_set_cs(bs, spi->chip_select, true);
|
||||
bcm63xx_hsspi_set_cs(bs, spi_get_chipselect(spi, 0), true);
|
||||
}
|
||||
} else if (!list_is_last(&t->transfer_list, &msg->transfers) &&
|
||||
t->cs_off != list_next_entry(t, transfer_list)->cs_off) {
|
||||
bcm63xx_hsspi_set_cs(bs, spi->chip_select, t->cs_off);
|
||||
bcm63xx_hsspi_set_cs(bs, spi_get_chipselect(spi, 0), t->cs_off);
|
||||
}
|
||||
}
|
||||
|
||||
bcm63xx_hsspi_set_cs(bs, dummy_cs, false);
|
||||
if (status || !keep_cs)
|
||||
bcm63xx_hsspi_set_cs(bs, spi->chip_select, false);
|
||||
bcm63xx_hsspi_set_cs(bs, spi_get_chipselect(spi, 0), false);
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -878,7 +878,7 @@ out_disable_clk:
|
||||
}
|
||||
|
||||
|
||||
static int bcm63xx_hsspi_remove(struct platform_device *pdev)
|
||||
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);
|
||||
@ -888,8 +888,6 @@ static int bcm63xx_hsspi_remove(struct platform_device *pdev)
|
||||
clk_disable_unprepare(bs->pll_clk);
|
||||
clk_disable_unprepare(bs->clk);
|
||||
sysfs_remove_group(&pdev->dev.kobj, &bcm63xx_hsspi_group);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
@ -946,7 +944,7 @@ static struct platform_driver bcm63xx_hsspi_driver = {
|
||||
.of_match_table = bcm63xx_hsspi_of_match,
|
||||
},
|
||||
.probe = bcm63xx_hsspi_probe,
|
||||
.remove = bcm63xx_hsspi_remove,
|
||||
.remove_new = bcm63xx_hsspi_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(bcm63xx_hsspi_driver);
|
||||
|
@ -157,16 +157,6 @@ static inline u8 bcm_spi_readb(struct bcm63xx_spi *bs,
|
||||
return readb(bs->regs + bs->reg_offsets[offset]);
|
||||
}
|
||||
|
||||
static inline u16 bcm_spi_readw(struct bcm63xx_spi *bs,
|
||||
unsigned int offset)
|
||||
{
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
return ioread16be(bs->regs + bs->reg_offsets[offset]);
|
||||
#else
|
||||
return readw(bs->regs + bs->reg_offsets[offset]);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void bcm_spi_writeb(struct bcm63xx_spi *bs,
|
||||
u8 value, unsigned int offset)
|
||||
{
|
||||
@ -292,7 +282,7 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
|
||||
/* Issue the transfer */
|
||||
cmd = SPI_CMD_START_IMMEDIATE;
|
||||
cmd |= (prepend_len << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
|
||||
cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT);
|
||||
cmd |= (spi_get_chipselect(spi, 0) << SPI_CMD_DEVICE_ID_SHIFT);
|
||||
bcm_spi_writew(bs, cmd, SPI_CMD);
|
||||
|
||||
/* Enable the CMD_DONE interrupt */
|
||||
@ -615,7 +605,7 @@ out_err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bcm63xx_spi_remove(struct platform_device *pdev)
|
||||
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);
|
||||
@ -625,11 +615,8 @@ static int bcm63xx_spi_remove(struct platform_device *pdev)
|
||||
|
||||
/* HW shutdown */
|
||||
clk_disable_unprepare(bs->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int bcm63xx_spi_suspend(struct device *dev)
|
||||
{
|
||||
struct spi_master *master = dev_get_drvdata(dev);
|
||||
@ -656,11 +643,8 @@ static int bcm63xx_spi_resume(struct device *dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct dev_pm_ops bcm63xx_spi_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(bcm63xx_spi_suspend, bcm63xx_spi_resume)
|
||||
};
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(bcm63xx_spi_pm_ops, bcm63xx_spi_suspend, bcm63xx_spi_resume);
|
||||
|
||||
static struct platform_driver bcm63xx_spi_driver = {
|
||||
.driver = {
|
||||
@ -670,7 +654,7 @@ static struct platform_driver bcm63xx_spi_driver = {
|
||||
},
|
||||
.id_table = bcm63xx_spi_dev_match,
|
||||
.probe = bcm63xx_spi_probe,
|
||||
.remove = bcm63xx_spi_remove,
|
||||
.remove_new = bcm63xx_spi_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(bcm63xx_spi_driver);
|
||||
|
@ -193,7 +193,7 @@ static void bcmbca_hsspi_set_cs(struct bcmbca_hsspi *bs, unsigned int cs,
|
||||
static void bcmbca_hsspi_set_clk(struct bcmbca_hsspi *bs,
|
||||
struct spi_device *spi, int hz)
|
||||
{
|
||||
unsigned int profile = spi->chip_select;
|
||||
unsigned int profile = spi_get_chipselect(spi, 0);
|
||||
u32 reg;
|
||||
|
||||
reg = DIV_ROUND_UP(2048, DIV_ROUND_UP(bs->speed_hz, hz));
|
||||
@ -251,7 +251,7 @@ 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);
|
||||
unsigned int chip_select = spi->chip_select;
|
||||
unsigned int chip_select = spi_get_chipselect(spi, 0);
|
||||
u16 opcode = 0, val;
|
||||
int pending = t->len;
|
||||
int step_size = HSSPI_BUFFER_LEN;
|
||||
@ -312,7 +312,7 @@ static int bcmbca_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t,
|
||||
PINGPONG_COMMAND_START_NOW;
|
||||
__raw_writel(reg, bs->regs + HSSPI_PINGPONG_COMMAND_REG(0));
|
||||
|
||||
if (bcmbca_hsspi_wait_cmd(bs, spi->chip_select))
|
||||
if (bcmbca_hsspi_wait_cmd(bs, spi_get_chipselect(spi, 0)))
|
||||
return -ETIMEDOUT;
|
||||
|
||||
pending -= curr_step;
|
||||
@ -332,33 +332,33 @@ static int bcmbca_hsspi_setup(struct spi_device *spi)
|
||||
u32 reg;
|
||||
|
||||
reg = __raw_readl(bs->regs +
|
||||
HSSPI_PROFILE_SIGNAL_CTRL_REG(spi->chip_select));
|
||||
HSSPI_PROFILE_SIGNAL_CTRL_REG(spi_get_chipselect(spi, 0)));
|
||||
reg &= ~(SIGNAL_CTRL_LAUNCH_RISING | SIGNAL_CTRL_LATCH_RISING);
|
||||
if (spi->mode & SPI_CPHA)
|
||||
reg |= SIGNAL_CTRL_LAUNCH_RISING;
|
||||
else
|
||||
reg |= SIGNAL_CTRL_LATCH_RISING;
|
||||
__raw_writel(reg, bs->regs +
|
||||
HSSPI_PROFILE_SIGNAL_CTRL_REG(spi->chip_select));
|
||||
HSSPI_PROFILE_SIGNAL_CTRL_REG(spi_get_chipselect(spi, 0)));
|
||||
|
||||
mutex_lock(&bs->bus_mutex);
|
||||
reg = __raw_readl(bs->regs + HSSPI_GLOBAL_CTRL_REG);
|
||||
|
||||
if (spi->mode & SPI_CS_HIGH)
|
||||
reg |= BIT(spi->chip_select);
|
||||
reg |= BIT(spi_get_chipselect(spi, 0));
|
||||
else
|
||||
reg &= ~BIT(spi->chip_select);
|
||||
reg &= ~BIT(spi_get_chipselect(spi, 0));
|
||||
__raw_writel(reg, bs->regs + HSSPI_GLOBAL_CTRL_REG);
|
||||
|
||||
if (spi->mode & SPI_CS_HIGH)
|
||||
bs->cs_polarity |= BIT(spi->chip_select);
|
||||
bs->cs_polarity |= BIT(spi_get_chipselect(spi, 0));
|
||||
else
|
||||
bs->cs_polarity &= ~BIT(spi->chip_select);
|
||||
bs->cs_polarity &= ~BIT(spi_get_chipselect(spi, 0));
|
||||
|
||||
reg = __raw_readl(bs->spim_ctrl);
|
||||
reg &= ~BIT(spi->chip_select + SPIM_CTRL_CS_OVERRIDE_VAL_SHIFT);
|
||||
reg &= ~BIT(spi_get_chipselect(spi, 0) + SPIM_CTRL_CS_OVERRIDE_VAL_SHIFT);
|
||||
if (spi->mode & SPI_CS_HIGH)
|
||||
reg |= BIT(spi->chip_select + SPIM_CTRL_CS_OVERRIDE_VAL_SHIFT);
|
||||
reg |= BIT(spi_get_chipselect(spi, 0) + SPIM_CTRL_CS_OVERRIDE_VAL_SHIFT);
|
||||
__raw_writel(reg, bs->spim_ctrl);
|
||||
|
||||
mutex_unlock(&bs->bus_mutex);
|
||||
@ -388,16 +388,16 @@ static int bcmbca_hsspi_transfer_one(struct spi_master *master,
|
||||
keep_cs = true;
|
||||
} else {
|
||||
if (!t->cs_off)
|
||||
bcmbca_hsspi_set_cs(bs, spi->chip_select, false);
|
||||
bcmbca_hsspi_set_cs(bs, spi_get_chipselect(spi, 0), false);
|
||||
|
||||
spi_transfer_cs_change_delay_exec(msg, t);
|
||||
|
||||
if (!list_next_entry(t, transfer_list)->cs_off)
|
||||
bcmbca_hsspi_set_cs(bs, spi->chip_select, true);
|
||||
bcmbca_hsspi_set_cs(bs, spi_get_chipselect(spi, 0), true);
|
||||
}
|
||||
} else if (!list_is_last(&t->transfer_list, &msg->transfers) &&
|
||||
t->cs_off != list_next_entry(t, transfer_list)->cs_off) {
|
||||
bcmbca_hsspi_set_cs(bs, spi->chip_select, t->cs_off);
|
||||
bcmbca_hsspi_set_cs(bs, spi_get_chipselect(spi, 0), t->cs_off);
|
||||
}
|
||||
|
||||
msg->actual_length += t->len;
|
||||
@ -406,7 +406,7 @@ static int bcmbca_hsspi_transfer_one(struct spi_master *master,
|
||||
mutex_unlock(&bs->msg_mutex);
|
||||
|
||||
if (status || !keep_cs)
|
||||
bcmbca_hsspi_set_cs(bs, spi->chip_select, false);
|
||||
bcmbca_hsspi_set_cs(bs, spi_get_chipselect(spi, 0), false);
|
||||
|
||||
msg->status = status;
|
||||
spi_finalize_current_message(master);
|
||||
@ -576,7 +576,7 @@ out_disable_clk:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bcmbca_hsspi_remove(struct platform_device *pdev)
|
||||
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);
|
||||
@ -586,8 +586,6 @@ static int bcmbca_hsspi_remove(struct platform_device *pdev)
|
||||
clk_disable_unprepare(bs->pll_clk);
|
||||
clk_disable_unprepare(bs->clk);
|
||||
sysfs_remove_group(&pdev->dev.kobj, &bcmbca_hsspi_group);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
@ -644,7 +642,7 @@ static struct platform_driver bcmbca_hsspi_driver = {
|
||||
.of_match_table = bcmbca_hsspi_of_match,
|
||||
},
|
||||
.probe = bcmbca_hsspi_probe,
|
||||
.remove = bcmbca_hsspi_remove,
|
||||
.remove_new = bcmbca_hsspi_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(bcmbca_hsspi_driver);
|
||||
|
@ -21,16 +21,14 @@ static int brcmstb_qspi_probe(struct platform_device *pdev)
|
||||
return bcm_qspi_probe(pdev, NULL);
|
||||
}
|
||||
|
||||
static int brcmstb_qspi_remove(struct platform_device *pdev)
|
||||
static void brcmstb_qspi_remove(struct platform_device *pdev)
|
||||
{
|
||||
bcm_qspi_remove(pdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver brcmstb_qspi_driver = {
|
||||
.probe = brcmstb_qspi_probe,
|
||||
.remove = brcmstb_qspi_remove,
|
||||
.remove_new = brcmstb_qspi_remove,
|
||||
.driver = {
|
||||
.name = "brcmstb_qspi",
|
||||
.pm = &bcm_qspi_pm_ops,
|
||||
|
@ -791,6 +791,21 @@ failrd:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cqspi_controller_enable(struct cqspi_st *cqspi, bool enable)
|
||||
{
|
||||
void __iomem *reg_base = cqspi->iobase;
|
||||
unsigned int reg;
|
||||
|
||||
reg = readl(reg_base + CQSPI_REG_CONFIG);
|
||||
|
||||
if (enable)
|
||||
reg |= CQSPI_REG_CONFIG_ENABLE_MASK;
|
||||
else
|
||||
reg &= ~CQSPI_REG_CONFIG_ENABLE_MASK;
|
||||
|
||||
writel(reg, reg_base + CQSPI_REG_CONFIG);
|
||||
}
|
||||
|
||||
static int cqspi_versal_indirect_read_dma(struct cqspi_flash_pdata *f_pdata,
|
||||
u_char *rxbuf, loff_t from_addr,
|
||||
size_t n_rx)
|
||||
@ -815,10 +830,14 @@ static int cqspi_versal_indirect_read_dma(struct cqspi_flash_pdata *f_pdata,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
cqspi_controller_enable(cqspi, 0);
|
||||
|
||||
reg = readl(cqspi->iobase + CQSPI_REG_CONFIG);
|
||||
reg |= CQSPI_REG_CONFIG_DMA_MASK;
|
||||
writel(reg, cqspi->iobase + CQSPI_REG_CONFIG);
|
||||
|
||||
cqspi_controller_enable(cqspi, 1);
|
||||
|
||||
dma_addr = dma_map_single(dev, rxbuf, bytes_to_dma, DMA_FROM_DEVICE);
|
||||
if (dma_mapping_error(dev, dma_addr)) {
|
||||
dev_err(dev, "dma mapping failed\n");
|
||||
@ -863,7 +882,7 @@ static int cqspi_versal_indirect_read_dma(struct cqspi_flash_pdata *f_pdata,
|
||||
reinit_completion(&cqspi->transfer_complete);
|
||||
|
||||
if (!wait_for_completion_timeout(&cqspi->transfer_complete,
|
||||
msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS))) {
|
||||
msecs_to_jiffies(max_t(size_t, bytes_to_dma, 500)))) {
|
||||
ret = -ETIMEDOUT;
|
||||
goto failrd;
|
||||
}
|
||||
@ -876,10 +895,14 @@ static int cqspi_versal_indirect_read_dma(struct cqspi_flash_pdata *f_pdata,
|
||||
cqspi->iobase + CQSPI_REG_INDIRECTRD);
|
||||
dma_unmap_single(dev, dma_addr, bytes_to_dma, DMA_FROM_DEVICE);
|
||||
|
||||
cqspi_controller_enable(cqspi, 0);
|
||||
|
||||
reg = readl(cqspi->iobase + CQSPI_REG_CONFIG);
|
||||
reg &= ~CQSPI_REG_CONFIG_DMA_MASK;
|
||||
writel(reg, cqspi->iobase + CQSPI_REG_CONFIG);
|
||||
|
||||
cqspi_controller_enable(cqspi, 1);
|
||||
|
||||
ret = zynqmp_pm_ospi_mux_select(cqspi->pd_dev_id,
|
||||
PM_OSPI_MUX_SEL_LINEAR);
|
||||
if (ret)
|
||||
@ -1182,21 +1205,6 @@ static void cqspi_readdata_capture(struct cqspi_st *cqspi,
|
||||
writel(reg, reg_base + CQSPI_REG_READCAPTURE);
|
||||
}
|
||||
|
||||
static void cqspi_controller_enable(struct cqspi_st *cqspi, bool enable)
|
||||
{
|
||||
void __iomem *reg_base = cqspi->iobase;
|
||||
unsigned int reg;
|
||||
|
||||
reg = readl(reg_base + CQSPI_REG_CONFIG);
|
||||
|
||||
if (enable)
|
||||
reg |= CQSPI_REG_CONFIG_ENABLE_MASK;
|
||||
else
|
||||
reg &= ~CQSPI_REG_CONFIG_ENABLE_MASK;
|
||||
|
||||
writel(reg, reg_base + CQSPI_REG_CONFIG);
|
||||
}
|
||||
|
||||
static void cqspi_configure(struct cqspi_flash_pdata *f_pdata,
|
||||
unsigned long sclk)
|
||||
{
|
||||
@ -1355,7 +1363,7 @@ 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_flash_pdata *f_pdata;
|
||||
|
||||
f_pdata = &cqspi->f_pdata[mem->spi->chip_select];
|
||||
f_pdata = &cqspi->f_pdata[spi_get_chipselect(mem->spi, 0)];
|
||||
cqspi_configure(f_pdata, mem->spi->max_speed_hz);
|
||||
|
||||
if (op->data.dir == SPI_MEM_DATA_IN && op->data.buf.in) {
|
||||
@ -1561,7 +1569,8 @@ static const char *cqspi_get_name(struct spi_mem *mem)
|
||||
struct cqspi_st *cqspi = spi_master_get_devdata(mem->spi->master);
|
||||
struct device *dev = &cqspi->pdev->dev;
|
||||
|
||||
return devm_kasprintf(dev, GFP_KERNEL, "%s.%d", dev_name(dev), mem->spi->chip_select);
|
||||
return devm_kasprintf(dev, GFP_KERNEL, "%s.%d", dev_name(dev),
|
||||
spi_get_chipselect(mem->spi, 0));
|
||||
}
|
||||
|
||||
static const struct spi_controller_mem_ops cqspi_mem_ops = {
|
||||
@ -1615,7 +1624,7 @@ static int cqspi_setup_flash(struct cqspi_st *cqspi)
|
||||
static int cqspi_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct cqspi_driver_platdata *ddata;
|
||||
struct reset_control *rstc, *rstc_ocp;
|
||||
struct reset_control *rstc, *rstc_ocp, *rstc_ref;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct spi_master *master;
|
||||
struct resource *res_ahb;
|
||||
@ -1705,6 +1714,17 @@ static int cqspi_probe(struct platform_device *pdev)
|
||||
goto probe_reset_failed;
|
||||
}
|
||||
|
||||
if (of_device_is_compatible(pdev->dev.of_node, "starfive,jh7110-qspi")) {
|
||||
rstc_ref = devm_reset_control_get_optional_exclusive(dev, "rstc_ref");
|
||||
if (IS_ERR(rstc_ref)) {
|
||||
ret = PTR_ERR(rstc_ref);
|
||||
dev_err(dev, "Cannot get QSPI REF reset.\n");
|
||||
goto probe_reset_failed;
|
||||
}
|
||||
reset_control_assert(rstc_ref);
|
||||
reset_control_deassert(rstc_ref);
|
||||
}
|
||||
|
||||
reset_control_assert(rstc);
|
||||
reset_control_deassert(rstc);
|
||||
|
||||
@ -1784,7 +1804,7 @@ probe_pm_failed:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cqspi_remove(struct platform_device *pdev)
|
||||
static void cqspi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct cqspi_st *cqspi = platform_get_drvdata(pdev);
|
||||
|
||||
@ -1798,36 +1818,38 @@ static int cqspi_remove(struct platform_device *pdev)
|
||||
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int cqspi_suspend(struct device *dev)
|
||||
{
|
||||
struct cqspi_st *cqspi = dev_get_drvdata(dev);
|
||||
struct spi_master *master = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = spi_master_suspend(master);
|
||||
cqspi_controller_enable(cqspi, 0);
|
||||
return 0;
|
||||
|
||||
clk_disable_unprepare(cqspi->clk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cqspi_resume(struct device *dev)
|
||||
{
|
||||
struct cqspi_st *cqspi = dev_get_drvdata(dev);
|
||||
struct spi_master *master = dev_get_drvdata(dev);
|
||||
|
||||
cqspi_controller_enable(cqspi, 1);
|
||||
return 0;
|
||||
clk_prepare_enable(cqspi->clk);
|
||||
cqspi_wait_idle(cqspi);
|
||||
cqspi_controller_init(cqspi);
|
||||
|
||||
cqspi->current_cs = -1;
|
||||
cqspi->sclk = 0;
|
||||
|
||||
return spi_master_resume(master);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops cqspi__dev_pm_ops = {
|
||||
.suspend = cqspi_suspend,
|
||||
.resume = cqspi_resume,
|
||||
};
|
||||
|
||||
#define CQSPI_DEV_PM_OPS (&cqspi__dev_pm_ops)
|
||||
#else
|
||||
#define CQSPI_DEV_PM_OPS NULL
|
||||
#endif
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(cqspi_dev_pm_ops, cqspi_suspend, cqspi_resume);
|
||||
|
||||
static const struct cqspi_driver_platdata cdns_qspi = {
|
||||
.quirks = CQSPI_DISABLE_DAC_MODE,
|
||||
@ -1859,6 +1881,10 @@ static const struct cqspi_driver_platdata versal_ospi = {
|
||||
.get_dma_status = cqspi_get_versal_dma_status,
|
||||
};
|
||||
|
||||
static const struct cqspi_driver_platdata jh7110_qspi = {
|
||||
.quirks = CQSPI_DISABLE_DAC_MODE,
|
||||
};
|
||||
|
||||
static const struct of_device_id cqspi_dt_ids[] = {
|
||||
{
|
||||
.compatible = "cdns,qspi-nor",
|
||||
@ -1884,6 +1910,10 @@ static const struct of_device_id cqspi_dt_ids[] = {
|
||||
.compatible = "intel,socfpga-qspi",
|
||||
.data = &socfpga_qspi,
|
||||
},
|
||||
{
|
||||
.compatible = "starfive,jh7110-qspi",
|
||||
.data = &jh7110_qspi,
|
||||
},
|
||||
{ /* end of table */ }
|
||||
};
|
||||
|
||||
@ -1891,10 +1921,10 @@ MODULE_DEVICE_TABLE(of, cqspi_dt_ids);
|
||||
|
||||
static struct platform_driver cqspi_platform_driver = {
|
||||
.probe = cqspi_probe,
|
||||
.remove = cqspi_remove,
|
||||
.remove_new = cqspi_remove,
|
||||
.driver = {
|
||||
.name = CQSPI_NAME,
|
||||
.pm = CQSPI_DEV_PM_OPS,
|
||||
.pm = &cqspi_dev_pm_ops,
|
||||
.of_match_table = cqspi_dt_ids,
|
||||
},
|
||||
};
|
||||
|
@ -409,8 +409,8 @@ static int cdns_xspi_mem_op(struct cdns_xspi_dev *cdns_xspi,
|
||||
{
|
||||
enum spi_mem_data_dir dir = op->data.dir;
|
||||
|
||||
if (cdns_xspi->cur_cs != mem->spi->chip_select)
|
||||
cdns_xspi->cur_cs = mem->spi->chip_select;
|
||||
if (cdns_xspi->cur_cs != spi_get_chipselect(mem->spi, 0))
|
||||
cdns_xspi->cur_cs = spi_get_chipselect(mem->spi, 0);
|
||||
|
||||
return cdns_xspi_send_stig_command(cdns_xspi, op,
|
||||
(dir != SPI_MEM_NO_DATA));
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Cadence SPI controller driver (master mode only)
|
||||
* Cadence SPI controller driver (master and slave mode)
|
||||
*
|
||||
* Copyright (C) 2008 - 2014 Xilinx, Inc.
|
||||
*
|
||||
@ -139,17 +139,21 @@ 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
|
||||
* not full interrupt is set to 1 and size of the word to be transferred as 8 bit.
|
||||
*
|
||||
* On reset the SPI controller is configured to be in master 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
|
||||
* chip select lines, and enable the SPI controller.
|
||||
*/
|
||||
static void cdns_spi_init_hw(struct cdns_spi *xspi)
|
||||
static void cdns_spi_init_hw(struct cdns_spi *xspi, bool is_slave)
|
||||
{
|
||||
u32 ctrl_reg = CDNS_SPI_CR_DEFAULT;
|
||||
u32 ctrl_reg = 0;
|
||||
|
||||
if (!is_slave)
|
||||
ctrl_reg |= CDNS_SPI_CR_DEFAULT;
|
||||
|
||||
if (xspi->is_decoded_cs)
|
||||
ctrl_reg |= CDNS_SPI_CR_PERI_SEL;
|
||||
@ -173,7 +177,7 @@ static void cdns_spi_init_hw(struct cdns_spi *xspi)
|
||||
*/
|
||||
static void cdns_spi_chipselect(struct spi_device *spi, bool is_high)
|
||||
{
|
||||
struct cdns_spi *xspi = spi_master_get_devdata(spi->master);
|
||||
struct cdns_spi *xspi = spi_controller_get_devdata(spi->controller);
|
||||
u32 ctrl_reg;
|
||||
|
||||
ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR);
|
||||
@ -185,11 +189,11 @@ static void cdns_spi_chipselect(struct spi_device *spi, bool is_high)
|
||||
/* Select the slave */
|
||||
ctrl_reg &= ~CDNS_SPI_CR_SSCTRL;
|
||||
if (!(xspi->is_decoded_cs))
|
||||
ctrl_reg |= ((~(CDNS_SPI_SS0 << spi->chip_select)) <<
|
||||
ctrl_reg |= ((~(CDNS_SPI_SS0 << spi_get_chipselect(spi, 0))) <<
|
||||
CDNS_SPI_SS_SHIFT) &
|
||||
CDNS_SPI_CR_SSCTRL;
|
||||
else
|
||||
ctrl_reg |= (spi->chip_select << CDNS_SPI_SS_SHIFT) &
|
||||
ctrl_reg |= (spi_get_chipselect(spi, 0) << CDNS_SPI_SS_SHIFT) &
|
||||
CDNS_SPI_CR_SSCTRL;
|
||||
}
|
||||
|
||||
@ -204,7 +208,7 @@ static void cdns_spi_chipselect(struct spi_device *spi, bool is_high)
|
||||
*/
|
||||
static void cdns_spi_config_clock_mode(struct spi_device *spi)
|
||||
{
|
||||
struct cdns_spi *xspi = spi_master_get_devdata(spi->master);
|
||||
struct cdns_spi *xspi = spi_controller_get_devdata(spi->controller);
|
||||
u32 ctrl_reg, new_ctrl_reg;
|
||||
|
||||
new_ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR);
|
||||
@ -247,7 +251,7 @@ static void cdns_spi_config_clock_mode(struct spi_device *spi)
|
||||
static void cdns_spi_config_clock_freq(struct spi_device *spi,
|
||||
struct spi_transfer *transfer)
|
||||
{
|
||||
struct cdns_spi *xspi = spi_master_get_devdata(spi->master);
|
||||
struct cdns_spi *xspi = spi_controller_get_devdata(spi->controller);
|
||||
u32 ctrl_reg, baud_rate_val;
|
||||
unsigned long frequency;
|
||||
|
||||
@ -285,7 +289,7 @@ static void cdns_spi_config_clock_freq(struct spi_device *spi,
|
||||
static int cdns_spi_setup_transfer(struct spi_device *spi,
|
||||
struct spi_transfer *transfer)
|
||||
{
|
||||
struct cdns_spi *xspi = spi_master_get_devdata(spi->master);
|
||||
struct cdns_spi *xspi = spi_controller_get_devdata(spi->controller);
|
||||
|
||||
cdns_spi_config_clock_freq(spi, transfer);
|
||||
|
||||
@ -324,6 +328,25 @@ static void cdns_spi_fill_tx_fifo(struct cdns_spi *xspi)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* cdns_spi_read_rx_fifo - Reads the RX FIFO with as many bytes as possible
|
||||
* @xspi: Pointer to the cdns_spi structure
|
||||
* @count: Read byte count
|
||||
*/
|
||||
static void cdns_spi_read_rx_fifo(struct cdns_spi *xspi, unsigned long count)
|
||||
{
|
||||
u8 data;
|
||||
|
||||
/* Read out the data from the RX FIFO */
|
||||
while (count > 0) {
|
||||
data = cdns_spi_read(xspi, CDNS_SPI_RXD);
|
||||
if (xspi->rxbuf)
|
||||
*xspi->rxbuf++ = data;
|
||||
xspi->rx_bytes--;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* cdns_spi_irq - Interrupt service routine of the SPI controller
|
||||
* @irq: IRQ number
|
||||
@ -340,8 +363,8 @@ static void cdns_spi_fill_tx_fifo(struct cdns_spi *xspi)
|
||||
*/
|
||||
static irqreturn_t cdns_spi_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct spi_master *master = dev_id;
|
||||
struct cdns_spi *xspi = spi_master_get_devdata(master);
|
||||
struct spi_controller *ctlr = dev_id;
|
||||
struct cdns_spi *xspi = spi_controller_get_devdata(ctlr);
|
||||
irqreturn_t status;
|
||||
u32 intr_status;
|
||||
|
||||
@ -355,33 +378,39 @@ static irqreturn_t cdns_spi_irq(int irq, void *dev_id)
|
||||
* transferred is non-zero
|
||||
*/
|
||||
cdns_spi_write(xspi, CDNS_SPI_IDR, CDNS_SPI_IXR_DEFAULT);
|
||||
spi_finalize_current_transfer(master);
|
||||
spi_finalize_current_transfer(ctlr);
|
||||
status = IRQ_HANDLED;
|
||||
} else if (intr_status & CDNS_SPI_IXR_TXOW) {
|
||||
unsigned long trans_cnt;
|
||||
int trans_cnt = cdns_spi_read(xspi, CDNS_SPI_THLD);
|
||||
/* Set threshold to one if number of pending are
|
||||
* less than half fifo
|
||||
*/
|
||||
if (xspi->tx_bytes < xspi->tx_fifo_depth >> 1)
|
||||
cdns_spi_write(xspi, CDNS_SPI_THLD, 1);
|
||||
|
||||
trans_cnt = xspi->rx_bytes - xspi->tx_bytes;
|
||||
|
||||
/* Read out the data from the RX FIFO */
|
||||
while (trans_cnt) {
|
||||
u8 data;
|
||||
cdns_spi_read_rx_fifo(xspi, 1);
|
||||
|
||||
data = cdns_spi_read(xspi, CDNS_SPI_RXD);
|
||||
if (xspi->rxbuf)
|
||||
*xspi->rxbuf++ = data;
|
||||
|
||||
xspi->rx_bytes--;
|
||||
if (xspi->tx_bytes) {
|
||||
if (xspi->txbuf)
|
||||
cdns_spi_write(xspi, CDNS_SPI_TXD,
|
||||
*xspi->txbuf++);
|
||||
else
|
||||
cdns_spi_write(xspi, CDNS_SPI_TXD, 0);
|
||||
xspi->tx_bytes--;
|
||||
}
|
||||
trans_cnt--;
|
||||
}
|
||||
|
||||
if (xspi->tx_bytes) {
|
||||
/* There is more data to send */
|
||||
cdns_spi_fill_tx_fifo(xspi);
|
||||
} else {
|
||||
/* Transfer is completed */
|
||||
if (!xspi->tx_bytes) {
|
||||
/* Fixed delay due to controller limitation with
|
||||
* RX_NEMPTY incorrect status
|
||||
* Xilinx AR:65885 contains more details
|
||||
*/
|
||||
udelay(10);
|
||||
cdns_spi_read_rx_fifo(xspi, xspi->rx_bytes);
|
||||
cdns_spi_write(xspi, CDNS_SPI_IDR,
|
||||
CDNS_SPI_IXR_DEFAULT);
|
||||
spi_finalize_current_transfer(master);
|
||||
spi_finalize_current_transfer(ctlr);
|
||||
}
|
||||
status = IRQ_HANDLED;
|
||||
}
|
||||
@ -389,37 +418,47 @@ static irqreturn_t cdns_spi_irq(int irq, void *dev_id)
|
||||
return status;
|
||||
}
|
||||
|
||||
static int cdns_prepare_message(struct spi_master *master,
|
||||
static int cdns_prepare_message(struct spi_controller *ctlr,
|
||||
struct spi_message *msg)
|
||||
{
|
||||
cdns_spi_config_clock_mode(msg->spi);
|
||||
if (!spi_controller_is_slave(ctlr))
|
||||
cdns_spi_config_clock_mode(msg->spi);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdns_transfer_one - Initiates the SPI transfer
|
||||
* @master: Pointer to spi_master structure
|
||||
* @ctlr: Pointer to spi_controller structure
|
||||
* @spi: Pointer to the spi_device structure
|
||||
* @transfer: Pointer to the spi_transfer structure which provides
|
||||
* information about next transfer parameters
|
||||
*
|
||||
* This function fills the TX FIFO, starts the SPI transfer and
|
||||
* This function in master 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.
|
||||
*
|
||||
* Return: Number of bytes transferred in the last transfer
|
||||
*/
|
||||
static int cdns_transfer_one(struct spi_master *master,
|
||||
static int cdns_transfer_one(struct spi_controller *ctlr,
|
||||
struct spi_device *spi,
|
||||
struct spi_transfer *transfer)
|
||||
{
|
||||
struct cdns_spi *xspi = spi_master_get_devdata(master);
|
||||
struct cdns_spi *xspi = spi_controller_get_devdata(ctlr);
|
||||
|
||||
xspi->txbuf = transfer->tx_buf;
|
||||
xspi->rxbuf = transfer->rx_buf;
|
||||
xspi->tx_bytes = transfer->len;
|
||||
xspi->rx_bytes = transfer->len;
|
||||
|
||||
cdns_spi_setup_transfer(spi, transfer);
|
||||
if (!spi_controller_is_slave(ctlr))
|
||||
cdns_spi_setup_transfer(spi, transfer);
|
||||
|
||||
/* Set TX empty threshold to half of FIFO depth
|
||||
* only if TX bytes are more than half FIFO depth.
|
||||
*/
|
||||
if (xspi->tx_bytes > (xspi->tx_fifo_depth >> 1))
|
||||
cdns_spi_write(xspi, CDNS_SPI_THLD, xspi->tx_fifo_depth >> 1);
|
||||
|
||||
cdns_spi_fill_tx_fifo(xspi);
|
||||
spi_transfer_delay_exec(transfer);
|
||||
|
||||
@ -429,16 +468,16 @@ static int cdns_transfer_one(struct spi_master *master,
|
||||
|
||||
/**
|
||||
* cdns_prepare_transfer_hardware - Prepares hardware for transfer.
|
||||
* @master: Pointer to the spi_master structure which provides
|
||||
* @ctlr: Pointer to the spi_controller structure which provides
|
||||
* information about the controller.
|
||||
*
|
||||
* This function enables SPI master controller.
|
||||
*
|
||||
* Return: 0 always
|
||||
*/
|
||||
static int cdns_prepare_transfer_hardware(struct spi_master *master)
|
||||
static int cdns_prepare_transfer_hardware(struct spi_controller *ctlr)
|
||||
{
|
||||
struct cdns_spi *xspi = spi_master_get_devdata(master);
|
||||
struct cdns_spi *xspi = spi_controller_get_devdata(ctlr);
|
||||
|
||||
cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_ENABLE);
|
||||
|
||||
@ -447,24 +486,33 @@ static int cdns_prepare_transfer_hardware(struct spi_master *master)
|
||||
|
||||
/**
|
||||
* cdns_unprepare_transfer_hardware - Relaxes hardware after transfer
|
||||
* @master: Pointer to the spi_master structure which provides
|
||||
* @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 flush out if any pending data in FIFO.
|
||||
*
|
||||
* Return: 0 always
|
||||
*/
|
||||
static int cdns_unprepare_transfer_hardware(struct spi_master *master)
|
||||
static int cdns_unprepare_transfer_hardware(struct spi_controller *ctlr)
|
||||
{
|
||||
struct cdns_spi *xspi = spi_master_get_devdata(master);
|
||||
struct cdns_spi *xspi = spi_controller_get_devdata(ctlr);
|
||||
u32 ctrl_reg;
|
||||
unsigned int cnt = xspi->tx_fifo_depth;
|
||||
|
||||
if (spi_controller_is_slave(ctlr)) {
|
||||
while (cnt--)
|
||||
cdns_spi_read(xspi, CDNS_SPI_RXD);
|
||||
}
|
||||
|
||||
/* Disable the SPI if slave 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)
|
||||
if (ctrl_reg == CDNS_SPI_NOSS || spi_controller_is_slave(ctlr))
|
||||
cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE);
|
||||
|
||||
/* Reset to default */
|
||||
cdns_spi_write(xspi, CDNS_SPI_THLD, 0x1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -486,6 +534,27 @@ static void cdns_spi_detect_fifo_depth(struct cdns_spi *xspi)
|
||||
cdns_spi_write(xspi, CDNS_SPI_THLD, 0x1);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdns_slave_abort - Abort slave transfer
|
||||
* @ctlr: Pointer to the spi_controller structure
|
||||
*
|
||||
* This function abort slave transfer if there any transfer timeout.
|
||||
*
|
||||
* Return: 0 always
|
||||
*/
|
||||
static int cdns_slave_abort(struct spi_controller *ctlr)
|
||||
{
|
||||
struct cdns_spi *xspi = spi_controller_get_devdata(ctlr);
|
||||
u32 intr_status;
|
||||
|
||||
intr_status = cdns_spi_read(xspi, CDNS_SPI_ISR);
|
||||
cdns_spi_write(xspi, CDNS_SPI_ISR, intr_status);
|
||||
cdns_spi_write(xspi, CDNS_SPI_IDR, (CDNS_SPI_IXR_MODF | CDNS_SPI_IXR_RXNEMTY));
|
||||
spi_finalize_current_transfer(ctlr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdns_spi_probe - Probe method for the SPI driver
|
||||
* @pdev: Pointer to the platform_device structure
|
||||
@ -497,71 +566,79 @@ static void cdns_spi_detect_fifo_depth(struct cdns_spi *xspi)
|
||||
static int cdns_spi_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret = 0, irq;
|
||||
struct spi_master *master;
|
||||
struct spi_controller *ctlr;
|
||||
struct cdns_spi *xspi;
|
||||
u32 num_cs;
|
||||
bool slave;
|
||||
|
||||
master = spi_alloc_master(&pdev->dev, sizeof(*xspi));
|
||||
if (!master)
|
||||
slave = of_property_read_bool(pdev->dev.of_node, "spi-slave");
|
||||
if (slave)
|
||||
ctlr = spi_alloc_slave(&pdev->dev, sizeof(*xspi));
|
||||
else
|
||||
ctlr = spi_alloc_master(&pdev->dev, sizeof(*xspi));
|
||||
|
||||
if (!ctlr)
|
||||
return -ENOMEM;
|
||||
|
||||
xspi = spi_master_get_devdata(master);
|
||||
master->dev.of_node = pdev->dev.of_node;
|
||||
platform_set_drvdata(pdev, master);
|
||||
xspi = spi_controller_get_devdata(ctlr);
|
||||
ctlr->dev.of_node = pdev->dev.of_node;
|
||||
platform_set_drvdata(pdev, ctlr);
|
||||
|
||||
xspi->regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(xspi->regs)) {
|
||||
ret = PTR_ERR(xspi->regs);
|
||||
goto remove_master;
|
||||
goto remove_ctlr;
|
||||
}
|
||||
|
||||
xspi->pclk = devm_clk_get(&pdev->dev, "pclk");
|
||||
if (IS_ERR(xspi->pclk)) {
|
||||
dev_err(&pdev->dev, "pclk clock not found.\n");
|
||||
ret = PTR_ERR(xspi->pclk);
|
||||
goto remove_master;
|
||||
}
|
||||
|
||||
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");
|
||||
ret = PTR_ERR(xspi->ref_clk);
|
||||
goto remove_master;
|
||||
goto remove_ctlr;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(xspi->pclk);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Unable to enable APB clock.\n");
|
||||
goto remove_master;
|
||||
goto remove_ctlr;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(xspi->ref_clk);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Unable to enable device clock.\n");
|
||||
goto clk_dis_apb;
|
||||
if (!spi_controller_is_slave(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");
|
||||
ret = PTR_ERR(xspi->ref_clk);
|
||||
goto clk_dis_apb;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(xspi->ref_clk);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Unable to enable device clock.\n");
|
||||
goto clk_dis_apb;
|
||||
}
|
||||
|
||||
pm_runtime_use_autosuspend(&pdev->dev);
|
||||
pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT);
|
||||
pm_runtime_get_noresume(&pdev->dev);
|
||||
pm_runtime_set_active(&pdev->dev);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
ret = of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs);
|
||||
if (ret < 0)
|
||||
ctlr->num_chipselect = CDNS_SPI_DEFAULT_NUM_CS;
|
||||
else
|
||||
ctlr->num_chipselect = num_cs;
|
||||
|
||||
ret = of_property_read_u32(pdev->dev.of_node, "is-decoded-cs",
|
||||
&xspi->is_decoded_cs);
|
||||
if (ret < 0)
|
||||
xspi->is_decoded_cs = 0;
|
||||
}
|
||||
|
||||
pm_runtime_use_autosuspend(&pdev->dev);
|
||||
pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT);
|
||||
pm_runtime_get_noresume(&pdev->dev);
|
||||
pm_runtime_set_active(&pdev->dev);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
ret = of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs);
|
||||
if (ret < 0)
|
||||
master->num_chipselect = CDNS_SPI_DEFAULT_NUM_CS;
|
||||
else
|
||||
master->num_chipselect = num_cs;
|
||||
|
||||
ret = of_property_read_u32(pdev->dev.of_node, "is-decoded-cs",
|
||||
&xspi->is_decoded_cs);
|
||||
if (ret < 0)
|
||||
xspi->is_decoded_cs = 0;
|
||||
|
||||
cdns_spi_detect_fifo_depth(xspi);
|
||||
|
||||
/* SPI controller initializations */
|
||||
cdns_spi_init_hw(xspi);
|
||||
cdns_spi_init_hw(xspi, spi_controller_is_slave(ctlr));
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq <= 0) {
|
||||
@ -570,48 +647,53 @@ static int cdns_spi_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, irq, cdns_spi_irq,
|
||||
0, pdev->name, master);
|
||||
0, pdev->name, ctlr);
|
||||
if (ret != 0) {
|
||||
ret = -ENXIO;
|
||||
dev_err(&pdev->dev, "request_irq failed\n");
|
||||
goto clk_dis_all;
|
||||
}
|
||||
|
||||
master->use_gpio_descriptors = true;
|
||||
master->prepare_transfer_hardware = cdns_prepare_transfer_hardware;
|
||||
master->prepare_message = cdns_prepare_message;
|
||||
master->transfer_one = cdns_transfer_one;
|
||||
master->unprepare_transfer_hardware = cdns_unprepare_transfer_hardware;
|
||||
master->set_cs = cdns_spi_chipselect;
|
||||
master->auto_runtime_pm = true;
|
||||
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
|
||||
ctlr->use_gpio_descriptors = true;
|
||||
ctlr->prepare_transfer_hardware = cdns_prepare_transfer_hardware;
|
||||
ctlr->prepare_message = cdns_prepare_message;
|
||||
ctlr->transfer_one = cdns_transfer_one;
|
||||
ctlr->unprepare_transfer_hardware = cdns_unprepare_transfer_hardware;
|
||||
ctlr->mode_bits = SPI_CPOL | SPI_CPHA;
|
||||
ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
|
||||
|
||||
xspi->clk_rate = clk_get_rate(xspi->ref_clk);
|
||||
/* Set to default valid value */
|
||||
master->max_speed_hz = xspi->clk_rate / 4;
|
||||
xspi->speed_hz = master->max_speed_hz;
|
||||
|
||||
master->bits_per_word_mask = SPI_BPW_MASK(8);
|
||||
|
||||
pm_runtime_mark_last_busy(&pdev->dev);
|
||||
pm_runtime_put_autosuspend(&pdev->dev);
|
||||
|
||||
ret = spi_register_master(master);
|
||||
if (!spi_controller_is_slave(ctlr)) {
|
||||
ctlr->mode_bits |= SPI_CS_HIGH;
|
||||
ctlr->set_cs = cdns_spi_chipselect;
|
||||
ctlr->auto_runtime_pm = true;
|
||||
xspi->clk_rate = clk_get_rate(xspi->ref_clk);
|
||||
/* Set to default valid value */
|
||||
ctlr->max_speed_hz = xspi->clk_rate / 4;
|
||||
xspi->speed_hz = ctlr->max_speed_hz;
|
||||
pm_runtime_mark_last_busy(&pdev->dev);
|
||||
pm_runtime_put_autosuspend(&pdev->dev);
|
||||
} else {
|
||||
ctlr->mode_bits |= SPI_NO_CS;
|
||||
ctlr->slave_abort = cdns_slave_abort;
|
||||
}
|
||||
ret = spi_register_controller(ctlr);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "spi_register_master failed\n");
|
||||
dev_err(&pdev->dev, "spi_register_controller failed\n");
|
||||
goto clk_dis_all;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
clk_dis_all:
|
||||
pm_runtime_set_suspended(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
clk_disable_unprepare(xspi->ref_clk);
|
||||
if (!spi_controller_is_slave(ctlr)) {
|
||||
pm_runtime_set_suspended(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
clk_disable_unprepare(xspi->ref_clk);
|
||||
}
|
||||
clk_dis_apb:
|
||||
clk_disable_unprepare(xspi->pclk);
|
||||
remove_master:
|
||||
spi_master_put(master);
|
||||
remove_ctlr:
|
||||
spi_controller_put(ctlr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -625,10 +707,10 @@ remove_master:
|
||||
*
|
||||
* Return: 0 on success and error value on error
|
||||
*/
|
||||
static int cdns_spi_remove(struct platform_device *pdev)
|
||||
static void cdns_spi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_master *master = platform_get_drvdata(pdev);
|
||||
struct cdns_spi *xspi = spi_master_get_devdata(master);
|
||||
struct spi_controller *ctlr = platform_get_drvdata(pdev);
|
||||
struct cdns_spi *xspi = spi_controller_get_devdata(ctlr);
|
||||
|
||||
cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE);
|
||||
|
||||
@ -637,9 +719,7 @@ static int cdns_spi_remove(struct platform_device *pdev)
|
||||
pm_runtime_set_suspended(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
spi_unregister_master(master);
|
||||
|
||||
return 0;
|
||||
spi_unregister_controller(ctlr);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -653,9 +733,9 @@ static int cdns_spi_remove(struct platform_device *pdev)
|
||||
*/
|
||||
static int __maybe_unused cdns_spi_suspend(struct device *dev)
|
||||
{
|
||||
struct spi_master *master = dev_get_drvdata(dev);
|
||||
struct spi_controller *ctlr = dev_get_drvdata(dev);
|
||||
|
||||
return spi_master_suspend(master);
|
||||
return spi_controller_suspend(ctlr);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -668,11 +748,11 @@ static int __maybe_unused cdns_spi_suspend(struct device *dev)
|
||||
*/
|
||||
static int __maybe_unused cdns_spi_resume(struct device *dev)
|
||||
{
|
||||
struct spi_master *master = dev_get_drvdata(dev);
|
||||
struct cdns_spi *xspi = spi_master_get_devdata(master);
|
||||
struct spi_controller *ctlr = dev_get_drvdata(dev);
|
||||
struct cdns_spi *xspi = spi_controller_get_devdata(ctlr);
|
||||
|
||||
cdns_spi_init_hw(xspi);
|
||||
return spi_master_resume(master);
|
||||
cdns_spi_init_hw(xspi, spi_controller_is_slave(ctlr));
|
||||
return spi_controller_resume(ctlr);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -685,8 +765,8 @@ static int __maybe_unused cdns_spi_resume(struct device *dev)
|
||||
*/
|
||||
static int __maybe_unused cdns_spi_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct spi_master *master = dev_get_drvdata(dev);
|
||||
struct cdns_spi *xspi = spi_master_get_devdata(master);
|
||||
struct spi_controller *ctlr = dev_get_drvdata(dev);
|
||||
struct cdns_spi *xspi = spi_controller_get_devdata(ctlr);
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(xspi->pclk);
|
||||
@ -714,8 +794,8 @@ static int __maybe_unused cdns_spi_runtime_resume(struct device *dev)
|
||||
*/
|
||||
static int __maybe_unused cdns_spi_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct spi_master *master = dev_get_drvdata(dev);
|
||||
struct cdns_spi *xspi = spi_master_get_devdata(master);
|
||||
struct spi_controller *ctlr = dev_get_drvdata(dev);
|
||||
struct cdns_spi *xspi = spi_controller_get_devdata(ctlr);
|
||||
|
||||
clk_disable_unprepare(xspi->ref_clk);
|
||||
clk_disable_unprepare(xspi->pclk);
|
||||
@ -739,7 +819,7 @@ MODULE_DEVICE_TABLE(of, cdns_spi_of_match);
|
||||
/* cdns_spi_driver - This structure defines the SPI subsystem platform driver */
|
||||
static struct platform_driver cdns_spi_driver = {
|
||||
.probe = cdns_spi_probe,
|
||||
.remove = cdns_spi_remove,
|
||||
.remove_new = cdns_spi_remove,
|
||||
.driver = {
|
||||
.name = CDNS_SPI_NAME,
|
||||
.of_match_table = cdns_spi_of_match,
|
||||
|
@ -69,15 +69,13 @@ fail:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int octeon_spi_remove(struct platform_device *pdev)
|
||||
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);
|
||||
|
||||
/* Clear the CSENA* and put everything in a known state. */
|
||||
writeq(0, p->register_base + OCTEON_SPI_CFG(p));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id octeon_spi_match[] = {
|
||||
@ -92,7 +90,7 @@ static struct platform_driver octeon_spi_driver = {
|
||||
.of_match_table = octeon_spi_match,
|
||||
},
|
||||
.probe = octeon_spi_probe,
|
||||
.remove = octeon_spi_remove,
|
||||
.remove_new = octeon_spi_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(octeon_spi_driver);
|
||||
|
@ -57,8 +57,8 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,
|
||||
mpi_cfg.s.cslate = cpha ? 1 : 0;
|
||||
mpi_cfg.s.enable = 1;
|
||||
|
||||
if (spi->chip_select < 4)
|
||||
p->cs_enax |= 1ull << (12 + spi->chip_select);
|
||||
if (spi_get_chipselect(spi, 0) < 4)
|
||||
p->cs_enax |= 1ull << (12 + spi_get_chipselect(spi, 0));
|
||||
mpi_cfg.u64 |= p->cs_enax;
|
||||
|
||||
if (mpi_cfg.u64 != p->last_cfg) {
|
||||
@ -78,7 +78,7 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,
|
||||
writeq(d, p->register_base + OCTEON_SPI_DAT0(p) + (8 * i));
|
||||
}
|
||||
mpi_tx.u64 = 0;
|
||||
mpi_tx.s.csid = spi->chip_select;
|
||||
mpi_tx.s.csid = spi_get_chipselect(spi, 0);
|
||||
mpi_tx.s.leavecs = 1;
|
||||
mpi_tx.s.txnum = tx_buf ? OCTEON_SPI_MAX_BYTES : 0;
|
||||
mpi_tx.s.totnum = OCTEON_SPI_MAX_BYTES;
|
||||
@ -103,7 +103,7 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,
|
||||
}
|
||||
|
||||
mpi_tx.u64 = 0;
|
||||
mpi_tx.s.csid = spi->chip_select;
|
||||
mpi_tx.s.csid = spi_get_chipselect(spi, 0);
|
||||
if (last_xfer)
|
||||
mpi_tx.s.leavecs = xfer->cs_change;
|
||||
else
|
||||
|
@ -290,9 +290,9 @@ static void mcfqspi_set_cs(struct spi_device *spi, bool enable)
|
||||
bool cs_high = spi->mode & SPI_CS_HIGH;
|
||||
|
||||
if (enable)
|
||||
mcfqspi_cs_select(mcfqspi, spi->chip_select, cs_high);
|
||||
mcfqspi_cs_select(mcfqspi, spi_get_chipselect(spi, 0), cs_high);
|
||||
else
|
||||
mcfqspi_cs_deselect(mcfqspi, spi->chip_select, cs_high);
|
||||
mcfqspi_cs_deselect(mcfqspi, spi_get_chipselect(spi, 0), cs_high);
|
||||
}
|
||||
|
||||
static int mcfqspi_transfer_one(struct spi_master *master,
|
||||
@ -324,11 +324,11 @@ 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),
|
||||
spi->chip_select, spi->mode & SPI_CS_HIGH);
|
||||
spi_get_chipselect(spi, 0), spi->mode & SPI_CS_HIGH);
|
||||
|
||||
dev_dbg(&spi->dev,
|
||||
"bits per word %d, chip select %d, speed %d KHz\n",
|
||||
spi->bits_per_word, spi->chip_select,
|
||||
spi->bits_per_word, spi_get_chipselect(spi, 0),
|
||||
(MCFQSPI_BUSCLK / mcfqspi_qmr_baud(spi->max_speed_hz))
|
||||
/ 1000);
|
||||
|
||||
@ -434,7 +434,7 @@ fail0:
|
||||
return status;
|
||||
}
|
||||
|
||||
static int mcfqspi_remove(struct platform_device *pdev)
|
||||
static void mcfqspi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_master *master = platform_get_drvdata(pdev);
|
||||
struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
|
||||
@ -445,8 +445,6 @@ static int mcfqspi_remove(struct platform_device *pdev)
|
||||
|
||||
mcfqspi_cs_teardown(mcfqspi);
|
||||
clk_disable_unprepare(mcfqspi->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
@ -509,7 +507,7 @@ static struct platform_driver mcfqspi_driver = {
|
||||
.driver.owner = THIS_MODULE,
|
||||
.driver.pm = &mcfqspi_pm,
|
||||
.probe = mcfqspi_probe,
|
||||
.remove = mcfqspi_remove,
|
||||
.remove_new = mcfqspi_remove,
|
||||
};
|
||||
module_platform_driver(mcfqspi_driver);
|
||||
|
||||
|
@ -199,7 +199,7 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)
|
||||
{
|
||||
struct davinci_spi *dspi;
|
||||
struct davinci_spi_config *spicfg = spi->controller_data;
|
||||
u8 chip_sel = spi->chip_select;
|
||||
u8 chip_sel = spi_get_chipselect(spi, 0);
|
||||
u16 spidat1 = CS_DEFAULT;
|
||||
|
||||
dspi = spi_master_get_devdata(spi->master);
|
||||
@ -212,11 +212,11 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)
|
||||
* Board specific chip select logic decides the polarity and cs
|
||||
* line for the controller
|
||||
*/
|
||||
if (spi->cs_gpiod) {
|
||||
if (spi_get_csgpiod(spi, 0)) {
|
||||
if (value == BITBANG_CS_ACTIVE)
|
||||
gpiod_set_value(spi->cs_gpiod, 1);
|
||||
gpiod_set_value(spi_get_csgpiod(spi, 0), 1);
|
||||
else
|
||||
gpiod_set_value(spi->cs_gpiod, 0);
|
||||
gpiod_set_value(spi_get_csgpiod(spi, 0), 0);
|
||||
} else {
|
||||
if (value == BITBANG_CS_ACTIVE) {
|
||||
if (!(spi->mode & SPI_CS_WORD))
|
||||
@ -293,11 +293,11 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
|
||||
if (bits_per_word <= 8) {
|
||||
dspi->get_rx = davinci_spi_rx_buf_u8;
|
||||
dspi->get_tx = davinci_spi_tx_buf_u8;
|
||||
dspi->bytes_per_word[spi->chip_select] = 1;
|
||||
dspi->bytes_per_word[spi_get_chipselect(spi, 0)] = 1;
|
||||
} else {
|
||||
dspi->get_rx = davinci_spi_rx_buf_u16;
|
||||
dspi->get_tx = davinci_spi_tx_buf_u16;
|
||||
dspi->bytes_per_word[spi->chip_select] = 2;
|
||||
dspi->bytes_per_word[spi_get_chipselect(spi, 0)] = 2;
|
||||
}
|
||||
|
||||
if (!hz)
|
||||
@ -415,11 +415,11 @@ static int davinci_spi_setup(struct spi_device *spi)
|
||||
dspi = spi_master_get_devdata(spi->master);
|
||||
|
||||
if (!(spi->mode & SPI_NO_CS)) {
|
||||
if (np && spi->cs_gpiod)
|
||||
if (np && spi_get_csgpiod(spi, 0))
|
||||
internal_cs = false;
|
||||
|
||||
if (internal_cs)
|
||||
set_io_bits(dspi->base + SPIPC0, 1 << spi->chip_select);
|
||||
set_io_bits(dspi->base + SPIPC0, 1 << spi_get_chipselect(spi, 0));
|
||||
}
|
||||
|
||||
if (spi->mode & SPI_READY)
|
||||
@ -579,7 +579,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
|
||||
spicfg = &davinci_spi_default_cfg;
|
||||
|
||||
/* convert len to words based on bits_per_word */
|
||||
data_type = dspi->bytes_per_word[spi->chip_select];
|
||||
data_type = dspi->bytes_per_word[spi_get_chipselect(spi, 0)];
|
||||
|
||||
dspi->tx = t->tx_buf;
|
||||
dspi->rx = t->rx_buf;
|
||||
@ -1018,7 +1018,7 @@ err:
|
||||
* It will also call spi_bitbang_stop to destroy the work queue which was
|
||||
* created by spi_bitbang_start.
|
||||
*/
|
||||
static int davinci_spi_remove(struct platform_device *pdev)
|
||||
static void davinci_spi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct davinci_spi *dspi;
|
||||
struct spi_master *master;
|
||||
@ -1036,7 +1036,6 @@ static int davinci_spi_remove(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
spi_master_put(master);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver davinci_spi_driver = {
|
||||
@ -1045,7 +1044,7 @@ static struct platform_driver davinci_spi_driver = {
|
||||
.of_match_table = of_match_ptr(davinci_spi_of_match),
|
||||
},
|
||||
.probe = davinci_spi_probe,
|
||||
.remove = davinci_spi_remove,
|
||||
.remove_new = davinci_spi_remove,
|
||||
};
|
||||
module_platform_driver(davinci_spi_driver);
|
||||
|
||||
|
@ -596,12 +596,12 @@ static int dln2_spi_prepare_message(struct spi_master *master,
|
||||
struct dln2_spi *dln2 = spi_master_get_devdata(master);
|
||||
struct spi_device *spi = message->spi;
|
||||
|
||||
if (dln2->cs != spi->chip_select) {
|
||||
ret = dln2_spi_cs_set_one(dln2, spi->chip_select);
|
||||
if (dln2->cs != spi_get_chipselect(spi, 0)) {
|
||||
ret = dln2_spi_cs_set_one(dln2, spi_get_chipselect(spi, 0));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dln2->cs = spi->chip_select;
|
||||
dln2->cs = spi_get_chipselect(spi, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -781,7 +781,7 @@ exit_free_master:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dln2_spi_remove(struct platform_device *pdev)
|
||||
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);
|
||||
@ -790,8 +790,6 @@ static int dln2_spi_remove(struct platform_device *pdev)
|
||||
|
||||
if (dln2_spi_enable(dln2, false) < 0)
|
||||
dev_err(&pdev->dev, "Failed to disable SPI module\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
@ -873,7 +871,7 @@ static struct platform_driver spi_dln2_driver = {
|
||||
.pm = &dln2_spi_pm,
|
||||
},
|
||||
.probe = dln2_spi_probe,
|
||||
.remove = dln2_spi_remove,
|
||||
.remove_new = dln2_spi_remove,
|
||||
};
|
||||
module_platform_driver(spi_dln2_driver);
|
||||
|
||||
|
@ -308,7 +308,7 @@ err_disable_clk:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dw_spi_bt1_remove(struct platform_device *pdev)
|
||||
static void dw_spi_bt1_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct dw_spi_bt1 *dwsbt1 = platform_get_drvdata(pdev);
|
||||
|
||||
@ -317,8 +317,6 @@ static int dw_spi_bt1_remove(struct platform_device *pdev)
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
clk_disable_unprepare(dwsbt1->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id dw_spi_bt1_of_match[] = {
|
||||
@ -330,7 +328,7 @@ MODULE_DEVICE_TABLE(of, dw_spi_bt1_of_match);
|
||||
|
||||
static struct platform_driver dw_spi_bt1_driver = {
|
||||
.probe = dw_spi_bt1_probe,
|
||||
.remove = dw_spi_bt1_remove,
|
||||
.remove_new = dw_spi_bt1_remove,
|
||||
.driver = {
|
||||
.name = "bt1-sys-ssi",
|
||||
.of_match_table = dw_spi_bt1_of_match,
|
||||
|
@ -103,7 +103,7 @@ void dw_spi_set_cs(struct spi_device *spi, bool enable)
|
||||
* support active-high or active-low CS level.
|
||||
*/
|
||||
if (cs_high == enable)
|
||||
dw_writel(dws, DW_SPI_SER, BIT(spi->chip_select));
|
||||
dw_writel(dws, DW_SPI_SER, BIT(spi_get_chipselect(spi, 0)));
|
||||
else
|
||||
dw_writel(dws, DW_SPI_SER, 0);
|
||||
}
|
||||
|
@ -53,6 +53,20 @@ struct dw_spi_mscc {
|
||||
void __iomem *spi_mst; /* Not sparx5 */
|
||||
};
|
||||
|
||||
/*
|
||||
* Elba SoC does not use ssi, pin override is used for cs 0,1 and
|
||||
* gpios for cs 2,3 as defined in the device tree.
|
||||
*
|
||||
* cs: | 1 0
|
||||
* bit: |---3-------2-------1-------0
|
||||
* | cs1 cs1_ovr cs0 cs0_ovr
|
||||
*/
|
||||
#define ELBA_SPICS_REG 0x2468
|
||||
#define ELBA_SPICS_OFFSET(cs) ((cs) << 1)
|
||||
#define ELBA_SPICS_MASK(cs) (GENMASK(1, 0) << ELBA_SPICS_OFFSET(cs))
|
||||
#define ELBA_SPICS_SET(cs, val) \
|
||||
((((val) << 1) | BIT(0)) << ELBA_SPICS_OFFSET(cs))
|
||||
|
||||
/*
|
||||
* The Designware SPI controller (referred to as master in the documentation)
|
||||
* automatically deasserts chip select when the tx fifo is empty. The chip
|
||||
@ -65,7 +79,7 @@ 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_mmio *dwsmmio = container_of(dws, struct dw_spi_mmio, dws);
|
||||
struct dw_spi_mscc *dwsmscc = dwsmmio->priv;
|
||||
u32 cs = spi->chip_select;
|
||||
u32 cs = spi_get_chipselect(spi, 0);
|
||||
|
||||
if (cs < 4) {
|
||||
u32 sw_mode = MSCC_SPI_MST_SW_MODE_SW_PIN_CTRL_MODE;
|
||||
@ -138,7 +152,7 @@ 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_mmio *dwsmmio = container_of(dws, struct dw_spi_mmio, dws);
|
||||
struct dw_spi_mscc *dwsmscc = dwsmmio->priv;
|
||||
u8 cs = spi->chip_select;
|
||||
u8 cs = spi_get_chipselect(spi, 0);
|
||||
|
||||
if (!enable) {
|
||||
/* CS override drive enable */
|
||||
@ -237,6 +251,49 @@ static int dw_spi_canaan_k210_init(struct platform_device *pdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dw_spi_elba_override_cs(struct regmap *syscon, int cs, int enable)
|
||||
{
|
||||
regmap_update_bits(syscon, ELBA_SPICS_REG, ELBA_SPICS_MASK(cs),
|
||||
ELBA_SPICS_SET(cs, 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_mmio *dwsmmio = container_of(dws, struct dw_spi_mmio, dws);
|
||||
struct regmap *syscon = dwsmmio->priv;
|
||||
u8 cs;
|
||||
|
||||
cs = spi->chip_select;
|
||||
if (cs < 2)
|
||||
dw_spi_elba_override_cs(syscon, spi->chip_select, enable);
|
||||
|
||||
/*
|
||||
* The DW SPI controller needs a native CS bit selected to start
|
||||
* the serial engine.
|
||||
*/
|
||||
spi->chip_select = 0;
|
||||
dw_spi_set_cs(spi, enable);
|
||||
spi->chip_select = cs;
|
||||
}
|
||||
|
||||
static int dw_spi_elba_init(struct platform_device *pdev,
|
||||
struct dw_spi_mmio *dwsmmio)
|
||||
{
|
||||
struct regmap *syscon;
|
||||
|
||||
syscon = syscon_regmap_lookup_by_phandle(dev_of_node(&pdev->dev),
|
||||
"amd,pensando-elba-syscon");
|
||||
if (IS_ERR(syscon))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(syscon),
|
||||
"syscon regmap lookup failed\n");
|
||||
|
||||
dwsmmio->priv = syscon;
|
||||
dwsmmio->dws.set_cs = dw_spi_elba_set_cs;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dw_spi_mmio_probe(struct platform_device *pdev)
|
||||
{
|
||||
int (*init_func)(struct platform_device *pdev,
|
||||
@ -328,7 +385,7 @@ out_clk:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dw_spi_mmio_remove(struct platform_device *pdev)
|
||||
static void dw_spi_mmio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct dw_spi_mmio *dwsmmio = platform_get_drvdata(pdev);
|
||||
|
||||
@ -337,8 +394,6 @@ static int dw_spi_mmio_remove(struct platform_device *pdev)
|
||||
clk_disable_unprepare(dwsmmio->pclk);
|
||||
clk_disable_unprepare(dwsmmio->clk);
|
||||
reset_control_assert(dwsmmio->rstc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id dw_spi_mmio_of_match[] = {
|
||||
@ -352,6 +407,7 @@ static const struct of_device_id dw_spi_mmio_of_match[] = {
|
||||
{ .compatible = "intel,thunderbay-ssi", .data = dw_spi_intel_init},
|
||||
{ .compatible = "microchip,sparx5-spi", dw_spi_mscc_sparx5_init},
|
||||
{ .compatible = "canaan,k210-spi", dw_spi_canaan_k210_init},
|
||||
{ .compatible = "amd,pensando-elba-spi", .data = dw_spi_elba_init},
|
||||
{ /* end of table */}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, dw_spi_mmio_of_match);
|
||||
@ -366,7 +422,7 @@ MODULE_DEVICE_TABLE(acpi, dw_spi_mmio_acpi_match);
|
||||
|
||||
static struct platform_driver dw_spi_mmio_driver = {
|
||||
.probe = dw_spi_mmio_probe,
|
||||
.remove = dw_spi_mmio_remove,
|
||||
.remove_new = dw_spi_mmio_remove,
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.of_match_table = dw_spi_mmio_of_match,
|
||||
|
@ -745,14 +745,12 @@ fail_release_master:
|
||||
return error;
|
||||
}
|
||||
|
||||
static int ep93xx_spi_remove(struct platform_device *pdev)
|
||||
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);
|
||||
|
||||
ep93xx_spi_release_dma(espi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver ep93xx_spi_driver = {
|
||||
@ -760,7 +758,7 @@ static struct platform_driver ep93xx_spi_driver = {
|
||||
.name = "ep93xx-spi",
|
||||
},
|
||||
.probe = ep93xx_spi_probe,
|
||||
.remove = ep93xx_spi_remove,
|
||||
.remove_new = ep93xx_spi_remove,
|
||||
};
|
||||
module_platform_driver(ep93xx_spi_driver);
|
||||
|
||||
|
@ -131,7 +131,7 @@ int falcon_sflash_xfer(struct spi_device *spi, struct spi_transfer *t,
|
||||
* especially alen and dumlen.
|
||||
*/
|
||||
|
||||
priv->sfcmd = ((spi->chip_select
|
||||
priv->sfcmd = ((spi_get_chipselect(spi, 0)
|
||||
<< SFCMD_CS_OFFSET)
|
||||
& SFCMD_CS_MASK);
|
||||
priv->sfcmd |= SFCMD_KEEP_CS_KEEP_SELECTED;
|
||||
|
@ -425,7 +425,7 @@ static int fsi_spi_transfer_one_message(struct spi_controller *ctlr,
|
||||
struct spi_message *mesg)
|
||||
{
|
||||
int rc;
|
||||
u8 seq_slave = SPI_FSI_SEQUENCE_SEL_SLAVE(mesg->spi->chip_select + 1);
|
||||
u8 seq_slave = SPI_FSI_SEQUENCE_SEL_SLAVE(spi_get_chipselect(mesg->spi, 0) + 1);
|
||||
unsigned int len;
|
||||
struct spi_transfer *transfer;
|
||||
struct fsi_spi *ctx = spi_controller_get_devdata(ctlr);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
|
||||
#include "spi-fsl-cpm.h"
|
||||
#include "spi-fsl-lib.h"
|
||||
@ -120,6 +121,21 @@ int fsl_spi_cpm_bufs(struct mpc8xxx_spi *mspi,
|
||||
mspi->rx_dma = mspi->dma_dummy_rx;
|
||||
mspi->map_rx_dma = 0;
|
||||
}
|
||||
if (t->bits_per_word == 16 && t->tx_buf) {
|
||||
const u16 *src = t->tx_buf;
|
||||
u16 *dst;
|
||||
int i;
|
||||
|
||||
dst = kmalloc(t->len, GFP_KERNEL);
|
||||
if (!dst)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < t->len >> 1; i++)
|
||||
dst[i] = cpu_to_le16p(src + i);
|
||||
|
||||
mspi->tx = dst;
|
||||
mspi->map_tx_dma = 1;
|
||||
}
|
||||
|
||||
if (mspi->map_tx_dma) {
|
||||
void *nonconst_tx = (void *)mspi->tx; /* shut up gcc */
|
||||
@ -173,6 +189,13 @@ void fsl_spi_cpm_bufs_complete(struct mpc8xxx_spi *mspi)
|
||||
if (mspi->map_rx_dma)
|
||||
dma_unmap_single(dev, mspi->rx_dma, t->len, DMA_FROM_DEVICE);
|
||||
mspi->xfer_in_progress = NULL;
|
||||
|
||||
if (t->bits_per_word == 16 && t->rx_buf) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < t->len; i += 2)
|
||||
le16_to_cpus(t->rx_buf + i);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fsl_spi_cpm_bufs_complete);
|
||||
|
||||
|
@ -902,19 +902,19 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id)
|
||||
|
||||
static void dspi_assert_cs(struct spi_device *spi, bool *cs)
|
||||
{
|
||||
if (!spi->cs_gpiod || *cs)
|
||||
if (!spi_get_csgpiod(spi, 0) || *cs)
|
||||
return;
|
||||
|
||||
gpiod_set_value_cansleep(spi->cs_gpiod, true);
|
||||
gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), true);
|
||||
*cs = true;
|
||||
}
|
||||
|
||||
static void dspi_deassert_cs(struct spi_device *spi, bool *cs)
|
||||
{
|
||||
if (!spi->cs_gpiod || !*cs)
|
||||
if (!spi_get_csgpiod(spi, 0) || !*cs)
|
||||
return;
|
||||
|
||||
gpiod_set_value_cansleep(spi->cs_gpiod, false);
|
||||
gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), false);
|
||||
*cs = false;
|
||||
}
|
||||
|
||||
@ -938,8 +938,8 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr,
|
||||
|
||||
/* Prepare command word for CMD FIFO */
|
||||
dspi->tx_cmd = SPI_PUSHR_CMD_CTAS(0);
|
||||
if (!spi->cs_gpiod)
|
||||
dspi->tx_cmd |= SPI_PUSHR_CMD_PCS(spi->chip_select);
|
||||
if (!spi_get_csgpiod(spi, 0))
|
||||
dspi->tx_cmd |= SPI_PUSHR_CMD_PCS(spi_get_chipselect(spi, 0));
|
||||
|
||||
if (list_is_last(&dspi->cur_transfer->transfer_list,
|
||||
&dspi->cur_msg->transfers)) {
|
||||
@ -1058,7 +1058,7 @@ static int dspi_setup(struct spi_device *spi)
|
||||
chip->ctar_val |= SPI_CTAR_LSBFE;
|
||||
}
|
||||
|
||||
gpiod_direction_output(spi->cs_gpiod, false);
|
||||
gpiod_direction_output(spi_get_csgpiod(spi, 0), false);
|
||||
dspi_deassert_cs(spi, &cs);
|
||||
|
||||
spi_set_ctldata(spi, chip);
|
||||
@ -1068,10 +1068,10 @@ static int dspi_setup(struct spi_device *spi)
|
||||
|
||||
static void dspi_cleanup(struct spi_device *spi)
|
||||
{
|
||||
struct chip_data *chip = spi_get_ctldata((struct spi_device *)spi);
|
||||
struct chip_data *chip = spi_get_ctldata(spi);
|
||||
|
||||
dev_dbg(&spi->dev, "spi_device %u.%u cleanup\n",
|
||||
spi->controller->bus_num, spi->chip_select);
|
||||
spi->controller->bus_num, spi_get_chipselect(spi, 0));
|
||||
|
||||
kfree(chip);
|
||||
}
|
||||
@ -1425,7 +1425,7 @@ out_ctlr_put:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dspi_remove(struct platform_device *pdev)
|
||||
static void dspi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct fsl_dspi *dspi = platform_get_drvdata(pdev);
|
||||
|
||||
@ -1444,8 +1444,6 @@ static int dspi_remove(struct platform_device *pdev)
|
||||
if (dspi->irq)
|
||||
free_irq(dspi->irq, dspi);
|
||||
clk_disable_unprepare(dspi->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dspi_shutdown(struct platform_device *pdev)
|
||||
@ -1459,7 +1457,7 @@ static struct platform_driver fsl_dspi_driver = {
|
||||
.driver.owner = THIS_MODULE,
|
||||
.driver.pm = &dspi_pm,
|
||||
.probe = dspi_probe,
|
||||
.remove = dspi_remove,
|
||||
.remove_new = dspi_remove,
|
||||
.shutdown = dspi_shutdown,
|
||||
};
|
||||
module_platform_driver(fsl_dspi_driver);
|
||||
|
@ -345,7 +345,7 @@ static void fsl_espi_setup_transfer(struct spi_device *spi,
|
||||
|
||||
/* don't write the mode register if the mode doesn't change */
|
||||
if (cs->hw_mode != hw_mode_old)
|
||||
fsl_espi_write_reg(espi, ESPI_SPMODEx(spi->chip_select),
|
||||
fsl_espi_write_reg(espi, ESPI_SPMODEx(spi_get_chipselect(spi, 0)),
|
||||
cs->hw_mode);
|
||||
}
|
||||
|
||||
@ -359,7 +359,7 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
|
||||
reinit_completion(&espi->done);
|
||||
|
||||
/* Set SPCOM[CS] and SPCOM[TRANLEN] field */
|
||||
spcom = SPCOM_CS(spi->chip_select);
|
||||
spcom = SPCOM_CS(spi_get_chipselect(spi, 0));
|
||||
spcom |= SPCOM_TRANLEN(t->len - 1);
|
||||
|
||||
/* configure RXSKIP mode */
|
||||
@ -492,7 +492,7 @@ static int fsl_espi_setup(struct spi_device *spi)
|
||||
|
||||
pm_runtime_get_sync(espi->dev);
|
||||
|
||||
cs->hw_mode = fsl_espi_read_reg(espi, ESPI_SPMODEx(spi->chip_select));
|
||||
cs->hw_mode = fsl_espi_read_reg(espi, ESPI_SPMODEx(spi_get_chipselect(spi, 0)));
|
||||
/* mask out bits we are going to set */
|
||||
cs->hw_mode &= ~(CSMODE_CP_BEGIN_EDGECLK | CSMODE_CI_INACTIVEHIGH
|
||||
| CSMODE_REV);
|
||||
@ -783,11 +783,9 @@ static int of_fsl_espi_probe(struct platform_device *ofdev)
|
||||
return fsl_espi_probe(dev, &mem, irq, num_cs);
|
||||
}
|
||||
|
||||
static int of_fsl_espi_remove(struct platform_device *dev)
|
||||
static void of_fsl_espi_remove(struct platform_device *dev)
|
||||
{
|
||||
pm_runtime_disable(&dev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
@ -837,7 +835,7 @@ static struct platform_driver fsl_espi_driver = {
|
||||
.pm = &espi_pm,
|
||||
},
|
||||
.probe = of_fsl_espi_probe,
|
||||
.remove = of_fsl_espi_remove,
|
||||
.remove_new = of_fsl_espi_remove,
|
||||
};
|
||||
module_platform_driver(fsl_espi_driver);
|
||||
|
||||
|
@ -425,7 +425,7 @@ static int fsl_lpspi_setup_transfer(struct spi_controller *controller,
|
||||
if (fsl_lpspi->is_only_cs1)
|
||||
fsl_lpspi->config.chip_select = 1;
|
||||
else
|
||||
fsl_lpspi->config.chip_select = spi->chip_select;
|
||||
fsl_lpspi->config.chip_select = spi_get_chipselect(spi, 0);
|
||||
|
||||
if (!fsl_lpspi->config.speed_hz)
|
||||
fsl_lpspi->config.speed_hz = spi->max_speed_hz;
|
||||
@ -937,7 +937,7 @@ out_controller_put:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fsl_lpspi_remove(struct platform_device *pdev)
|
||||
static void fsl_lpspi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_controller *controller = platform_get_drvdata(pdev);
|
||||
struct fsl_lpspi_data *fsl_lpspi =
|
||||
@ -946,7 +946,6 @@ static int fsl_lpspi_remove(struct platform_device *pdev)
|
||||
fsl_lpspi_dma_exit(controller);
|
||||
|
||||
pm_runtime_disable(fsl_lpspi->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused fsl_lpspi_suspend(struct device *dev)
|
||||
@ -983,7 +982,7 @@ static struct platform_driver fsl_lpspi_driver = {
|
||||
.pm = &fsl_lpspi_pm_ops,
|
||||
},
|
||||
.probe = fsl_lpspi_probe,
|
||||
.remove = fsl_lpspi_remove,
|
||||
.remove_new = fsl_lpspi_remove,
|
||||
};
|
||||
module_platform_driver(fsl_lpspi_driver);
|
||||
|
||||
|
@ -528,7 +528,7 @@ static void fsl_qspi_select_mem(struct fsl_qspi *q, struct spi_device *spi)
|
||||
unsigned long rate = spi->max_speed_hz;
|
||||
int ret;
|
||||
|
||||
if (q->selected == spi->chip_select)
|
||||
if (q->selected == spi_get_chipselect(spi, 0))
|
||||
return;
|
||||
|
||||
if (needs_4x_clock(q))
|
||||
@ -544,7 +544,7 @@ static void fsl_qspi_select_mem(struct fsl_qspi *q, struct spi_device *spi)
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
q->selected = spi->chip_select;
|
||||
q->selected = spi_get_chipselect(spi, 0);
|
||||
|
||||
fsl_qspi_invalidate(q);
|
||||
}
|
||||
@ -823,7 +823,7 @@ static const char *fsl_qspi_get_name(struct spi_mem *mem)
|
||||
|
||||
name = devm_kasprintf(dev, GFP_KERNEL,
|
||||
"%s-%d", dev_name(q->dev),
|
||||
mem->spi->chip_select);
|
||||
spi_get_chipselect(mem->spi, 0));
|
||||
|
||||
if (!name) {
|
||||
dev_err(dev, "failed to get memory for custom flash name\n");
|
||||
@ -948,7 +948,7 @@ err_put_ctrl:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fsl_qspi_remove(struct platform_device *pdev)
|
||||
static void fsl_qspi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct fsl_qspi *q = platform_get_drvdata(pdev);
|
||||
|
||||
@ -959,8 +959,6 @@ static int fsl_qspi_remove(struct platform_device *pdev)
|
||||
fsl_qspi_clk_disable_unprep(q);
|
||||
|
||||
mutex_destroy(&q->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsl_qspi_suspend(struct device *dev)
|
||||
@ -1000,7 +998,7 @@ static struct platform_driver fsl_qspi_driver = {
|
||||
.pm = &fsl_qspi_pm_ops,
|
||||
},
|
||||
.probe = fsl_qspi_probe,
|
||||
.remove = fsl_qspi_remove,
|
||||
.remove_new = fsl_qspi_remove,
|
||||
};
|
||||
module_platform_driver(fsl_qspi_driver);
|
||||
|
||||
|
@ -145,10 +145,10 @@ static void fsl_spi_grlib_set_shifts(u32 *rx_shift, u32 *tx_shift,
|
||||
}
|
||||
}
|
||||
|
||||
static int mspi_apply_cpu_mode_quirks(struct spi_mpc8xxx_cs *cs,
|
||||
struct spi_device *spi,
|
||||
struct mpc8xxx_spi *mpc8xxx_spi,
|
||||
int bits_per_word)
|
||||
static void mspi_apply_cpu_mode_quirks(struct spi_mpc8xxx_cs *cs,
|
||||
struct spi_device *spi,
|
||||
struct mpc8xxx_spi *mpc8xxx_spi,
|
||||
int bits_per_word)
|
||||
{
|
||||
cs->rx_shift = 0;
|
||||
cs->tx_shift = 0;
|
||||
@ -161,8 +161,7 @@ static int mspi_apply_cpu_mode_quirks(struct spi_mpc8xxx_cs *cs,
|
||||
} else if (bits_per_word <= 32) {
|
||||
cs->get_rx = mpc8xxx_spi_rx_buf_u32;
|
||||
cs->get_tx = mpc8xxx_spi_tx_buf_u32;
|
||||
} else
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (mpc8xxx_spi->set_shifts)
|
||||
mpc8xxx_spi->set_shifts(&cs->rx_shift, &cs->tx_shift,
|
||||
@ -173,26 +172,6 @@ static int mspi_apply_cpu_mode_quirks(struct spi_mpc8xxx_cs *cs,
|
||||
mpc8xxx_spi->tx_shift = cs->tx_shift;
|
||||
mpc8xxx_spi->get_rx = cs->get_rx;
|
||||
mpc8xxx_spi->get_tx = cs->get_tx;
|
||||
|
||||
return bits_per_word;
|
||||
}
|
||||
|
||||
static int mspi_apply_qe_mode_quirks(struct spi_mpc8xxx_cs *cs,
|
||||
struct spi_device *spi,
|
||||
int bits_per_word)
|
||||
{
|
||||
/* QE uses Little Endian for words > 8
|
||||
* so transform all words > 8 into 8 bits
|
||||
* Unfortnatly that doesn't work for LSB so
|
||||
* reject these for now */
|
||||
/* Note: 32 bits word, LSB works iff
|
||||
* tfcr/rfcr is set to CPMFCR_GBL */
|
||||
if (spi->mode & SPI_LSB_FIRST &&
|
||||
bits_per_word > 8)
|
||||
return -EINVAL;
|
||||
if (bits_per_word > 8)
|
||||
return 8; /* pretend its 8 bits */
|
||||
return bits_per_word;
|
||||
}
|
||||
|
||||
static int fsl_spi_setup_transfer(struct spi_device *spi,
|
||||
@ -219,15 +198,7 @@ static int fsl_spi_setup_transfer(struct spi_device *spi,
|
||||
hz = spi->max_speed_hz;
|
||||
|
||||
if (!(mpc8xxx_spi->flags & SPI_CPM_MODE))
|
||||
bits_per_word = mspi_apply_cpu_mode_quirks(cs, spi,
|
||||
mpc8xxx_spi,
|
||||
bits_per_word);
|
||||
else if (mpc8xxx_spi->flags & SPI_QE)
|
||||
bits_per_word = mspi_apply_qe_mode_quirks(cs, spi,
|
||||
bits_per_word);
|
||||
|
||||
if (bits_per_word < 0)
|
||||
return bits_per_word;
|
||||
mspi_apply_cpu_mode_quirks(cs, spi, mpc8xxx_spi, bits_per_word);
|
||||
|
||||
if (bits_per_word == 32)
|
||||
bits_per_word = 0;
|
||||
@ -292,18 +263,10 @@ static int fsl_spi_bufs(struct spi_device *spi, struct spi_transfer *t,
|
||||
if (t->bits_per_word)
|
||||
bits_per_word = t->bits_per_word;
|
||||
|
||||
if (bits_per_word > 8) {
|
||||
/* invalid length? */
|
||||
if (len & 1)
|
||||
return -EINVAL;
|
||||
if (bits_per_word > 8)
|
||||
len /= 2;
|
||||
}
|
||||
if (bits_per_word > 16) {
|
||||
/* invalid length? */
|
||||
if (len & 1)
|
||||
return -EINVAL;
|
||||
if (bits_per_word > 16)
|
||||
len /= 2;
|
||||
}
|
||||
|
||||
mpc8xxx_spi->tx = t->tx_buf;
|
||||
mpc8xxx_spi->rx = t->rx_buf;
|
||||
@ -359,6 +322,22 @@ static int fsl_spi_prepare_message(struct spi_controller *ctlr,
|
||||
t->bits_per_word = 32;
|
||||
else if ((t->len & 1) == 0)
|
||||
t->bits_per_word = 16;
|
||||
} else {
|
||||
/*
|
||||
* CPM/QE uses Little Endian for words > 8
|
||||
* so transform 16 and 32 bits words into 8 bits
|
||||
* Unfortnatly that doesn't work for LSB so
|
||||
* reject these for now
|
||||
* Note: 32 bits word, LSB works iff
|
||||
* tfcr/rfcr is set to CPMFCR_GBL
|
||||
*/
|
||||
if (m->spi->mode & SPI_LSB_FIRST && t->bits_per_word > 8)
|
||||
return -EINVAL;
|
||||
if (t->bits_per_word == 16 || t->bits_per_word == 32)
|
||||
t->bits_per_word = 8; /* pretend its 8 bits */
|
||||
if (t->bits_per_word == 8 && t->len >= 256 &&
|
||||
(mpc8xxx_spi->flags & SPI_CPM1))
|
||||
t->bits_per_word = 16;
|
||||
}
|
||||
}
|
||||
return fsl_spi_setup_transfer(m->spi, first);
|
||||
@ -503,7 +482,7 @@ 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 fsl_spi_reg __iomem *reg_base = mpc8xxx_spi->reg_base;
|
||||
u32 slvsel;
|
||||
u16 cs = spi->chip_select;
|
||||
u16 cs = spi_get_chipselect(spi, 0);
|
||||
|
||||
if (cs < mpc8xxx_spi->native_chipselects) {
|
||||
slvsel = mpc8xxx_spi_read_reg(®_base->slvsel);
|
||||
@ -592,8 +571,14 @@ static struct spi_master *fsl_spi_probe(struct device *dev,
|
||||
if (mpc8xxx_spi->type == TYPE_GRLIB)
|
||||
fsl_spi_grlib_probe(dev);
|
||||
|
||||
master->bits_per_word_mask =
|
||||
(SPI_BPW_RANGE_MASK(4, 16) | SPI_BPW_MASK(32)) &
|
||||
if (mpc8xxx_spi->flags & SPI_CPM_MODE)
|
||||
master->bits_per_word_mask =
|
||||
(SPI_BPW_RANGE_MASK(4, 8) | SPI_BPW_MASK(16) | SPI_BPW_MASK(32));
|
||||
else
|
||||
master->bits_per_word_mask =
|
||||
(SPI_BPW_RANGE_MASK(4, 16) | SPI_BPW_MASK(32));
|
||||
|
||||
master->bits_per_word_mask &=
|
||||
SPI_BPW_RANGE_MASK(1, mpc8xxx_spi->max_bits_per_word);
|
||||
|
||||
if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE)
|
||||
@ -716,13 +701,12 @@ unmap_out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int of_fsl_spi_remove(struct platform_device *ofdev)
|
||||
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);
|
||||
|
||||
fsl_spi_cpm_free(mpc8xxx_spi);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver of_fsl_spi_driver = {
|
||||
@ -731,7 +715,7 @@ static struct platform_driver of_fsl_spi_driver = {
|
||||
.of_match_table = of_fsl_spi_match,
|
||||
},
|
||||
.probe = of_fsl_spi_probe,
|
||||
.remove = of_fsl_spi_remove,
|
||||
.remove_new = of_fsl_spi_remove,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MPC832x_RDB
|
||||
@ -763,20 +747,18 @@ static int plat_mpc8xxx_spi_probe(struct platform_device *pdev)
|
||||
return PTR_ERR_OR_ZERO(master);
|
||||
}
|
||||
|
||||
static int plat_mpc8xxx_spi_remove(struct platform_device *pdev)
|
||||
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);
|
||||
|
||||
fsl_spi_cpm_free(mpc8xxx_spi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MODULE_ALIAS("platform:mpc8xxx_spi");
|
||||
static struct platform_driver mpc8xxx_spi_driver = {
|
||||
.probe = plat_mpc8xxx_spi_probe,
|
||||
.remove = plat_mpc8xxx_spi_remove,
|
||||
.remove_new = plat_mpc8xxx_spi_remove,
|
||||
.driver = {
|
||||
.name = "mpc8xxx_spi",
|
||||
},
|
||||
|
@ -391,9 +391,9 @@ static int setup_fifo_params(struct spi_device *spi_slv,
|
||||
cpha = CPHA;
|
||||
|
||||
if (spi_slv->mode & SPI_CS_HIGH)
|
||||
demux_output_inv = BIT(spi_slv->chip_select);
|
||||
demux_output_inv = BIT(spi_get_chipselect(spi_slv, 0));
|
||||
|
||||
demux_sel = spi_slv->chip_select;
|
||||
demux_sel = spi_get_chipselect(spi_slv, 0);
|
||||
mas->cur_bits_per_word = spi_slv->bits_per_word;
|
||||
|
||||
spi_setup_word_len(mas, spi_slv->mode, spi_slv->bits_per_word);
|
||||
@ -469,7 +469,7 @@ static int setup_gsi_xfer(struct spi_transfer *xfer, struct spi_geni_master *mas
|
||||
peripheral.loopback_en = !!(spi_slv->mode & SPI_LOOP);
|
||||
peripheral.clock_pol_high = !!(spi_slv->mode & SPI_CPOL);
|
||||
peripheral.data_pol_high = !!(spi_slv->mode & SPI_CPHA);
|
||||
peripheral.cs = spi_slv->chip_select;
|
||||
peripheral.cs = spi_get_chipselect(spi_slv, 0);
|
||||
peripheral.pack_en = true;
|
||||
peripheral.word_len = xfer->bits_per_word - MIN_WORD_LEN;
|
||||
|
||||
@ -1114,7 +1114,7 @@ spi_geni_probe_runtime_disable:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int spi_geni_remove(struct platform_device *pdev)
|
||||
static void spi_geni_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_master *spi = platform_get_drvdata(pdev);
|
||||
struct spi_geni_master *mas = spi_master_get_devdata(spi);
|
||||
@ -1126,7 +1126,6 @@ static int spi_geni_remove(struct platform_device *pdev)
|
||||
|
||||
free_irq(mas->irq, spi);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused spi_geni_runtime_suspend(struct device *dev)
|
||||
@ -1208,7 +1207,7 @@ MODULE_DEVICE_TABLE(of, spi_geni_dt_match);
|
||||
|
||||
static struct platform_driver spi_geni_driver = {
|
||||
.probe = spi_geni_probe,
|
||||
.remove = spi_geni_remove,
|
||||
.remove_new = spi_geni_remove,
|
||||
.driver = {
|
||||
.name = "geni_spi",
|
||||
.pm = &spi_geni_pm_ops,
|
||||
|
@ -230,7 +230,7 @@ static void spi_gpio_chipselect(struct spi_device *spi, int is_active)
|
||||
|
||||
/* Drive chip select line, if we have one */
|
||||
if (spi_gpio->cs_gpios) {
|
||||
struct gpio_desc *cs = spi_gpio->cs_gpios[spi->chip_select];
|
||||
struct gpio_desc *cs = spi_gpio->cs_gpios[spi_get_chipselect(spi, 0)];
|
||||
|
||||
/* SPI chip selects are normally active-low */
|
||||
gpiod_set_value_cansleep(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active);
|
||||
@ -248,7 +248,7 @@ static int spi_gpio_setup(struct spi_device *spi)
|
||||
* initialized from the descriptor lookup.
|
||||
*/
|
||||
if (spi_gpio->cs_gpios) {
|
||||
cs = spi_gpio->cs_gpios[spi->chip_select];
|
||||
cs = spi_gpio->cs_gpios[spi_get_chipselect(spi, 0)];
|
||||
if (!spi->controller_state && cs)
|
||||
status = gpiod_direction_output(cs,
|
||||
!(spi->mode & SPI_CS_HIGH));
|
||||
|
@ -201,7 +201,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_chip *chip = &spifi->chips[mem->spi->chip_select];
|
||||
struct gxp_spi_chip *chip = &spifi->chips[spi_get_chipselect(mem->spi, 0)];
|
||||
int ret;
|
||||
|
||||
if (op->data.dir == SPI_MEM_DATA_IN) {
|
||||
@ -237,7 +237,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);
|
||||
unsigned int cs = spi->chip_select;
|
||||
unsigned int cs = spi_get_chipselect(spi, 0);
|
||||
struct gxp_spi_chip *chip = &spifi->chips[cs];
|
||||
|
||||
chip->spifi = spifi;
|
||||
|
@ -523,15 +523,13 @@ static int hisi_spi_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hisi_spi_remove(struct platform_device *pdev)
|
||||
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);
|
||||
|
||||
debugfs_remove_recursive(hs->debugfs);
|
||||
spi_unregister_controller(master);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct acpi_device_id hisi_spi_acpi_match[] = {
|
||||
@ -542,7 +540,7 @@ MODULE_DEVICE_TABLE(acpi, hisi_spi_acpi_match);
|
||||
|
||||
static struct platform_driver hisi_spi_driver = {
|
||||
.probe = hisi_spi_probe,
|
||||
.remove = hisi_spi_remove,
|
||||
.remove_new = hisi_spi_remove,
|
||||
.driver = {
|
||||
.name = "hisi-kunpeng-spi",
|
||||
.acpi_match_table = hisi_spi_acpi_match,
|
||||
|
@ -361,7 +361,7 @@ static int hisi_sfc_v3xx_exec_op(struct spi_mem *mem,
|
||||
{
|
||||
struct hisi_sfc_v3xx_host *host;
|
||||
struct spi_device *spi = mem->spi;
|
||||
u8 chip_select = spi->chip_select;
|
||||
u8 chip_select = spi_get_chipselect(spi, 0);
|
||||
|
||||
host = spi_controller_get_devdata(spi->master);
|
||||
|
||||
|
@ -413,15 +413,15 @@ static int img_spfi_prepare(struct spi_master *master, struct spi_message *msg)
|
||||
val = spfi_readl(spfi, SPFI_PORT_STATE);
|
||||
val &= ~(SPFI_PORT_STATE_DEV_SEL_MASK <<
|
||||
SPFI_PORT_STATE_DEV_SEL_SHIFT);
|
||||
val |= msg->spi->chip_select << SPFI_PORT_STATE_DEV_SEL_SHIFT;
|
||||
val |= spi_get_chipselect(msg->spi, 0) << SPFI_PORT_STATE_DEV_SEL_SHIFT;
|
||||
if (msg->spi->mode & SPI_CPHA)
|
||||
val |= SPFI_PORT_STATE_CK_PHASE(msg->spi->chip_select);
|
||||
val |= SPFI_PORT_STATE_CK_PHASE(spi_get_chipselect(msg->spi, 0));
|
||||
else
|
||||
val &= ~SPFI_PORT_STATE_CK_PHASE(msg->spi->chip_select);
|
||||
val &= ~SPFI_PORT_STATE_CK_PHASE(spi_get_chipselect(msg->spi, 0));
|
||||
if (msg->spi->mode & SPI_CPOL)
|
||||
val |= SPFI_PORT_STATE_CK_POL(msg->spi->chip_select);
|
||||
val |= SPFI_PORT_STATE_CK_POL(spi_get_chipselect(msg->spi, 0));
|
||||
else
|
||||
val &= ~SPFI_PORT_STATE_CK_POL(msg->spi->chip_select);
|
||||
val &= ~SPFI_PORT_STATE_CK_POL(spi_get_chipselect(msg->spi, 0));
|
||||
spfi_writel(spfi, val, SPFI_PORT_STATE);
|
||||
|
||||
return 0;
|
||||
@ -450,11 +450,11 @@ static void img_spfi_config(struct spi_master *master, struct spi_device *spi,
|
||||
div = DIV_ROUND_UP(clk_get_rate(spfi->spfi_clk), xfer->speed_hz);
|
||||
div = clamp(512 / (1 << get_count_order(div)), 1, 128);
|
||||
|
||||
val = spfi_readl(spfi, SPFI_DEVICE_PARAMETER(spi->chip_select));
|
||||
val = spfi_readl(spfi, SPFI_DEVICE_PARAMETER(spi_get_chipselect(spi, 0)));
|
||||
val &= ~(SPFI_DEVICE_PARAMETER_BITCLK_MASK <<
|
||||
SPFI_DEVICE_PARAMETER_BITCLK_SHIFT);
|
||||
val |= div << SPFI_DEVICE_PARAMETER_BITCLK_SHIFT;
|
||||
spfi_writel(spfi, val, SPFI_DEVICE_PARAMETER(spi->chip_select));
|
||||
spfi_writel(spfi, val, SPFI_DEVICE_PARAMETER(spi_get_chipselect(spi, 0)));
|
||||
|
||||
spfi_writel(spfi, xfer->len << SPFI_TRANSACTION_TSIZE_SHIFT,
|
||||
SPFI_TRANSACTION);
|
||||
@ -665,7 +665,7 @@ put_spi:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int img_spfi_remove(struct platform_device *pdev)
|
||||
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);
|
||||
@ -680,8 +680,6 @@ static int img_spfi_remove(struct platform_device *pdev)
|
||||
clk_disable_unprepare(spfi->spfi_clk);
|
||||
clk_disable_unprepare(spfi->sys_clk);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
@ -758,7 +756,7 @@ static struct platform_driver img_spfi_driver = {
|
||||
.of_match_table = of_match_ptr(img_spfi_of_match),
|
||||
},
|
||||
.probe = img_spfi_probe,
|
||||
.remove = img_spfi_remove,
|
||||
.remove_new = img_spfi_remove,
|
||||
};
|
||||
module_platform_driver(img_spfi_driver);
|
||||
|
||||
|
@ -252,6 +252,18 @@ static bool spi_imx_can_dma(struct spi_controller *controller, struct spi_device
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note the number of natively supported chip selects for MX51 is 4. Some
|
||||
* devices may have less actual SS pins but the register map supports 4. When
|
||||
* using gpio chip selects the cs values passed into the macros below can go
|
||||
* outside the range 0 - 3. We therefore need to limit the cs value to avoid
|
||||
* corrupting bits outside the allocated locations.
|
||||
*
|
||||
* The simplest way to do this is to just mask the cs bits to 2 bits. This
|
||||
* still allows all 4 native chip selects to work as well as gpio chip selects
|
||||
* (which can use any of the 4 chip select configurations).
|
||||
*/
|
||||
|
||||
#define MX51_ECSPI_CTRL 0x08
|
||||
#define MX51_ECSPI_CTRL_ENABLE (1 << 0)
|
||||
#define MX51_ECSPI_CTRL_XCH (1 << 2)
|
||||
@ -260,16 +272,16 @@ static bool spi_imx_can_dma(struct spi_controller *controller, struct spi_device
|
||||
#define MX51_ECSPI_CTRL_DRCTL(drctl) ((drctl) << 16)
|
||||
#define MX51_ECSPI_CTRL_POSTDIV_OFFSET 8
|
||||
#define MX51_ECSPI_CTRL_PREDIV_OFFSET 12
|
||||
#define MX51_ECSPI_CTRL_CS(cs) ((cs) << 18)
|
||||
#define MX51_ECSPI_CTRL_CS(cs) ((cs & 3) << 18)
|
||||
#define MX51_ECSPI_CTRL_BL_OFFSET 20
|
||||
#define MX51_ECSPI_CTRL_BL_MASK (0xfff << 20)
|
||||
|
||||
#define MX51_ECSPI_CONFIG 0x0c
|
||||
#define MX51_ECSPI_CONFIG_SCLKPHA(cs) (1 << ((cs) + 0))
|
||||
#define MX51_ECSPI_CONFIG_SCLKPOL(cs) (1 << ((cs) + 4))
|
||||
#define MX51_ECSPI_CONFIG_SBBCTRL(cs) (1 << ((cs) + 8))
|
||||
#define MX51_ECSPI_CONFIG_SSBPOL(cs) (1 << ((cs) + 12))
|
||||
#define MX51_ECSPI_CONFIG_SCLKCTL(cs) (1 << ((cs) + 20))
|
||||
#define MX51_ECSPI_CONFIG_SCLKPHA(cs) (1 << ((cs & 3) + 0))
|
||||
#define MX51_ECSPI_CONFIG_SCLKPOL(cs) (1 << ((cs & 3) + 4))
|
||||
#define MX51_ECSPI_CONFIG_SBBCTRL(cs) (1 << ((cs & 3) + 8))
|
||||
#define MX51_ECSPI_CONFIG_SSBPOL(cs) (1 << ((cs & 3) + 12))
|
||||
#define MX51_ECSPI_CONFIG_SCLKCTL(cs) (1 << ((cs & 3) + 20))
|
||||
|
||||
#define MX51_ECSPI_INT 0x10
|
||||
#define MX51_ECSPI_INT_TEEN (1 << 0)
|
||||
@ -528,7 +540,7 @@ static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx,
|
||||
ctrl |= MX51_ECSPI_CTRL_DRCTL(spi_imx->spi_drctl);
|
||||
|
||||
/* set chip select to use */
|
||||
ctrl |= MX51_ECSPI_CTRL_CS(spi->chip_select);
|
||||
ctrl |= MX51_ECSPI_CTRL_CS(spi_get_chipselect(spi, 0));
|
||||
|
||||
/*
|
||||
* The ctrl register must be written first, with the EN bit set other
|
||||
@ -549,22 +561,22 @@ static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx,
|
||||
* BURST_LENGTH + 1 bits are received
|
||||
*/
|
||||
if (spi_imx->slave_mode && is_imx53_ecspi(spi_imx))
|
||||
cfg &= ~MX51_ECSPI_CONFIG_SBBCTRL(spi->chip_select);
|
||||
cfg &= ~MX51_ECSPI_CONFIG_SBBCTRL(spi_get_chipselect(spi, 0));
|
||||
else
|
||||
cfg |= MX51_ECSPI_CONFIG_SBBCTRL(spi->chip_select);
|
||||
cfg |= MX51_ECSPI_CONFIG_SBBCTRL(spi_get_chipselect(spi, 0));
|
||||
|
||||
if (spi->mode & SPI_CPOL) {
|
||||
cfg |= MX51_ECSPI_CONFIG_SCLKPOL(spi->chip_select);
|
||||
cfg |= MX51_ECSPI_CONFIG_SCLKCTL(spi->chip_select);
|
||||
cfg |= MX51_ECSPI_CONFIG_SCLKPOL(spi_get_chipselect(spi, 0));
|
||||
cfg |= MX51_ECSPI_CONFIG_SCLKCTL(spi_get_chipselect(spi, 0));
|
||||
} else {
|
||||
cfg &= ~MX51_ECSPI_CONFIG_SCLKPOL(spi->chip_select);
|
||||
cfg &= ~MX51_ECSPI_CONFIG_SCLKCTL(spi->chip_select);
|
||||
cfg &= ~MX51_ECSPI_CONFIG_SCLKPOL(spi_get_chipselect(spi, 0));
|
||||
cfg &= ~MX51_ECSPI_CONFIG_SCLKCTL(spi_get_chipselect(spi, 0));
|
||||
}
|
||||
|
||||
if (spi->mode & SPI_CS_HIGH)
|
||||
cfg |= MX51_ECSPI_CONFIG_SSBPOL(spi->chip_select);
|
||||
cfg |= MX51_ECSPI_CONFIG_SSBPOL(spi_get_chipselect(spi, 0));
|
||||
else
|
||||
cfg &= ~MX51_ECSPI_CONFIG_SSBPOL(spi->chip_select);
|
||||
cfg &= ~MX51_ECSPI_CONFIG_SSBPOL(spi_get_chipselect(spi, 0));
|
||||
|
||||
if (cfg == current_cfg)
|
||||
return 0;
|
||||
@ -614,9 +626,9 @@ static void mx51_configure_cpha(struct spi_imx_data *spi_imx,
|
||||
cpha ^= flip_cpha;
|
||||
|
||||
if (cpha)
|
||||
cfg |= MX51_ECSPI_CONFIG_SCLKPHA(spi->chip_select);
|
||||
cfg |= MX51_ECSPI_CONFIG_SCLKPHA(spi_get_chipselect(spi, 0));
|
||||
else
|
||||
cfg &= ~MX51_ECSPI_CONFIG_SCLKPHA(spi->chip_select);
|
||||
cfg &= ~MX51_ECSPI_CONFIG_SCLKPHA(spi_get_chipselect(spi, 0));
|
||||
|
||||
writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG);
|
||||
}
|
||||
@ -768,8 +780,8 @@ static int mx31_prepare_transfer(struct spi_imx_data *spi_imx,
|
||||
reg |= MX31_CSPICTRL_POL;
|
||||
if (spi->mode & SPI_CS_HIGH)
|
||||
reg |= MX31_CSPICTRL_SSPOL;
|
||||
if (!spi->cs_gpiod)
|
||||
reg |= (spi->chip_select) <<
|
||||
if (!spi_get_csgpiod(spi, 0))
|
||||
reg |= (spi_get_chipselect(spi, 0)) <<
|
||||
(is_imx35_cspi(spi_imx) ? MX35_CSPICTRL_CS_SHIFT :
|
||||
MX31_CSPICTRL_CS_SHIFT);
|
||||
|
||||
@ -868,8 +880,8 @@ static int mx21_prepare_transfer(struct spi_imx_data *spi_imx,
|
||||
reg |= MX21_CSPICTRL_POL;
|
||||
if (spi->mode & SPI_CS_HIGH)
|
||||
reg |= MX21_CSPICTRL_SSPOL;
|
||||
if (!spi->cs_gpiod)
|
||||
reg |= spi->chip_select << MX21_CSPICTRL_CS_SHIFT;
|
||||
if (!spi_get_csgpiod(spi, 0))
|
||||
reg |= spi_get_chipselect(spi, 0) << MX21_CSPICTRL_CS_SHIFT;
|
||||
|
||||
writel(reg, spi_imx->base + MXC_CSPICTRL);
|
||||
|
||||
@ -1753,8 +1765,7 @@ static int spi_imx_probe(struct platform_device *pdev)
|
||||
|
||||
init_completion(&spi_imx->xfer_done);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
spi_imx->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
spi_imx->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
if (IS_ERR(spi_imx->base)) {
|
||||
ret = PTR_ERR(spi_imx->base);
|
||||
goto out_controller_put;
|
||||
@ -1848,7 +1859,7 @@ out_controller_put:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int spi_imx_remove(struct platform_device *pdev)
|
||||
static void spi_imx_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_controller *controller = platform_get_drvdata(pdev);
|
||||
struct spi_imx_data *spi_imx = spi_controller_get_devdata(controller);
|
||||
@ -1856,21 +1867,17 @@ static int spi_imx_remove(struct platform_device *pdev)
|
||||
|
||||
spi_unregister_controller(controller);
|
||||
|
||||
ret = pm_runtime_resume_and_get(spi_imx->dev);
|
||||
if (ret < 0) {
|
||||
dev_err(spi_imx->dev, "failed to enable clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
writel(0, spi_imx->base + MXC_CSPICTRL);
|
||||
ret = pm_runtime_get_sync(spi_imx->dev);
|
||||
if (ret >= 0)
|
||||
writel(0, spi_imx->base + MXC_CSPICTRL);
|
||||
else
|
||||
dev_warn(spi_imx->dev, "failed to enable clock, skip hw disable\n");
|
||||
|
||||
pm_runtime_dont_use_autosuspend(spi_imx->dev);
|
||||
pm_runtime_put_sync(spi_imx->dev);
|
||||
pm_runtime_disable(spi_imx->dev);
|
||||
|
||||
spi_imx_sdma_exit(spi_imx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused spi_imx_runtime_resume(struct device *dev)
|
||||
@ -1932,7 +1939,7 @@ static struct platform_driver spi_imx_driver = {
|
||||
.pm = &imx_spi_pm,
|
||||
},
|
||||
.probe = spi_imx_probe,
|
||||
.remove = spi_imx_remove,
|
||||
.remove_new = spi_imx_remove,
|
||||
};
|
||||
module_platform_driver(spi_imx_driver);
|
||||
|
||||
|
@ -263,7 +263,7 @@ static int spi_ingenic_prepare_message(struct spi_controller *ctlr,
|
||||
{
|
||||
struct ingenic_spi *priv = spi_controller_get_devdata(ctlr);
|
||||
struct spi_device *spi = message->spi;
|
||||
unsigned int cs = REG_SSICR1_FRMHL << spi->chip_select;
|
||||
unsigned int cs = REG_SSICR1_FRMHL << spi_get_chipselect(spi, 0);
|
||||
unsigned int ssicr0_mask = REG_SSICR0_LOOP | REG_SSICR0_FSEL;
|
||||
unsigned int ssicr1_mask = REG_SSICR1_PHA | REG_SSICR1_POL | cs;
|
||||
unsigned int ssicr0 = 0, ssicr1 = 0;
|
||||
@ -282,7 +282,7 @@ static int spi_ingenic_prepare_message(struct spi_controller *ctlr,
|
||||
|
||||
if (spi->mode & SPI_LOOP)
|
||||
ssicr0 |= REG_SSICR0_LOOP;
|
||||
if (spi->chip_select)
|
||||
if (spi_get_chipselect(spi, 0))
|
||||
ssicr0 |= REG_SSICR0_FSEL;
|
||||
|
||||
if (spi->mode & SPI_CPHA)
|
||||
|
@ -83,6 +83,7 @@ static const struct pci_device_id intel_spi_pci_ids[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0xa2a4), (unsigned long)&cnl_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa324), (unsigned long)&cnl_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa3a4), (unsigned long)&cnl_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xae23), (unsigned long)&cnl_info },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, intel_spi_pci_ids);
|
||||
|
@ -451,7 +451,7 @@ static u32 intel_spi_chip_addr(const struct intel_spi *ispi,
|
||||
/* Pick up the correct start address */
|
||||
if (!mem)
|
||||
return 0;
|
||||
return mem->spi->chip_select == 1 ? ispi->chip0_size : 0;
|
||||
return (spi_get_chipselect(mem->spi, 0) == 1) ? ispi->chip0_size : 0;
|
||||
}
|
||||
|
||||
static int intel_spi_read_reg(struct intel_spi *ispi, const struct spi_mem *mem,
|
||||
|
@ -127,11 +127,9 @@ static int bcm_iproc_probe(struct platform_device *pdev)
|
||||
return bcm_qspi_probe(pdev, soc_intc);
|
||||
}
|
||||
|
||||
static int bcm_iproc_remove(struct platform_device *pdev)
|
||||
static void bcm_iproc_remove(struct platform_device *pdev)
|
||||
{
|
||||
bcm_qspi_remove(pdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id bcm_iproc_of_match[] = {
|
||||
@ -143,7 +141,7 @@ MODULE_DEVICE_TABLE(of, bcm_iproc_of_match);
|
||||
|
||||
static struct platform_driver bcm_iproc_driver = {
|
||||
.probe = bcm_iproc_probe,
|
||||
.remove = bcm_iproc_remove,
|
||||
.remove_new = bcm_iproc_remove,
|
||||
.driver = {
|
||||
.name = "bcm_iproc",
|
||||
.pm = &bcm_qspi_pm_ops,
|
||||
|
@ -68,9 +68,9 @@ 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);
|
||||
u32 csbit = 1U << (2 * spi->chip_select);
|
||||
u32 csbit = 1U << (2 * spi_get_chipselect(spi, 0));
|
||||
|
||||
dev_dbg(hw->master->dev.parent, "chipselect %d\n", spi->chip_select);
|
||||
dev_dbg(hw->master->dev.parent, "chipselect %d\n", spi_get_chipselect(spi, 0));
|
||||
|
||||
if (value)
|
||||
hw->cs_reg |= csbit;
|
||||
|
@ -388,11 +388,11 @@ 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);
|
||||
unsigned int cs = spidev->chip_select;
|
||||
unsigned int cs = spi_get_chipselect(spidev, 0);
|
||||
u32 gpocon;
|
||||
|
||||
/* GPIOs are used for CS */
|
||||
if (spidev->cs_gpiod)
|
||||
if (spi_get_csgpiod(spidev, 0))
|
||||
return 0;
|
||||
|
||||
dev_dbg(spi->dev, "using internal chipselect %u\n", cs);
|
||||
@ -796,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);
|
||||
unsigned int cs = spidev->chip_select;
|
||||
unsigned int cs = spi_get_chipselect(spidev, 0);
|
||||
u32 fgpo;
|
||||
|
||||
if (!!(spidev->mode & SPI_CS_HIGH) == enable)
|
||||
@ -1017,7 +1017,7 @@ err_master_put:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int lantiq_ssc_remove(struct platform_device *pdev)
|
||||
static void lantiq_ssc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct lantiq_ssc_spi *spi = platform_get_drvdata(pdev);
|
||||
|
||||
@ -1030,13 +1030,11 @@ static int lantiq_ssc_remove(struct platform_device *pdev)
|
||||
destroy_workqueue(spi->wq);
|
||||
clk_disable_unprepare(spi->spi_clk);
|
||||
clk_put(spi->fpi_clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver lantiq_ssc_driver = {
|
||||
.probe = lantiq_ssc_probe,
|
||||
.remove = lantiq_ssc_remove,
|
||||
.remove_new = lantiq_ssc_remove,
|
||||
.driver = {
|
||||
.name = "spi-lantiq-ssc",
|
||||
.of_match_table = lantiq_ssc_match,
|
||||
|
@ -53,6 +53,12 @@ module_param(no_cs, int, 0);
|
||||
MODULE_PARM_DESC(no_cs,
|
||||
"if set Chip Select (CS) will not be used");
|
||||
|
||||
/* run tests only for a specific length */
|
||||
static int run_only_iter_len = -1;
|
||||
module_param(run_only_iter_len, int, 0);
|
||||
MODULE_PARM_DESC(run_only_iter_len,
|
||||
"only run tests for a length of this number in iterate_len list");
|
||||
|
||||
/* run only a specific test */
|
||||
static int run_only_test = -1;
|
||||
module_param(run_only_test, int, 0);
|
||||
@ -1033,6 +1039,8 @@ int spi_test_run_test(struct spi_device *spi, const struct spi_test *test,
|
||||
|
||||
for (idx_len = 0; idx_len < SPI_TEST_MAX_ITERATE &&
|
||||
(len = test->iterate_len[idx_len]) != -1; idx_len++) {
|
||||
if ((run_only_iter_len > -1) && len != run_only_iter_len)
|
||||
continue;
|
||||
FOR_EACH_ALIGNMENT(tx_align) {
|
||||
FOR_EACH_ALIGNMENT(rx_align) {
|
||||
/* and run the iteration */
|
||||
|
@ -325,7 +325,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
|
||||
if (!spi_mem_internal_supports_op(mem, op))
|
||||
return -ENOTSUPP;
|
||||
|
||||
if (ctlr->mem_ops && ctlr->mem_ops->exec_op && !mem->spi->cs_gpiod) {
|
||||
if (ctlr->mem_ops && ctlr->mem_ops->exec_op && !spi_get_csgpiod(mem->spi, 0)) {
|
||||
ret = spi_mem_access_start(mem);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -808,7 +808,7 @@ int spi_mem_poll_status(struct spi_mem *mem,
|
||||
op->data.dir != SPI_MEM_DATA_IN)
|
||||
return -EINVAL;
|
||||
|
||||
if (ctlr->mem_ops && ctlr->mem_ops->poll_status && !mem->spi->cs_gpiod) {
|
||||
if (ctlr->mem_ops && ctlr->mem_ops->poll_status && !spi_get_csgpiod(mem->spi, 0)) {
|
||||
ret = spi_mem_access_start(mem);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -505,7 +505,7 @@ static int meson_spicc_prepare_message(struct spi_master *master,
|
||||
conf |= FIELD_PREP(SPICC_DRCTL_MASK, SPICC_DRCTL_IGNORE);
|
||||
|
||||
/* Select CS */
|
||||
conf |= FIELD_PREP(SPICC_CS_MASK, spi->chip_select);
|
||||
conf |= FIELD_PREP(SPICC_CS_MASK, spi_get_chipselect(spi, 0));
|
||||
|
||||
/* Default 8bit word */
|
||||
conf |= FIELD_PREP(SPICC_BITLENGTH_MASK, 8 - 1);
|
||||
@ -910,7 +910,7 @@ out_master:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int meson_spicc_remove(struct platform_device *pdev)
|
||||
static void meson_spicc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct meson_spicc_device *spicc = platform_get_drvdata(pdev);
|
||||
|
||||
@ -921,8 +921,6 @@ static int meson_spicc_remove(struct platform_device *pdev)
|
||||
clk_disable_unprepare(spicc->pclk);
|
||||
|
||||
spi_master_put(spicc->master);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct meson_spicc_data meson_spicc_gx_data = {
|
||||
@ -967,7 +965,7 @@ MODULE_DEVICE_TABLE(of, meson_spicc_of_match);
|
||||
|
||||
static struct platform_driver meson_spicc_driver = {
|
||||
.probe = meson_spicc_probe,
|
||||
.remove = meson_spicc_remove,
|
||||
.remove_new = meson_spicc_remove,
|
||||
.driver = {
|
||||
.name = "meson-spicc",
|
||||
.of_match_table = of_match_ptr(meson_spicc_of_match),
|
||||
|
@ -355,7 +355,7 @@ out_err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int meson_spifc_remove(struct platform_device *pdev)
|
||||
static void meson_spifc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_master *master = platform_get_drvdata(pdev);
|
||||
struct meson_spifc *spifc = spi_master_get_devdata(master);
|
||||
@ -363,8 +363,6 @@ static int meson_spifc_remove(struct platform_device *pdev)
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
clk_disable_unprepare(spifc->clk);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
@ -442,7 +440,7 @@ MODULE_DEVICE_TABLE(of, meson_spifc_dt_match);
|
||||
|
||||
static struct platform_driver meson_spifc_driver = {
|
||||
.probe = meson_spifc_probe,
|
||||
.remove = meson_spifc_remove,
|
||||
.remove_new = meson_spifc_remove,
|
||||
.driver = {
|
||||
.name = "meson-spifc",
|
||||
.of_match_table = of_match_ptr(meson_spifc_dt_match),
|
||||
|
@ -566,7 +566,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mchp_coreqspi_remove(struct platform_device *pdev)
|
||||
static void mchp_coreqspi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct mchp_coreqspi *qspi = platform_get_drvdata(pdev);
|
||||
u32 control = readl_relaxed(qspi->regs + REG_CONTROL);
|
||||
@ -575,8 +575,6 @@ static int mchp_coreqspi_remove(struct platform_device *pdev)
|
||||
control &= ~CONTROL_ENABLE;
|
||||
writel_relaxed(control, qspi->regs + REG_CONTROL);
|
||||
clk_disable_unprepare(qspi->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id mchp_coreqspi_of_match[] = {
|
||||
@ -591,7 +589,7 @@ static struct platform_driver mchp_coreqspi_driver = {
|
||||
.name = "microchip,coreqspi",
|
||||
.of_match_table = mchp_coreqspi_of_match,
|
||||
},
|
||||
.remove = mchp_coreqspi_remove,
|
||||
.remove_new = mchp_coreqspi_remove,
|
||||
};
|
||||
module_platform_driver(mchp_coreqspi_driver);
|
||||
|
||||
|
@ -247,8 +247,8 @@ static void mchp_corespi_set_cs(struct spi_device *spi, bool disable)
|
||||
struct mchp_corespi *corespi = spi_master_get_devdata(spi->master);
|
||||
|
||||
reg = mchp_corespi_read(corespi, REG_SLAVE_SELECT);
|
||||
reg &= ~BIT(spi->chip_select);
|
||||
reg |= !disable << spi->chip_select;
|
||||
reg &= ~BIT(spi_get_chipselect(spi, 0));
|
||||
reg |= !disable << spi_get_chipselect(spi, 0);
|
||||
|
||||
mchp_corespi_write(corespi, REG_SLAVE_SELECT, reg);
|
||||
}
|
||||
@ -265,7 +265,7 @@ static int mchp_corespi_setup(struct spi_device *spi)
|
||||
*/
|
||||
if (spi->mode & SPI_CS_HIGH) {
|
||||
reg = mchp_corespi_read(corespi, REG_SLAVE_SELECT);
|
||||
reg |= BIT(spi->chip_select);
|
||||
reg |= BIT(spi_get_chipselect(spi, 0));
|
||||
mchp_corespi_write(corespi, REG_SLAVE_SELECT, reg);
|
||||
}
|
||||
return 0;
|
||||
@ -566,7 +566,7 @@ static int mchp_corespi_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mchp_corespi_remove(struct platform_device *pdev)
|
||||
static void mchp_corespi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_master *master = platform_get_drvdata(pdev);
|
||||
struct mchp_corespi *spi = spi_master_get_devdata(master);
|
||||
@ -574,8 +574,6 @@ static int mchp_corespi_remove(struct platform_device *pdev)
|
||||
mchp_corespi_disable_ints(spi);
|
||||
clk_disable_unprepare(spi->clk);
|
||||
mchp_corespi_disable(spi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MICROCHIP_SPI_PM_OPS (NULL)
|
||||
@ -599,7 +597,7 @@ static struct platform_driver mchp_corespi_driver = {
|
||||
.pm = MICROCHIP_SPI_PM_OPS,
|
||||
.of_match_table = of_match_ptr(mchp_corespi_dt_ids),
|
||||
},
|
||||
.remove = mchp_corespi_remove,
|
||||
.remove_new = mchp_corespi_remove,
|
||||
};
|
||||
module_platform_driver(mchp_corespi_driver);
|
||||
MODULE_DESCRIPTION("Microchip coreSPI SPI controller driver");
|
||||
|
@ -14,15 +14,13 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/fsl_devices.h>
|
||||
#include <asm/mpc52xx_psc.h>
|
||||
|
||||
enum {
|
||||
@ -51,16 +49,12 @@ enum {
|
||||
__ret; })
|
||||
|
||||
struct mpc512x_psc_spi {
|
||||
void (*cs_control)(struct spi_device *spi, bool on);
|
||||
|
||||
/* driver internal data */
|
||||
int type;
|
||||
void __iomem *psc;
|
||||
struct mpc512x_psc_fifo __iomem *fifo;
|
||||
unsigned int irq;
|
||||
u8 bits_per_word;
|
||||
struct clk *clk_mclk;
|
||||
struct clk *clk_ipg;
|
||||
u32 mclk_rate;
|
||||
|
||||
struct completion txisrdone;
|
||||
@ -127,27 +121,17 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi)
|
||||
out_be32(psc_addr(mps, ccr), ccr);
|
||||
mps->bits_per_word = cs->bits_per_word;
|
||||
|
||||
if (spi->cs_gpiod) {
|
||||
if (mps->cs_control)
|
||||
/* boardfile override */
|
||||
mps->cs_control(spi, (spi->mode & SPI_CS_HIGH) ? 1 : 0);
|
||||
else
|
||||
/* gpiolib will deal with the inversion */
|
||||
gpiod_set_value(spi->cs_gpiod, 1);
|
||||
if (spi_get_csgpiod(spi, 0)) {
|
||||
/* gpiolib will deal with the inversion */
|
||||
gpiod_set_value(spi_get_csgpiod(spi, 0), 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void mpc512x_psc_spi_deactivate_cs(struct spi_device *spi)
|
||||
{
|
||||
struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master);
|
||||
|
||||
if (spi->cs_gpiod) {
|
||||
if (mps->cs_control)
|
||||
/* boardfile override */
|
||||
mps->cs_control(spi, (spi->mode & SPI_CS_HIGH) ? 0 : 1);
|
||||
else
|
||||
/* gpiolib will deal with the inversion */
|
||||
gpiod_set_value(spi->cs_gpiod, 0);
|
||||
if (spi_get_csgpiod(spi, 0)) {
|
||||
/* gpiolib will deal with the inversion */
|
||||
gpiod_set_value(spi_get_csgpiod(spi, 0), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -471,30 +455,22 @@ static irqreturn_t mpc512x_psc_spi_isr(int irq, void *dev_id)
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
|
||||
u32 size, unsigned int irq)
|
||||
static int mpc512x_psc_spi_of_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
|
||||
struct device *dev = &pdev->dev;
|
||||
struct mpc512x_psc_spi *mps;
|
||||
struct spi_master *master;
|
||||
int ret;
|
||||
void *tempp;
|
||||
struct clk *clk;
|
||||
|
||||
master = spi_alloc_master(dev, sizeof(*mps));
|
||||
master = devm_spi_alloc_master(dev, sizeof(*mps));
|
||||
if (master == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
dev_set_drvdata(dev, master);
|
||||
mps = spi_master_get_devdata(master);
|
||||
mps->type = (int)of_device_get_match_data(dev);
|
||||
mps->irq = irq;
|
||||
|
||||
if (pdata) {
|
||||
mps->cs_control = pdata->cs_control;
|
||||
master->bus_num = pdata->bus_num;
|
||||
master->num_chipselect = pdata->max_chipselect;
|
||||
}
|
||||
mps->type = (int)device_get_match_data(dev);
|
||||
|
||||
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
|
||||
master->setup = mpc512x_psc_spi_setup;
|
||||
@ -503,94 +479,41 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
|
||||
master->unprepare_transfer_hardware = mpc512x_psc_spi_unprep_xfer_hw;
|
||||
master->use_gpio_descriptors = true;
|
||||
master->cleanup = mpc512x_psc_spi_cleanup;
|
||||
master->dev.of_node = dev->of_node;
|
||||
|
||||
tempp = devm_ioremap(dev, regaddr, size);
|
||||
if (!tempp) {
|
||||
dev_err(dev, "could not ioremap I/O port range\n");
|
||||
ret = -EFAULT;
|
||||
goto free_master;
|
||||
}
|
||||
device_set_node(&master->dev, dev_fwnode(dev));
|
||||
|
||||
tempp = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||
if (IS_ERR(tempp))
|
||||
return dev_err_probe(dev, PTR_ERR(tempp), "could not ioremap I/O port range\n");
|
||||
mps->psc = tempp;
|
||||
mps->fifo =
|
||||
(struct mpc512x_psc_fifo *)(tempp + sizeof(struct mpc52xx_psc));
|
||||
|
||||
mps->irq = platform_get_irq(pdev, 0);
|
||||
if (mps->irq < 0)
|
||||
return mps->irq;
|
||||
|
||||
ret = devm_request_irq(dev, mps->irq, mpc512x_psc_spi_isr, IRQF_SHARED,
|
||||
"mpc512x-psc-spi", mps);
|
||||
if (ret)
|
||||
goto free_master;
|
||||
return ret;
|
||||
init_completion(&mps->txisrdone);
|
||||
|
||||
clk = devm_clk_get(dev, "mclk");
|
||||
if (IS_ERR(clk)) {
|
||||
ret = PTR_ERR(clk);
|
||||
goto free_master;
|
||||
}
|
||||
ret = clk_prepare_enable(clk);
|
||||
if (ret)
|
||||
goto free_master;
|
||||
mps->clk_mclk = clk;
|
||||
clk = devm_clk_get_enabled(dev, "mclk");
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
|
||||
mps->mclk_rate = clk_get_rate(clk);
|
||||
|
||||
clk = devm_clk_get(dev, "ipg");
|
||||
if (IS_ERR(clk)) {
|
||||
ret = PTR_ERR(clk);
|
||||
goto free_mclk_clock;
|
||||
}
|
||||
ret = clk_prepare_enable(clk);
|
||||
if (ret)
|
||||
goto free_mclk_clock;
|
||||
mps->clk_ipg = clk;
|
||||
clk = devm_clk_get_enabled(dev, "ipg");
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
|
||||
ret = mpc512x_psc_spi_port_config(master, mps);
|
||||
if (ret < 0)
|
||||
goto free_ipg_clock;
|
||||
return ret;
|
||||
|
||||
ret = devm_spi_register_master(dev, master);
|
||||
if (ret < 0)
|
||||
goto free_ipg_clock;
|
||||
|
||||
return ret;
|
||||
|
||||
free_ipg_clock:
|
||||
clk_disable_unprepare(mps->clk_ipg);
|
||||
free_mclk_clock:
|
||||
clk_disable_unprepare(mps->clk_mclk);
|
||||
free_master:
|
||||
spi_master_put(master);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mpc512x_psc_spi_do_remove(struct device *dev)
|
||||
{
|
||||
struct spi_master *master = dev_get_drvdata(dev);
|
||||
struct mpc512x_psc_spi *mps = spi_master_get_devdata(master);
|
||||
|
||||
clk_disable_unprepare(mps->clk_mclk);
|
||||
clk_disable_unprepare(mps->clk_ipg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpc512x_psc_spi_of_probe(struct platform_device *op)
|
||||
{
|
||||
const u32 *regaddr_p;
|
||||
u64 regaddr64, size64;
|
||||
|
||||
regaddr_p = of_get_address(op->dev.of_node, 0, &size64, NULL);
|
||||
if (!regaddr_p) {
|
||||
dev_err(&op->dev, "Invalid PSC address\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
regaddr64 = of_translate_address(op->dev.of_node, regaddr_p);
|
||||
|
||||
return mpc512x_psc_spi_do_probe(&op->dev, (u32) regaddr64, (u32) size64,
|
||||
irq_of_parse_and_map(op->dev.of_node, 0));
|
||||
}
|
||||
|
||||
static int mpc512x_psc_spi_of_remove(struct platform_device *op)
|
||||
{
|
||||
return mpc512x_psc_spi_do_remove(&op->dev);
|
||||
return devm_spi_register_master(dev, master);
|
||||
}
|
||||
|
||||
static const struct of_device_id mpc512x_psc_spi_of_match[] = {
|
||||
@ -603,7 +526,6 @@ MODULE_DEVICE_TABLE(of, mpc512x_psc_spi_of_match);
|
||||
|
||||
static struct platform_driver mpc512x_psc_spi_of_driver = {
|
||||
.probe = mpc512x_psc_spi_of_probe,
|
||||
.remove = mpc512x_psc_spi_of_remove,
|
||||
.driver = {
|
||||
.name = "mpc512x-psc-spi",
|
||||
.of_match_table = mpc512x_psc_spi_of_match,
|
||||
|
@ -11,16 +11,14 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/fsl_devices.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of_irq.h>
|
||||
|
||||
#include <asm/mpc52xx.h>
|
||||
#include <asm/mpc52xx_psc.h>
|
||||
@ -28,10 +26,6 @@
|
||||
#define MCLK 20000000 /* PSC port MClk in hz */
|
||||
|
||||
struct mpc52xx_psc_spi {
|
||||
/* fsl_spi_platform data */
|
||||
void (*cs_control)(struct spi_device *spi, bool on);
|
||||
u32 sysclk;
|
||||
|
||||
/* driver internal data */
|
||||
struct mpc52xx_psc __iomem *psc;
|
||||
struct mpc52xx_psc_fifo __iomem *fifo;
|
||||
@ -101,17 +95,6 @@ static void mpc52xx_psc_spi_activate_cs(struct spi_device *spi)
|
||||
ccr |= (MCLK / 1000000 - 1) & 0xFF;
|
||||
out_be16((u16 __iomem *)&psc->ccr, ccr);
|
||||
mps->bits_per_word = cs->bits_per_word;
|
||||
|
||||
if (mps->cs_control)
|
||||
mps->cs_control(spi, (spi->mode & SPI_CS_HIGH) ? 1 : 0);
|
||||
}
|
||||
|
||||
static void mpc52xx_psc_spi_deactivate_cs(struct spi_device *spi)
|
||||
{
|
||||
struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master);
|
||||
|
||||
if (mps->cs_control)
|
||||
mps->cs_control(spi, (spi->mode & SPI_CS_HIGH) ? 0 : 1);
|
||||
}
|
||||
|
||||
#define MPC52xx_PSC_BUFSIZE (MPC52xx_PSC_RFNUM_MASK + 1)
|
||||
@ -220,14 +203,9 @@ int mpc52xx_psc_spi_transfer_one_message(struct spi_controller *ctlr,
|
||||
m->actual_length += t->len;
|
||||
|
||||
spi_transfer_delay_exec(t);
|
||||
|
||||
if (cs_change)
|
||||
mpc52xx_psc_spi_deactivate_cs(spi);
|
||||
}
|
||||
|
||||
m->status = status;
|
||||
if (status || !cs_change)
|
||||
mpc52xx_psc_spi_deactivate_cs(spi);
|
||||
|
||||
mpc52xx_psc_spi_transfer_setup(spi, NULL);
|
||||
|
||||
@ -269,7 +247,7 @@ static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps)
|
||||
int ret;
|
||||
|
||||
/* default sysclk is 512MHz */
|
||||
mclken_div = (mps->sysclk ? mps->sysclk : 512000000) / MCLK;
|
||||
mclken_div = 512000000 / MCLK;
|
||||
ret = mpc52xx_set_psc_clkdiv(psc_id, mclken_div);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -313,16 +291,15 @@ static irqreturn_t mpc52xx_psc_spi_isr(int irq, void *dev_id)
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
/* bus_num is used only for the case dev->platform_data == NULL */
|
||||
static int mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr,
|
||||
u32 size, unsigned int irq, s16 bus_num)
|
||||
static int mpc52xx_psc_spi_of_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
|
||||
struct device *dev = &pdev->dev;
|
||||
struct mpc52xx_psc_spi *mps;
|
||||
struct spi_master *master;
|
||||
u32 bus_num;
|
||||
int ret;
|
||||
|
||||
master = spi_alloc_master(dev, sizeof(*mps));
|
||||
master = devm_spi_alloc_master(dev, sizeof(*mps));
|
||||
if (master == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -332,104 +309,41 @@ static int mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr,
|
||||
/* the spi->mode bits understood by this driver: */
|
||||
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
|
||||
|
||||
mps->irq = irq;
|
||||
if (pdata == NULL) {
|
||||
dev_warn(dev,
|
||||
"probe called without platform data, no cs_control function will be called\n");
|
||||
mps->cs_control = NULL;
|
||||
mps->sysclk = 0;
|
||||
master->bus_num = bus_num;
|
||||
master->num_chipselect = 255;
|
||||
} else {
|
||||
mps->cs_control = pdata->cs_control;
|
||||
mps->sysclk = pdata->sysclk;
|
||||
master->bus_num = pdata->bus_num;
|
||||
master->num_chipselect = pdata->max_chipselect;
|
||||
}
|
||||
ret = device_property_read_u32(dev, "cell-index", &bus_num);
|
||||
if (ret || bus_num > 5)
|
||||
return dev_err_probe(dev, ret ? : -EINVAL, "Invalid cell-index property\n");
|
||||
master->bus_num = bus_num + 1;
|
||||
|
||||
master->num_chipselect = 255;
|
||||
master->setup = mpc52xx_psc_spi_setup;
|
||||
master->transfer_one_message = mpc52xx_psc_spi_transfer_one_message;
|
||||
master->cleanup = mpc52xx_psc_spi_cleanup;
|
||||
master->dev.of_node = dev->of_node;
|
||||
|
||||
mps->psc = ioremap(regaddr, size);
|
||||
if (!mps->psc) {
|
||||
dev_err(dev, "could not ioremap I/O port range\n");
|
||||
ret = -EFAULT;
|
||||
goto free_master;
|
||||
}
|
||||
device_set_node(&master->dev, dev_fwnode(dev));
|
||||
|
||||
mps->psc = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||
if (IS_ERR(mps->psc))
|
||||
return dev_err_probe(dev, PTR_ERR(mps->psc), "could not ioremap I/O port range\n");
|
||||
|
||||
/* On the 5200, fifo regs are immediately ajacent to the psc regs */
|
||||
mps->fifo = ((void __iomem *)mps->psc) + sizeof(struct mpc52xx_psc);
|
||||
|
||||
ret = request_irq(mps->irq, mpc52xx_psc_spi_isr, 0, "mpc52xx-psc-spi",
|
||||
mps);
|
||||
mps->irq = platform_get_irq(pdev, 0);
|
||||
if (mps->irq < 0)
|
||||
return mps->irq;
|
||||
|
||||
ret = devm_request_irq(dev, mps->irq, mpc52xx_psc_spi_isr, 0,
|
||||
"mpc52xx-psc-spi", mps);
|
||||
if (ret)
|
||||
goto free_master;
|
||||
return ret;
|
||||
|
||||
ret = mpc52xx_psc_spi_port_config(master->bus_num, mps);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "can't configure PSC! Is it capable of SPI?\n");
|
||||
goto free_irq;
|
||||
}
|
||||
if (ret < 0)
|
||||
return dev_err_probe(dev, ret, "can't configure PSC! Is it capable of SPI?\n");
|
||||
|
||||
init_completion(&mps->done);
|
||||
|
||||
ret = spi_register_master(master);
|
||||
if (ret < 0)
|
||||
goto free_irq;
|
||||
|
||||
return ret;
|
||||
|
||||
free_irq:
|
||||
free_irq(mps->irq, mps);
|
||||
free_master:
|
||||
if (mps->psc)
|
||||
iounmap(mps->psc);
|
||||
spi_master_put(master);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mpc52xx_psc_spi_of_probe(struct platform_device *op)
|
||||
{
|
||||
const u32 *regaddr_p;
|
||||
u64 regaddr64, size64;
|
||||
s16 id = -1;
|
||||
|
||||
regaddr_p = of_get_address(op->dev.of_node, 0, &size64, NULL);
|
||||
if (!regaddr_p) {
|
||||
dev_err(&op->dev, "Invalid PSC address\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
regaddr64 = of_translate_address(op->dev.of_node, regaddr_p);
|
||||
|
||||
/* get PSC id (1..6, used by port_config) */
|
||||
if (op->dev.platform_data == NULL) {
|
||||
const u32 *psc_nump;
|
||||
|
||||
psc_nump = of_get_property(op->dev.of_node, "cell-index", NULL);
|
||||
if (!psc_nump || *psc_nump > 5) {
|
||||
dev_err(&op->dev, "Invalid cell-index property\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
id = *psc_nump + 1;
|
||||
}
|
||||
|
||||
return mpc52xx_psc_spi_do_probe(&op->dev, (u32)regaddr64, (u32)size64,
|
||||
irq_of_parse_and_map(op->dev.of_node, 0), id);
|
||||
}
|
||||
|
||||
static int mpc52xx_psc_spi_of_remove(struct platform_device *op)
|
||||
{
|
||||
struct spi_master *master = spi_master_get(platform_get_drvdata(op));
|
||||
struct mpc52xx_psc_spi *mps = spi_master_get_devdata(master);
|
||||
|
||||
spi_unregister_master(master);
|
||||
free_irq(mps->irq, mps);
|
||||
if (mps->psc)
|
||||
iounmap(mps->psc);
|
||||
spi_master_put(master);
|
||||
|
||||
return 0;
|
||||
return devm_spi_register_master(dev, master);
|
||||
}
|
||||
|
||||
static const struct of_device_id mpc52xx_psc_spi_of_match[] = {
|
||||
@ -442,7 +356,6 @@ MODULE_DEVICE_TABLE(of, mpc52xx_psc_spi_of_match);
|
||||
|
||||
static struct platform_driver mpc52xx_psc_spi_of_driver = {
|
||||
.probe = mpc52xx_psc_spi_of_probe,
|
||||
.remove = mpc52xx_psc_spi_of_remove,
|
||||
.driver = {
|
||||
.name = "mpc52xx-psc-spi",
|
||||
.of_match_table = mpc52xx_psc_spi_of_match,
|
||||
|
@ -101,7 +101,7 @@ static void mpc52xx_spi_chipsel(struct mpc52xx_spi *ms, int value)
|
||||
int cs;
|
||||
|
||||
if (ms->gpio_cs_count > 0) {
|
||||
cs = ms->message->spi->chip_select;
|
||||
cs = spi_get_chipselect(ms->message->spi, 0);
|
||||
gpiod_set_value(ms->gpio_cs[cs], value);
|
||||
} else {
|
||||
out_8(ms->regs + SPI_PORTDATA, value ? 0 : 0x08);
|
||||
@ -513,7 +513,7 @@ static int mpc52xx_spi_probe(struct platform_device *op)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int mpc52xx_spi_remove(struct platform_device *op)
|
||||
static void mpc52xx_spi_remove(struct platform_device *op)
|
||||
{
|
||||
struct spi_master *master = spi_master_get(platform_get_drvdata(op));
|
||||
struct mpc52xx_spi *ms = spi_master_get_devdata(master);
|
||||
@ -529,8 +529,6 @@ static int mpc52xx_spi_remove(struct platform_device *op)
|
||||
spi_unregister_master(master);
|
||||
iounmap(ms->regs);
|
||||
spi_master_put(master);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id mpc52xx_spi_match[] = {
|
||||
@ -545,6 +543,6 @@ static struct platform_driver mpc52xx_spi_of_driver = {
|
||||
.of_match_table = mpc52xx_spi_match,
|
||||
},
|
||||
.probe = mpc52xx_spi_probe,
|
||||
.remove = mpc52xx_spi_remove,
|
||||
.remove_new = mpc52xx_spi_remove,
|
||||
};
|
||||
module_platform_driver(mpc52xx_spi_of_driver);
|
||||
|
@ -421,7 +421,7 @@ static int mtk_spi_hw_init(struct spi_master *master,
|
||||
|
||||
/* pad select */
|
||||
if (mdata->dev_comp->need_pad_sel)
|
||||
writel(mdata->pad_sel[spi->chip_select],
|
||||
writel(mdata->pad_sel[spi_get_chipselect(spi, 0)],
|
||||
mdata->base + SPI_PAD_SEL_REG);
|
||||
|
||||
/* tick delay */
|
||||
@ -735,9 +735,9 @@ static int mtk_spi_setup(struct spi_device *spi)
|
||||
if (!spi->controller_data)
|
||||
spi->controller_data = (void *)&mtk_default_chip_info;
|
||||
|
||||
if (mdata->dev_comp->need_pad_sel && spi->cs_gpiod)
|
||||
if (mdata->dev_comp->need_pad_sel && spi_get_csgpiod(spi, 0))
|
||||
/* CS de-asserted, gpiolib will handle inversion */
|
||||
gpiod_direction_output(spi->cs_gpiod, 0);
|
||||
gpiod_direction_output(spi_get_csgpiod(spi, 0), 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ static inline void mt7621_spi_write(struct mt7621_spi *rs, u32 reg, u32 val)
|
||||
static void mt7621_spi_set_cs(struct spi_device *spi, int enable)
|
||||
{
|
||||
struct mt7621_spi *rs = spidev_to_mt7621_spi(spi);
|
||||
int cs = spi->chip_select;
|
||||
int cs = spi_get_chipselect(spi, 0);
|
||||
u32 polar = 0;
|
||||
u32 master;
|
||||
|
||||
|
@ -934,7 +934,7 @@ err_probe:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mtk_nor_remove(struct platform_device *pdev)
|
||||
static void mtk_nor_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_controller *ctlr = dev_get_drvdata(&pdev->dev);
|
||||
struct mtk_nor *sp = spi_controller_get_devdata(ctlr);
|
||||
@ -944,8 +944,6 @@ static int mtk_nor_remove(struct platform_device *pdev)
|
||||
pm_runtime_dont_use_autosuspend(&pdev->dev);
|
||||
|
||||
mtk_nor_disable_clk(sp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused mtk_nor_runtime_suspend(struct device *dev)
|
||||
@ -999,7 +997,7 @@ static struct platform_driver mtk_nor_driver = {
|
||||
.pm = &mtk_nor_pm_ops,
|
||||
},
|
||||
.probe = mtk_nor_probe,
|
||||
.remove = mtk_nor_remove,
|
||||
.remove_new = mtk_nor_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(mtk_nor_driver);
|
||||
|
@ -1506,7 +1506,7 @@ release_ecc:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mtk_snand_remove(struct platform_device *pdev)
|
||||
static void mtk_snand_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_controller *ctlr = platform_get_drvdata(pdev);
|
||||
struct mtk_snand *ms = spi_controller_get_devdata(ctlr);
|
||||
@ -1515,12 +1515,11 @@ static int mtk_snand_remove(struct platform_device *pdev)
|
||||
mtk_snand_disable_clk(ms);
|
||||
mtk_ecc_release(ms->ecc);
|
||||
kfree(ms->buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver mtk_snand_driver = {
|
||||
.probe = mtk_snand_probe,
|
||||
.remove = mtk_snand_remove,
|
||||
.remove_new = mtk_snand_remove,
|
||||
.driver = {
|
||||
.name = "mtk-snand",
|
||||
.of_match_table = mtk_snand_ids,
|
||||
|
@ -51,22 +51,22 @@ static int spi_mux_select(struct spi_device *spi)
|
||||
struct spi_mux_priv *priv = spi_controller_get_devdata(spi->controller);
|
||||
int ret;
|
||||
|
||||
ret = mux_control_select(priv->mux, spi->chip_select);
|
||||
ret = mux_control_select(priv->mux, spi_get_chipselect(spi, 0));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (priv->current_cs == spi->chip_select)
|
||||
if (priv->current_cs == spi_get_chipselect(spi, 0))
|
||||
return 0;
|
||||
|
||||
dev_dbg(&priv->spi->dev, "setting up the mux for cs %d\n",
|
||||
spi->chip_select);
|
||||
spi_get_chipselect(spi, 0));
|
||||
|
||||
/* copy the child device's settings except for the cs */
|
||||
priv->spi->max_speed_hz = spi->max_speed_hz;
|
||||
priv->spi->mode = spi->mode;
|
||||
priv->spi->bits_per_word = spi->bits_per_word;
|
||||
|
||||
priv->current_cs = spi->chip_select;
|
||||
priv->current_cs = spi_get_chipselect(spi, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -306,8 +306,8 @@ static u32 mxic_spi_prep_hc_cfg(struct spi_device *spi, u32 flags)
|
||||
nio = 2;
|
||||
|
||||
return flags | HC_CFG_NIO(nio) |
|
||||
HC_CFG_TYPE(spi->chip_select, HC_CFG_TYPE_SPI_NOR) |
|
||||
HC_CFG_SLV_ACT(spi->chip_select) | HC_CFG_IDLE_SIO_LVL(1);
|
||||
HC_CFG_TYPE(spi_get_chipselect(spi, 0), HC_CFG_TYPE_SPI_NOR) |
|
||||
HC_CFG_SLV_ACT(spi_get_chipselect(spi, 0)) | HC_CFG_IDLE_SIO_LVL(1);
|
||||
}
|
||||
|
||||
static u32 mxic_spi_mem_prep_op_cfg(const struct spi_mem_op *op,
|
||||
@ -405,7 +405,7 @@ static ssize_t mxic_spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc,
|
||||
len = min_t(size_t, len, mxic->linear.size);
|
||||
writel(len, mxic->regs + LRD_RANGE);
|
||||
writel(LMODE_CMD0(desc->info.op_tmpl.cmd.opcode) |
|
||||
LMODE_SLV_ACT(desc->mem->spi->chip_select) |
|
||||
LMODE_SLV_ACT(spi_get_chipselect(desc->mem->spi, 0)) |
|
||||
LMODE_EN,
|
||||
mxic->regs + LRD_CTRL);
|
||||
|
||||
@ -449,7 +449,7 @@ static ssize_t mxic_spi_mem_dirmap_write(struct spi_mem_dirmap_desc *desc,
|
||||
len = min_t(size_t, len, mxic->linear.size);
|
||||
writel(len, mxic->regs + LWR_RANGE);
|
||||
writel(LMODE_CMD0(desc->info.op_tmpl.cmd.opcode) |
|
||||
LMODE_SLV_ACT(desc->mem->spi->chip_select) |
|
||||
LMODE_SLV_ACT(spi_get_chipselect(desc->mem->spi, 0)) |
|
||||
LMODE_EN,
|
||||
mxic->regs + LWR_CTRL);
|
||||
|
||||
@ -524,7 +524,7 @@ static int mxic_spi_mem_exec_op(struct spi_mem *mem,
|
||||
writel(HC_EN_BIT, mxic->regs + HC_EN);
|
||||
|
||||
writel(mxic_spi_mem_prep_op_cfg(op, op->data.nbytes),
|
||||
mxic->regs + SS_CTRL(mem->spi->chip_select));
|
||||
mxic->regs + SS_CTRL(spi_get_chipselect(mem->spi, 0)));
|
||||
|
||||
writel(readl(mxic->regs + HC_CFG) | HC_CFG_MAN_CS_ASSERT,
|
||||
mxic->regs + HC_CFG);
|
||||
@ -818,7 +818,7 @@ static int mxic_spi_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mxic_spi_remove(struct platform_device *pdev)
|
||||
static void mxic_spi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_master *master = platform_get_drvdata(pdev);
|
||||
struct mxic_spi *mxic = spi_master_get_devdata(master);
|
||||
@ -826,8 +826,6 @@ static int mxic_spi_remove(struct platform_device *pdev)
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
mxic_spi_mem_ecc_remove(mxic);
|
||||
spi_unregister_master(master);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id mxic_spi_of_ids[] = {
|
||||
@ -838,7 +836,7 @@ MODULE_DEVICE_TABLE(of, mxic_spi_of_ids);
|
||||
|
||||
static struct platform_driver mxic_spi_driver = {
|
||||
.probe = mxic_spi_probe,
|
||||
.remove = mxic_spi_remove,
|
||||
.remove_new = mxic_spi_remove,
|
||||
.driver = {
|
||||
.name = "mxic-spi",
|
||||
.of_match_table = mxic_spi_of_ids,
|
||||
|
@ -369,7 +369,7 @@ static int mxs_spi_transfer_one(struct spi_master *master,
|
||||
/* Program CS register bits here, it will be used for all transfers. */
|
||||
writel(BM_SSP_CTRL0_WAIT_FOR_CMD | BM_SSP_CTRL0_WAIT_FOR_IRQ,
|
||||
ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
|
||||
writel(mxs_spi_cs_to_reg(m->spi->chip_select),
|
||||
writel(mxs_spi_cs_to_reg(spi_get_chipselect(m->spi, 0)),
|
||||
ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
|
||||
|
||||
list_for_each_entry(t, &m->transfers, transfer_list) {
|
||||
@ -638,7 +638,7 @@ out_master_free:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mxs_spi_remove(struct platform_device *pdev)
|
||||
static void mxs_spi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_master *master;
|
||||
struct mxs_spi *spi;
|
||||
@ -653,13 +653,11 @@ static int mxs_spi_remove(struct platform_device *pdev)
|
||||
mxs_spi_runtime_suspend(&pdev->dev);
|
||||
|
||||
dma_release_channel(ssp->dmach);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver mxs_spi_driver = {
|
||||
.probe = mxs_spi_probe,
|
||||
.remove = mxs_spi_remove,
|
||||
.remove_new = mxs_spi_remove,
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.of_match_table = mxs_spi_dt_ids,
|
||||
|
@ -288,7 +288,7 @@ static ssize_t npcm_fiu_direct_read(struct spi_mem_dirmap_desc *desc,
|
||||
{
|
||||
struct npcm_fiu_spi *fiu =
|
||||
spi_controller_get_devdata(desc->mem->spi->master);
|
||||
struct npcm_fiu_chip *chip = &fiu->chip[desc->mem->spi->chip_select];
|
||||
struct npcm_fiu_chip *chip = &fiu->chip[spi_get_chipselect(desc->mem->spi, 0)];
|
||||
void __iomem *src = (void __iomem *)(chip->flash_region_mapped_ptr +
|
||||
offs);
|
||||
u8 *buf_rx = buf;
|
||||
@ -315,7 +315,7 @@ static ssize_t npcm_fiu_direct_write(struct spi_mem_dirmap_desc *desc,
|
||||
{
|
||||
struct npcm_fiu_spi *fiu =
|
||||
spi_controller_get_devdata(desc->mem->spi->master);
|
||||
struct npcm_fiu_chip *chip = &fiu->chip[desc->mem->spi->chip_select];
|
||||
struct npcm_fiu_chip *chip = &fiu->chip[spi_get_chipselect(desc->mem->spi, 0)];
|
||||
void __iomem *dst = (void __iomem *)(chip->flash_region_mapped_ptr +
|
||||
offs);
|
||||
const u8 *buf_tx = buf;
|
||||
@ -344,7 +344,7 @@ static int npcm_fiu_uma_read(struct spi_mem *mem,
|
||||
|
||||
regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
|
||||
NPCM_FIU_UMA_CTS_DEV_NUM,
|
||||
(mem->spi->chip_select <<
|
||||
(spi_get_chipselect(mem->spi, 0) <<
|
||||
NPCM_FIU_UMA_CTS_DEV_NUM_SHIFT));
|
||||
regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CMD,
|
||||
NPCM_FIU_UMA_CMD_CMD, op->cmd.opcode);
|
||||
@ -398,7 +398,7 @@ static int npcm_fiu_uma_write(struct spi_mem *mem,
|
||||
|
||||
regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
|
||||
NPCM_FIU_UMA_CTS_DEV_NUM,
|
||||
(mem->spi->chip_select <<
|
||||
(spi_get_chipselect(mem->spi, 0) <<
|
||||
NPCM_FIU_UMA_CTS_DEV_NUM_SHIFT));
|
||||
|
||||
regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CMD,
|
||||
@ -451,7 +451,7 @@ static int npcm_fiu_manualwrite(struct spi_mem *mem,
|
||||
|
||||
regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
|
||||
NPCM_FIU_UMA_CTS_DEV_NUM,
|
||||
(mem->spi->chip_select <<
|
||||
(spi_get_chipselect(mem->spi, 0) <<
|
||||
NPCM_FIU_UMA_CTS_DEV_NUM_SHIFT));
|
||||
regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
|
||||
NPCM_FIU_UMA_CTS_SW_CS, 0);
|
||||
@ -545,7 +545,7 @@ static int npcm_fiu_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
|
||||
{
|
||||
struct npcm_fiu_spi *fiu =
|
||||
spi_controller_get_devdata(mem->spi->master);
|
||||
struct npcm_fiu_chip *chip = &fiu->chip[mem->spi->chip_select];
|
||||
struct npcm_fiu_chip *chip = &fiu->chip[spi_get_chipselect(mem->spi, 0)];
|
||||
int ret = 0;
|
||||
u8 *buf;
|
||||
|
||||
@ -605,7 +605,7 @@ static int npcm_fiu_dirmap_create(struct spi_mem_dirmap_desc *desc)
|
||||
{
|
||||
struct npcm_fiu_spi *fiu =
|
||||
spi_controller_get_devdata(desc->mem->spi->master);
|
||||
struct npcm_fiu_chip *chip = &fiu->chip[desc->mem->spi->chip_select];
|
||||
struct npcm_fiu_chip *chip = &fiu->chip[spi_get_chipselect(desc->mem->spi, 0)];
|
||||
struct regmap *gcr_regmap;
|
||||
|
||||
if (!fiu->res_mem) {
|
||||
@ -624,7 +624,7 @@ static int npcm_fiu_dirmap_create(struct spi_mem_dirmap_desc *desc)
|
||||
chip->flash_region_mapped_ptr =
|
||||
devm_ioremap(fiu->dev, (fiu->res_mem->start +
|
||||
(fiu->info->max_map_size *
|
||||
desc->mem->spi->chip_select)),
|
||||
spi_get_chipselect(desc->mem->spi, 0))),
|
||||
(u32)desc->info.length);
|
||||
if (!chip->flash_region_mapped_ptr) {
|
||||
dev_warn(fiu->dev, "Error mapping memory region, direct read disabled\n");
|
||||
@ -669,9 +669,9 @@ static int npcm_fiu_setup(struct spi_device *spi)
|
||||
struct npcm_fiu_spi *fiu = spi_controller_get_devdata(ctrl);
|
||||
struct npcm_fiu_chip *chip;
|
||||
|
||||
chip = &fiu->chip[spi->chip_select];
|
||||
chip = &fiu->chip[spi_get_chipselect(spi, 0)];
|
||||
chip->fiu = fiu;
|
||||
chip->chipselect = spi->chip_select;
|
||||
chip->chipselect = spi_get_chipselect(spi, 0);
|
||||
chip->clkrate = spi->max_speed_hz;
|
||||
|
||||
fiu->clkrate = clk_get_rate(fiu->clk);
|
||||
@ -762,12 +762,11 @@ static int npcm_fiu_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int npcm_fiu_remove(struct platform_device *pdev)
|
||||
static void npcm_fiu_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct npcm_fiu_spi *fiu = platform_get_drvdata(pdev);
|
||||
|
||||
clk_disable_unprepare(fiu->clk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
MODULE_DEVICE_TABLE(of, npcm_fiu_dt_ids);
|
||||
@ -779,7 +778,7 @@ static struct platform_driver npcm_fiu_driver = {
|
||||
.of_match_table = npcm_fiu_dt_ids,
|
||||
},
|
||||
.probe = npcm_fiu_probe,
|
||||
.remove = npcm_fiu_remove,
|
||||
.remove_new = npcm_fiu_remove,
|
||||
};
|
||||
module_platform_driver(npcm_fiu_driver);
|
||||
|
||||
|
@ -430,15 +430,13 @@ out_master_put:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int npcm_pspi_remove(struct platform_device *pdev)
|
||||
static void npcm_pspi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_master *master = platform_get_drvdata(pdev);
|
||||
struct npcm_pspi *priv = spi_master_get_devdata(master);
|
||||
|
||||
npcm_pspi_reset_hw(priv);
|
||||
clk_disable_unprepare(priv->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id npcm_pspi_match[] = {
|
||||
@ -454,7 +452,7 @@ static struct platform_driver npcm_pspi_driver = {
|
||||
.of_match_table = npcm_pspi_match,
|
||||
},
|
||||
.probe = npcm_pspi_probe,
|
||||
.remove = npcm_pspi_remove,
|
||||
.remove_new = npcm_pspi_remove,
|
||||
};
|
||||
module_platform_driver(npcm_pspi_driver);
|
||||
|
||||
|
@ -214,9 +214,15 @@
|
||||
|
||||
#define FSPI_DLLACR 0xC0
|
||||
#define FSPI_DLLACR_OVRDEN BIT(8)
|
||||
#define FSPI_DLLACR_SLVDLY(x) ((x) << 3)
|
||||
#define FSPI_DLLACR_DLLRESET BIT(1)
|
||||
#define FSPI_DLLACR_DLLEN BIT(0)
|
||||
|
||||
#define FSPI_DLLBCR 0xC4
|
||||
#define FSPI_DLLBCR_OVRDEN BIT(8)
|
||||
#define FSPI_DLLBCR_SLVDLY(x) ((x) << 3)
|
||||
#define FSPI_DLLBCR_DLLRESET BIT(1)
|
||||
#define FSPI_DLLBCR_DLLEN BIT(0)
|
||||
|
||||
#define FSPI_STS0 0xE0
|
||||
#define FSPI_STS0_DLPHB(x) ((x) << 8)
|
||||
@ -231,6 +237,16 @@
|
||||
#define FSPI_STS1_AHB_ERRCD(x) ((x) << 8)
|
||||
#define FSPI_STS1_AHB_ERRID(x) (x)
|
||||
|
||||
#define FSPI_STS2 0xE8
|
||||
#define FSPI_STS2_BREFLOCK BIT(17)
|
||||
#define FSPI_STS2_BSLVLOCK BIT(16)
|
||||
#define FSPI_STS2_AREFLOCK BIT(1)
|
||||
#define FSPI_STS2_ASLVLOCK BIT(0)
|
||||
#define FSPI_STS2_AB_LOCK (FSPI_STS2_BREFLOCK | \
|
||||
FSPI_STS2_BSLVLOCK | \
|
||||
FSPI_STS2_AREFLOCK | \
|
||||
FSPI_STS2_ASLVLOCK)
|
||||
|
||||
#define FSPI_AHBSPNST 0xEC
|
||||
#define FSPI_AHBSPNST_DATLFT(x) ((x) << 16)
|
||||
#define FSPI_AHBSPNST_BUFID(x) ((x) << 1)
|
||||
@ -615,6 +631,35 @@ static int nxp_fspi_clk_disable_unprep(struct nxp_fspi *f)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nxp_fspi_dll_calibration(struct nxp_fspi *f)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Reset the DLL, set the DLLRESET to 1 and then set to 0 */
|
||||
fspi_writel(f, FSPI_DLLACR_DLLRESET, f->iobase + FSPI_DLLACR);
|
||||
fspi_writel(f, FSPI_DLLBCR_DLLRESET, f->iobase + FSPI_DLLBCR);
|
||||
fspi_writel(f, 0, f->iobase + FSPI_DLLACR);
|
||||
fspi_writel(f, 0, f->iobase + FSPI_DLLBCR);
|
||||
|
||||
/*
|
||||
* Enable the DLL calibration mode.
|
||||
* The delay target for slave delay line is:
|
||||
* ((SLVDLYTARGET+1) * 1/32 * clock cycle of reference clock.
|
||||
* When clock rate > 100MHz, recommend SLVDLYTARGET is 0xF, which
|
||||
* means half of clock cycle of reference clock.
|
||||
*/
|
||||
fspi_writel(f, FSPI_DLLACR_DLLEN | FSPI_DLLACR_SLVDLY(0xF),
|
||||
f->iobase + FSPI_DLLACR);
|
||||
fspi_writel(f, FSPI_DLLBCR_DLLEN | FSPI_DLLBCR_SLVDLY(0xF),
|
||||
f->iobase + FSPI_DLLBCR);
|
||||
|
||||
/* Wait to get REF/SLV lock */
|
||||
ret = fspi_readl_poll_tout(f, f->iobase + FSPI_STS2, FSPI_STS2_AB_LOCK,
|
||||
0, POLL_TOUT, true);
|
||||
if (ret)
|
||||
dev_warn(f->dev, "DLL lock failed, please fix it!\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* In FlexSPI controller, flash access is based on value of FSPI_FLSHXXCR0
|
||||
* register and start base address of the slave device.
|
||||
@ -663,7 +708,7 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi)
|
||||
* Return, if previously selected slave device is same as current
|
||||
* requested slave device.
|
||||
*/
|
||||
if (f->selected == spi->chip_select)
|
||||
if (f->selected == spi_get_chipselect(spi, 0))
|
||||
return;
|
||||
|
||||
/* Reset FLSHxxCR0 registers */
|
||||
@ -676,9 +721,9 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi)
|
||||
size_kb = FSPI_FLSHXCR0_SZ(f->memmap_phy_size);
|
||||
|
||||
fspi_writel(f, size_kb, f->iobase + FSPI_FLSHA1CR0 +
|
||||
4 * spi->chip_select);
|
||||
4 * spi_get_chipselect(spi, 0));
|
||||
|
||||
dev_dbg(f->dev, "Slave device [CS:%x] selected\n", spi->chip_select);
|
||||
dev_dbg(f->dev, "Slave device [CS:%x] selected\n", spi_get_chipselect(spi, 0));
|
||||
|
||||
nxp_fspi_clk_disable_unprep(f);
|
||||
|
||||
@ -690,7 +735,14 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi)
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
f->selected = spi->chip_select;
|
||||
/*
|
||||
* If clock rate > 100MHz, then switch from DLL override mode to
|
||||
* DLL calibration mode.
|
||||
*/
|
||||
if (rate > 100000000)
|
||||
nxp_fspi_dll_calibration(f);
|
||||
|
||||
f->selected = spi_get_chipselect(spi, 0);
|
||||
}
|
||||
|
||||
static int nxp_fspi_read_ahb(struct nxp_fspi *f, const struct spi_mem_op *op)
|
||||
@ -997,7 +1049,11 @@ static int nxp_fspi_default_setup(struct nxp_fspi *f)
|
||||
/* Disable the module */
|
||||
fspi_writel(f, FSPI_MCR0_MDIS, base + FSPI_MCR0);
|
||||
|
||||
/* Reset the DLL register to default value */
|
||||
/*
|
||||
* Config the DLL register to default value, enable the slave clock delay
|
||||
* line delay cell override mode, and use 1 fixed delay cell in DLL delay
|
||||
* chain, this is the suggested setting when clock rate < 100MHz.
|
||||
*/
|
||||
fspi_writel(f, FSPI_DLLACR_OVRDEN, base + FSPI_DLLACR);
|
||||
fspi_writel(f, FSPI_DLLBCR_OVRDEN, base + FSPI_DLLBCR);
|
||||
|
||||
@ -1055,7 +1111,7 @@ static const char *nxp_fspi_get_name(struct spi_mem *mem)
|
||||
|
||||
name = devm_kasprintf(dev, GFP_KERNEL,
|
||||
"%s-%d", dev_name(f->dev),
|
||||
mem->spi->chip_select);
|
||||
spi_get_chipselect(mem->spi, 0));
|
||||
|
||||
if (!name) {
|
||||
dev_err(dev, "failed to get memory for custom flash name\n");
|
||||
@ -1195,7 +1251,7 @@ err_put_ctrl:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nxp_fspi_remove(struct platform_device *pdev)
|
||||
static void nxp_fspi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct nxp_fspi *f = platform_get_drvdata(pdev);
|
||||
|
||||
@ -1208,8 +1264,6 @@ static int nxp_fspi_remove(struct platform_device *pdev)
|
||||
|
||||
if (f->ahb_addr)
|
||||
iounmap(f->ahb_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nxp_fspi_suspend(struct device *dev)
|
||||
@ -1257,7 +1311,7 @@ static struct platform_driver nxp_fspi_driver = {
|
||||
.pm = &nxp_fspi_pm_ops,
|
||||
},
|
||||
.probe = nxp_fspi_probe,
|
||||
.remove = nxp_fspi_remove,
|
||||
.remove_new = nxp_fspi_remove,
|
||||
};
|
||||
module_platform_driver(nxp_fspi_driver);
|
||||
|
||||
|
@ -271,14 +271,13 @@ exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int tiny_spi_remove(struct platform_device *pdev)
|
||||
static void tiny_spi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct tiny_spi *hw = platform_get_drvdata(pdev);
|
||||
struct spi_master *master = hw->bitbang.master;
|
||||
|
||||
spi_bitbang_stop(&hw->bitbang);
|
||||
spi_master_put(master);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
@ -291,7 +290,7 @@ MODULE_DEVICE_TABLE(of, tiny_spi_match);
|
||||
|
||||
static struct platform_driver tiny_spi_driver = {
|
||||
.probe = tiny_spi_probe,
|
||||
.remove = tiny_spi_remove,
|
||||
.remove_new = tiny_spi_remove,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.pm = NULL,
|
||||
|
@ -179,7 +179,7 @@ static void uwire_chipselect(struct spi_device *spi, int value)
|
||||
|
||||
w = uwire_read_reg(UWIRE_CSR);
|
||||
old_cs = (w >> 10) & 0x03;
|
||||
if (value == BITBANG_CS_INACTIVE || old_cs != spi->chip_select) {
|
||||
if (value == BITBANG_CS_INACTIVE || old_cs != spi_get_chipselect(spi, 0)) {
|
||||
/* Deselect this CS, or the previous CS */
|
||||
w &= ~CS_CMD;
|
||||
uwire_write_reg(UWIRE_CSR, w);
|
||||
@ -193,7 +193,7 @@ static void uwire_chipselect(struct spi_device *spi, int value)
|
||||
else
|
||||
uwire_write_reg(UWIRE_SR4, 0);
|
||||
|
||||
w = spi->chip_select << 10;
|
||||
w = spi_get_chipselect(spi, 0) << 10;
|
||||
w |= CS_CMD;
|
||||
uwire_write_reg(UWIRE_CSR, w);
|
||||
}
|
||||
@ -210,7 +210,7 @@ static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)
|
||||
if (!t->tx_buf && !t->rx_buf)
|
||||
return 0;
|
||||
|
||||
w = spi->chip_select << 10;
|
||||
w = spi_get_chipselect(spi, 0) << 10;
|
||||
w |= CS_CMD;
|
||||
|
||||
if (t->tx_buf) {
|
||||
@ -408,7 +408,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
|
||||
rate /= 8;
|
||||
break;
|
||||
}
|
||||
omap_uwire_configure_mode(spi->chip_select, flags);
|
||||
omap_uwire_configure_mode(spi_get_chipselect(spi, 0), flags);
|
||||
pr_debug("%s: uwire flags %02x, armxor %lu KHz, SCK %lu KHz\n",
|
||||
__func__, flags,
|
||||
clk_get_rate(uwire->ck) / 1000,
|
||||
@ -505,7 +505,7 @@ static int uwire_probe(struct platform_device *pdev)
|
||||
return status;
|
||||
}
|
||||
|
||||
static int uwire_remove(struct platform_device *pdev)
|
||||
static void uwire_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct uwire_spi *uwire = platform_get_drvdata(pdev);
|
||||
|
||||
@ -513,7 +513,6 @@ static int uwire_remove(struct platform_device *pdev)
|
||||
|
||||
spi_bitbang_stop(&uwire->bitbang);
|
||||
uwire_off(uwire);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* work with hotplug and coldplug */
|
||||
@ -524,7 +523,7 @@ static struct platform_driver uwire_driver = {
|
||||
.name = "omap_uwire",
|
||||
},
|
||||
.probe = uwire_probe,
|
||||
.remove = uwire_remove,
|
||||
.remove_new = uwire_remove,
|
||||
// suspend ... unuse ck
|
||||
// resume ... use ck
|
||||
};
|
||||
|
@ -379,7 +379,7 @@ static void omap2_mcspi_rx_callback(void *data)
|
||||
{
|
||||
struct spi_device *spi = data;
|
||||
struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master);
|
||||
struct omap2_mcspi_dma *mcspi_dma = &mcspi->dma_channels[spi->chip_select];
|
||||
struct omap2_mcspi_dma *mcspi_dma = &mcspi->dma_channels[spi_get_chipselect(spi, 0)];
|
||||
|
||||
/* We must disable the DMA RX request */
|
||||
omap2_mcspi_set_dma_req(spi, 1, 0);
|
||||
@ -391,7 +391,7 @@ static void omap2_mcspi_tx_callback(void *data)
|
||||
{
|
||||
struct spi_device *spi = data;
|
||||
struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master);
|
||||
struct omap2_mcspi_dma *mcspi_dma = &mcspi->dma_channels[spi->chip_select];
|
||||
struct omap2_mcspi_dma *mcspi_dma = &mcspi->dma_channels[spi_get_chipselect(spi, 0)];
|
||||
|
||||
/* We must disable the DMA TX request */
|
||||
omap2_mcspi_set_dma_req(spi, 0, 0);
|
||||
@ -408,7 +408,7 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi,
|
||||
struct dma_async_tx_descriptor *tx;
|
||||
|
||||
mcspi = spi_master_get_devdata(spi->master);
|
||||
mcspi_dma = &mcspi->dma_channels[spi->chip_select];
|
||||
mcspi_dma = &mcspi->dma_channels[spi_get_chipselect(spi, 0)];
|
||||
|
||||
dmaengine_slave_config(mcspi_dma->dma_tx, &cfg);
|
||||
|
||||
@ -446,7 +446,7 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
|
||||
struct dma_async_tx_descriptor *tx;
|
||||
|
||||
mcspi = spi_master_get_devdata(spi->master);
|
||||
mcspi_dma = &mcspi->dma_channels[spi->chip_select];
|
||||
mcspi_dma = &mcspi->dma_channels[spi_get_chipselect(spi, 0)];
|
||||
count = xfer->len;
|
||||
|
||||
/*
|
||||
@ -591,7 +591,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
|
||||
int wait_res;
|
||||
|
||||
mcspi = spi_master_get_devdata(spi->master);
|
||||
mcspi_dma = &mcspi->dma_channels[spi->chip_select];
|
||||
mcspi_dma = &mcspi->dma_channels[spi_get_chipselect(spi, 0)];
|
||||
|
||||
if (cs->word_len <= 8) {
|
||||
width = DMA_SLAVE_BUSWIDTH_1_BYTE;
|
||||
@ -1062,8 +1062,8 @@ static int omap2_mcspi_setup(struct spi_device *spi)
|
||||
cs = kzalloc(sizeof(*cs), GFP_KERNEL);
|
||||
if (!cs)
|
||||
return -ENOMEM;
|
||||
cs->base = mcspi->base + spi->chip_select * 0x14;
|
||||
cs->phys = mcspi->phys + spi->chip_select * 0x14;
|
||||
cs->base = mcspi->base + spi_get_chipselect(spi, 0) * 0x14;
|
||||
cs->phys = mcspi->phys + spi_get_chipselect(spi, 0) * 0x14;
|
||||
cs->mode = 0;
|
||||
cs->chconf0 = 0;
|
||||
cs->chctrl0 = 0;
|
||||
@ -1142,7 +1142,7 @@ static int omap2_mcspi_transfer_one(struct spi_master *master,
|
||||
u32 chconf;
|
||||
|
||||
mcspi = spi_master_get_devdata(master);
|
||||
mcspi_dma = mcspi->dma_channels + spi->chip_select;
|
||||
mcspi_dma = mcspi->dma_channels + spi_get_chipselect(spi, 0);
|
||||
cs = spi->controller_state;
|
||||
cd = spi->controller_data;
|
||||
|
||||
@ -1158,7 +1158,7 @@ static int omap2_mcspi_transfer_one(struct spi_master *master,
|
||||
|
||||
omap2_mcspi_set_enable(spi, 0);
|
||||
|
||||
if (spi->cs_gpiod)
|
||||
if (spi_get_csgpiod(spi, 0))
|
||||
omap2_mcspi_set_cs(spi, spi->mode & SPI_CS_HIGH);
|
||||
|
||||
if (par_override ||
|
||||
@ -1247,7 +1247,7 @@ out:
|
||||
|
||||
omap2_mcspi_set_enable(spi, 0);
|
||||
|
||||
if (spi->cs_gpiod)
|
||||
if (spi_get_csgpiod(spi, 0))
|
||||
omap2_mcspi_set_cs(spi, !(spi->mode & SPI_CS_HIGH));
|
||||
|
||||
if (mcspi->fifo_depth > 0 && t)
|
||||
@ -1289,7 +1289,7 @@ static bool omap2_mcspi_can_dma(struct spi_master *master,
|
||||
{
|
||||
struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master);
|
||||
struct omap2_mcspi_dma *mcspi_dma =
|
||||
&mcspi->dma_channels[spi->chip_select];
|
||||
&mcspi->dma_channels[spi_get_chipselect(spi, 0)];
|
||||
|
||||
if (!mcspi_dma->dma_rx || !mcspi_dma->dma_tx)
|
||||
return false;
|
||||
@ -1307,7 +1307,7 @@ static size_t omap2_mcspi_max_xfer_size(struct spi_device *spi)
|
||||
{
|
||||
struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master);
|
||||
struct omap2_mcspi_dma *mcspi_dma =
|
||||
&mcspi->dma_channels[spi->chip_select];
|
||||
&mcspi->dma_channels[spi_get_chipselect(spi, 0)];
|
||||
|
||||
if (mcspi->max_xfer_len && mcspi_dma->dma_rx)
|
||||
return mcspi->max_xfer_len;
|
||||
@ -1464,7 +1464,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
|
||||
|
||||
of_property_read_u32(node, "ti,spi-num-cs", &num_cs);
|
||||
master->num_chipselect = num_cs;
|
||||
if (of_get_property(node, "ti,pindir-d0-out-d1-in", NULL))
|
||||
if (of_property_read_bool(node, "ti,pindir-d0-out-d1-in"))
|
||||
mcspi->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN;
|
||||
} else {
|
||||
pdata = dev_get_platdata(&pdev->dev);
|
||||
@ -1477,8 +1477,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
|
||||
master->max_transfer_size = omap2_mcspi_max_xfer_size;
|
||||
}
|
||||
|
||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
mcspi->base = devm_ioremap_resource(&pdev->dev, r);
|
||||
mcspi->base = devm_platform_get_and_ioremap_resource(pdev, 0, &r);
|
||||
if (IS_ERR(mcspi->base)) {
|
||||
status = PTR_ERR(mcspi->base);
|
||||
goto free_master;
|
||||
@ -1546,7 +1545,7 @@ free_master:
|
||||
return status;
|
||||
}
|
||||
|
||||
static int omap2_mcspi_remove(struct platform_device *pdev)
|
||||
static void omap2_mcspi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_master *master = platform_get_drvdata(pdev);
|
||||
struct omap2_mcspi *mcspi = spi_master_get_devdata(master);
|
||||
@ -1556,8 +1555,6 @@ static int omap2_mcspi_remove(struct platform_device *pdev)
|
||||
pm_runtime_dont_use_autosuspend(mcspi->dev);
|
||||
pm_runtime_put_sync(mcspi->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* work with hotplug and coldplug */
|
||||
@ -1610,7 +1607,7 @@ static struct platform_driver omap2_mcspi_driver = {
|
||||
.of_match_table = omap_mcspi_of_match,
|
||||
},
|
||||
.probe = omap2_mcspi_probe,
|
||||
.remove = omap2_mcspi_remove,
|
||||
.remove_new = omap2_mcspi_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(omap2_mcspi_driver);
|
||||
|
@ -346,7 +346,7 @@ static void orion_spi_set_cs(struct spi_device *spi, bool enable)
|
||||
* as it is handled by a GPIO, but that doesn't matter. What we need
|
||||
* is to deassert the old chip select and assert some other chip select.
|
||||
*/
|
||||
val |= ORION_SPI_CS(spi->chip_select);
|
||||
val |= ORION_SPI_CS(spi_get_chipselect(spi, 0));
|
||||
|
||||
/*
|
||||
* Chip select logic is inverted from spi_set_cs(). For lines using a
|
||||
@ -470,7 +470,7 @@ orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
|
||||
unsigned int count;
|
||||
int word_len;
|
||||
struct orion_spi *orion_spi;
|
||||
int cs = spi->chip_select;
|
||||
int cs = spi_get_chipselect(spi, 0);
|
||||
void __iomem *vaddr;
|
||||
|
||||
word_len = spi->bits_per_word;
|
||||
@ -728,8 +728,7 @@ static int orion_spi_probe(struct platform_device *pdev)
|
||||
master->max_speed_hz = devdata->max_hz;
|
||||
master->min_speed_hz = DIV_ROUND_UP(tclk_hz, devdata->max_divisor);
|
||||
|
||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
spi->base = devm_ioremap_resource(&pdev->dev, r);
|
||||
spi->base = devm_platform_get_and_ioremap_resource(pdev, 0, &r);
|
||||
if (IS_ERR(spi->base)) {
|
||||
status = PTR_ERR(spi->base);
|
||||
goto out_rel_axi_clk;
|
||||
@ -805,7 +804,7 @@ out:
|
||||
}
|
||||
|
||||
|
||||
static int orion_spi_remove(struct platform_device *pdev)
|
||||
static void orion_spi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_master *master = platform_get_drvdata(pdev);
|
||||
struct orion_spi *spi = spi_master_get_devdata(master);
|
||||
@ -816,8 +815,6 @@ static int orion_spi_remove(struct platform_device *pdev)
|
||||
|
||||
spi_unregister_master(master);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MODULE_ALIAS("platform:" DRIVER_NAME);
|
||||
@ -857,7 +854,7 @@ static struct platform_driver orion_spi_driver = {
|
||||
.of_match_table = of_match_ptr(orion_spi_of_match_table),
|
||||
},
|
||||
.probe = orion_spi_probe,
|
||||
.remove = orion_spi_remove,
|
||||
.remove_new = orion_spi_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(orion_spi_driver);
|
||||
|
@ -58,7 +58,7 @@
|
||||
#define VENDOR_ID_MCHP 0x1055
|
||||
|
||||
#define SPI_SUSPEND_CONFIG 0x101
|
||||
#define SPI_RESUME_CONFIG 0x303
|
||||
#define SPI_RESUME_CONFIG 0x203
|
||||
|
||||
struct pci1xxxx_spi_internal {
|
||||
u8 hw_inst;
|
||||
@ -114,17 +114,14 @@ static void pci1xxxx_spi_set_cs(struct spi_device *spi, bool enable)
|
||||
|
||||
/* Set the DEV_SEL bits of the SPI_MST_CTL_REG */
|
||||
regval = readl(par->reg_base + SPI_MST_CTL_REG_OFFSET(p->hw_inst));
|
||||
if (enable) {
|
||||
if (!enable) {
|
||||
regval |= SPI_FORCE_CE;
|
||||
regval &= ~SPI_MST_CTL_DEVSEL_MASK;
|
||||
regval |= (spi->chip_select << 25);
|
||||
writel(regval,
|
||||
par->reg_base + SPI_MST_CTL_REG_OFFSET(p->hw_inst));
|
||||
regval |= (spi_get_chipselect(spi, 0) << 25);
|
||||
} else {
|
||||
regval &= ~(spi->chip_select << 25);
|
||||
writel(regval,
|
||||
par->reg_base + SPI_MST_CTL_REG_OFFSET(p->hw_inst));
|
||||
|
||||
regval &= ~SPI_FORCE_CE;
|
||||
}
|
||||
writel(regval, par->reg_base + SPI_MST_CTL_REG_OFFSET(p->hw_inst));
|
||||
}
|
||||
|
||||
static u8 pci1xxxx_get_clock_div(u32 hz)
|
||||
@ -199,8 +196,9 @@ static int pci1xxxx_spi_transfer_one(struct spi_controller *spi_ctlr,
|
||||
else
|
||||
regval &= ~SPI_MST_CTL_MODE_SEL;
|
||||
|
||||
regval |= ((clkdiv << 5) | SPI_FORCE_CE | (len << 8));
|
||||
regval |= (clkdiv << 5);
|
||||
regval &= ~SPI_MST_CTL_CMD_LEN_MASK;
|
||||
regval |= (len << 8);
|
||||
writel(regval, par->reg_base +
|
||||
SPI_MST_CTL_REG_OFFSET(p->hw_inst));
|
||||
regval = readl(par->reg_base +
|
||||
@ -222,10 +220,6 @@ static int pci1xxxx_spi_transfer_one(struct spi_controller *spi_ctlr,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
regval = readl(par->reg_base + SPI_MST_CTL_REG_OFFSET(p->hw_inst));
|
||||
regval &= ~SPI_FORCE_CE;
|
||||
writel(regval, par->reg_base + SPI_MST_CTL_REG_OFFSET(p->hw_inst));
|
||||
p->spi_xfer_in_progress = false;
|
||||
|
||||
return 0;
|
||||
|
@ -267,7 +267,7 @@ static int pic32_sqi_one_transfer(struct pic32_sqi *sqi,
|
||||
u32 nbits;
|
||||
|
||||
/* Device selection */
|
||||
bd_ctrl = spi->chip_select << BD_DEVSEL_SHIFT;
|
||||
bd_ctrl = spi_get_chipselect(spi, 0) << BD_DEVSEL_SHIFT;
|
||||
|
||||
/* half-duplex: select transfer buffer, direction and lane */
|
||||
if (xfer->rx_buf) {
|
||||
@ -678,7 +678,7 @@ err_free_master:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pic32_sqi_remove(struct platform_device *pdev)
|
||||
static void pic32_sqi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct pic32_sqi *sqi = platform_get_drvdata(pdev);
|
||||
|
||||
@ -689,8 +689,6 @@ static int pic32_sqi_remove(struct platform_device *pdev)
|
||||
/* disable clk */
|
||||
clk_disable_unprepare(sqi->base_clk);
|
||||
clk_disable_unprepare(sqi->sys_clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id pic32_sqi_of_ids[] = {
|
||||
@ -705,7 +703,7 @@ static struct platform_driver pic32_sqi_driver = {
|
||||
.of_match_table = of_match_ptr(pic32_sqi_of_ids),
|
||||
},
|
||||
.probe = pic32_sqi_probe,
|
||||
.remove = pic32_sqi_remove,
|
||||
.remove_new = pic32_sqi_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(pic32_sqi_driver);
|
||||
|
@ -591,7 +591,7 @@ static int pic32_spi_setup(struct spi_device *spi)
|
||||
* unreliable/erroneous SPI transactions.
|
||||
* To avoid that we will always handle /CS by toggling GPIO.
|
||||
*/
|
||||
if (!spi->cs_gpiod)
|
||||
if (!spi_get_csgpiod(spi, 0))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
@ -600,7 +600,7 @@ static int pic32_spi_setup(struct spi_device *spi)
|
||||
static void pic32_spi_cleanup(struct spi_device *spi)
|
||||
{
|
||||
/* de-activate cs-gpio, gpiolib will handle inversion */
|
||||
gpiod_direction_output(spi->cs_gpiod, 0);
|
||||
gpiod_direction_output(spi_get_csgpiod(spi, 0), 0);
|
||||
}
|
||||
|
||||
static int pic32_spi_dma_prep(struct pic32_spi *pic32s, struct device *dev)
|
||||
@ -710,8 +710,7 @@ static int pic32_spi_hw_probe(struct platform_device *pdev,
|
||||
struct resource *mem;
|
||||
int ret;
|
||||
|
||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
pic32s->regs = devm_ioremap_resource(&pdev->dev, mem);
|
||||
pic32s->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
|
||||
if (IS_ERR(pic32s->regs))
|
||||
return PTR_ERR(pic32s->regs);
|
||||
|
||||
@ -844,7 +843,7 @@ err_master:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pic32_spi_remove(struct platform_device *pdev)
|
||||
static void pic32_spi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct pic32_spi *pic32s;
|
||||
|
||||
@ -852,8 +851,6 @@ static int pic32_spi_remove(struct platform_device *pdev)
|
||||
pic32_spi_disable(pic32s);
|
||||
clk_disable_unprepare(pic32s->clk);
|
||||
pic32_spi_dma_unprep(pic32s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id pic32_spi_of_match[] = {
|
||||
@ -868,7 +865,7 @@ static struct platform_driver pic32_spi_driver = {
|
||||
.of_match_table = of_match_ptr(pic32_spi_of_match),
|
||||
},
|
||||
.probe = pic32_spi_probe,
|
||||
.remove = pic32_spi_remove,
|
||||
.remove_new = pic32_spi_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(pic32_spi_driver);
|
||||
|
@ -1587,9 +1587,9 @@ static int pl022_transfer_one_message(struct spi_master *master,
|
||||
|
||||
/* Setup the SPI using the per chip configuration */
|
||||
pl022->cur_chip = spi_get_ctldata(msg->spi);
|
||||
pl022->cur_cs = msg->spi->chip_select;
|
||||
pl022->cur_cs = spi_get_chipselect(msg->spi, 0);
|
||||
/* This is always available but may be set to -ENOENT */
|
||||
pl022->cur_gpiod = msg->spi->cs_gpiod;
|
||||
pl022->cur_gpiod = spi_get_csgpiod(msg->spi, 0);
|
||||
|
||||
restore_state(pl022);
|
||||
flush(pl022);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user