diff options
149 files changed, 1845 insertions, 1288 deletions
diff --git a/Documentation/devicetree/bindings/spi/amlogic,a1-spifc.yaml b/Documentation/devicetree/bindings/spi/amlogic,a1-spifc.yaml new file mode 100644 index 000000000000..ea47d30eef43 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/amlogic,a1-spifc.yaml @@ -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>; + }; diff --git a/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml b/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml index 5c01db128be0..b310069762dd 100644 --- a/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml +++ b/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml @@ -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 diff --git a/Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml b/Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml index 491a695a2deb..00acbbb0f65d 100644 --- a/Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml +++ b/Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml @@ -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>; }; diff --git a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml index a132b5fc56e0..12ca108864c6 100644 --- a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml +++ b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml @@ -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 diff --git a/Documentation/spi/spi-summary.rst b/Documentation/spi/spi-summary.rst index 3c95ae322fb1..33f05901ccf3 100644 --- a/Documentation/spi/spi-summary.rst +++ b/Documentation/spi/spi-summary.rst @@ -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? diff --git a/MAINTAINERS b/MAINTAINERS index b5169b19449a..a5901cbf781a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -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 diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c index caa96edf0e72..4ab1d48cd229 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c @@ -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); } diff --git a/drivers/iio/imu/adis16400.c b/drivers/iio/imu/adis16400.c index c02fc35dceb4..3eda32e12a53 100644 --- a/drivers/iio/imu/adis16400.c +++ b/drivers/iio/imu/adis16400.c @@ -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) { diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index 3bbaa590c768..1d3b2a94581f 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c @@ -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; diff --git a/drivers/net/ethernet/adi/adin1110.c b/drivers/net/ethernet/adi/adin1110.c index 3f316a0f4158..f5c2d7a9abc1 100644 --- a/drivers/net/ethernet/adi/adin1110.c +++ b/drivers/net/ethernet/adi/adin1110.c @@ -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; diff --git a/drivers/net/ethernet/asix/ax88796c_main.c b/drivers/net/ethernet/asix/ax88796c_main.c index 21376c79f671..e551ffaed20d 100644 --- a/drivers/net/ethernet/asix/ax88796c_main.c +++ b/drivers/net/ethernet/asix/ax88796c_main.c @@ -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) { diff --git a/drivers/net/ethernet/davicom/dm9051.c b/drivers/net/ethernet/davicom/dm9051.c index de7105a84747..70728b2e5f18 100644 --- a/drivers/net/ethernet/davicom/dm9051.c +++ b/drivers/net/ethernet/davicom/dm9051.c @@ -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) diff --git a/drivers/net/ethernet/qualcomm/qca_debug.c b/drivers/net/ethernet/qualcomm/qca_debug.c index f62c39544e08..6f2fa2a42770 100644 --- a/drivers/net/ethernet/qualcomm/qca_debug.c +++ b/drivers/net/ethernet/qualcomm/qca_debug.c @@ -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", diff --git a/drivers/net/ieee802154/ca8210.c b/drivers/net/ieee802154/ca8210.c index cf12d71e9411..0134ebac227a 100644 --- a/drivers/net/ieee802154/ca8210.c +++ b/drivers/net/ieee802154/ca8210.c @@ -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( diff --git a/drivers/net/wan/slic_ds26522.c b/drivers/net/wan/slic_ds26522.c index 6063552cea9b..8a51cfcff99e 100644 --- a/drivers/net/wan/slic_ds26522.c +++ b/drivers/net/wan/slic_ds26522.c @@ -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; } diff --git a/drivers/net/wireless/marvell/libertas/if_spi.c b/drivers/net/wireless/marvell/libertas/if_spi.c index ff1c7ec8c450..1225fc0e3352 100644 --- a/drivers/net/wireless/marvell/libertas/if_spi.c +++ b/drivers/net/wireless/marvell/libertas/if_spi.c @@ -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) diff --git a/drivers/net/wireless/silabs/wfx/bus_spi.c b/drivers/net/wireless/silabs/wfx/bus_spi.c index 7fb1afb8ed31..160b90114aad 100644 --- a/drivers/net/wireless/silabs/wfx/bus_spi.c +++ b/drivers/net/wireless/silabs/wfx/bus_spi.c @@ -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) diff --git a/drivers/net/wireless/st/cw1200/cw1200_spi.c b/drivers/net/wireless/st/cw1200/cw1200_spi.c index fe0d220da44d..c82c0688b549 100644 --- a/drivers/net/wireless/st/cw1200/cw1200_spi.c +++ b/drivers/net/wireless/st/cw1200/cw1200_spi.c @@ -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)) { diff --git a/drivers/platform/x86/serial-multi-instantiate.c b/drivers/platform/x86/serial-multi-instantiate.c index cd25125b7923..f3dcbdd72fec 100644 --- a/drivers/platform/x86/serial-multi-instantiate.c +++ b/drivers/platform/x86/serial-multi-instantiate.c @@ -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++; diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 47bbba04fe3a..3de2ebe8294a 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -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. diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index d87cf75bee6a..28c4817a8a74 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -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 diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c index f4632cb07495..3d1252566134 100644 --- a/drivers/spi/atmel-quadspi.c +++ b/drivers/spi/atmel-quadspi.c @@ -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); diff --git a/drivers/spi/spi-altera-core.c b/drivers/spi/spi-altera-core.c index 94fe6bf1b9a6..87e37f48f196 100644 --- a/drivers/spi/spi-altera-core.c +++ b/drivers/spi/spi-altera-core.c @@ -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); } diff --git a/drivers/spi/spi-amd.c b/drivers/spi/spi-amd.c index bfc3ab5f39ea..fecead757a3c 100644 --- a/drivers/spi/spi-amd.c +++ b/drivers/spi/spi-amd.c @@ -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 diff --git a/drivers/spi/spi-amlogic-spifc-a1.c b/drivers/spi/spi-amlogic-spifc-a1.c new file mode 100644 index 000000000000..3c4224c38399 --- /dev/null +++ b/drivers/spi/spi-amlogic-spifc-a1.c @@ -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"); diff --git a/drivers/spi/spi-ar934x.c b/drivers/spi/spi-ar934x.c index 4a6ecaa0a9c9..9dcada8c4cb9 100644 --- a/drivers/spi/spi-ar934x.c +++ b/drivers/spi/spi-ar934x.c @@ -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); diff --git a/drivers/spi/spi-armada-3700.c b/drivers/spi/spi-armada-3700.c index 4d554b948d71..a7fb7c94e70e 100644 --- a/drivers/spi/spi-armada-3700.c +++ b/drivers/spi/spi-armada-3700.c @@ -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); diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c index 873ff2cf72c9..e75b0d51f06a 100644 --- a/drivers/spi/spi-aspeed-smc.c +++ b/drivers/spi/spi-aspeed-smc.c @@ -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, diff --git a/drivers/spi/spi-at91-usart.c b/drivers/spi/spi-at91-usart.c index fab9d223e24a..7854d9790fe9 100644 --- a/drivers/spi/spi-at91-usart.c +++ b/drivers/spi/spi-at91-usart.c @@ -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); diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c index 795e88dbef1b..d3dd21386f12 100644 --- a/drivers/spi/spi-ath79.c +++ b/drivers/spi/spi-ath79.c @@ -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, diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 5c5678f065f3..7f06305e16cb 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -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); diff --git a/drivers/spi/spi-au1550.c b/drivers/spi/spi-au1550.c index e008761298da..0b57e6afce0f 100644 --- a/drivers/spi/spi-au1550.c +++ b/drivers/spi/spi-au1550.c @@ -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", }, diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c index 80c3e38f5c1b..89661f3b0d44 100644 --- a/drivers/spi/spi-axi-spi-engine.c +++ b/drivers/spi/spi-axi-spi-engine.c @@ -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, diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c index 0eee574d3e1f..6b46a3b67c41 100644 --- a/drivers/spi/spi-bcm-qspi.c +++ b/drivers/spi/spi-bcm-qspi.c @@ -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, diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index 747e03228c48..3b253da98c05 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -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); diff --git a/drivers/spi/spi-bcm2835aux.c b/drivers/spi/spi-bcm2835aux.c index e28521922330..288f7b994b36 100644 --- a/drivers/spi/spi-bcm2835aux.c +++ b/drivers/spi/spi-bcm2835aux.c @@ -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); diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c index cd0a6478f5e7..ee2528dad02d 100644 --- a/drivers/spi/spi-bcm63xx-hsspi.c +++ b/drivers/spi/spi-bcm63xx-hsspi.c @@ -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); diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 3686d78c44a6..9aecb77c3d89 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -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); diff --git a/drivers/spi/spi-bcmbca-hsspi.c b/drivers/spi/spi-bcmbca-hsspi.c index 3f9e6131ad86..8cbd01619789 100644 --- a/drivers/spi/spi-bcmbca-hsspi.c +++ b/drivers/spi/spi-bcmbca-hsspi.c @@ -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); diff --git a/drivers/spi/spi-brcmstb-qspi.c b/drivers/spi/spi-brcmstb-qspi.c index de362b35718f..e1b137419f5c 100644 --- a/drivers/spi/spi-brcmstb-qspi.c +++ b/drivers/spi/spi-brcmstb-qspi.c @@ -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, diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 64b6a460d739..6ddb2dfc0f00 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -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); -static const struct dev_pm_ops cqspi__dev_pm_ops = { - .suspend = cqspi_suspend, - .resume = cqspi_resume, -}; + cqspi->current_cs = -1; + cqspi->sclk = 0; + + return spi_master_resume(master); +} -#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, }, }; diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c index 91db3c973167..ce4a3145f065 100644 --- a/drivers/spi/spi-cadence-xspi.c +++ b/drivers/spi/spi-cadence-xspi.c @@ -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)); diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c index 6a7f7df1e776..ac85d5562212 100644 --- a/drivers/spi/spi-cadence.c +++ b/drivers/spi/spi-cadence.c @@ -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); @@ -325,6 +329,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 * @dev_id: Pointer to the xspi structure @@ -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; - - trans_cnt = xspi->rx_bytes - xspi->tx_bytes; + 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); - /* Read out the data from the RX FIFO */ while (trans_cnt) { - u8 data; - - data = cdns_spi_read(xspi, CDNS_SPI_RXD); - if (xspi->rxbuf) - *xspi->rxbuf++ = data; - - xspi->rx_bytes--; + cdns_spi_read_rx_fifo(xspi, 1); + + 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; } @@ -487,6 +535,27 @@ static void cdns_spi_detect_fifo_depth(struct cdns_spi *xspi) } /** + * 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; + } - 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 = clk_prepare_enable(xspi->ref_clk); + if (ret) { + dev_err(&pdev->dev, "Unable to enable device clock.\n"); + goto clk_dis_apb; + } - 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; + 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; + 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; - - 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); + 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); + + 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, diff --git a/drivers/spi/spi-cavium-octeon.c b/drivers/spi/spi-cavium-octeon.c index 1a2de6ce9064..58060be33106 100644 --- a/drivers/spi/spi-cavium-octeon.c +++ b/drivers/spi/spi-cavium-octeon.c @@ -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); diff --git a/drivers/spi/spi-cavium.c b/drivers/spi/spi-cavium.c index 6854c3ce423b..dfe224defd6e 100644 --- a/drivers/spi/spi-cavium.c +++ b/drivers/spi/spi-cavium.c @@ -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 diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c index 263ce9047327..b1bd8a6b5bf9 100644 --- a/drivers/spi/spi-coldfire-qspi.c +++ b/drivers/spi/spi-coldfire-qspi.c @@ -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); diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index d112c2cac042..b04811c911e2 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -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); diff --git a/drivers/spi/spi-dln2.c b/drivers/spi/spi-dln2.c index 0a1fb2bc9e54..6bd93c47853c 100644 --- a/drivers/spi/spi-dln2.c +++ b/drivers/spi/spi-dln2.c @@ -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); diff --git a/drivers/spi/spi-dw-bt1.c b/drivers/spi/spi-dw-bt1.c index 3fb89dee595e..5e1c01822967 100644 --- a/drivers/spi/spi-dw-bt1.c +++ b/drivers/spi/spi-dw-bt1.c @@ -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, diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index c3bfb6c84cab..ae3108c70f50 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -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); } diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c index 26c40ea6dd12..5e6faa98aa85 100644 --- a/drivers/spi/spi-dw-mmio.c +++ b/drivers/spi/spi-dw-mmio.c @@ -54,6 +54,20 @@ struct dw_spi_mscc { }; /* + * 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 * selects then needs to be either driven as GPIOs or, for the first 4 using @@ -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, diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index 5896a7b2fade..1615fd22f9a2 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c @@ -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); diff --git a/drivers/spi/spi-falcon.c b/drivers/spi/spi-falcon.c index a7d4dffac66b..4c103dff0d44 100644 --- a/drivers/spi/spi-falcon.c +++ b/drivers/spi/spi-falcon.c @@ -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; diff --git a/drivers/spi/spi-fsi.c b/drivers/spi/spi-fsi.c index cf1e4f9ebd72..ba3b17d7c9ec 100644 --- a/drivers/spi/spi-fsi.c +++ b/drivers/spi/spi-fsi.c @@ -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); diff --git a/drivers/spi/spi-fsl-cpm.c b/drivers/spi/spi-fsl-cpm.c index 17a44d4f5021..38452089e8f3 100644 --- a/drivers/spi/spi-fsl-cpm.c +++ b/drivers/spi/spi-fsl-cpm.c @@ -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); diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index e419642eb10e..4339485d202c 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -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); diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index f7066bef7b06..b3d2d3db5850 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c @@ -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); diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c index 34488de55587..f2341ab99556 100644 --- a/drivers/spi/spi-fsl-lpspi.c +++ b/drivers/spi/spi-fsl-lpspi.c @@ -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); diff --git a/drivers/spi/spi-fsl-qspi.c b/drivers/spi/spi-fsl-qspi.c index 85cc71ba624a..8ade61e5ebc0 100644 --- a/drivers/spi/spi-fsl-qspi.c +++ b/drivers/spi/spi-fsl-qspi.c @@ -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); diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index 93152144fd2e..106fe60a0a50 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -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", }, diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c index babb039bcb43..ba7be505ec4e 100644 --- a/drivers/spi/spi-geni-qcom.c +++ b/drivers/spi/spi-geni-qcom.c @@ -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, diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c index 9c8c7948044e..092afc7679d4 100644 --- a/drivers/spi/spi-gpio.c +++ b/drivers/spi/spi-gpio.c @@ -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)); diff --git a/drivers/spi/spi-gxp.c b/drivers/spi/spi-gxp.c index c900c2f39b57..684d63f402f3 100644 --- a/drivers/spi/spi-gxp.c +++ b/drivers/spi/spi-gxp.c @@ -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; diff --git a/drivers/spi/spi-hisi-kunpeng.c b/drivers/spi/spi-hisi-kunpeng.c index 525cc0143a30..524eadbef87b 100644 --- a/drivers/spi/spi-hisi-kunpeng.c +++ b/drivers/spi/spi-hisi-kunpeng.c @@ -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, diff --git a/drivers/spi/spi-hisi-sfc-v3xx.c b/drivers/spi/spi-hisi-sfc-v3xx.c index f07d1045a30a..7cbcb065bb44 100644 --- a/drivers/spi/spi-hisi-sfc-v3xx.c +++ b/drivers/spi/spi-hisi-sfc-v3xx.c @@ -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); diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c index 257046f843ff..d775f87770e3 100644 --- a/drivers/spi/spi-img-spfi.c +++ b/drivers/spi/spi-img-spfi.c @@ -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); diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index e4ccd0c329d0..34e5f81ec431 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -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); diff --git a/drivers/spi/spi-ingenic.c b/drivers/spi/spi-ingenic.c index 713a238bee63..7d4b515a160d 100644 --- a/drivers/spi/spi-ingenic.c +++ b/drivers/spi/spi-ingenic.c @@ -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) diff --git a/drivers/spi/spi-intel-pci.c b/drivers/spi/spi-intel-pci.c index 4d69e320d018..a7381e774b95 100644 --- a/drivers/spi/spi-intel-pci.c +++ b/drivers/spi/spi-intel-pci.c @@ -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); diff --git a/drivers/spi/spi-intel.c b/drivers/spi/spi-intel.c index f4679868c49f..bc6d22149e7e 100644 --- a/drivers/spi/spi-intel.c +++ b/drivers/spi/spi-intel.c @@ -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, diff --git a/drivers/spi/spi-iproc-qspi.c b/drivers/spi/spi-iproc-qspi.c index 91cf8eb7213c..5980a0dbbccb 100644 --- a/drivers/spi/spi-iproc-qspi.c +++ b/drivers/spi/spi-iproc-qspi.c @@ -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, diff --git a/drivers/spi/spi-jcore.c b/drivers/spi/spi-jcore.c index 74c8319c29f1..c42a3358e8c9 100644 --- a/drivers/spi/spi-jcore.c +++ b/drivers/spi/spi-jcore.c @@ -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; diff --git a/drivers/spi/spi-lantiq-ssc.c b/drivers/spi/spi-lantiq-ssc.c index aae26f62ea87..8d6ecc5d6f70 100644 --- a/drivers/spi/spi-lantiq-ssc.c +++ b/drivers/spi/spi-lantiq-ssc.c @@ -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, diff --git a/drivers/spi/spi-loopback-test.c b/drivers/spi/spi-loopback-test.c index 313106eb8d40..675a73cf1579 100644 --- a/drivers/spi/spi-loopback-test.c +++ b/drivers/spi/spi-loopback-test.c @@ -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 */ diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index 701838b6f0c4..edd7430d4c05 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -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; diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c index d47f2623a60f..141562c882f1 100644 --- a/drivers/spi/spi-meson-spicc.c +++ b/drivers/spi/spi-meson-spicc.c @@ -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), diff --git a/drivers/spi/spi-meson-spifc.c b/drivers/spi/spi-meson-spifc.c index c8ed7815c4ba..06626f406f68 100644 --- a/drivers/spi/spi-meson-spifc.c +++ b/drivers/spi/spi-meson-spifc.c @@ -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), diff --git a/drivers/spi/spi-microchip-core-qspi.c b/drivers/spi/spi-microchip-core-qspi.c index 19a6a46829f6..4f76ddf97b10 100644 --- a/drivers/spi/spi-microchip-core-qspi.c +++ b/drivers/spi/spi-microchip-core-qspi.c @@ -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); diff --git a/drivers/spi/spi-microchip-core.c b/drivers/spi/spi-microchip-core.c index aeaa1da88f39..b59e8a0c5b97 100644 --- a/drivers/spi/spi-microchip-core.c +++ b/drivers/spi/spi-microchip-core.c @@ -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"); diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index 03630359ce70..99aeef28a477 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -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; - - 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; - 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, diff --git a/drivers/spi/spi-mpc52xx-psc.c b/drivers/spi/spi-mpc52xx-psc.c index 609311231e64..9a1a080fb688 100644 --- a/drivers/spi/spi-mpc52xx-psc.c +++ b/drivers/spi/spi-mpc52xx-psc.c @@ -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; - } - - init_completion(&mps->done); - - ret = spi_register_master(master); if (ret < 0) - goto free_irq; + return dev_err_probe(dev, ret, "can't configure PSC! Is it capable of SPI?\n"); - 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); + init_completion(&mps->done); - 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, diff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c index 7b64e64c65cf..ab7df5f64342 100644 --- a/drivers/spi/spi-mpc52xx.c +++ b/drivers/spi/spi-mpc52xx.c @@ -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); diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c index 9eab6c20dbc5..21c321f43766 100644 --- a/drivers/spi/spi-mt65xx.c +++ b/drivers/spi/spi-mt65xx.c @@ -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; } diff --git a/drivers/spi/spi-mt7621.c b/drivers/spi/spi-mt7621.c index c4cc8e2f85e2..3e9d396b33bd 100644 --- a/drivers/spi/spi-mt7621.c +++ b/drivers/spi/spi-mt7621.c @@ -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; diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c index aad92a58c4b8..baa7a5353987 100644 --- a/drivers/spi/spi-mtk-nor.c +++ b/drivers/spi/spi-mtk-nor.c @@ -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); diff --git a/drivers/spi/spi-mtk-snfi.c b/drivers/spi/spi-mtk-snfi.c index f3f95eb37365..bed8317cd205 100644 --- a/drivers/spi/spi-mtk-snfi.c +++ b/drivers/spi/spi-mtk-snfi.c @@ -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, diff --git a/drivers/spi/spi-mux.c b/drivers/spi/spi-mux.c index 0709e987bd5a..fa8c1f740c70 100644 --- a/drivers/spi/spi-mux.c +++ b/drivers/spi/spi-mux.c @@ -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; } diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c index a3dba17390eb..00617fd4b2c3 100644 --- a/drivers/spi/spi-mxic.c +++ b/drivers/spi/spi-mxic.c @@ -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, diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c index 55178579f3c6..963a53dd680b 100644 --- a/drivers/spi/spi-mxs.c +++ b/drivers/spi/spi-mxs.c @@ -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, diff --git a/drivers/spi/spi-npcm-fiu.c b/drivers/spi/spi-npcm-fiu.c index 559d3a5b4062..eb353561509a 100644 --- a/drivers/spi/spi-npcm-fiu.c +++ b/drivers/spi/spi-npcm-fiu.c @@ -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); diff --git a/drivers/spi/spi-npcm-pspi.c b/drivers/spi/spi-npcm-pspi.c index 7f2e4d1b0d43..64585c2a25c5 100644 --- a/drivers/spi/spi-npcm-pspi.c +++ b/drivers/spi/spi-npcm-pspi.c @@ -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); diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c index 1c1991a26c15..544017655787 100644 --- a/drivers/spi/spi-nxp-fspi.c +++ b/drivers/spi/spi-nxp-fspi.c @@ -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); diff --git a/drivers/spi/spi-oc-tiny.c b/drivers/spi/spi-oc-tiny.c index 38c14c4e4e21..3af499838e84 100644 --- a/drivers/spi/spi-oc-tiny.c +++ b/drivers/spi/spi-oc-tiny.c @@ -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, diff --git a/drivers/spi/spi-omap-uwire.c b/drivers/spi/spi-omap-uwire.c index 20c87163d612..902d2e0c1f2f 100644 --- a/drivers/spi/spi-omap-uwire.c +++ b/drivers/spi/spi-omap-uwire.c @@ -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 }; diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 6ba9b0d7710b..8331e247bf5c 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -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); diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index 565cd4c48d7b..ad9e83e34297 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c @@ -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); diff --git a/drivers/spi/spi-pci1xxxx.c b/drivers/spi/spi-pci1xxxx.c index a31c3b612a43..4445d82409d6 100644 --- a/drivers/spi/spi-pci1xxxx.c +++ b/drivers/spi/spi-pci1xxxx.c @@ -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; diff --git a/drivers/spi/spi-pic32-sqi.c b/drivers/spi/spi-pic32-sqi.c index 86ad17597f5f..51dfb49523f3 100644 --- a/drivers/spi/spi-pic32-sqi.c +++ b/drivers/spi/spi-pic32-sqi.c @@ -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); diff --git a/drivers/spi/spi-pic32.c b/drivers/spi/spi-pic32.c index 7e5c09a7d489..f2af5e653f3d 100644 --- a/drivers/spi/spi-pic32.c +++ b/drivers/spi/spi-pic32.c @@ -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); diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index a17ff839117f..982407bc5d9f 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -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); diff --git a/drivers/spi/spi-ppc4xx.c b/drivers/spi/spi-ppc4xx.c index d65f047b6c82..d725e915025d 100644 --- a/drivers/spi/spi-ppc4xx.c +++ b/drivers/spi/spi-ppc4xx.c @@ -464,7 +464,7 @@ free_master: return ret; } -static int spi_ppc4xx_of_remove(struct platform_device *op) +static void spi_ppc4xx_of_remove(struct platform_device *op) { struct spi_master *master = platform_get_drvdata(op); struct ppc4xx_spi *hw = spi_master_get_devdata(master); @@ -474,7 +474,6 @@ static int spi_ppc4xx_of_remove(struct platform_device *op) free_irq(hw->irqnum, hw); iounmap(hw->regs); spi_master_put(master); - return 0; } static const struct of_device_id spi_ppc4xx_of_match[] = { @@ -486,7 +485,7 @@ MODULE_DEVICE_TABLE(of, spi_ppc4xx_of_match); static struct platform_driver spi_ppc4xx_of_driver = { .probe = spi_ppc4xx_of_probe, - .remove = spi_ppc4xx_of_remove, + .remove_new = spi_ppc4xx_of_remove, .driver = { .name = DRIVER_NAME, .of_match_table = spi_ppc4xx_of_match, diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 32cc82a89ec1..1bab18a0f262 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -368,7 +368,7 @@ static void lpss_ssp_select_cs(struct spi_device *spi, value = __lpss_ssp_read_priv(drv_data, config->reg_cs_ctrl); - cs = spi->chip_select; + cs = spi_get_chipselect(spi, 0); cs <<= config->cs_sel_shift; if (cs != (value & config->cs_sel_mask)) { /* @@ -429,7 +429,7 @@ static void cs_assert(struct spi_device *spi) spi_controller_get_devdata(spi->controller); if (drv_data->ssp_type == CE4100_SSP) { - pxa2xx_spi_write(drv_data, SSSR, spi->chip_select); + pxa2xx_spi_write(drv_data, SSSR, spi_get_chipselect(spi, 0)); return; } @@ -1217,7 +1217,7 @@ static int setup(struct spi_device *spi) return -ENOMEM; if (drv_data->ssp_type == CE4100_SSP) { - if (spi->chip_select > 4) { + if (spi_get_chipselect(spi, 0) > 4) { dev_err(&spi->dev, "failed setup: cs number must not be > 4.\n"); kfree(chip); @@ -1659,7 +1659,7 @@ out_error_controller_alloc: return status; } -static int pxa2xx_spi_remove(struct platform_device *pdev) +static void pxa2xx_spi_remove(struct platform_device *pdev) { struct driver_data *drv_data = platform_get_drvdata(pdev); struct ssp_device *ssp = drv_data->ssp; @@ -1684,8 +1684,6 @@ static int pxa2xx_spi_remove(struct platform_device *pdev) /* Release SSP */ pxa_ssp_free(ssp); - - return 0; } static int pxa2xx_spi_suspend(struct device *dev) @@ -1756,7 +1754,7 @@ static const struct acpi_device_id pxa2xx_spi_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, pxa2xx_spi_acpi_match); #endif -static const struct of_device_id pxa2xx_spi_of_match[] = { +static const struct of_device_id pxa2xx_spi_of_match[] __maybe_unused = { { .compatible = "marvell,mmp2-ssp", .data = (void *)MMP2_SSP }, {} }; @@ -1770,7 +1768,7 @@ static struct platform_driver driver = { .of_match_table = of_match_ptr(pxa2xx_spi_of_match), }, .probe = pxa2xx_spi_probe, - .remove = pxa2xx_spi_remove, + .remove_new = pxa2xx_spi_remove, }; static int __init pxa2xx_spi_init(void) diff --git a/drivers/spi/spi-qcom-qspi.c b/drivers/spi/spi-qcom-qspi.c index c334dfec4117..fab155389999 100644 --- a/drivers/spi/spi-qcom-qspi.c +++ b/drivers/spi/spi-qcom-qspi.c @@ -8,6 +8,7 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/of_platform.h> +#include <linux/pinctrl/consumer.h> #include <linux/pm_runtime.h> #include <linux/pm_opp.h> #include <linux/spi/spi.h> @@ -311,7 +312,7 @@ static int qcom_qspi_prepare_message(struct spi_master *master, mstr_cfg = readl(ctrl->base + MSTR_CONFIG); mstr_cfg &= ~CHIP_SELECT_NUM; - if (message->spi->chip_select) + if (spi_get_chipselect(message->spi, 0)) mstr_cfg |= CHIP_SELECT_NUM; mstr_cfg |= FB_CLK_EN | PIN_WPN | PIN_HOLDN | SBL_EN | FULL_CYCLE_MODE; @@ -552,7 +553,7 @@ static int qcom_qspi_probe(struct platform_device *pdev) return ret; } -static int qcom_qspi_remove(struct platform_device *pdev) +static void qcom_qspi_remove(struct platform_device *pdev) { struct spi_master *master = platform_get_drvdata(pdev); @@ -560,8 +561,6 @@ static int qcom_qspi_remove(struct platform_device *pdev) spi_unregister_master(master); pm_runtime_disable(&pdev->dev); - - return 0; } static int __maybe_unused qcom_qspi_runtime_suspend(struct device *dev) @@ -581,6 +580,8 @@ static int __maybe_unused qcom_qspi_runtime_suspend(struct device *dev) return ret; } + pinctrl_pm_select_sleep_state(dev); + return 0; } @@ -590,6 +591,8 @@ static int __maybe_unused qcom_qspi_runtime_resume(struct device *dev) struct qcom_qspi *ctrl = spi_master_get_devdata(master); int ret; + pinctrl_pm_select_default_state(dev); + ret = icc_enable(ctrl->icc_path_cpu_to_qspi); if (ret) { dev_err_ratelimited(ctrl->dev, "%s: ICC enable failed for cpu: %d\n", @@ -655,7 +658,7 @@ static struct platform_driver qcom_qspi_driver = { .of_match_table = qcom_qspi_dt_match, }, .probe = qcom_qspi_probe, - .remove = qcom_qspi_remove, + .remove_new = qcom_qspi_remove, }; module_platform_driver(qcom_qspi_driver); diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c index 678dc51ef017..944ef6b42bce 100644 --- a/drivers/spi/spi-qup.c +++ b/drivers/spi/spi-qup.c @@ -1003,8 +1003,7 @@ static int spi_qup_probe(struct platform_device *pdev) int ret, irq, size; dev = &pdev->dev; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(dev, res); + base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(base)) return PTR_ERR(base); @@ -1271,29 +1270,31 @@ disable_clk: } #endif /* CONFIG_PM_SLEEP */ -static int spi_qup_remove(struct platform_device *pdev) +static void spi_qup_remove(struct platform_device *pdev) { struct spi_master *master = dev_get_drvdata(&pdev->dev); struct spi_qup *controller = spi_master_get_devdata(master); int ret; - ret = pm_runtime_resume_and_get(&pdev->dev); - if (ret < 0) - return ret; + ret = pm_runtime_get_sync(&pdev->dev); - ret = spi_qup_set_state(controller, QUP_STATE_RESET); - if (ret) - return ret; + if (ret >= 0) { + ret = spi_qup_set_state(controller, QUP_STATE_RESET); + if (ret) + dev_warn(&pdev->dev, "failed to reset controller (%pe)\n", + ERR_PTR(ret)); - spi_qup_release_dma(master); + clk_disable_unprepare(controller->cclk); + clk_disable_unprepare(controller->iclk); + } else { + dev_warn(&pdev->dev, "failed to resume, skip hw disable (%pe)\n", + ERR_PTR(ret)); + } - clk_disable_unprepare(controller->cclk); - clk_disable_unprepare(controller->iclk); + spi_qup_release_dma(master); pm_runtime_put_noidle(&pdev->dev); pm_runtime_disable(&pdev->dev); - - return 0; } static const struct of_device_id spi_qup_dt_match[] = { @@ -1318,7 +1319,7 @@ static struct platform_driver spi_qup_driver = { .of_match_table = spi_qup_dt_match, }, .probe = spi_qup_probe, - .remove = spi_qup_remove, + .remove_new = spi_qup_remove, }; module_platform_driver(spi_qup_driver); diff --git a/drivers/spi/spi-rb4xx.c b/drivers/spi/spi-rb4xx.c index 9f97d18a05c1..5073736d3d1f 100644 --- a/drivers/spi/spi-rb4xx.c +++ b/drivers/spi/spi-rb4xx.c @@ -107,7 +107,7 @@ static int rb4xx_transfer_one(struct spi_master *master, * command set was designed to almost not clash with that of the * boot flash. */ - if (spi->chip_select == 2) + if (spi_get_chipselect(spi, 0) == 2) /* MMC */ spi_ioc = AR71XX_SPI_IOC_CS0; else @@ -181,13 +181,11 @@ static int rb4xx_spi_probe(struct platform_device *pdev) return 0; } -static int rb4xx_spi_remove(struct platform_device *pdev) +static void rb4xx_spi_remove(struct platform_device *pdev) { struct rb4xx_spi *rbspi = platform_get_drvdata(pdev); clk_disable_unprepare(rbspi->clk); - - return 0; } static const struct of_device_id rb4xx_spi_dt_match[] = { @@ -198,7 +196,7 @@ MODULE_DEVICE_TABLE(of, rb4xx_spi_dt_match); static struct platform_driver rb4xx_spi_drv = { .probe = rb4xx_spi_probe, - .remove = rb4xx_spi_remove, + .remove_new = rb4xx_spi_remove, .driver = { .name = "rb4xx-spi", .of_match_table = of_match_ptr(rb4xx_spi_dt_match), diff --git a/drivers/spi/spi-rockchip-sfc.c b/drivers/spi/spi-rockchip-sfc.c index 69347b6bf60c..583f4187f030 100644 --- a/drivers/spi/spi-rockchip-sfc.c +++ b/drivers/spi/spi-rockchip-sfc.c @@ -346,7 +346,7 @@ static int rockchip_sfc_xfer_setup(struct rockchip_sfc *sfc, /* set the Controller */ ctrl |= SFC_CTRL_PHASE_SEL_NEGETIVE; - cmd |= mem->spi->chip_select << SFC_CMD_CS_SHIFT; + cmd |= spi_get_chipselect(mem->spi, 0) << SFC_CMD_CS_SHIFT; dev_dbg(sfc->dev, "sfc addr.nbytes=%x(x%d) dummy.nbytes=%x(x%d)\n", op->addr.nbytes, op->addr.buswidth, @@ -558,7 +558,6 @@ static int rockchip_sfc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct spi_master *master; - struct resource *res; struct rockchip_sfc *sfc; int ret; @@ -576,8 +575,7 @@ static int rockchip_sfc_probe(struct platform_device *pdev) sfc = spi_master_get_devdata(master); sfc->dev = dev; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - sfc->regbase = devm_ioremap_resource(dev, res); + sfc->regbase = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(sfc->regbase)) return PTR_ERR(sfc->regbase); @@ -656,7 +654,7 @@ err_hclk: return ret; } -static int rockchip_sfc_remove(struct platform_device *pdev) +static void rockchip_sfc_remove(struct platform_device *pdev) { struct spi_master *master = platform_get_drvdata(pdev); struct rockchip_sfc *sfc = platform_get_drvdata(pdev); @@ -665,8 +663,6 @@ static int rockchip_sfc_remove(struct platform_device *pdev) clk_disable_unprepare(sfc->clk); clk_disable_unprepare(sfc->hclk); - - return 0; } static const struct of_device_id rockchip_sfc_dt_ids[] = { @@ -681,7 +677,7 @@ static struct platform_driver rockchip_sfc_driver = { .of_match_table = rockchip_sfc_dt_ids, }, .probe = rockchip_sfc_probe, - .remove = rockchip_sfc_remove, + .remove_new = rockchip_sfc_remove, }; module_platform_driver(rockchip_sfc_driver); diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c index 79242dc5272d..143ede958ac1 100644 --- a/drivers/spi/spi-rockchip.c +++ b/drivers/spi/spi-rockchip.c @@ -246,28 +246,30 @@ static void rockchip_spi_set_cs(struct spi_device *spi, bool enable) bool cs_asserted = spi->mode & SPI_CS_HIGH ? enable : !enable; /* Return immediately for no-op */ - if (cs_asserted == rs->cs_asserted[spi->chip_select]) + if (cs_asserted == rs->cs_asserted[spi_get_chipselect(spi, 0)]) return; if (cs_asserted) { /* Keep things powered as long as CS is asserted */ pm_runtime_get_sync(rs->dev); - if (spi->cs_gpiod) + if (spi_get_csgpiod(spi, 0)) ROCKCHIP_SPI_SET_BITS(rs->regs + ROCKCHIP_SPI_SER, 1); else - ROCKCHIP_SPI_SET_BITS(rs->regs + ROCKCHIP_SPI_SER, BIT(spi->chip_select)); + ROCKCHIP_SPI_SET_BITS(rs->regs + ROCKCHIP_SPI_SER, + BIT(spi_get_chipselect(spi, 0))); } else { - if (spi->cs_gpiod) + if (spi_get_csgpiod(spi, 0)) ROCKCHIP_SPI_CLR_BITS(rs->regs + ROCKCHIP_SPI_SER, 1); else - ROCKCHIP_SPI_CLR_BITS(rs->regs + ROCKCHIP_SPI_SER, BIT(spi->chip_select)); + ROCKCHIP_SPI_CLR_BITS(rs->regs + ROCKCHIP_SPI_SER, + BIT(spi_get_chipselect(spi, 0))); /* Drop reference from when we first asserted CS */ pm_runtime_put(rs->dev); } - rs->cs_asserted[spi->chip_select] = cs_asserted; + rs->cs_asserted[spi_get_chipselect(spi, 0)] = cs_asserted; } static void rockchip_spi_handle_err(struct spi_controller *ctlr, @@ -541,7 +543,7 @@ static int rockchip_spi_config(struct rockchip_spi *rs, if (spi->mode & SPI_LSB_FIRST) cr0 |= CR0_FBM_LSB << CR0_FBM_OFFSET; if (spi->mode & SPI_CS_HIGH) - cr0 |= BIT(spi->chip_select) << CR0_SOI_OFFSET; + cr0 |= BIT(spi_get_chipselect(spi, 0)) << CR0_SOI_OFFSET; if (xfer->rx_buf && xfer->tx_buf) cr0 |= CR0_XFM_TR << CR0_XFM_OFFSET; @@ -724,7 +726,7 @@ static int rockchip_spi_setup(struct spi_device *spi) struct rockchip_spi *rs = spi_controller_get_devdata(spi->controller); u32 cr0; - if (!spi->cs_gpiod && (spi->mode & SPI_CS_HIGH) && !rs->cs_high_supported) { + if (!spi_get_csgpiod(spi, 0) && (spi->mode & SPI_CS_HIGH) && !rs->cs_high_supported) { dev_warn(&spi->dev, "setup: non GPIO CS can't be active-high\n"); return -EINVAL; } @@ -735,10 +737,10 @@ static int rockchip_spi_setup(struct spi_device *spi) cr0 &= ~(0x3 << CR0_SCPH_OFFSET); cr0 |= ((spi->mode & 0x3) << CR0_SCPH_OFFSET); - if (spi->mode & SPI_CS_HIGH && spi->chip_select <= 1) - cr0 |= BIT(spi->chip_select) << CR0_SOI_OFFSET; - else if (spi->chip_select <= 1) - cr0 &= ~(BIT(spi->chip_select) << CR0_SOI_OFFSET); + if (spi->mode & SPI_CS_HIGH && spi_get_chipselect(spi, 0) <= 1) + cr0 |= BIT(spi_get_chipselect(spi, 0)) << CR0_SOI_OFFSET; + else if (spi_get_chipselect(spi, 0) <= 1) + cr0 &= ~(BIT(spi_get_chipselect(spi, 0)) << CR0_SOI_OFFSET); writel_relaxed(cr0, rs->regs + ROCKCHIP_SPI_CTRLR0); @@ -772,11 +774,9 @@ static int rockchip_spi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ctlr); rs = spi_controller_get_devdata(ctlr); - ctlr->slave = slave_mode; /* Get basic io resource and map it */ - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - rs->regs = devm_ioremap_resource(&pdev->dev, mem); + rs->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &mem); if (IS_ERR(rs->regs)) { ret = PTR_ERR(rs->regs); goto err_put_ctlr; @@ -947,7 +947,7 @@ err_put_ctlr: return ret; } -static int rockchip_spi_remove(struct platform_device *pdev) +static void rockchip_spi_remove(struct platform_device *pdev) { struct spi_controller *ctlr = spi_controller_get(platform_get_drvdata(pdev)); struct rockchip_spi *rs = spi_controller_get_devdata(ctlr); @@ -967,8 +967,6 @@ static int rockchip_spi_remove(struct platform_device *pdev) dma_release_channel(ctlr->dma_rx); spi_controller_put(ctlr); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -1076,7 +1074,7 @@ static struct platform_driver rockchip_spi_driver = { .of_match_table = of_match_ptr(rockchip_spi_dt_match), }, .probe = rockchip_spi_probe, - .remove = rockchip_spi_remove, + .remove_new = rockchip_spi_remove, }; module_platform_driver(rockchip_spi_driver); diff --git a/drivers/spi/spi-rpc-if.c b/drivers/spi/spi-rpc-if.c index ec0904faf3a1..2f78124a1b59 100644 --- a/drivers/spi/spi-rpc-if.c +++ b/drivers/spi/spi-rpc-if.c @@ -173,15 +173,13 @@ out_disable_rpm: return error; } -static int rpcif_spi_remove(struct platform_device *pdev) +static void rpcif_spi_remove(struct platform_device *pdev) { struct spi_controller *ctlr = platform_get_drvdata(pdev); struct rpcif *rpc = spi_controller_get_devdata(ctlr); spi_unregister_controller(ctlr); pm_runtime_disable(rpc->dev); - - return 0; } static int __maybe_unused rpcif_spi_suspend(struct device *dev) @@ -202,7 +200,7 @@ static SIMPLE_DEV_PM_OPS(rpcif_spi_pm_ops, rpcif_spi_suspend, rpcif_spi_resume); static struct platform_driver rpcif_spi_driver = { .probe = rpcif_spi_probe, - .remove = rpcif_spi_remove, + .remove_new = rpcif_spi_remove, .driver = { .name = "rpc-if-spi", #ifdef CONFIG_PM_SLEEP diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 411b1307b7fd..08ceebbaf69b 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -950,7 +950,7 @@ static int rspi_setup(struct spi_device *spi) struct rspi_data *rspi = spi_controller_get_devdata(spi->controller); u8 sslp; - if (spi->cs_gpiod) + if (spi_get_csgpiod(spi, 0)) return 0; pm_runtime_get_sync(&rspi->pdev->dev); @@ -958,9 +958,9 @@ static int rspi_setup(struct spi_device *spi) sslp = rspi_read8(rspi, RSPI_SSLP); if (spi->mode & SPI_CS_HIGH) - sslp |= SSLP_SSLP(spi->chip_select); + sslp |= SSLP_SSLP(spi_get_chipselect(spi, 0)); else - sslp &= ~SSLP_SSLP(spi->chip_select); + sslp &= ~SSLP_SSLP(spi_get_chipselect(spi, 0)); rspi_write8(rspi, sslp, RSPI_SSLP); spin_unlock_irq(&rspi->lock); @@ -1001,8 +1001,8 @@ static int rspi_prepare_message(struct spi_controller *ctlr, rspi->spcmd |= SPCMD_LSBF; /* Configure slave signal to assert */ - rspi->spcmd |= SPCMD_SSLA(spi->cs_gpiod ? rspi->ctlr->unused_native_cs - : spi->chip_select); + rspi->spcmd |= SPCMD_SSLA(spi_get_csgpiod(spi, 0) ? rspi->ctlr->unused_native_cs + : spi_get_chipselect(spi, 0)); /* CMOS output mode and MOSI signal from previous transfer */ rspi->sppcr = 0; @@ -1172,14 +1172,12 @@ static void rspi_release_dma(struct spi_controller *ctlr) dma_release_channel(ctlr->dma_rx); } -static int rspi_remove(struct platform_device *pdev) +static void rspi_remove(struct platform_device *pdev) { struct rspi_data *rspi = platform_get_drvdata(pdev); rspi_release_dma(rspi->ctlr); pm_runtime_disable(&pdev->dev); - - return 0; } static const struct spi_ops rspi_ops = { @@ -1192,7 +1190,7 @@ static const struct spi_ops rspi_ops = { .num_hw_ss = 2, }; -static const struct spi_ops rspi_rz_ops = { +static const struct spi_ops rspi_rz_ops __maybe_unused = { .set_config_register = rspi_rz_set_config_register, .transfer_one = rspi_rz_transfer_one, .min_div = 2, @@ -1202,7 +1200,7 @@ static const struct spi_ops rspi_rz_ops = { .num_hw_ss = 1, }; -static const struct spi_ops qspi_ops = { +static const struct spi_ops qspi_ops __maybe_unused = { .set_config_register = qspi_set_config_register, .transfer_one = qspi_transfer_one, .extra_mode_bits = SPI_TX_DUAL | SPI_TX_QUAD | @@ -1214,8 +1212,7 @@ static const struct spi_ops qspi_ops = { .num_hw_ss = 1, }; -#ifdef CONFIG_OF -static const struct of_device_id rspi_of_match[] = { +static const struct of_device_id rspi_of_match[] __maybe_unused = { /* RSPI on legacy SH */ { .compatible = "renesas,rspi", .data = &rspi_ops }, /* RSPI on RZ/A1H */ @@ -1227,6 +1224,7 @@ static const struct of_device_id rspi_of_match[] = { MODULE_DEVICE_TABLE(of, rspi_of_match); +#ifdef CONFIG_OF static void rspi_reset_control_assert(void *data) { reset_control_assert(data); @@ -1440,7 +1438,7 @@ static SIMPLE_DEV_PM_OPS(rspi_pm_ops, rspi_suspend, rspi_resume); static struct platform_driver rspi_driver = { .probe = rspi_probe, - .remove = rspi_remove, + .remove_new = rspi_remove, .id_table = spi_driver_ids, .driver = { .name = "renesas_spi", diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 71d324ec9a70..7ac17f0d18a9 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -891,7 +891,7 @@ static int s3c64xx_spi_setup(struct spi_device *spi) /* NULL is fine, we just avoid using the FB delay (=0) */ if (IS_ERR(cs)) { - dev_err(&spi->dev, "No CS for SPI(%d)\n", spi->chip_select); + dev_err(&spi->dev, "No CS for SPI(%d)\n", spi_get_chipselect(spi, 0)); return -ENODEV; } @@ -1286,7 +1286,7 @@ err_deref_master: return ret; } -static int s3c64xx_spi_remove(struct platform_device *pdev) +static void s3c64xx_spi_remove(struct platform_device *pdev) { struct spi_master *master = platform_get_drvdata(pdev); struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); @@ -1309,8 +1309,6 @@ static int s3c64xx_spi_remove(struct platform_device *pdev) pm_runtime_put_noidle(&pdev->dev); pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -1531,7 +1529,7 @@ static struct platform_driver s3c64xx_spi_driver = { .of_match_table = of_match_ptr(s3c64xx_spi_dt_match), }, .probe = s3c64xx_spi_probe, - .remove = s3c64xx_spi_remove, + .remove_new = s3c64xx_spi_remove, .id_table = s3c64xx_spi_driver_ids, }; MODULE_ALIAS("platform:s3c64xx-spi"); diff --git a/drivers/spi/spi-sc18is602.c b/drivers/spi/spi-sc18is602.c index 983b3621bc2a..70012333020b 100644 --- a/drivers/spi/spi-sc18is602.c +++ b/drivers/spi/spi-sc18is602.c @@ -70,7 +70,7 @@ static int sc18is602_txrx(struct sc18is602 *hw, struct spi_message *msg, if (hw->tlen == 0) { /* First byte (I2C command) is chip select */ - hw->buffer[0] = 1 << msg->spi->chip_select; + hw->buffer[0] = 1 << spi_get_chipselect(msg->spi, 0); hw->tlen = 1; hw->rindex = 0; } @@ -229,7 +229,7 @@ static int sc18is602_setup(struct spi_device *spi) struct sc18is602 *hw = spi_master_get_devdata(spi->master); /* SC18IS602 does not support CS2 */ - if (hw->id == sc18is602 && spi->chip_select == 2) + if (hw->id == sc18is602 && (spi_get_chipselect(spi, 0) == 2)) return -ENXIO; return 0; @@ -315,7 +315,7 @@ static const struct i2c_device_id sc18is602_id[] = { }; MODULE_DEVICE_TABLE(i2c, sc18is602_id); -static const struct of_device_id sc18is602_of_match[] = { +static const struct of_device_id sc18is602_of_match[] __maybe_unused = { { .compatible = "nxp,sc18is602", .data = (void *)sc18is602 diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c index a62034e2a7cb..d6ffeae66ed3 100644 --- a/drivers/spi/spi-sh-hspi.c +++ b/drivers/spi/spi-sh-hspi.c @@ -276,15 +276,13 @@ static int hspi_probe(struct platform_device *pdev) return ret; } -static int hspi_remove(struct platform_device *pdev) +static void hspi_remove(struct platform_device *pdev) { struct hspi_priv *hspi = platform_get_drvdata(pdev); pm_runtime_disable(&pdev->dev); clk_put(hspi->clk); - - return 0; } static const struct of_device_id hspi_of_match[] = { @@ -295,7 +293,7 @@ MODULE_DEVICE_TABLE(of, hspi_of_match); static struct platform_driver hspi_driver = { .probe = hspi_probe, - .remove = hspi_remove, + .remove_new = hspi_remove, .driver = { .name = "sh-hspi", .of_match_table = hspi_of_match, diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 9bca3d076f05..9e90b4f8b357 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -554,7 +554,7 @@ static int sh_msiof_spi_setup(struct spi_device *spi) spi_controller_get_devdata(spi->controller); u32 clr, set, tmp; - if (spi->cs_gpiod || spi_controller_is_slave(p->ctlr)) + if (spi_get_csgpiod(spi, 0) || spi_controller_is_slave(p->ctlr)) return 0; if (p->native_cs_inited && @@ -587,11 +587,11 @@ static int sh_msiof_prepare_message(struct spi_controller *ctlr, u32 ss, cs_high; /* Configure pins before asserting CS */ - if (spi->cs_gpiod) { + if (spi_get_csgpiod(spi, 0)) { ss = ctlr->unused_native_cs; cs_high = p->native_cs_high; } else { - ss = spi->chip_select; + ss = spi_get_chipselect(spi, 0); cs_high = !!(spi->mode & SPI_CS_HIGH); } sh_msiof_spi_set_pin_regs(p, ss, !!(spi->mode & SPI_CPOL), @@ -1073,7 +1073,7 @@ static const struct sh_msiof_chipdata rcar_gen3_data = { .min_div_pow = 1, }; -static const struct of_device_id sh_msiof_match[] = { +static const struct of_device_id sh_msiof_match[] __maybe_unused = { { .compatible = "renesas,sh-mobile-msiof", .data = &sh_data }, { .compatible = "renesas,msiof-r8a7743", .data = &rcar_gen2_data }, { .compatible = "renesas,msiof-r8a7745", .data = &rcar_gen2_data }, @@ -1375,13 +1375,12 @@ static int sh_msiof_spi_probe(struct platform_device *pdev) return ret; } -static int sh_msiof_spi_remove(struct platform_device *pdev) +static void sh_msiof_spi_remove(struct platform_device *pdev) { struct sh_msiof_spi_priv *p = platform_get_drvdata(pdev); sh_msiof_release_dma(p); pm_runtime_disable(&pdev->dev); - return 0; } static const struct platform_device_id spi_driver_ids[] = { @@ -1414,7 +1413,7 @@ static SIMPLE_DEV_PM_OPS(sh_msiof_spi_pm_ops, sh_msiof_spi_suspend, static struct platform_driver sh_msiof_spi_drv = { .probe = sh_msiof_spi_probe, - .remove = sh_msiof_spi_remove, + .remove_new = sh_msiof_spi_remove, .id_table = spi_driver_ids, .driver = { .name = "spi_sh_msiof", diff --git a/drivers/spi/spi-sh-sci.c b/drivers/spi/spi-sh-sci.c index 8f30531e1418..92ca3f2d61ba 100644 --- a/drivers/spi/spi-sh-sci.c +++ b/drivers/spi/spi-sh-sci.c @@ -108,7 +108,7 @@ static void sh_sci_spi_chipselect(struct spi_device *dev, int value) struct sh_sci_spi *sp = spi_master_get_devdata(dev->master); if (sp->info->chip_select) - (sp->info->chip_select)(sp->info, dev->chip_select, value); + (sp->info->chip_select)(sp->info, spi_get_chipselect(dev, 0), value); } static int sh_sci_spi_probe(struct platform_device *dev) @@ -171,7 +171,7 @@ static int sh_sci_spi_probe(struct platform_device *dev) return ret; } -static int sh_sci_spi_remove(struct platform_device *dev) +static void sh_sci_spi_remove(struct platform_device *dev) { struct sh_sci_spi *sp = platform_get_drvdata(dev); @@ -179,12 +179,11 @@ static int sh_sci_spi_remove(struct platform_device *dev) setbits(sp, PIN_INIT, 0); iounmap(sp->membase); spi_master_put(sp->bitbang.master); - return 0; } static struct platform_driver sh_sci_spi_drv = { .probe = sh_sci_spi_probe, - .remove = sh_sci_spi_remove, + .remove_new = sh_sci_spi_remove, .driver = { .name = "spi_sh_sci", }, diff --git a/drivers/spi/spi-sh.c b/drivers/spi/spi-sh.c index 3e72fad99adf..d358a2a9c3f5 100644 --- a/drivers/spi/spi-sh.c +++ b/drivers/spi/spi-sh.c @@ -377,14 +377,12 @@ static irqreturn_t spi_sh_irq(int irq, void *_ss) return IRQ_HANDLED; } -static int spi_sh_remove(struct platform_device *pdev) +static void spi_sh_remove(struct platform_device *pdev) { struct spi_sh_data *ss = platform_get_drvdata(pdev); spi_unregister_master(ss->master); free_irq(ss->irq, ss); - - return 0; } static int spi_sh_probe(struct platform_device *pdev) @@ -461,7 +459,7 @@ static int spi_sh_probe(struct platform_device *pdev) static struct platform_driver spi_sh_driver = { .probe = spi_sh_probe, - .remove = spi_sh_remove, + .remove_new = spi_sh_remove, .driver = { .name = "sh_spi", }, diff --git a/drivers/spi/spi-sifive.c b/drivers/spi/spi-sifive.c index e29e85cee88a..dae9e097c333 100644 --- a/drivers/spi/spi-sifive.c +++ b/drivers/spi/spi-sifive.c @@ -135,13 +135,13 @@ sifive_spi_prepare_message(struct spi_master *master, struct spi_message *msg) /* Update the chip select polarity */ if (device->mode & SPI_CS_HIGH) - spi->cs_inactive &= ~BIT(device->chip_select); + spi->cs_inactive &= ~BIT(spi_get_chipselect(device, 0)); else - spi->cs_inactive |= BIT(device->chip_select); + spi->cs_inactive |= BIT(spi_get_chipselect(device, 0)); sifive_spi_write(spi, SIFIVE_SPI_REG_CSDEF, spi->cs_inactive); /* Select the correct device */ - sifive_spi_write(spi, SIFIVE_SPI_REG_CSID, device->chip_select); + sifive_spi_write(spi, SIFIVE_SPI_REG_CSID, spi_get_chipselect(device, 0)); /* Set clock mode */ sifive_spi_write(spi, SIFIVE_SPI_REG_SCKMODE, @@ -415,7 +415,7 @@ put_master: return ret; } -static int sifive_spi_remove(struct platform_device *pdev) +static void sifive_spi_remove(struct platform_device *pdev) { struct spi_master *master = platform_get_drvdata(pdev); struct sifive_spi *spi = spi_master_get_devdata(master); @@ -423,8 +423,6 @@ static int sifive_spi_remove(struct platform_device *pdev) /* Disable all the interrupts just in case */ sifive_spi_write(spi, SIFIVE_SPI_REG_IE, 0); clk_disable_unprepare(spi->clk); - - return 0; } static int sifive_spi_suspend(struct device *dev) @@ -473,7 +471,7 @@ MODULE_DEVICE_TABLE(of, sifive_spi_of_match); static struct platform_driver sifive_spi_driver = { .probe = sifive_spi_probe, - .remove = sifive_spi_remove, + .remove_new = sifive_spi_remove, .driver = { .name = SIFIVE_SPI_DRIVER_NAME, .pm = &sifive_spi_pm_ops, diff --git a/drivers/spi/spi-slave-mt27xx.c b/drivers/spi/spi-slave-mt27xx.c index f199a6c4738a..4e4d426bfb43 100644 --- a/drivers/spi/spi-slave-mt27xx.c +++ b/drivers/spi/spi-slave-mt27xx.c @@ -474,11 +474,9 @@ err_put_ctlr: return ret; } -static int mtk_spi_slave_remove(struct platform_device *pdev) +static void mtk_spi_slave_remove(struct platform_device *pdev) { pm_runtime_disable(&pdev->dev); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -560,7 +558,7 @@ static struct platform_driver mtk_spi_slave_driver = { .of_match_table = mtk_spi_slave_of_match, }, .probe = mtk_spi_slave_probe, - .remove = mtk_spi_slave_remove, + .remove_new = mtk_spi_slave_remove, }; module_platform_driver(mtk_spi_slave_driver); diff --git a/drivers/spi/spi-sn-f-ospi.c b/drivers/spi/spi-sn-f-ospi.c index 333b22dfd8db..a2bd9dcde075 100644 --- a/drivers/spi/spi-sn-f-ospi.c +++ b/drivers/spi/spi-sn-f-ospi.c @@ -267,7 +267,7 @@ static void f_ospi_config_indir_protocol(struct f_ospi *ospi, int unit; /* Set one chip select */ - writel(BIT(spi->chip_select), ospi->base + OSPI_SSEL); + writel(BIT(spi_get_chipselect(spi, 0)), ospi->base + OSPI_SSEL); mode = f_ospi_get_mode(ospi, op->cmd.buswidth, 1); prot |= FIELD_PREP(OSPI_PROT_MODE_CODE_MASK, mode); @@ -561,7 +561,7 @@ static bool f_ospi_supports_op(struct spi_mem *mem, if (!f_ospi_supports_op_width(mem, op)) return false; - return true; + return spi_mem_default_supports_op(mem, op); } static int f_ospi_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op) @@ -670,15 +670,13 @@ err_put_ctlr: return ret; } -static int f_ospi_remove(struct platform_device *pdev) +static void f_ospi_remove(struct platform_device *pdev) { struct f_ospi *ospi = platform_get_drvdata(pdev); clk_disable_unprepare(ospi->clk); mutex_destroy(&ospi->mlock); - - return 0; } static const struct of_device_id f_ospi_dt_ids[] = { @@ -693,7 +691,7 @@ static struct platform_driver f_ospi_driver = { .of_match_table = f_ospi_dt_ids, }, .probe = f_ospi_probe, - .remove = f_ospi_remove, + .remove_new = f_ospi_remove, }; module_platform_driver(f_ospi_driver); diff --git a/drivers/spi/spi-sprd-adi.c b/drivers/spi/spi-sprd-adi.c index 1edbf44c05a7..22e39c4c12c4 100644 --- a/drivers/spi/spi-sprd-adi.c +++ b/drivers/spi/spi-sprd-adi.c @@ -541,8 +541,7 @@ static int sprd_adi_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, ctlr); sadi = spi_controller_get_devdata(ctlr); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - sadi->base = devm_ioremap_resource(&pdev->dev, res); + sadi->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(sadi->base)) { ret = PTR_ERR(sadi->base); goto put_ctlr; @@ -608,13 +607,12 @@ put_ctlr: return ret; } -static int sprd_adi_remove(struct platform_device *pdev) +static void sprd_adi_remove(struct platform_device *pdev) { struct spi_controller *ctlr = dev_get_drvdata(&pdev->dev); struct sprd_adi *sadi = spi_controller_get_devdata(ctlr); unregister_restart_handler(&sadi->restart_handler); - return 0; } static struct sprd_adi_data sc9860_data = { @@ -660,7 +658,7 @@ static struct platform_driver sprd_adi_driver = { .of_match_table = sprd_adi_of_match, }, .probe = sprd_adi_probe, - .remove = sprd_adi_remove, + .remove_new = sprd_adi_remove, }; module_platform_driver(sprd_adi_driver); diff --git a/drivers/spi/spi-sprd.c b/drivers/spi/spi-sprd.c index 65b8075da4eb..518c7eaca84e 100644 --- a/drivers/spi/spi-sprd.c +++ b/drivers/spi/spi-sprd.c @@ -929,8 +929,7 @@ static int sprd_spi_probe(struct platform_device *pdev) return -ENOMEM; ss = spi_controller_get_devdata(sctlr); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - ss->base = devm_ioremap_resource(&pdev->dev, res); + ss->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(ss->base)) { ret = PTR_ERR(ss->base); goto free_controller; @@ -1002,27 +1001,25 @@ free_controller: return ret; } -static int sprd_spi_remove(struct platform_device *pdev) +static void sprd_spi_remove(struct platform_device *pdev) { struct spi_controller *sctlr = platform_get_drvdata(pdev); struct sprd_spi *ss = spi_controller_get_devdata(sctlr); int ret; - ret = pm_runtime_resume_and_get(ss->dev); - if (ret < 0) { + ret = pm_runtime_get_sync(ss->dev); + if (ret < 0) dev_err(ss->dev, "failed to resume SPI controller\n"); - return ret; - } spi_controller_suspend(sctlr); - if (ss->dma.enable) - sprd_spi_dma_release(ss); - clk_disable_unprepare(ss->clk); + if (ret >= 0) { + if (ss->dma.enable) + sprd_spi_dma_release(ss); + clk_disable_unprepare(ss->clk); + } pm_runtime_put_noidle(&pdev->dev); pm_runtime_disable(&pdev->dev); - - return 0; } static int __maybe_unused sprd_spi_runtime_suspend(struct device *dev) @@ -1076,7 +1073,7 @@ static struct platform_driver sprd_spi_driver = { .pm = &sprd_spi_pm_ops, }, .probe = sprd_spi_probe, - .remove = sprd_spi_remove, + .remove_new = sprd_spi_remove, }; module_platform_driver(sprd_spi_driver); diff --git a/drivers/spi/spi-st-ssc4.c b/drivers/spi/spi-st-ssc4.c index 843be803696b..7fcff9c539e2 100644 --- a/drivers/spi/spi-st-ssc4.c +++ b/drivers/spi/spi-st-ssc4.c @@ -183,7 +183,7 @@ static int spi_st_setup(struct spi_device *spi) return -EINVAL; } - if (!spi->cs_gpiod) { + if (!spi_get_csgpiod(spi, 0)) { dev_err(&spi->dev, "no valid gpio assigned\n"); return -EINVAL; } @@ -366,7 +366,7 @@ put_master: return ret; } -static int spi_st_remove(struct platform_device *pdev) +static void spi_st_remove(struct platform_device *pdev) { struct spi_master *master = platform_get_drvdata(pdev); struct spi_st *spi_st = spi_master_get_devdata(master); @@ -376,8 +376,6 @@ static int spi_st_remove(struct platform_device *pdev) clk_disable_unprepare(spi_st->clk); pinctrl_pm_select_sleep_state(&pdev->dev); - - return 0; } #ifdef CONFIG_PM @@ -451,7 +449,7 @@ static struct platform_driver spi_st_driver = { .of_match_table = of_match_ptr(stm_spi_match), }, .probe = spi_st_probe, - .remove = spi_st_remove, + .remove_new = spi_st_remove, }; module_platform_driver(spi_st_driver); diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c index 9131660c1afb..2b6804aa6901 100644 --- a/drivers/spi/spi-stm32-qspi.c +++ b/drivers/spi/spi-stm32-qspi.c @@ -359,7 +359,7 @@ static int stm32_qspi_get_mode(u8 buswidth) static int stm32_qspi_send(struct spi_device *spi, const struct spi_mem_op *op) { struct stm32_qspi *qspi = spi_controller_get_devdata(spi->master); - struct stm32_qspi_flash *flash = &qspi->flash[spi->chip_select]; + struct stm32_qspi_flash *flash = &qspi->flash[spi_get_chipselect(spi, 0)]; u32 ccr, cr; int timeout, err = 0, err_poll_status = 0; @@ -564,7 +564,7 @@ static int stm32_qspi_transfer_one_message(struct spi_controller *ctrl, struct spi_mem_op op; int ret = 0; - if (!spi->cs_gpiod) + if (!spi_get_csgpiod(spi, 0)) return -EOPNOTSUPP; ret = pm_runtime_resume_and_get(qspi->dev); @@ -573,7 +573,7 @@ static int stm32_qspi_transfer_one_message(struct spi_controller *ctrl, mutex_lock(&qspi->lock); - gpiod_set_value_cansleep(spi->cs_gpiod, true); + gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), true); list_for_each_entry(transfer, &msg->transfers, transfer_list) { u8 dummy_bytes = 0; @@ -626,7 +626,7 @@ static int stm32_qspi_transfer_one_message(struct spi_controller *ctrl, } end_of_transfer: - gpiod_set_value_cansleep(spi->cs_gpiod, false); + gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), false); mutex_unlock(&qspi->lock); @@ -669,8 +669,8 @@ static int stm32_qspi_setup(struct spi_device *spi) presc = DIV_ROUND_UP(qspi->clk_rate, spi->max_speed_hz) - 1; - flash = &qspi->flash[spi->chip_select]; - flash->cs = spi->chip_select; + flash = &qspi->flash[spi_get_chipselect(spi, 0)]; + flash->cs = spi_get_chipselect(spi, 0); flash->presc = presc; mutex_lock(&qspi->lock); @@ -888,7 +888,7 @@ err_clk_disable: return ret; } -static int stm32_qspi_remove(struct platform_device *pdev) +static void stm32_qspi_remove(struct platform_device *pdev) { struct stm32_qspi *qspi = platform_get_drvdata(pdev); @@ -903,8 +903,6 @@ static int stm32_qspi_remove(struct platform_device *pdev) pm_runtime_set_suspended(qspi->dev); pm_runtime_dont_use_autosuspend(qspi->dev); clk_disable_unprepare(qspi->clk); - - return 0; } static int __maybe_unused stm32_qspi_runtime_suspend(struct device *dev) @@ -968,7 +966,7 @@ MODULE_DEVICE_TABLE(of, stm32_qspi_match); static struct platform_driver stm32_qspi_driver = { .probe = stm32_qspi_probe, - .remove = stm32_qspi_remove, + .remove_new = stm32_qspi_remove, .driver = { .name = "stm32-qspi", .of_match_table = stm32_qspi_match, diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c index def09cf0dc14..d6598e4116bd 100644 --- a/drivers/spi/spi-stm32.c +++ b/drivers/spi/spi-stm32.c @@ -984,9 +984,9 @@ static int stm32_spi_prepare_msg(struct spi_master *master, if (spi->cfg->set_number_of_data) { int ret; - ret = spi_split_transfers_maxsize(master, msg, - STM32H7_SPI_TSIZE_MAX, - GFP_KERNEL | GFP_DMA); + ret = spi_split_transfers_maxwords(master, msg, + STM32H7_SPI_TSIZE_MAX, + GFP_KERNEL | GFP_DMA); if (ret) return ret; } @@ -1780,8 +1780,7 @@ static int stm32_spi_probe(struct platform_device *pdev) of_match_device(pdev->dev.driver->of_match_table, &pdev->dev)->data; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - spi->base = devm_ioremap_resource(&pdev->dev, res); + spi->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(spi->base)) return PTR_ERR(spi->base); @@ -1922,7 +1921,7 @@ err_clk_disable: return ret; } -static int stm32_spi_remove(struct platform_device *pdev) +static void stm32_spi_remove(struct platform_device *pdev) { struct spi_master *master = platform_get_drvdata(pdev); struct stm32_spi *spi = spi_master_get_devdata(master); @@ -1946,8 +1945,6 @@ static int stm32_spi_remove(struct platform_device *pdev) pinctrl_pm_select_sleep_state(&pdev->dev); - - return 0; } static int __maybe_unused stm32_spi_runtime_suspend(struct device *dev) @@ -2023,7 +2020,7 @@ static const struct dev_pm_ops stm32_spi_pm_ops = { static struct platform_driver stm32_spi_driver = { .probe = stm32_spi_probe, - .remove = stm32_spi_remove, + .remove_new = stm32_spi_remove, .driver = { .name = DRIVER_NAME, .pm = &stm32_spi_pm_ops, diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c index 6000d0761206..b8947265d329 100644 --- a/drivers/spi/spi-sun4i.c +++ b/drivers/spi/spi-sun4i.c @@ -167,7 +167,7 @@ static void sun4i_spi_set_cs(struct spi_device *spi, bool enable) reg = sun4i_spi_read(sspi, SUN4I_CTL_REG); reg &= ~SUN4I_CTL_CS_MASK; - reg |= SUN4I_CTL_CS(spi->chip_select); + reg |= SUN4I_CTL_CS(spi_get_chipselect(spi, 0)); /* We want to control the chip select manually */ reg |= SUN4I_CTL_CS_MANUAL; @@ -516,11 +516,9 @@ err_free_master: return ret; } -static int sun4i_spi_remove(struct platform_device *pdev) +static void sun4i_spi_remove(struct platform_device *pdev) { pm_runtime_force_suspend(&pdev->dev); - - return 0; } static const struct of_device_id sun4i_spi_match[] = { @@ -536,7 +534,7 @@ static const struct dev_pm_ops sun4i_spi_pm_ops = { static struct platform_driver sun4i_spi_driver = { .probe = sun4i_spi_probe, - .remove = sun4i_spi_remove, + .remove_new = sun4i_spi_remove, .driver = { .name = "sun4i-spi", .of_match_table = sun4i_spi_match, diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c index 23ad052528db..7532c85a352c 100644 --- a/drivers/spi/spi-sun6i.c +++ b/drivers/spi/spi-sun6i.c @@ -174,7 +174,7 @@ static void sun6i_spi_set_cs(struct spi_device *spi, bool enable) reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG); reg &= ~SUN6I_TFR_CTL_CS_MASK; - reg |= SUN6I_TFR_CTL_CS(spi->chip_select); + reg |= SUN6I_TFR_CTL_CS(spi_get_chipselect(spi, 0)); if (enable) reg |= SUN6I_TFR_CTL_CS_LEVEL; @@ -683,7 +683,7 @@ err_free_master: return ret; } -static int sun6i_spi_remove(struct platform_device *pdev) +static void sun6i_spi_remove(struct platform_device *pdev) { struct spi_master *master = platform_get_drvdata(pdev); @@ -693,7 +693,6 @@ static int sun6i_spi_remove(struct platform_device *pdev) dma_release_channel(master->dma_tx); if (master->dma_rx) dma_release_channel(master->dma_rx); - return 0; } static const struct of_device_id sun6i_spi_match[] = { @@ -710,7 +709,7 @@ static const struct dev_pm_ops sun6i_spi_pm_ops = { static struct platform_driver sun6i_spi_driver = { .probe = sun6i_spi_probe, - .remove = sun6i_spi_remove, + .remove_new = sun6i_spi_remove, .driver = { .name = "sun6i-spi", .of_match_table = sun6i_spi_match, diff --git a/drivers/spi/spi-sunplus-sp7021.c b/drivers/spi/spi-sunplus-sp7021.c index f1fa88777575..eb8f835a4771 100644 --- a/drivers/spi/spi-sunplus-sp7021.c +++ b/drivers/spi/spi-sunplus-sp7021.c @@ -504,14 +504,13 @@ static int sp7021_spi_controller_probe(struct platform_device *pdev) return 0; } -static int sp7021_spi_controller_remove(struct platform_device *pdev) +static void sp7021_spi_controller_remove(struct platform_device *pdev) { struct spi_controller *ctlr = dev_get_drvdata(&pdev->dev); spi_unregister_controller(ctlr); pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); - return 0; } static int __maybe_unused sp7021_spi_controller_suspend(struct device *dev) @@ -564,7 +563,7 @@ MODULE_DEVICE_TABLE(of, sp7021_spi_controller_ids); static struct platform_driver sp7021_spi_controller_driver = { .probe = sp7021_spi_controller_probe, - .remove = sp7021_spi_controller_remove, + .remove_new = sp7021_spi_controller_remove, .driver = { .name = "sunplus,sp7021-spi-controller", .of_match_table = sp7021_spi_controller_ids, diff --git a/drivers/spi/spi-synquacer.c b/drivers/spi/spi-synquacer.c index dc188f9202c9..aeaf7db022f0 100644 --- a/drivers/spi/spi-synquacer.c +++ b/drivers/spi/spi-synquacer.c @@ -250,7 +250,7 @@ static int synquacer_spi_config(struct spi_master *master, } mode = spi->mode; - cs = spi->chip_select; + cs = spi_get_chipselect(spi, 0); speed = xfer->speed_hz; bpw = xfer->bits_per_word; @@ -344,7 +344,7 @@ static int synquacer_spi_config(struct spi_master *master, sspi->bpw = bpw; sspi->mode = mode; sspi->speed = speed; - sspi->cs = spi->chip_select; + sspi->cs = spi_get_chipselect(spi, 0); sspi->bus_width = bus_width; return 0; @@ -488,7 +488,7 @@ static void synquacer_spi_set_cs(struct spi_device *spi, bool enable) val = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMSTART); val &= ~(SYNQUACER_HSSPI_DMPSEL_CS_MASK << SYNQUACER_HSSPI_DMPSEL_CS_SHIFT); - val |= spi->chip_select << SYNQUACER_HSSPI_DMPSEL_CS_SHIFT; + val |= spi_get_chipselect(spi, 0) << SYNQUACER_HSSPI_DMPSEL_CS_SHIFT; if (!enable) val |= SYNQUACER_HSSPI_DMSTOP_STOP; @@ -735,7 +735,7 @@ put_spi: return ret; } -static int synquacer_spi_remove(struct platform_device *pdev) +static void synquacer_spi_remove(struct platform_device *pdev) { struct spi_master *master = platform_get_drvdata(pdev); struct synquacer_spi *sspi = spi_master_get_devdata(master); @@ -743,8 +743,6 @@ static int synquacer_spi_remove(struct platform_device *pdev) pm_runtime_disable(sspi->dev); clk_disable_unprepare(sspi->clk); - - return 0; } static int __maybe_unused synquacer_spi_suspend(struct device *dev) @@ -820,7 +818,7 @@ static struct platform_driver synquacer_spi_driver = { .acpi_match_table = ACPI_PTR(synquacer_hsspi_acpi_ids), }, .probe = synquacer_spi_probe, - .remove = synquacer_spi_remove, + .remove_new = synquacer_spi_remove, }; module_platform_driver(synquacer_spi_driver); diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index d9be80e3e1bc..488df681eaef 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c @@ -747,7 +747,7 @@ static int tegra_spi_set_hw_cs_timing(struct spi_device *spi) if (setup_dly && hold_dly) { setup_hold = SPI_SETUP_HOLD(setup_dly - 1, hold_dly - 1); spi_cs_timing = SPI_CS_SETUP_HOLD(tspi->spi_cs_timing1, - spi->chip_select, + spi_get_chipselect(spi, 0), setup_hold); if (tspi->spi_cs_timing1 != spi_cs_timing) { tspi->spi_cs_timing1 = spi_cs_timing; @@ -760,9 +760,9 @@ static int tegra_spi_set_hw_cs_timing(struct spi_device *spi) inactive_cycles--; cs_state = inactive_cycles ? 0 : 1; spi_cs_timing = tspi->spi_cs_timing2; - SPI_SET_CS_ACTIVE_BETWEEN_PACKETS(spi_cs_timing, spi->chip_select, + SPI_SET_CS_ACTIVE_BETWEEN_PACKETS(spi_cs_timing, spi_get_chipselect(spi, 0), cs_state); - SPI_SET_CYCLES_BETWEEN_PACKETS(spi_cs_timing, spi->chip_select, + SPI_SET_CYCLES_BETWEEN_PACKETS(spi_cs_timing, spi_get_chipselect(spi, 0), inactive_cycles); if (tspi->spi_cs_timing2 != spi_cs_timing) { tspi->spi_cs_timing2 = spi_cs_timing; @@ -831,8 +831,8 @@ static u32 tegra_spi_setup_transfer_one(struct spi_device *spi, tegra_spi_writel(tspi, command1, SPI_COMMAND1); /* GPIO based chip select control */ - if (spi->cs_gpiod) - gpiod_set_value(spi->cs_gpiod, 1); + if (spi_get_csgpiod(spi, 0)) + gpiod_set_value(spi_get_csgpiod(spi, 0), 1); if (is_single_xfer && !(t->cs_change)) { tspi->use_hw_based_cs = true; @@ -846,7 +846,7 @@ static u32 tegra_spi_setup_transfer_one(struct spi_device *spi, command1 &= ~SPI_CS_SW_VAL; } - if (tspi->last_used_cs != spi->chip_select) { + if (tspi->last_used_cs != spi_get_chipselect(spi, 0)) { if (cdata && cdata->tx_clk_tap_delay) tx_tap = cdata->tx_clk_tap_delay; if (cdata && cdata->rx_clk_tap_delay) @@ -855,7 +855,7 @@ static u32 tegra_spi_setup_transfer_one(struct spi_device *spi, SPI_RX_TAP_DELAY(rx_tap); if (command2 != tspi->def_command2_reg) tegra_spi_writel(tspi, command2, SPI_COMMAND2); - tspi->last_used_cs = spi->chip_select; + tspi->last_used_cs = spi_get_chipselect(spi, 0); } } else { @@ -896,7 +896,7 @@ static int tegra_spi_start_transfer_one(struct spi_device *spi, command1 |= SPI_TX_EN; tspi->cur_direction |= DATA_DIR_TX; } - command1 |= SPI_CS_SEL(spi->chip_select); + command1 |= SPI_CS_SEL(spi_get_chipselect(spi, 0)); tegra_spi_writel(tspi, command1, SPI_COMMAND1); tspi->command1_reg = command1; @@ -980,14 +980,14 @@ static int tegra_spi_setup(struct spi_device *spi) spin_lock_irqsave(&tspi->lock, flags); /* GPIO based chip select control */ - if (spi->cs_gpiod) - gpiod_set_value(spi->cs_gpiod, 0); + if (spi_get_csgpiod(spi, 0)) + gpiod_set_value(spi_get_csgpiod(spi, 0), 0); val = tspi->def_command1_reg; if (spi->mode & SPI_CS_HIGH) - val &= ~SPI_CS_POL_INACTIVE(spi->chip_select); + val &= ~SPI_CS_POL_INACTIVE(spi_get_chipselect(spi, 0)); else - val |= SPI_CS_POL_INACTIVE(spi->chip_select); + val |= SPI_CS_POL_INACTIVE(spi_get_chipselect(spi, 0)); tspi->def_command1_reg = val; tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1); spin_unlock_irqrestore(&tspi->lock, flags); @@ -1002,8 +1002,8 @@ static void tegra_spi_transfer_end(struct spi_device *spi) int cs_val = (spi->mode & SPI_CS_HIGH) ? 0 : 1; /* GPIO based chip select control */ - if (spi->cs_gpiod) - gpiod_set_value(spi->cs_gpiod, 0); + if (spi_get_csgpiod(spi, 0)) + gpiod_set_value(spi_get_csgpiod(spi, 0), 0); if (!tspi->use_hw_based_cs) { if (cs_val) @@ -1342,8 +1342,7 @@ static int tegra_spi_probe(struct platform_device *pdev) goto exit_free_master; } - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - tspi->base = devm_ioremap_resource(&pdev->dev, r); + tspi->base = devm_platform_get_and_ioremap_resource(pdev, 0, &r); if (IS_ERR(tspi->base)) { ret = PTR_ERR(tspi->base); goto exit_free_master; @@ -1440,7 +1439,7 @@ exit_free_master: return ret; } -static int tegra_spi_remove(struct platform_device *pdev) +static void tegra_spi_remove(struct platform_device *pdev) { struct spi_master *master = platform_get_drvdata(pdev); struct tegra_spi_data *tspi = spi_master_get_devdata(master); @@ -1456,8 +1455,6 @@ static int tegra_spi_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); if (!pm_runtime_status_suspended(&pdev->dev)) tegra_spi_runtime_suspend(&pdev->dev); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -1526,7 +1523,7 @@ static struct platform_driver tegra_spi_driver = { .of_match_table = tegra_spi_of_match, }, .probe = tegra_spi_probe, - .remove = tegra_spi_remove, + .remove_new = tegra_spi_remove, }; module_platform_driver(tegra_spi_driver); diff --git a/drivers/spi/spi-tegra20-sflash.c b/drivers/spi/spi-tegra20-sflash.c index 220ee08c4a06..4286310628a2 100644 --- a/drivers/spi/spi-tegra20-sflash.c +++ b/drivers/spi/spi-tegra20-sflash.c @@ -280,7 +280,7 @@ static int tegra_sflash_start_transfer_one(struct spi_device *spi, command |= SPI_ACTIVE_SCLK_DRIVE_HIGH; else command |= SPI_ACTIVE_SCLK_DRIVE_LOW; - command |= SPI_CS0_EN << spi->chip_select; + command |= SPI_CS0_EN << spi_get_chipselect(spi, 0); } else { command = tsd->command_reg; command &= ~SPI_BIT_LENGTH(~0); @@ -520,7 +520,7 @@ exit_free_master: return ret; } -static int tegra_sflash_remove(struct platform_device *pdev) +static void tegra_sflash_remove(struct platform_device *pdev) { struct spi_master *master = platform_get_drvdata(pdev); struct tegra_sflash_data *tsd = spi_master_get_devdata(master); @@ -530,8 +530,6 @@ static int tegra_sflash_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); if (!pm_runtime_status_suspended(&pdev->dev)) tegra_sflash_runtime_suspend(&pdev->dev); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -598,7 +596,7 @@ static struct platform_driver tegra_sflash_driver = { .of_match_table = tegra_sflash_of_match, }, .probe = tegra_sflash_probe, - .remove = tegra_sflash_remove, + .remove_new = tegra_sflash_remove, }; module_platform_driver(tegra_sflash_driver); diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index 148043d0c2b8..c2915f7672cc 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c @@ -758,9 +758,9 @@ static int tegra_slink_setup(struct spi_device *spi) spin_lock_irqsave(&tspi->lock, flags); val = tspi->def_command_reg; if (spi->mode & SPI_CS_HIGH) - val |= cs_pol_bit[spi->chip_select]; + val |= cs_pol_bit[spi_get_chipselect(spi, 0)]; else - val &= ~cs_pol_bit[spi->chip_select]; + val &= ~cs_pol_bit[spi_get_chipselect(spi, 0)]; tspi->def_command_reg = val; tegra_slink_writel(tspi, tspi->def_command_reg, SLINK_COMMAND); spin_unlock_irqrestore(&tspi->lock, flags); @@ -781,7 +781,7 @@ static int tegra_slink_prepare_message(struct spi_master *master, tspi->command_reg |= SLINK_CS_SW | SLINK_CS_VALUE; tspi->command2_reg = tspi->def_command2_reg; - tspi->command2_reg |= SLINK_SS_EN_CS(spi->chip_select); + tspi->command2_reg |= SLINK_SS_EN_CS(spi_get_chipselect(spi, 0)); tspi->command_reg &= ~SLINK_MODES; if (spi->mode & SPI_CPHA) @@ -1134,7 +1134,7 @@ exit_free_master: return ret; } -static int tegra_slink_remove(struct platform_device *pdev) +static void tegra_slink_remove(struct platform_device *pdev) { struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); struct tegra_slink_data *tspi = spi_master_get_devdata(master); @@ -1152,7 +1152,6 @@ static int tegra_slink_remove(struct platform_device *pdev) tegra_slink_deinit_dma_param(tspi, true); spi_master_put(master); - return 0; } #ifdef CONFIG_PM_SLEEP @@ -1220,7 +1219,7 @@ static struct platform_driver tegra_slink_driver = { .of_match_table = tegra_slink_of_match, }, .probe = tegra_slink_probe, - .remove = tegra_slink_remove, + .remove_new = tegra_slink_remove, }; module_platform_driver(tegra_slink_driver); diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c index 0b9bc3b7f53a..fbd14dd7be44 100644 --- a/drivers/spi/spi-tegra210-quad.c +++ b/drivers/spi/spi-tegra210-quad.c @@ -142,6 +142,7 @@ #define QSPI_GLOBAL_CONFIG 0X1a4 #define QSPI_CMB_SEQ_EN BIT(0) +#define QSPI_TPM_WAIT_POLL_EN BIT(1) #define QSPI_CMB_SEQ_ADDR 0x1a8 #define QSPI_ADDRESS_VALUE_SET(X) (((x) & 0xFFFF) << 0) @@ -164,6 +165,7 @@ struct tegra_qspi_soc_data { bool has_dma; bool cmb_xfer_capable; + bool supports_tpm; unsigned int cs_count; }; @@ -829,7 +831,7 @@ static u32 tegra_qspi_setup_transfer_one(struct spi_device *spi, struct spi_tran tegra_qspi_mask_clear_irq(tqspi); command1 = tqspi->def_command1_reg; - command1 |= QSPI_CS_SEL(spi->chip_select); + command1 |= QSPI_CS_SEL(spi_get_chipselect(spi, 0)); command1 |= QSPI_BIT_LENGTH(bits_per_word - 1); command1 &= ~QSPI_CONTROL_MODE_MASK; @@ -960,11 +962,11 @@ static int tegra_qspi_setup(struct spi_device *spi) /* keep default cs state to inactive */ val = tqspi->def_command1_reg; - val |= QSPI_CS_SEL(spi->chip_select); + val |= QSPI_CS_SEL(spi_get_chipselect(spi, 0)); if (spi->mode & SPI_CS_HIGH) - val &= ~QSPI_CS_POL_INACTIVE(spi->chip_select); + val &= ~QSPI_CS_POL_INACTIVE(spi_get_chipselect(spi, 0)); else - val |= QSPI_CS_POL_INACTIVE(spi->chip_select); + val |= QSPI_CS_POL_INACTIVE(spi_get_chipselect(spi, 0)); tqspi->def_command1_reg = val; tegra_qspi_writel(tqspi, tqspi->def_command1_reg, QSPI_COMMAND1); @@ -1065,6 +1067,12 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, /* Enable Combined sequence mode */ val = tegra_qspi_readl(tqspi, QSPI_GLOBAL_CONFIG); + if (spi->mode & SPI_TPM_HW_FLOW) { + if (tqspi->soc_data->supports_tpm) + val |= QSPI_TPM_WAIT_POLL_EN; + else + return -EIO; + } val |= QSPI_CMB_SEQ_EN; tegra_qspi_writel(tqspi, val, QSPI_GLOBAL_CONFIG); /* Process individual transfer list */ @@ -1196,6 +1204,8 @@ static int tegra_qspi_non_combined_seq_xfer(struct tegra_qspi *tqspi, /* Disable Combined sequence mode */ val = tegra_qspi_readl(tqspi, QSPI_GLOBAL_CONFIG); val &= ~QSPI_CMB_SEQ_EN; + if (tqspi->soc_data->supports_tpm) + val &= ~QSPI_TPM_WAIT_POLL_EN; tegra_qspi_writel(tqspi, val, QSPI_GLOBAL_CONFIG); list_for_each_entry(transfer, &msg->transfers, transfer_list) { struct spi_transfer *xfer = transfer; @@ -1454,24 +1464,28 @@ static irqreturn_t tegra_qspi_isr_thread(int irq, void *context_data) static struct tegra_qspi_soc_data tegra210_qspi_soc_data = { .has_dma = true, .cmb_xfer_capable = false, + .supports_tpm = false, .cs_count = 1, }; static struct tegra_qspi_soc_data tegra186_qspi_soc_data = { .has_dma = true, .cmb_xfer_capable = true, + .supports_tpm = false, .cs_count = 1, }; static struct tegra_qspi_soc_data tegra234_qspi_soc_data = { .has_dma = false, .cmb_xfer_capable = true, + .supports_tpm = true, .cs_count = 1, }; static struct tegra_qspi_soc_data tegra241_qspi_soc_data = { .has_dma = false, .cmb_xfer_capable = true, + .supports_tpm = true, .cs_count = 4, }; @@ -1552,8 +1566,7 @@ static int tegra_qspi_probe(struct platform_device *pdev) tqspi->soc_data = device_get_match_data(&pdev->dev); master->num_chipselect = tqspi->soc_data->cs_count; - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - tqspi->base = devm_ioremap_resource(&pdev->dev, r); + tqspi->base = devm_platform_get_and_ioremap_resource(pdev, 0, &r); if (IS_ERR(tqspi->base)) return PTR_ERR(tqspi->base); @@ -1630,7 +1643,7 @@ exit_pm_disable: return ret; } -static int tegra_qspi_remove(struct platform_device *pdev) +static void tegra_qspi_remove(struct platform_device *pdev) { struct spi_master *master = platform_get_drvdata(pdev); struct tegra_qspi *tqspi = spi_master_get_devdata(master); @@ -1639,8 +1652,6 @@ static int tegra_qspi_remove(struct platform_device *pdev) free_irq(tqspi->irq, tqspi); pm_runtime_force_suspend(&pdev->dev); tegra_qspi_deinit_dma(tqspi); - - return 0; } static int __maybe_unused tegra_qspi_suspend(struct device *dev) @@ -1714,7 +1725,7 @@ static struct platform_driver tegra_qspi_driver = { .acpi_match_table = ACPI_PTR(tegra_qspi_acpi_match), }, .probe = tegra_qspi_probe, - .remove = tegra_qspi_remove, + .remove_new = tegra_qspi_remove, }; module_platform_driver(tegra_qspi_driver); diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index 60086869bcae..5914335ff63d 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -533,10 +533,10 @@ static void ti_qspi_enable_memory_map(struct spi_device *spi) if (qspi->ctrl_base) { regmap_update_bits(qspi->ctrl_base, qspi->ctrl_reg, MEM_CS_MASK, - MEM_CS_EN(spi->chip_select)); + MEM_CS_EN(spi_get_chipselect(spi, 0))); } qspi->mmap_enabled = true; - qspi->current_cs = spi->chip_select; + qspi->current_cs = spi_get_chipselect(spi, 0); } static void ti_qspi_disable_memory_map(struct spi_device *spi) @@ -572,7 +572,7 @@ static void ti_qspi_setup_mmap_read(struct spi_device *spi, u8 opcode, memval |= ((addr_width - 1) << QSPI_SETUP_ADDR_SHIFT | dummy_bytes << QSPI_SETUP_DUMMY_SHIFT); ti_qspi_write(qspi, memval, - QSPI_SPI_SETUP_REG(spi->chip_select)); + QSPI_SPI_SETUP_REG(spi_get_chipselect(spi, 0))); } static int ti_qspi_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op) @@ -623,7 +623,7 @@ static int ti_qspi_exec_mem_op(struct spi_mem *mem, mutex_lock(&qspi->list_lock); - if (!qspi->mmap_enabled || qspi->current_cs != mem->spi->chip_select) { + if (!qspi->mmap_enabled || qspi->current_cs != spi_get_chipselect(mem->spi, 0)) { ti_qspi_setup_clk(qspi, mem->spi->max_speed_hz); ti_qspi_enable_memory_map(mem->spi); } @@ -673,11 +673,11 @@ static int ti_qspi_start_transfer_one(struct spi_master *master, qspi->dc = 0; if (spi->mode & SPI_CPHA) - qspi->dc |= QSPI_CKPHA(spi->chip_select); + qspi->dc |= QSPI_CKPHA(spi_get_chipselect(spi, 0)); if (spi->mode & SPI_CPOL) - qspi->dc |= QSPI_CKPOL(spi->chip_select); + qspi->dc |= QSPI_CKPOL(spi_get_chipselect(spi, 0)); if (spi->mode & SPI_CS_HIGH) - qspi->dc |= QSPI_CSPOL(spi->chip_select); + qspi->dc |= QSPI_CSPOL(spi_get_chipselect(spi, 0)); frame_len_words = 0; list_for_each_entry(t, &m->transfers, transfer_list) @@ -686,7 +686,7 @@ static int ti_qspi_start_transfer_one(struct spi_master *master, /* setup command reg */ qspi->cmd = 0; - qspi->cmd |= QSPI_EN_CS(spi->chip_select); + qspi->cmd |= QSPI_EN_CS(spi_get_chipselect(spi, 0)); qspi->cmd |= QSPI_FLEN(frame_len_words); ti_qspi_write(qspi, qspi->dc, QSPI_SPI_DC_REG); diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index cbb60198a7f0..af5846cfe5e9 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c @@ -499,7 +499,7 @@ static inline void pch_spi_select_chip(struct pch_spi_data *data, struct spi_device *pspi) { if (data->current_chip != NULL) { - if (pspi->chip_select != data->n_curnt_chip) { + if (spi_get_chipselect(pspi, 0) != data->n_curnt_chip) { dev_dbg(&pspi->dev, "%s : different slave\n", __func__); data->current_chip = NULL; } @@ -507,7 +507,7 @@ static inline void pch_spi_select_chip(struct pch_spi_data *data, data->current_chip = pspi; - data->n_curnt_chip = data->current_chip->chip_select; + data->n_curnt_chip = spi_get_chipselect(data->current_chip, 0); dev_dbg(&pspi->dev, "%s :Invoking pch_spi_setup_transfer\n", __func__); pch_spi_setup_transfer(pspi); @@ -1396,7 +1396,7 @@ err_pci_iomap: return ret; } -static int pch_spi_pd_remove(struct platform_device *plat_dev) +static void pch_spi_pd_remove(struct platform_device *plat_dev) { struct pch_spi_board_data *board_dat = dev_get_platdata(&plat_dev->dev); struct pch_spi_data *data = platform_get_drvdata(plat_dev); @@ -1434,8 +1434,6 @@ static int pch_spi_pd_remove(struct platform_device *plat_dev) pci_iounmap(board_dat->pdev, data->io_remap_addr); spi_unregister_master(data->master); - - return 0; } #ifdef CONFIG_PM static int pch_spi_pd_suspend(struct platform_device *pd_dev, @@ -1516,7 +1514,7 @@ static struct platform_driver pch_spi_pd_driver = { .name = "pch-spi", }, .probe = pch_spi_pd_probe, - .remove = pch_spi_pd_remove, + .remove_new = pch_spi_pd_remove, .suspend = pch_spi_pd_suspend, .resume = pch_spi_pd_resume }; diff --git a/drivers/spi/spi-uniphier.c b/drivers/spi/spi-uniphier.c index cc0da4822231..f5344527af0b 100644 --- a/drivers/spi/spi-uniphier.c +++ b/drivers/spi/spi-uniphier.c @@ -775,7 +775,7 @@ out_master_put: return ret; } -static int uniphier_spi_remove(struct platform_device *pdev) +static void uniphier_spi_remove(struct platform_device *pdev) { struct spi_master *master = platform_get_drvdata(pdev); struct uniphier_spi_priv *priv = spi_master_get_devdata(master); @@ -786,8 +786,6 @@ static int uniphier_spi_remove(struct platform_device *pdev) dma_release_channel(master->dma_rx); clk_disable_unprepare(priv->clk); - - return 0; } static const struct of_device_id uniphier_spi_match[] = { @@ -798,7 +796,7 @@ MODULE_DEVICE_TABLE(of, uniphier_spi_match); static struct platform_driver uniphier_spi_driver = { .probe = uniphier_spi_probe, - .remove = uniphier_spi_remove, + .remove_new = uniphier_spi_remove, .driver = { .name = "uniphier-spi", .of_match_table = uniphier_spi_match, diff --git a/drivers/spi/spi-wpcm-fiu.c b/drivers/spi/spi-wpcm-fiu.c index ab33710d50ac..f15312fdcdaf 100644 --- a/drivers/spi/spi-wpcm-fiu.c +++ b/drivers/spi/spi-wpcm-fiu.c @@ -158,7 +158,7 @@ static int wpcm_fiu_normal_exec(struct spi_mem *mem, const struct spi_mem_op *op if (op->data.dir == SPI_MEM_DATA_OUT) wpcm_fiu_set_data(fiu, op->data.buf.out, op->data.nbytes); - ret = wpcm_fiu_do_uma(fiu, mem->spi->chip_select, op->addr.nbytes == 3, + ret = wpcm_fiu_do_uma(fiu, spi_get_chipselect(mem->spi, 0), op->addr.nbytes == 3, op->data.dir == SPI_MEM_DATA_OUT, op->data.nbytes); if (op->data.dir == SPI_MEM_DATA_IN) @@ -196,7 +196,7 @@ static bool wpcm_fiu_4ba_match(const struct spi_mem_op *op) static int wpcm_fiu_4ba_exec(struct spi_mem *mem, const struct spi_mem_op *op) { struct wpcm_fiu_spi *fiu = spi_controller_get_devdata(mem->spi->controller); - int cs = mem->spi->chip_select; + int cs = spi_get_chipselect(mem->spi, 0); wpcm_fiu_ects_assert(fiu, cs); @@ -241,7 +241,7 @@ static bool wpcm_fiu_rdid_match(const struct spi_mem_op *op) static int wpcm_fiu_rdid_exec(struct spi_mem *mem, const struct spi_mem_op *op) { struct wpcm_fiu_spi *fiu = spi_controller_get_devdata(mem->spi->controller); - int cs = mem->spi->chip_select; + int cs = spi_get_chipselect(mem->spi, 0); /* First transfer */ wpcm_fiu_set_opcode(fiu, op->cmd.opcode); @@ -278,7 +278,7 @@ static bool wpcm_fiu_dummy_match(const struct spi_mem_op *op) static int wpcm_fiu_dummy_exec(struct spi_mem *mem, const struct spi_mem_op *op) { struct wpcm_fiu_spi *fiu = spi_controller_get_devdata(mem->spi->controller); - int cs = mem->spi->chip_select; + int cs = spi_get_chipselect(mem->spi, 0); wpcm_fiu_ects_assert(fiu, cs); @@ -376,7 +376,7 @@ static int wpcm_fiu_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op) static int wpcm_fiu_dirmap_create(struct spi_mem_dirmap_desc *desc) { struct wpcm_fiu_spi *fiu = spi_controller_get_devdata(desc->mem->spi->controller); - int cs = desc->mem->spi->chip_select; + int cs = spi_get_chipselect(desc->mem->spi, 0); if (desc->info.op_tmpl.data.dir != SPI_MEM_DATA_IN) return -ENOTSUPP; @@ -400,7 +400,7 @@ static int wpcm_fiu_dirmap_create(struct spi_mem_dirmap_desc *desc) static ssize_t wpcm_fiu_direct_read(struct spi_mem_dirmap_desc *desc, u64 offs, size_t len, void *buf) { struct wpcm_fiu_spi *fiu = spi_controller_get_devdata(desc->mem->spi->controller); - int cs = desc->mem->spi->chip_select; + int cs = spi_get_chipselect(desc->mem->spi, 0); if (offs >= MAX_MEMORY_SIZE_PER_CS) return -ENOTSUPP; diff --git a/drivers/spi/spi-xcomm.c b/drivers/spi/spi-xcomm.c index 8628241ec99e..5d23411f2a3e 100644 --- a/drivers/spi/spi-xcomm.c +++ b/drivers/spi/spi-xcomm.c @@ -58,7 +58,7 @@ static int spi_xcomm_sync_config(struct spi_xcomm *spi_xcomm, unsigned int len) static void spi_xcomm_chipselect(struct spi_xcomm *spi_xcomm, struct spi_device *spi, int is_active) { - unsigned long cs = spi->chip_select; + unsigned long cs = spi_get_chipselect(spi, 0); uint16_t chipselect = spi_xcomm->chipselect; if (is_active) diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c index 1411548f4255..8e6e3876aa9a 100644 --- a/drivers/spi/spi-xilinx.c +++ b/drivers/spi/spi-xilinx.c @@ -213,7 +213,7 @@ static void xilinx_spi_chipselect(struct spi_device *spi, int is_on) */ cs = xspi->cs_inactive; - cs ^= BIT(spi->chip_select); + cs ^= BIT(spi_get_chipselect(spi, 0)); /* Activate the chip select */ xspi->write_fn(cs, xspi->regs + XSPI_SSR_OFFSET); @@ -228,9 +228,9 @@ static int xilinx_spi_setup_transfer(struct spi_device *spi, struct xilinx_spi *xspi = spi_master_get_devdata(spi->master); if (spi->mode & SPI_CS_HIGH) - xspi->cs_inactive &= ~BIT(spi->chip_select); + xspi->cs_inactive &= ~BIT(spi_get_chipselect(spi, 0)); else - xspi->cs_inactive |= BIT(spi->chip_select); + xspi->cs_inactive |= BIT(spi_get_chipselect(spi, 0)); return 0; } @@ -440,8 +440,7 @@ static int xilinx_spi_probe(struct platform_device *pdev) xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs; init_completion(&xspi->done); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - xspi->regs = devm_ioremap_resource(&pdev->dev, res); + xspi->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(xspi->regs)) return PTR_ERR(xspi->regs); @@ -504,7 +503,7 @@ static int xilinx_spi_probe(struct platform_device *pdev) return 0; } -static int xilinx_spi_remove(struct platform_device *pdev) +static void xilinx_spi_remove(struct platform_device *pdev) { struct spi_master *master = platform_get_drvdata(pdev); struct xilinx_spi *xspi = spi_master_get_devdata(master); @@ -518,8 +517,6 @@ static int xilinx_spi_remove(struct platform_device *pdev) xspi->write_fn(0, regs_base + XIPIF_V123B_DGIER_OFFSET); spi_master_put(xspi->bitbang.master); - - return 0; } /* work with hotplug and coldplug */ @@ -527,7 +524,7 @@ MODULE_ALIAS("platform:" XILINX_SPI_NAME); static struct platform_driver xilinx_spi_driver = { .probe = xilinx_spi_probe, - .remove = xilinx_spi_remove, + .remove_new = xilinx_spi_remove, .driver = { .name = XILINX_SPI_NAME, .of_match_table = xilinx_spi_of_match, diff --git a/drivers/spi/spi-xlp.c b/drivers/spi/spi-xlp.c index e5707fe5c8f1..3b91cdd5ae21 100644 --- a/drivers/spi/spi-xlp.c +++ b/drivers/spi/spi-xlp.c @@ -139,7 +139,7 @@ static int xlp_spi_setup(struct spi_device *spi) int cs; xspi = spi_master_get_devdata(spi->master); - cs = spi->chip_select; + cs = spi_get_chipselect(spi, 0); /* * The value of fdiv must be between 4 and 65535. */ @@ -350,7 +350,7 @@ static int xlp_spi_transfer_one(struct spi_master *master, struct xlp_spi_priv *xspi = spi_master_get_devdata(master); int ret = 0; - xspi->cs = spi->chip_select; + xspi->cs = spi_get_chipselect(spi, 0); xspi->dev = spi->dev; if (spi_transfer_is_last(master, t)) diff --git a/drivers/spi/spi-xtensa-xtfpga.c b/drivers/spi/spi-xtensa-xtfpga.c index 2fa7608f94cd..24dc845b940e 100644 --- a/drivers/spi/spi-xtensa-xtfpga.c +++ b/drivers/spi/spi-xtensa-xtfpga.c @@ -117,15 +117,13 @@ static int xtfpga_spi_probe(struct platform_device *pdev) return 0; } -static int xtfpga_spi_remove(struct platform_device *pdev) +static void xtfpga_spi_remove(struct platform_device *pdev) { struct spi_master *master = platform_get_drvdata(pdev); struct xtfpga_spi *xspi = spi_master_get_devdata(master); spi_bitbang_stop(&xspi->bitbang); spi_master_put(master); - - return 0; } MODULE_ALIAS("platform:" XTFPGA_SPI_NAME); @@ -140,7 +138,7 @@ MODULE_DEVICE_TABLE(of, xtfpga_spi_of_match); static struct platform_driver xtfpga_spi_driver = { .probe = xtfpga_spi_probe, - .remove = xtfpga_spi_remove, + .remove_new = xtfpga_spi_remove, .driver = { .name = XTFPGA_SPI_NAME, .of_match_table = of_match_ptr(xtfpga_spi_of_match), diff --git a/drivers/spi/spi-zynq-qspi.c b/drivers/spi/spi-zynq-qspi.c index 78f31b61a2aa..ee1995b91287 100644 --- a/drivers/spi/spi-zynq-qspi.c +++ b/drivers/spi/spi-zynq-qspi.c @@ -296,7 +296,7 @@ static void zynq_qspi_chipselect(struct spi_device *spi, bool assert) /* Select the lower (CS0) or upper (CS1) memory */ if (ctlr->num_chipselect > 1) { config_reg = zynq_qspi_read(xqspi, ZYNQ_QSPI_LINEAR_CFG_OFFSET); - if (!spi->chip_select) + if (!spi_get_chipselect(spi, 0)) config_reg &= ~ZYNQ_QSPI_LCFG_U_PAGE; else config_reg |= ZYNQ_QSPI_LCFG_U_PAGE; @@ -741,7 +741,7 @@ remove_master: * * Return: 0 on success and error value on failure */ -static int zynq_qspi_remove(struct platform_device *pdev) +static void zynq_qspi_remove(struct platform_device *pdev) { struct zynq_qspi *xqspi = platform_get_drvdata(pdev); @@ -749,8 +749,6 @@ static int zynq_qspi_remove(struct platform_device *pdev) clk_disable_unprepare(xqspi->refclk); clk_disable_unprepare(xqspi->pclk); - - return 0; } static const struct of_device_id zynq_qspi_of_match[] = { @@ -765,7 +763,7 @@ MODULE_DEVICE_TABLE(of, zynq_qspi_of_match); */ static struct platform_driver zynq_qspi_driver = { .probe = zynq_qspi_probe, - .remove = zynq_qspi_remove, + .remove_new = zynq_qspi_remove, .driver = { .name = "zynq-qspi", .of_match_table = zynq_qspi_of_match, diff --git a/drivers/spi/spi-zynqmp-gqspi.c b/drivers/spi/spi-zynqmp-gqspi.c index 95ff15665d44..fb2ca9b90eab 100644 --- a/drivers/spi/spi-zynqmp-gqspi.c +++ b/drivers/spi/spi-zynqmp-gqspi.c @@ -468,7 +468,7 @@ static void zynqmp_qspi_chipselect(struct spi_device *qspi, bool is_high) genfifoentry |= GQSPI_GENFIFO_MODE_SPI; if (!is_high) { - if (!qspi->chip_select) { + if (!spi_get_chipselect(qspi, 0)) { xqspi->genfifobus = GQSPI_GENFIFO_BUS_LOWER; xqspi->genfifocs = GQSPI_GENFIFO_CS_LOWER; } else { @@ -1364,7 +1364,7 @@ remove_master: * * Return: 0 Always */ -static int zynqmp_qspi_remove(struct platform_device *pdev) +static void zynqmp_qspi_remove(struct platform_device *pdev) { struct zynqmp_qspi *xqspi = platform_get_drvdata(pdev); @@ -1373,15 +1373,13 @@ static int zynqmp_qspi_remove(struct platform_device *pdev) clk_disable_unprepare(xqspi->pclk); pm_runtime_set_suspended(&pdev->dev); pm_runtime_disable(&pdev->dev); - - return 0; } MODULE_DEVICE_TABLE(of, zynqmp_qspi_of_match); static struct platform_driver zynqmp_qspi_driver = { .probe = zynqmp_qspi_probe, - .remove = zynqmp_qspi_remove, + .remove_new = zynqmp_qspi_remove, .driver = { .name = "zynqmp-qspi", .of_match_table = zynqmp_qspi_of_match, diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 7bc14fb309a6..a1ad8f41fb86 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -117,24 +117,28 @@ static struct spi_statistics __percpu *spi_alloc_pcpu_stats(struct device *dev) return pcpu_stats; } -#define spi_pcpu_stats_totalize(ret, in, field) \ -do { \ - int i; \ - ret = 0; \ - for_each_possible_cpu(i) { \ - const struct spi_statistics *pcpu_stats; \ - u64 inc; \ - unsigned int start; \ - pcpu_stats = per_cpu_ptr(in, i); \ - do { \ - start = u64_stats_fetch_begin( \ - &pcpu_stats->syncp); \ - inc = u64_stats_read(&pcpu_stats->field); \ - } while (u64_stats_fetch_retry( \ - &pcpu_stats->syncp, start)); \ - ret += inc; \ - } \ -} while (0) +static ssize_t spi_emit_pcpu_stats(struct spi_statistics __percpu *stat, + char *buf, size_t offset) +{ + u64 val = 0; + int i; + + for_each_possible_cpu(i) { + const struct spi_statistics *pcpu_stats; + u64_stats_t *field; + unsigned int start; + u64 inc; + + pcpu_stats = per_cpu_ptr(stat, i); + field = (void *)pcpu_stats + offset; + do { + start = u64_stats_fetch_begin(&pcpu_stats->syncp); + inc = u64_stats_read(field); + } while (u64_stats_fetch_retry(&pcpu_stats->syncp, start)); + val += inc; + } + return sysfs_emit(buf, "%llu\n", val); +} #define SPI_STATISTICS_ATTRS(field, file) \ static ssize_t spi_controller_##field##_show(struct device *dev, \ @@ -165,11 +169,8 @@ static struct device_attribute dev_attr_spi_device_##field = { \ static ssize_t spi_statistics_##name##_show(struct spi_statistics __percpu *stat, \ char *buf) \ { \ - ssize_t len; \ - u64 val; \ - spi_pcpu_stats_totalize(val, stat, field); \ - len = sysfs_emit(buf, "%llu\n", val); \ - return len; \ + return spi_emit_pcpu_stats(stat, buf, \ + offsetof(struct spi_statistics, field)); \ } \ SPI_STATISTICS_ATTRS(name, file) @@ -2367,8 +2368,8 @@ of_register_spi_device(struct spi_controller *ctlr, struct device_node *nc) /* Store a pointer to the node in the device structure */ of_node_get(nc); - spi->dev.of_node = nc; - spi->dev.fwnode = of_fwnode_handle(nc); + + device_set_node(&spi->dev, of_fwnode_handle(nc)); /* Register the new device */ rc = spi_add_device(spi); @@ -3075,7 +3076,7 @@ static int spi_controller_check_ops(struct spi_controller *ctlr) * If ->mem_ops or ->mem_ops->exec_op is NULL, we request that at least * one of the ->transfer_xxx() method be implemented. */ - if (!ctlr->mem_ops || (ctlr->mem_ops && !ctlr->mem_ops->exec_op)) { + if (!ctlr->mem_ops || !ctlr->mem_ops->exec_op) { if (!ctlr->transfer && !ctlr->transfer_one && !ctlr->transfer_one_message) { return -EINVAL; @@ -3621,6 +3622,55 @@ int spi_split_transfers_maxsize(struct spi_controller *ctlr, } EXPORT_SYMBOL_GPL(spi_split_transfers_maxsize); + +/** + * spi_split_transfers_maxwords - split spi transfers into multiple transfers + * when an individual transfer exceeds a + * certain number of SPI words + * @ctlr: the @spi_controller for this transfer + * @msg: the @spi_message to transform + * @maxwords: the number of words to limit each transfer to + * @gfp: GFP allocation flags + * + * Return: status of transformation + */ +int spi_split_transfers_maxwords(struct spi_controller *ctlr, + struct spi_message *msg, + size_t maxwords, + gfp_t gfp) +{ + struct spi_transfer *xfer; + + /* + * Iterate over the transfer_list, + * but note that xfer is advanced to the last transfer inserted + * to avoid checking sizes again unnecessarily (also xfer does + * potentially belong to a different list by the time the + * replacement has happened). + */ + list_for_each_entry(xfer, &msg->transfers, transfer_list) { + size_t maxsize; + int ret; + + if (xfer->bits_per_word <= 8) + maxsize = maxwords; + else if (xfer->bits_per_word <= 16) + maxsize = 2 * maxwords; + else + maxsize = 4 * maxwords; + + if (xfer->len > maxsize) { + ret = __spi_split_transfer_maxsize(ctlr, msg, &xfer, + maxsize, gfp); + if (ret) + return ret; + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(spi_split_transfers_maxwords); + /*-------------------------------------------------------------------------*/ /* Core methods for SPI controller protocol drivers. Some of the diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 5a038c667401..a399c617ca25 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -393,7 +393,7 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) struct spi_controller *ctlr = spi->controller; if (ctlr->use_gpio_descriptors && ctlr->cs_gpiods && - ctlr->cs_gpiods[spi->chip_select]) + ctlr->cs_gpiods[spi_get_chipselect(spi, 0)]) tmp &= ~SPI_CS_HIGH; } @@ -432,7 +432,7 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } if (ctlr->use_gpio_descriptors && ctlr->cs_gpiods && - ctlr->cs_gpiods[spi->chip_select]) + ctlr->cs_gpiods[spi_get_chipselect(spi, 0)]) tmp |= SPI_CS_HIGH; tmp |= spi->mode & ~SPI_MODE_MASK; @@ -805,7 +805,7 @@ static int spidev_probe(struct spi_device *spi) spidev->devt = MKDEV(SPIDEV_MAJOR, minor); dev = device_create(spidev_class, &spi->dev, spidev->devt, spidev, "spidev%d.%d", - spi->master->bus_num, spi->chip_select); + spi->master->bus_num, spi_get_chipselect(spi, 0)); status = PTR_ERR_OR_ZERO(dev); } else { dev_dbg(&spi->dev, "no minor number available!\n"); diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c index afaba94d1d1c..3a4abf3bae40 100644 --- a/drivers/staging/fbtft/fbtft-core.c +++ b/drivers/staging/fbtft/fbtft-core.c @@ -840,7 +840,7 @@ int fbtft_register_framebuffer(struct fb_info *fb_info) sprintf(text1, ", %zu KiB buffer memory", par->txbuf.len >> 10); if (spi) sprintf(text2, ", spi%d.%d at %d MHz", spi->master->bus_num, - spi->chip_select, spi->max_speed_hz / 1000000); + spi_get_chipselect(spi, 0), spi->max_speed_hz / 1000000); dev_info(fb_info->dev, "%s frame buffer, %dx%d, %d KiB video memory%s, fps=%lu%s\n", fb_info->fix.id, fb_info->var.xres, fb_info->var.yres, diff --git a/drivers/staging/greybus/spilib.c b/drivers/staging/greybus/spilib.c index ad0700a0bb81..efb3bec58e15 100644 --- a/drivers/staging/greybus/spilib.c +++ b/drivers/staging/greybus/spilib.c @@ -237,7 +237,7 @@ static struct gb_operation *gb_spi_operation_create(struct gb_spilib *spi, request = operation->request->payload; request->count = cpu_to_le16(count); request->mode = dev->mode; - request->chip_select = dev->chip_select; + request->chip_select = spi_get_chipselect(dev, 0); gb_xfer = &request->transfers[0]; tx_data = gb_xfer + count; /* place tx data after last gb_xfer */ diff --git a/include/linux/platform_data/spi-s3c64xx.h b/include/linux/platform_data/spi-s3c64xx.h index 5df1ace6d2c9..3101152ce449 100644 --- a/include/linux/platform_data/spi-s3c64xx.h +++ b/include/linux/platform_data/spi-s3c64xx.h @@ -29,6 +29,7 @@ struct s3c64xx_spi_csinfo { * struct s3c64xx_spi_info - SPI Controller defining structure * @src_clk_nr: Clock source index for the CLK_CFG[SPI_CLKSEL] field. * @num_cs: Number of CS this controller emulates. + * @no_cs: Used when CS line is not connected. * @cfg_gpio: Configure pins for this SPI controller. */ struct s3c64xx_spi_info { diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 4fa26b9a3572..cfe42f8cd7a4 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -184,8 +184,18 @@ struct spi_device { u8 chip_select; u8 bits_per_word; bool rt; -#define SPI_NO_TX BIT(31) /* No transmit wire */ -#define SPI_NO_RX BIT(30) /* No receive wire */ +#define SPI_NO_TX BIT(31) /* No transmit wire */ +#define SPI_NO_RX BIT(30) /* No receive wire */ + /* + * TPM specification defines flow control over SPI. Client device + * can insert a wait state on MISO when address is transmitted by + * controller on MOSI. Detecting the wait state in software is only + * possible for full duplex controllers. For controllers that support + * only half-duplex, the wait state detection needs to be implemented + * in hardware. TPM devices would set this flag when hardware flow + * control is expected from SPI controller. + */ +#define SPI_TPM_HW_FLOW BIT(29) /* TPM HW flow control */ /* * All bits defined above should be covered by SPI_MODE_KERNEL_MASK. * The SPI_MODE_KERNEL_MASK has the SPI_MODE_USER_MASK counterpart, @@ -195,7 +205,7 @@ struct spi_device { * These bits must not overlap. A static assert check should make sure of that. * If adding extra bits, make sure to decrease the bit index below as well. */ -#define SPI_MODE_KERNEL_MASK (~(BIT(30) - 1)) +#define SPI_MODE_KERNEL_MASK (~(BIT(29) - 1)) u32 mode; int irq; void *controller_state; @@ -244,7 +254,7 @@ static inline void spi_dev_put(struct spi_device *spi) } /* ctldata is for the bus_controller driver's runtime state */ -static inline void *spi_get_ctldata(struct spi_device *spi) +static inline void *spi_get_ctldata(const struct spi_device *spi) { return spi->controller_state; } @@ -261,12 +271,12 @@ static inline void spi_set_drvdata(struct spi_device *spi, void *data) dev_set_drvdata(&spi->dev, data); } -static inline void *spi_get_drvdata(struct spi_device *spi) +static inline void *spi_get_drvdata(const struct spi_device *spi) { return dev_get_drvdata(&spi->dev); } -static inline u8 spi_get_chipselect(struct spi_device *spi, u8 idx) +static inline u8 spi_get_chipselect(const struct spi_device *spi, u8 idx) { return spi->chip_select; } @@ -276,7 +286,7 @@ static inline void spi_set_chipselect(struct spi_device *spi, u8 idx, u8 chipsel spi->chip_select = chipselect; } -static inline struct gpio_desc *spi_get_csgpiod(struct spi_device *spi, u8 idx) +static inline struct gpio_desc *spi_get_csgpiod(const struct spi_device *spi, u8 idx) { return spi->cs_gpiod; } @@ -1093,6 +1103,9 @@ struct spi_message { unsigned is_dma_mapped:1; + /* spi_prepare_message() was called for this message */ + bool prepared; + /* REVISIT: we might want a flag affecting the behavior of the * last transfer ... allowing things like "read 16 bit length L" * immediately followed by "read L bytes". Basically imposing @@ -1105,11 +1118,11 @@ struct spi_message { */ /* Completion is reported through a callback */ + int status; void (*complete)(void *context); void *context; unsigned frame_length; unsigned actual_length; - int status; /* For optional use by whatever driver currently owns the * spi_message ... between calls to spi_async and then later @@ -1120,9 +1133,6 @@ struct spi_message { /* List of spi_res reources when the spi message is processed */ struct list_head resources; - - /* spi_prepare_message() was called for this message */ - bool prepared; }; static inline void spi_message_init_no_memset(struct spi_message *m) @@ -1295,6 +1305,10 @@ extern int spi_split_transfers_maxsize(struct spi_controller *ctlr, struct spi_message *msg, size_t maxsize, gfp_t gfp); +extern int spi_split_transfers_maxwords(struct spi_controller *ctlr, + struct spi_message *msg, + size_t maxwords, + gfp_t gfp); /*---------------------------------------------------------------------------*/ diff --git a/include/trace/events/spi.h b/include/trace/events/spi.h index c0d9844befd7..c0248a8fa79c 100644 --- a/include/trace/events/spi.h +++ b/include/trace/events/spi.h @@ -57,7 +57,7 @@ TRACE_EVENT(spi_setup, TP_fast_assign( __entry->bus_num = spi->controller->bus_num; - __entry->chip_select = spi->chip_select; + __entry->chip_select = spi_get_chipselect(spi, 0); __entry->mode = spi->mode; __entry->bits_per_word = spi->bits_per_word; __entry->max_speed_hz = spi->max_speed_hz; @@ -88,7 +88,7 @@ TRACE_EVENT(spi_set_cs, TP_fast_assign( __entry->bus_num = spi->controller->bus_num; - __entry->chip_select = spi->chip_select; + __entry->chip_select = spi_get_chipselect(spi, 0); __entry->mode = spi->mode; __entry->enable = enable; ), @@ -113,7 +113,7 @@ DECLARE_EVENT_CLASS(spi_message, TP_fast_assign( __entry->bus_num = msg->spi->controller->bus_num; - __entry->chip_select = msg->spi->chip_select; + __entry->chip_select = spi_get_chipselect(msg->spi, 0); __entry->msg = msg; ), @@ -154,7 +154,7 @@ TRACE_EVENT(spi_message_done, TP_fast_assign( __entry->bus_num = msg->spi->controller->bus_num; - __entry->chip_select = msg->spi->chip_select; + __entry->chip_select = spi_get_chipselect(msg->spi, 0); __entry->msg = msg; __entry->frame = msg->frame_length; __entry->actual = msg->actual_length; @@ -197,7 +197,7 @@ DECLARE_EVENT_CLASS(spi_transfer, TP_fast_assign( __entry->bus_num = msg->spi->controller->bus_num; - __entry->chip_select = msg->spi->chip_select; + __entry->chip_select = spi_get_chipselect(msg->spi, 0); __entry->xfer = xfer; __entry->len = xfer->len; diff --git a/sound/pci/hda/cs35l41_hda_spi.c b/sound/pci/hda/cs35l41_hda_spi.c index 71979cfb4d7e..eb287aa5f782 100644 --- a/sound/pci/hda/cs35l41_hda_spi.c +++ b/sound/pci/hda/cs35l41_hda_spi.c @@ -25,7 +25,7 @@ static int cs35l41_hda_spi_probe(struct spi_device *spi) else return -ENODEV; - return cs35l41_hda_probe(&spi->dev, device_name, spi->chip_select, spi->irq, + return cs35l41_hda_probe(&spi->dev, device_name, spi_get_chipselect(spi, 0), spi->irq, devm_regmap_init_spi(spi, &cs35l41_regmap_spi)); } |