From 45971bdd8ca8b5a99a49f4db86737401c45e246f Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Tue, 2 Nov 2021 16:02:02 -0600 Subject: spi: remove unused header file Commit 6acaadc852f1 ("spi: clps711x: Driver refactor") removed the only use of , but left the header file behind. This file is unused, delete it. Cc: Signed-off-by: Arnd Bergmann Cc: Signed-off-by: Mark Brown Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Jonathan Corbet Acked-by: Arnd Bergmann Link: https://lore.kernel.org/r/20211102220203.940290-9-corbet@lwn.net Signed-off-by: Mark Brown --- include/linux/platform_data/spi-clps711x.h | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 include/linux/platform_data/spi-clps711x.h diff --git a/include/linux/platform_data/spi-clps711x.h b/include/linux/platform_data/spi-clps711x.h deleted file mode 100644 index efaa596848c9..000000000000 --- a/include/linux/platform_data/spi-clps711x.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * CLPS711X SPI bus driver definitions - * - * Copyright (C) 2012 Alexander Shiyan - */ - -#ifndef ____LINUX_PLATFORM_DATA_SPI_CLPS711X_H -#define ____LINUX_PLATFORM_DATA_SPI_CLPS711X_H - -/* Board specific platform_data */ -struct spi_clps711x_pdata { - int *chipselect; /* Array of GPIO-numbers */ - int num_chipselect; /* Total count of GPIOs */ -}; - -#endif -- cgit v1.2.3 From f02bff30114f385d53ae3e45141db602923bca5d Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Tue, 9 Nov 2021 11:31:34 +0100 Subject: spi: lpspi: release requested DMA channels The requested DMA channels are never released. Do this in .remove as well as in .probe. spi_register_controller() can return -EPROBE_DEFER if cs-gpios are not probed yet. Signed-off-by: Alexander Stein Link: https://lore.kernel.org/r/20211109103134.184216-1-alexander.stein@ew.tq-group.com Signed-off-by: Mark Brown --- drivers/spi/spi-fsl-lpspi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c index c72e501c270f..4c601294f8fa 100644 --- a/drivers/spi/spi-fsl-lpspi.c +++ b/drivers/spi/spi-fsl-lpspi.c @@ -913,7 +913,7 @@ static int fsl_lpspi_probe(struct platform_device *pdev) ret = devm_spi_register_controller(&pdev->dev, controller); if (ret < 0) { dev_err_probe(&pdev->dev, ret, "spi_register_controller error: %i\n", ret); - goto out_pm_get; + goto free_dma; } pm_runtime_mark_last_busy(fsl_lpspi->dev); @@ -921,6 +921,8 @@ static int fsl_lpspi_probe(struct platform_device *pdev) return 0; +free_dma: + fsl_lpspi_dma_exit(controller); out_pm_get: pm_runtime_dont_use_autosuspend(fsl_lpspi->dev); pm_runtime_put_sync(fsl_lpspi->dev); @@ -937,6 +939,8 @@ static int fsl_lpspi_remove(struct platform_device *pdev) struct fsl_lpspi_data *fsl_lpspi = spi_controller_get_devdata(controller); + fsl_lpspi_dma_exit(controller); + pm_runtime_disable(fsl_lpspi->dev); return 0; } -- cgit v1.2.3 From f7d344f2188c9f16e434cadf2a954b5d40365c14 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 9 Nov 2021 10:13:25 -0600 Subject: spi: xlp: Remove Netlogic XLP variants Netlogic XLP was removed in commit 95b8a5e0111a ("MIPS: Remove NETLOGIC support"). With those gone, the single platform left to support is Cavium ThunderX2. Remove the Netlogic variant and DT support. For simplicity, the existing kconfig name is retained. Cc: Mark Brown Cc: linux-spi@vger.kernel.org Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20211109161325.2203564-1-robh@kernel.org Signed-off-by: Mark Brown --- drivers/spi/Kconfig | 11 +++++------ drivers/spi/spi-xlp.c | 8 -------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 596705d24400..b2a8821971e1 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -974,14 +974,13 @@ config SPI_XILINX Or for the DS570, see "XPS Serial Peripheral Interface (SPI) (v2.00b)" config SPI_XLP - tristate "Netlogic XLP SPI controller driver" - depends on CPU_XLP || ARCH_THUNDER2 || COMPILE_TEST + tristate "Cavium ThunderX2 SPI controller driver" + depends on ARCH_THUNDER2 || COMPILE_TEST help - Enable support for the SPI controller on the Netlogic XLP SoCs. - Currently supported XLP variants are XLP8XX, XLP3XX, XLP2XX, XLP9XX - and XLP5XX. + Enable support for the SPI controller on the Cavium ThunderX2. + (Originally on Netlogic XLP SoCs.) - If you have a Netlogic XLP platform say Y here. + If you have a Cavium ThunderX2 platform say Y here. If unsure, say N. config SPI_XTENSA_XTFPGA diff --git a/drivers/spi/spi-xlp.c b/drivers/spi/spi-xlp.c index 797ac0ea8fa3..e5707fe5c8f1 100644 --- a/drivers/spi/spi-xlp.c +++ b/drivers/spi/spi-xlp.c @@ -9,7 +9,6 @@ #include #include #include -#include #include /* SPI Configuration Register */ @@ -436,17 +435,10 @@ static const struct acpi_device_id xlp_spi_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, xlp_spi_acpi_match); #endif -static const struct of_device_id xlp_spi_dt_id[] = { - { .compatible = "netlogic,xlp832-spi" }, - { }, -}; -MODULE_DEVICE_TABLE(of, xlp_spi_dt_id); - static struct platform_driver xlp_spi_driver = { .probe = xlp_spi_probe, .driver = { .name = "xlp-spi", - .of_match_table = xlp_spi_dt_id, .acpi_match_table = ACPI_PTR(xlp_spi_acpi_match), }, }; -- cgit v1.2.3 From a62bacba81c477a6fd8f15da593ad02305a3d6da Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Mon, 15 Nov 2021 21:19:11 +0300 Subject: spi: dw: Add a symbols namespace for the core module The exported from the DW SPI driver core/DMA symbols are only used by the spi-dw-{mmio,pci,bt1}.o objects. Add these symbols to a separate namespace then and make sure the depended modules have it imported. Signed-off-by: Serge Semin Suggested-by: Andy Shevchenko Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20211115181917.7521-2-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown --- drivers/spi/spi-dw-bt1.c | 1 + drivers/spi/spi-dw-core.c | 14 +++++++------- drivers/spi/spi-dw-dma.c | 5 +++-- drivers/spi/spi-dw-mmio.c | 1 + drivers/spi/spi-dw-pci.c | 1 + 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/spi/spi-dw-bt1.c b/drivers/spi/spi-dw-bt1.c index 5be6b7b80c21..ac7e4f30d1da 100644 --- a/drivers/spi/spi-dw-bt1.c +++ b/drivers/spi/spi-dw-bt1.c @@ -339,3 +339,4 @@ module_platform_driver(dw_spi_bt1_driver); MODULE_AUTHOR("Serge Semin "); MODULE_DESCRIPTION("Baikal-T1 System Boot SPI Controller driver"); MODULE_LICENSE("GPL v2"); +MODULE_IMPORT_NS(SPI_DW_CORE); diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index a305074c482e..a14940403ab4 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -106,7 +106,7 @@ void dw_spi_set_cs(struct spi_device *spi, bool enable) else dw_writel(dws, DW_SPI_SER, 0); } -EXPORT_SYMBOL_GPL(dw_spi_set_cs); +EXPORT_SYMBOL_NS_GPL(dw_spi_set_cs, SPI_DW_CORE); /* Return the max entries we can fill into tx fifo */ static inline u32 tx_max(struct dw_spi *dws) @@ -210,7 +210,7 @@ int dw_spi_check_status(struct dw_spi *dws, bool raw) return ret; } -EXPORT_SYMBOL_GPL(dw_spi_check_status); +EXPORT_SYMBOL_NS_GPL(dw_spi_check_status, SPI_DW_CORE); static irqreturn_t dw_spi_transfer_handler(struct dw_spi *dws) { @@ -345,7 +345,7 @@ void dw_spi_update_config(struct dw_spi *dws, struct spi_device *spi, dws->cur_rx_sample_dly = chip->rx_sample_dly; } } -EXPORT_SYMBOL_GPL(dw_spi_update_config); +EXPORT_SYMBOL_NS_GPL(dw_spi_update_config, SPI_DW_CORE); static void dw_spi_irq_setup(struct dw_spi *dws) { @@ -945,7 +945,7 @@ err_free_master: spi_controller_put(master); return ret; } -EXPORT_SYMBOL_GPL(dw_spi_add_host); +EXPORT_SYMBOL_NS_GPL(dw_spi_add_host, SPI_DW_CORE); void dw_spi_remove_host(struct dw_spi *dws) { @@ -960,7 +960,7 @@ void dw_spi_remove_host(struct dw_spi *dws) free_irq(dws->irq, dws->master); } -EXPORT_SYMBOL_GPL(dw_spi_remove_host); +EXPORT_SYMBOL_NS_GPL(dw_spi_remove_host, SPI_DW_CORE); int dw_spi_suspend_host(struct dw_spi *dws) { @@ -973,14 +973,14 @@ int dw_spi_suspend_host(struct dw_spi *dws) spi_shutdown_chip(dws); return 0; } -EXPORT_SYMBOL_GPL(dw_spi_suspend_host); +EXPORT_SYMBOL_NS_GPL(dw_spi_suspend_host, SPI_DW_CORE); int dw_spi_resume_host(struct dw_spi *dws) { spi_hw_init(&dws->master->dev, dws); return spi_controller_resume(dws->master); } -EXPORT_SYMBOL_GPL(dw_spi_resume_host); +EXPORT_SYMBOL_NS_GPL(dw_spi_resume_host, SPI_DW_CORE); MODULE_AUTHOR("Feng Tang "); MODULE_DESCRIPTION("Driver for DesignWare SPI controller core"); diff --git a/drivers/spi/spi-dw-dma.c b/drivers/spi/spi-dw-dma.c index a09831c62192..ca199eee0f13 100644 --- a/drivers/spi/spi-dw-dma.c +++ b/drivers/spi/spi-dw-dma.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -638,7 +639,7 @@ void dw_spi_dma_setup_mfld(struct dw_spi *dws) { dws->dma_ops = &dw_spi_dma_mfld_ops; } -EXPORT_SYMBOL_GPL(dw_spi_dma_setup_mfld); +EXPORT_SYMBOL_NS_GPL(dw_spi_dma_setup_mfld, SPI_DW_CORE); static const struct dw_spi_dma_ops dw_spi_dma_generic_ops = { .dma_init = dw_spi_dma_init_generic, @@ -653,4 +654,4 @@ void dw_spi_dma_setup_generic(struct dw_spi *dws) { dws->dma_ops = &dw_spi_dma_generic_ops; } -EXPORT_SYMBOL_GPL(dw_spi_dma_setup_generic); +EXPORT_SYMBOL_NS_GPL(dw_spi_dma_setup_generic, SPI_DW_CORE); diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c index 3379720cfcb8..c3bacd5a2843 100644 --- a/drivers/spi/spi-dw-mmio.c +++ b/drivers/spi/spi-dw-mmio.c @@ -377,3 +377,4 @@ module_platform_driver(dw_spi_mmio_driver); MODULE_AUTHOR("Jean-Hugues Deschenes "); MODULE_DESCRIPTION("Memory-mapped I/O interface driver for DW SPI Core"); MODULE_LICENSE("GPL v2"); +MODULE_IMPORT_NS(SPI_DW_CORE); diff --git a/drivers/spi/spi-dw-pci.c b/drivers/spi/spi-dw-pci.c index 8a91cd58102f..5552240fee55 100644 --- a/drivers/spi/spi-dw-pci.c +++ b/drivers/spi/spi-dw-pci.c @@ -213,3 +213,4 @@ module_pci_driver(dw_spi_driver); MODULE_AUTHOR("Feng Tang "); MODULE_DESCRIPTION("PCI interface driver for DW SPI Core"); MODULE_LICENSE("GPL v2"); +MODULE_IMPORT_NS(SPI_DW_CORE); -- cgit v1.2.3 From 21b6b3809b840ad3d3f0689aac227929c04e9518 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Mon, 15 Nov 2021 21:19:12 +0300 Subject: spi: dw: Discard redundant DW SSI Frame Formats enumeration The dw_ssi_type enumeration describes the SPI frame formats the controller supports, like Motorola SPI, Texas Instruments SSP and National Semiconductors Microwire, that is the serial protocol utilized for the SPI-transfers. Depending on the DW SSI IP-core configuration the protocol could be either fixed or selectable. If it is changebale the protocol can be selected by means of the CTRL0.FRF field, which possible values encoded by the dw_ssi_type enumeration. Aside with the denoted enum the field values are also described by a set of SPI_FRF_{SPI,SSP,MICROWIRE} macros. Thus currently the DW SPI driver has got two entities describing the same data. Let's get rid of the enumeration one then, since first it hasn't been used as enumeration-type but merely as a parametrized values set and second that would unify the macro-based CSR read/write interface of the driver. While at it convert the macro names to be more descriptive about the protocols they represent. Signed-off-by: Serge Semin Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20211115181917.7521-3-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown --- drivers/spi/spi-dw-core.c | 4 ++-- drivers/spi/spi-dw.h | 12 +++--------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index a14940403ab4..da6100fd185f 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -273,7 +273,7 @@ static u32 dw_spi_prepare_cr0(struct dw_spi *dws, struct spi_device *spi) if (!(dws->caps & DW_SPI_CAP_DWC_SSI)) { /* CTRLR0[ 5: 4] Frame Format */ - cr0 |= SSI_MOTO_SPI << SPI_FRF_OFFSET; + cr0 |= SPI_FRF_MOTO_SPI << SPI_FRF_OFFSET; /* * SPI mode (SCPOL|SCPH) @@ -287,7 +287,7 @@ static u32 dw_spi_prepare_cr0(struct dw_spi *dws, struct spi_device *spi) cr0 |= ((spi->mode & SPI_LOOP) ? 1 : 0) << SPI_SRL_OFFSET; } else { /* CTRLR0[ 7: 6] Frame Format */ - cr0 |= SSI_MOTO_SPI << DWC_SSI_CTRLR0_FRF_OFFSET; + cr0 |= SPI_FRF_MOTO_SPI << DWC_SSI_CTRLR0_FRF_OFFSET; /* * SPI mode (SCPOL|SCPH) diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index b665e040862c..467c342bfe56 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -46,9 +46,9 @@ #define SPI_DFS32_OFFSET 16 #define SPI_FRF_OFFSET 4 -#define SPI_FRF_SPI 0x0 -#define SPI_FRF_SSP 0x1 -#define SPI_FRF_MICROWIRE 0x2 +#define SPI_FRF_MOTO_SPI 0x0 +#define SPI_FRF_TI_SSP 0x1 +#define SPI_FRF_NS_MICROWIRE 0x2 #define SPI_FRF_RESV 0x3 #define SPI_MODE_OFFSET 6 @@ -114,12 +114,6 @@ #define SPI_GET_BYTE(_val, _idx) \ ((_val) >> (BITS_PER_BYTE * (_idx)) & 0xff) -enum dw_ssi_type { - SSI_MOTO_SPI = 0, - SSI_TI_SSP, - SSI_NS_MICROWIRE, -}; - /* DW SPI capabilities */ #define DW_SPI_CAP_CS_OVERRIDE BIT(0) #define DW_SPI_CAP_KEEMBAY_MST BIT(1) -- cgit v1.2.3 From 725b0e3ea899ff1cb799756ade302e7bc13a8559 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Mon, 15 Nov 2021 21:19:13 +0300 Subject: spi: dw: Put the driver entities naming in order Mostly due to a long driver history it's methods and macro names look a bit messy. In particularly that concerns the code their prefixes. A biggest part of the driver functions and macros have got the dw_spi/DW_SPI prefixes. But there are some entities which have been just "spi_/SPI_"-prefixed. Especially that concerns the CSR and their fields macro definitions. It makes the code harder to comprehend since such methods and macros can be easily confused with the global SPI-subsystem exports. In this case the only possible way to more or less quickly distinguish one naming space from another is either by context or by the argument type, which most of the times isn't that easy anyway. In addition to that a new DW SSI IP-core support has been added in the framework of commit e539f435cb9c ("spi: dw: Add support for DesignWare DWC_ssi"), which introduced a new set or macro-prefixes to describe CTRLR0-specific fields and worsen the situation. Finally there are methods with no DW SPI driver-reference prefix at all, that make the code reading even harder. So in order to ease the driver hacking let's bring the code naming to a common base: 1) Each method is supposed to have "dw_spi_" prefix so to be easily distinguished from the kernel API, e.g. SPI-subsystem methods and macros. (Exception is the local implementation of the readl/writel methods since being just the regspace accessors.) 2) Each generically used macro should have DW_SPI_-prefix thus being easily comprehended as the local driver definition. 3) DW APB SSI and DW SSI specific macros should have prefixes as DW_PSSI_ and DW_HSSI_ respectively so referring to the system buses they support (APB and AHB similarly to the DT clocks naming like pclk, hclk). Signed-off-by: Serge Semin Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20211115181917.7521-4-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown --- drivers/spi/spi-dw-bt1.c | 8 +-- drivers/spi/spi-dw-core.c | 138 +++++++++++++++++++++---------------------- drivers/spi/spi-dw-dma.c | 50 ++++++++-------- drivers/spi/spi-dw-mmio.c | 20 +++---- drivers/spi/spi-dw-pci.c | 59 ++++++++++--------- drivers/spi/spi-dw.h | 145 +++++++++++++++++++++++----------------------- 6 files changed, 211 insertions(+), 209 deletions(-) diff --git a/drivers/spi/spi-dw-bt1.c b/drivers/spi/spi-dw-bt1.c index ac7e4f30d1da..c06553416123 100644 --- a/drivers/spi/spi-dw-bt1.c +++ b/drivers/spi/spi-dw-bt1.c @@ -123,7 +123,7 @@ static ssize_t dw_spi_bt1_dirmap_read(struct spi_mem_dirmap_desc *desc, len = min_t(size_t, len, dwsbt1->map_len - offs); /* Collect the controller configuration required by the operation */ - cfg.tmode = SPI_TMOD_EPROMREAD; + cfg.tmode = DW_SPI_CTRLR0_TMOD_EPROMREAD; cfg.dfs = 8; cfg.ndf = 4; cfg.freq = mem->spi->max_speed_hz; @@ -131,13 +131,13 @@ static ssize_t dw_spi_bt1_dirmap_read(struct spi_mem_dirmap_desc *desc, /* Make sure the corresponding CS is de-asserted on transmission */ dw_spi_set_cs(mem->spi, false); - spi_enable_chip(dws, 0); + dw_spi_enable_chip(dws, 0); dw_spi_update_config(dws, mem->spi, &cfg); - spi_umask_intr(dws, SPI_INT_RXFI); + dw_spi_umask_intr(dws, DW_SPI_INT_RXFI); - spi_enable_chip(dws, 1); + dw_spi_enable_chip(dws, 1); /* * Enable the transparent mode of the System Boot Controller. diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index da6100fd185f..57bbffe6d6f9 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -24,7 +24,7 @@ #endif /* Slave spi_device related */ -struct chip_data { +struct dw_spi_chip_data { u32 cr0; u32 rx_sample_dly; /* RX sample delay */ }; @@ -109,7 +109,7 @@ void dw_spi_set_cs(struct spi_device *spi, bool enable) EXPORT_SYMBOL_NS_GPL(dw_spi_set_cs, SPI_DW_CORE); /* Return the max entries we can fill into tx fifo */ -static inline u32 tx_max(struct dw_spi *dws) +static inline u32 dw_spi_tx_max(struct dw_spi *dws) { u32 tx_room, rxtx_gap; @@ -129,14 +129,14 @@ static inline u32 tx_max(struct dw_spi *dws) } /* Return the max entries we should read out of rx fifo */ -static inline u32 rx_max(struct dw_spi *dws) +static inline u32 dw_spi_rx_max(struct dw_spi *dws) { return min_t(u32, dws->rx_len, dw_readl(dws, DW_SPI_RXFLR)); } static void dw_writer(struct dw_spi *dws) { - u32 max = tx_max(dws); + u32 max = dw_spi_tx_max(dws); u32 txw = 0; while (max--) { @@ -157,7 +157,7 @@ static void dw_writer(struct dw_spi *dws) static void dw_reader(struct dw_spi *dws) { - u32 max = rx_max(dws); + u32 max = dw_spi_rx_max(dws); u32 rxw; while (max--) { @@ -186,24 +186,24 @@ int dw_spi_check_status(struct dw_spi *dws, bool raw) else irq_status = dw_readl(dws, DW_SPI_ISR); - if (irq_status & SPI_INT_RXOI) { + if (irq_status & DW_SPI_INT_RXOI) { dev_err(&dws->master->dev, "RX FIFO overflow detected\n"); ret = -EIO; } - if (irq_status & SPI_INT_RXUI) { + if (irq_status & DW_SPI_INT_RXUI) { dev_err(&dws->master->dev, "RX FIFO underflow detected\n"); ret = -EIO; } - if (irq_status & SPI_INT_TXOI) { + if (irq_status & DW_SPI_INT_TXOI) { dev_err(&dws->master->dev, "TX FIFO overflow detected\n"); ret = -EIO; } /* Generically handle the erroneous situation */ if (ret) { - spi_reset_chip(dws); + dw_spi_reset_chip(dws); if (dws->master->cur_msg) dws->master->cur_msg->status = ret; } @@ -230,7 +230,7 @@ static irqreturn_t dw_spi_transfer_handler(struct dw_spi *dws) */ dw_reader(dws); if (!dws->rx_len) { - spi_mask_intr(dws, 0xff); + dw_spi_mask_intr(dws, 0xff); spi_finalize_current_transfer(dws->master); } else if (dws->rx_len <= dw_readl(dws, DW_SPI_RXFTLR)) { dw_writel(dws, DW_SPI_RXFTLR, dws->rx_len - 1); @@ -241,10 +241,10 @@ static irqreturn_t dw_spi_transfer_handler(struct dw_spi *dws) * disabled after the data transmission is finished so not to * have the TXE IRQ flood at the final stage of the transfer. */ - if (irq_status & SPI_INT_TXEI) { + if (irq_status & DW_SPI_INT_TXEI) { dw_writer(dws); if (!dws->tx_len) - spi_mask_intr(dws, SPI_INT_TXEI); + dw_spi_mask_intr(dws, DW_SPI_INT_TXEI); } return IRQ_HANDLED; @@ -260,7 +260,7 @@ static irqreturn_t dw_spi_irq(int irq, void *dev_id) return IRQ_NONE; if (!master->cur_msg) { - spi_mask_intr(dws, 0xff); + dw_spi_mask_intr(dws, 0xff); return IRQ_HANDLED; } @@ -271,37 +271,37 @@ static u32 dw_spi_prepare_cr0(struct dw_spi *dws, struct spi_device *spi) { u32 cr0 = 0; - if (!(dws->caps & DW_SPI_CAP_DWC_SSI)) { + if (!(dws->caps & DW_SPI_CAP_DWC_HSSI)) { /* CTRLR0[ 5: 4] Frame Format */ - cr0 |= SPI_FRF_MOTO_SPI << SPI_FRF_OFFSET; + cr0 |= DW_SPI_CTRLR0_FRF_MOTO_SPI << DW_PSSI_CTRLR0_FRF_OFFSET; /* * SPI mode (SCPOL|SCPH) * CTRLR0[ 6] Serial Clock Phase * CTRLR0[ 7] Serial Clock Polarity */ - cr0 |= ((spi->mode & SPI_CPOL) ? 1 : 0) << SPI_SCOL_OFFSET; - cr0 |= ((spi->mode & SPI_CPHA) ? 1 : 0) << SPI_SCPH_OFFSET; + cr0 |= ((spi->mode & SPI_CPOL) ? 1 : 0) << DW_PSSI_CTRLR0_SCOL_OFFSET; + cr0 |= ((spi->mode & SPI_CPHA) ? 1 : 0) << DW_PSSI_CTRLR0_SCPH_OFFSET; /* CTRLR0[11] Shift Register Loop */ - cr0 |= ((spi->mode & SPI_LOOP) ? 1 : 0) << SPI_SRL_OFFSET; + cr0 |= ((spi->mode & SPI_LOOP) ? 1 : 0) << DW_PSSI_CTRLR0_SRL_OFFSET; } else { /* CTRLR0[ 7: 6] Frame Format */ - cr0 |= SPI_FRF_MOTO_SPI << DWC_SSI_CTRLR0_FRF_OFFSET; + cr0 |= DW_SPI_CTRLR0_FRF_MOTO_SPI << DW_HSSI_CTRLR0_FRF_OFFSET; /* * SPI mode (SCPOL|SCPH) * CTRLR0[ 8] Serial Clock Phase * CTRLR0[ 9] Serial Clock Polarity */ - cr0 |= ((spi->mode & SPI_CPOL) ? 1 : 0) << DWC_SSI_CTRLR0_SCPOL_OFFSET; - cr0 |= ((spi->mode & SPI_CPHA) ? 1 : 0) << DWC_SSI_CTRLR0_SCPH_OFFSET; + cr0 |= ((spi->mode & SPI_CPOL) ? 1 : 0) << DW_HSSI_CTRLR0_SCPOL_OFFSET; + cr0 |= ((spi->mode & SPI_CPHA) ? 1 : 0) << DW_HSSI_CTRLR0_SCPH_OFFSET; /* CTRLR0[13] Shift Register Loop */ - cr0 |= ((spi->mode & SPI_LOOP) ? 1 : 0) << DWC_SSI_CTRLR0_SRL_OFFSET; + cr0 |= ((spi->mode & SPI_LOOP) ? 1 : 0) << DW_HSSI_CTRLR0_SRL_OFFSET; if (dws->caps & DW_SPI_CAP_KEEMBAY_MST) - cr0 |= DWC_SSI_CTRLR0_KEEMBAY_MST; + cr0 |= DW_HSSI_CTRLR0_KEEMBAY_MST; } return cr0; @@ -310,7 +310,7 @@ static u32 dw_spi_prepare_cr0(struct dw_spi *dws, struct spi_device *spi) void dw_spi_update_config(struct dw_spi *dws, struct spi_device *spi, struct dw_spi_cfg *cfg) { - struct chip_data *chip = spi_get_ctldata(spi); + struct dw_spi_chip_data *chip = spi_get_ctldata(spi); u32 cr0 = chip->cr0; u32 speed_hz; u16 clk_div; @@ -318,16 +318,17 @@ void dw_spi_update_config(struct dw_spi *dws, struct spi_device *spi, /* CTRLR0[ 4/3: 0] or CTRLR0[ 20: 16] Data Frame Size */ cr0 |= (cfg->dfs - 1) << dws->dfs_offset; - if (!(dws->caps & DW_SPI_CAP_DWC_SSI)) + if (!(dws->caps & DW_SPI_CAP_DWC_HSSI)) /* CTRLR0[ 9:8] Transfer Mode */ - cr0 |= cfg->tmode << SPI_TMOD_OFFSET; + cr0 |= cfg->tmode << DW_PSSI_CTRLR0_TMOD_OFFSET; else /* CTRLR0[11:10] Transfer Mode */ - cr0 |= cfg->tmode << DWC_SSI_CTRLR0_TMOD_OFFSET; + cr0 |= cfg->tmode << DW_HSSI_CTRLR0_TMOD_OFFSET; dw_writel(dws, DW_SPI_CTRLR0, cr0); - if (cfg->tmode == SPI_TMOD_EPROMREAD || cfg->tmode == SPI_TMOD_RO) + if (cfg->tmode == DW_SPI_CTRLR0_TMOD_EPROMREAD || + cfg->tmode == DW_SPI_CTRLR0_TMOD_RO) dw_writel(dws, DW_SPI_CTRLR1, cfg->ndf ? cfg->ndf - 1 : 0); /* Note DW APB SSI clock divider doesn't support odd numbers */ @@ -335,7 +336,7 @@ void dw_spi_update_config(struct dw_spi *dws, struct spi_device *spi, speed_hz = dws->max_freq / clk_div; if (dws->current_freq != speed_hz) { - spi_set_clk(dws, clk_div); + dw_spi_set_clk(dws, clk_div); dws->current_freq = speed_hz; } @@ -363,9 +364,9 @@ static void dw_spi_irq_setup(struct dw_spi *dws) dws->transfer_handler = dw_spi_transfer_handler; - imask = SPI_INT_TXEI | SPI_INT_TXOI | SPI_INT_RXUI | SPI_INT_RXOI | - SPI_INT_RXFI; - spi_umask_intr(dws, imask); + imask = DW_SPI_INT_TXEI | DW_SPI_INT_TXOI | + DW_SPI_INT_RXUI | DW_SPI_INT_RXOI | DW_SPI_INT_RXFI; + dw_spi_umask_intr(dws, imask); } /* @@ -405,11 +406,12 @@ static int dw_spi_poll_transfer(struct dw_spi *dws, } static int dw_spi_transfer_one(struct spi_controller *master, - struct spi_device *spi, struct spi_transfer *transfer) + struct spi_device *spi, + struct spi_transfer *transfer) { struct dw_spi *dws = spi_controller_get_devdata(master); struct dw_spi_cfg cfg = { - .tmode = SPI_TMOD_TR, + .tmode = DW_SPI_CTRLR0_TMOD_TR, .dfs = transfer->bits_per_word, .freq = transfer->speed_hz, }; @@ -425,7 +427,7 @@ static int dw_spi_transfer_one(struct spi_controller *master, /* Ensure the data above is visible for all CPUs */ smp_mb(); - spi_enable_chip(dws, 0); + dw_spi_enable_chip(dws, 0); dw_spi_update_config(dws, spi, &cfg); @@ -436,7 +438,7 @@ static int dw_spi_transfer_one(struct spi_controller *master, dws->dma_mapped = master->cur_msg_mapped; /* For poll mode just disable all interrupts */ - spi_mask_intr(dws, 0xff); + dw_spi_mask_intr(dws, 0xff); if (dws->dma_mapped) { ret = dws->dma_ops->dma_setup(dws, transfer); @@ -444,7 +446,7 @@ static int dw_spi_transfer_one(struct spi_controller *master, return ret; } - spi_enable_chip(dws, 1); + dw_spi_enable_chip(dws, 1); if (dws->dma_mapped) return dws->dma_ops->dma_transfer(dws, transfer); @@ -457,20 +459,20 @@ static int dw_spi_transfer_one(struct spi_controller *master, } static void dw_spi_handle_err(struct spi_controller *master, - struct spi_message *msg) + struct spi_message *msg) { struct dw_spi *dws = spi_controller_get_devdata(master); if (dws->dma_mapped) dws->dma_ops->dma_stop(dws); - spi_reset_chip(dws); + dw_spi_reset_chip(dws); } static int dw_spi_adjust_mem_op_size(struct spi_mem *mem, struct spi_mem_op *op) { if (op->data.dir == SPI_MEM_DATA_IN) - op->data.nbytes = clamp_val(op->data.nbytes, 0, SPI_NDF_MASK + 1); + op->data.nbytes = clamp_val(op->data.nbytes, 0, DW_SPI_NDF_MASK + 1); return 0; } @@ -498,7 +500,7 @@ static int dw_spi_init_mem_buf(struct dw_spi *dws, const struct spi_mem_op *op) if (op->data.dir == SPI_MEM_DATA_OUT) len += op->data.nbytes; - if (len <= SPI_BUF_SIZE) { + if (len <= DW_SPI_BUF_SIZE) { out = dws->buf; } else { out = kzalloc(len, GFP_KERNEL); @@ -512,9 +514,9 @@ static int dw_spi_init_mem_buf(struct dw_spi *dws, const struct spi_mem_op *op) * single buffer in order to speed the data transmission up. */ for (i = 0; i < op->cmd.nbytes; ++i) - out[i] = SPI_GET_BYTE(op->cmd.opcode, op->cmd.nbytes - i - 1); + out[i] = DW_SPI_GET_BYTE(op->cmd.opcode, op->cmd.nbytes - i - 1); for (j = 0; j < op->addr.nbytes; ++i, ++j) - out[i] = SPI_GET_BYTE(op->addr.val, op->addr.nbytes - j - 1); + out[i] = DW_SPI_GET_BYTE(op->addr.val, op->addr.nbytes - j - 1); for (j = 0; j < op->dummy.nbytes; ++i, ++j) out[i] = 0x0; @@ -587,7 +589,7 @@ static int dw_spi_write_then_read(struct dw_spi *dws, struct spi_device *spi) entries = readl_relaxed(dws->regs + DW_SPI_RXFLR); if (!entries) { sts = readl_relaxed(dws->regs + DW_SPI_RISR); - if (sts & SPI_INT_RXOI) { + if (sts & DW_SPI_INT_RXOI) { dev_err(&dws->master->dev, "FIFO overflow on Rx\n"); return -EIO; } @@ -603,12 +605,12 @@ static int dw_spi_write_then_read(struct dw_spi *dws, struct spi_device *spi) static inline bool dw_spi_ctlr_busy(struct dw_spi *dws) { - return dw_readl(dws, DW_SPI_SR) & SR_BUSY; + return dw_readl(dws, DW_SPI_SR) & DW_SPI_SR_BUSY; } static int dw_spi_wait_mem_op_done(struct dw_spi *dws) { - int retry = SPI_WAIT_RETRIES; + int retry = DW_SPI_WAIT_RETRIES; struct spi_delay delay; unsigned long ns, us; u32 nents; @@ -638,9 +640,9 @@ static int dw_spi_wait_mem_op_done(struct dw_spi *dws) static void dw_spi_stop_mem_op(struct dw_spi *dws, struct spi_device *spi) { - spi_enable_chip(dws, 0); + dw_spi_enable_chip(dws, 0); dw_spi_set_cs(spi, true); - spi_enable_chip(dws, 1); + dw_spi_enable_chip(dws, 1); } /* @@ -673,19 +675,19 @@ static int dw_spi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op) cfg.dfs = 8; cfg.freq = clamp(mem->spi->max_speed_hz, 0U, dws->max_mem_freq); if (op->data.dir == SPI_MEM_DATA_IN) { - cfg.tmode = SPI_TMOD_EPROMREAD; + cfg.tmode = DW_SPI_CTRLR0_TMOD_EPROMREAD; cfg.ndf = op->data.nbytes; } else { - cfg.tmode = SPI_TMOD_TO; + cfg.tmode = DW_SPI_CTRLR0_TMOD_TO; } - spi_enable_chip(dws, 0); + dw_spi_enable_chip(dws, 0); dw_spi_update_config(dws, mem->spi, &cfg); - spi_mask_intr(dws, 0xff); + dw_spi_mask_intr(dws, 0xff); - spi_enable_chip(dws, 1); + dw_spi_enable_chip(dws, 1); /* * DW APB SSI controller has very nasty peculiarities. First originally @@ -768,7 +770,7 @@ static void dw_spi_init_mem_ops(struct dw_spi *dws) static int dw_spi_setup(struct spi_device *spi) { struct dw_spi *dws = spi_controller_get_devdata(spi->controller); - struct chip_data *chip; + struct dw_spi_chip_data *chip; /* Only alloc on first setup */ chip = spi_get_ctldata(spi); @@ -776,7 +778,7 @@ static int dw_spi_setup(struct spi_device *spi) struct dw_spi *dws = spi_controller_get_devdata(spi->controller); u32 rx_sample_dly_ns; - chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (!chip) return -ENOMEM; spi_set_ctldata(spi, chip); @@ -803,16 +805,16 @@ static int dw_spi_setup(struct spi_device *spi) static void dw_spi_cleanup(struct spi_device *spi) { - struct chip_data *chip = spi_get_ctldata(spi); + struct dw_spi_chip_data *chip = spi_get_ctldata(spi); kfree(chip); spi_set_ctldata(spi, NULL); } /* Restart the controller, disable all interrupts, clean rx fifo */ -static void spi_hw_init(struct device *dev, struct dw_spi *dws) +static void dw_spi_hw_init(struct device *dev, struct dw_spi *dws) { - spi_reset_chip(dws); + dw_spi_reset_chip(dws); /* * Try to detect the FIFO depth if not set by interface driver, @@ -837,18 +839,18 @@ static void spi_hw_init(struct device *dev, struct dw_spi *dws) * writability. Note DWC SSI controller also has the extended DFS, but * with zero offset. */ - if (!(dws->caps & DW_SPI_CAP_DWC_SSI)) { + if (!(dws->caps & DW_SPI_CAP_DWC_HSSI)) { u32 cr0, tmp = dw_readl(dws, DW_SPI_CTRLR0); - spi_enable_chip(dws, 0); + dw_spi_enable_chip(dws, 0); dw_writel(dws, DW_SPI_CTRLR0, 0xffffffff); cr0 = dw_readl(dws, DW_SPI_CTRLR0); dw_writel(dws, DW_SPI_CTRLR0, tmp); - spi_enable_chip(dws, 1); + dw_spi_enable_chip(dws, 1); - if (!(cr0 & SPI_DFS_MASK)) { + if (!(cr0 & DW_PSSI_CTRLR0_DFS_MASK)) { dws->caps |= DW_SPI_CAP_DFS32; - dws->dfs_offset = SPI_DFS32_OFFSET; + dws->dfs_offset = DW_PSSI_CTRLR0_DFS32_OFFSET; dev_dbg(dev, "Detected 32-bits max data frame size\n"); } } else { @@ -878,7 +880,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) spi_controller_set_devdata(master, dws); /* Basic HW init */ - spi_hw_init(dev, dws); + dw_spi_hw_init(dev, dws); ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dev_name(dev), master); @@ -939,7 +941,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) err_dma_exit: if (dws->dma_ops && dws->dma_ops->dma_exit) dws->dma_ops->dma_exit(dws); - spi_enable_chip(dws, 0); + dw_spi_enable_chip(dws, 0); free_irq(dws->irq, master); err_free_master: spi_controller_put(master); @@ -956,7 +958,7 @@ void dw_spi_remove_host(struct dw_spi *dws) if (dws->dma_ops && dws->dma_ops->dma_exit) dws->dma_ops->dma_exit(dws); - spi_shutdown_chip(dws); + dw_spi_shutdown_chip(dws); free_irq(dws->irq, dws->master); } @@ -970,14 +972,14 @@ int dw_spi_suspend_host(struct dw_spi *dws) if (ret) return ret; - spi_shutdown_chip(dws); + dw_spi_shutdown_chip(dws); return 0; } EXPORT_SYMBOL_NS_GPL(dw_spi_suspend_host, SPI_DW_CORE); int dw_spi_resume_host(struct dw_spi *dws) { - spi_hw_init(&dws->master->dev, dws); + dw_spi_hw_init(&dws->master->dev, dws); return spi_controller_resume(dws->master); } EXPORT_SYMBOL_NS_GPL(dw_spi_resume_host, SPI_DW_CORE); diff --git a/drivers/spi/spi-dw-dma.c b/drivers/spi/spi-dw-dma.c index ca199eee0f13..63e5260100ec 100644 --- a/drivers/spi/spi-dw-dma.c +++ b/drivers/spi/spi-dw-dma.c @@ -18,10 +18,10 @@ #include "spi-dw.h" -#define RX_BUSY 0 -#define RX_BURST_LEVEL 16 -#define TX_BUSY 1 -#define TX_BURST_LEVEL 16 +#define DW_SPI_RX_BUSY 0 +#define DW_SPI_RX_BURST_LEVEL 16 +#define DW_SPI_TX_BUSY 1 +#define DW_SPI_TX_BURST_LEVEL 16 static bool dw_spi_dma_chan_filter(struct dma_chan *chan, void *param) { @@ -46,7 +46,7 @@ static void dw_spi_dma_maxburst_init(struct dw_spi *dws) if (!ret && caps.max_burst) max_burst = caps.max_burst; else - max_burst = RX_BURST_LEVEL; + max_burst = DW_SPI_RX_BURST_LEVEL; dws->rxburst = min(max_burst, def_burst); dw_writel(dws, DW_SPI_DMARDLR, dws->rxburst - 1); @@ -55,7 +55,7 @@ static void dw_spi_dma_maxburst_init(struct dw_spi *dws) if (!ret && caps.max_burst) max_burst = caps.max_burst; else - max_burst = TX_BURST_LEVEL; + max_burst = DW_SPI_TX_BURST_LEVEL; /* * Having a Rx DMA channel serviced with higher priority than a Tx DMA @@ -227,13 +227,13 @@ static int dw_spi_dma_wait(struct dw_spi *dws, unsigned int len, u32 speed) static inline bool dw_spi_dma_tx_busy(struct dw_spi *dws) { - return !(dw_readl(dws, DW_SPI_SR) & SR_TF_EMPT); + return !(dw_readl(dws, DW_SPI_SR) & DW_SPI_SR_TF_EMPT); } static int dw_spi_dma_wait_tx_done(struct dw_spi *dws, struct spi_transfer *xfer) { - int retry = SPI_WAIT_RETRIES; + int retry = DW_SPI_WAIT_RETRIES; struct spi_delay delay; u32 nents; @@ -260,8 +260,8 @@ static void dw_spi_dma_tx_done(void *arg) { struct dw_spi *dws = arg; - clear_bit(TX_BUSY, &dws->dma_chan_busy); - if (test_bit(RX_BUSY, &dws->dma_chan_busy)) + clear_bit(DW_SPI_TX_BUSY, &dws->dma_chan_busy); + if (test_bit(DW_SPI_RX_BUSY, &dws->dma_chan_busy)) return; complete(&dws->dma_completion); @@ -305,19 +305,19 @@ static int dw_spi_dma_submit_tx(struct dw_spi *dws, struct scatterlist *sgl, return ret; } - set_bit(TX_BUSY, &dws->dma_chan_busy); + set_bit(DW_SPI_TX_BUSY, &dws->dma_chan_busy); return 0; } static inline bool dw_spi_dma_rx_busy(struct dw_spi *dws) { - return !!(dw_readl(dws, DW_SPI_SR) & SR_RF_NOT_EMPT); + return !!(dw_readl(dws, DW_SPI_SR) & DW_SPI_SR_RF_NOT_EMPT); } static int dw_spi_dma_wait_rx_done(struct dw_spi *dws) { - int retry = SPI_WAIT_RETRIES; + int retry = DW_SPI_WAIT_RETRIES; struct spi_delay delay; unsigned long ns, us; u32 nents; @@ -361,8 +361,8 @@ static void dw_spi_dma_rx_done(void *arg) { struct dw_spi *dws = arg; - clear_bit(RX_BUSY, &dws->dma_chan_busy); - if (test_bit(TX_BUSY, &dws->dma_chan_busy)) + clear_bit(DW_SPI_RX_BUSY, &dws->dma_chan_busy); + if (test_bit(DW_SPI_TX_BUSY, &dws->dma_chan_busy)) return; complete(&dws->dma_completion); @@ -406,7 +406,7 @@ static int dw_spi_dma_submit_rx(struct dw_spi *dws, struct scatterlist *sgl, return ret; } - set_bit(RX_BUSY, &dws->dma_chan_busy); + set_bit(DW_SPI_RX_BUSY, &dws->dma_chan_busy); return 0; } @@ -431,16 +431,16 @@ static int dw_spi_dma_setup(struct dw_spi *dws, struct spi_transfer *xfer) } /* Set the DMA handshaking interface */ - dma_ctrl = SPI_DMA_TDMAE; + dma_ctrl = DW_SPI_DMACR_TDMAE; if (xfer->rx_buf) - dma_ctrl |= SPI_DMA_RDMAE; + dma_ctrl |= DW_SPI_DMACR_RDMAE; dw_writel(dws, DW_SPI_DMACR, dma_ctrl); /* Set the interrupt mask */ - imr = SPI_INT_TXOI; + imr = DW_SPI_INT_TXOI; if (xfer->rx_buf) - imr |= SPI_INT_RXUI | SPI_INT_RXOI; - spi_umask_intr(dws, imr); + imr |= DW_SPI_INT_RXUI | DW_SPI_INT_RXOI; + dw_spi_umask_intr(dws, imr); reinit_completion(&dws->dma_completion); @@ -616,13 +616,13 @@ static int dw_spi_dma_transfer(struct dw_spi *dws, struct spi_transfer *xfer) static void dw_spi_dma_stop(struct dw_spi *dws) { - if (test_bit(TX_BUSY, &dws->dma_chan_busy)) { + if (test_bit(DW_SPI_TX_BUSY, &dws->dma_chan_busy)) { dmaengine_terminate_sync(dws->txchan); - clear_bit(TX_BUSY, &dws->dma_chan_busy); + clear_bit(DW_SPI_TX_BUSY, &dws->dma_chan_busy); } - if (test_bit(RX_BUSY, &dws->dma_chan_busy)) { + if (test_bit(DW_SPI_RX_BUSY, &dws->dma_chan_busy)) { dmaengine_terminate_sync(dws->rxchan); - clear_bit(RX_BUSY, &dws->dma_chan_busy); + clear_bit(DW_SPI_RX_BUSY, &dws->dma_chan_busy); } } diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c index c3bacd5a2843..2193c2550e74 100644 --- a/drivers/spi/spi-dw-mmio.c +++ b/drivers/spi/spi-dw-mmio.c @@ -196,18 +196,18 @@ static int dw_spi_alpine_init(struct platform_device *pdev, return 0; } -static int dw_spi_dw_apb_init(struct platform_device *pdev, - struct dw_spi_mmio *dwsmmio) +static int dw_spi_pssi_init(struct platform_device *pdev, + struct dw_spi_mmio *dwsmmio) { dw_spi_dma_setup_generic(&dwsmmio->dws); return 0; } -static int dw_spi_dwc_ssi_init(struct platform_device *pdev, - struct dw_spi_mmio *dwsmmio) +static int dw_spi_hssi_init(struct platform_device *pdev, + struct dw_spi_mmio *dwsmmio) { - dwsmmio->dws.caps = DW_SPI_CAP_DWC_SSI; + dwsmmio->dws.caps = DW_SPI_CAP_DWC_HSSI; dw_spi_dma_setup_generic(&dwsmmio->dws); @@ -217,7 +217,7 @@ static int dw_spi_dwc_ssi_init(struct platform_device *pdev, static int dw_spi_keembay_init(struct platform_device *pdev, struct dw_spi_mmio *dwsmmio) { - dwsmmio->dws.caps = DW_SPI_CAP_KEEMBAY_MST | DW_SPI_CAP_DWC_SSI; + dwsmmio->dws.caps = DW_SPI_CAP_KEEMBAY_MST | DW_SPI_CAP_DWC_HSSI; return 0; } @@ -342,12 +342,12 @@ static int dw_spi_mmio_remove(struct platform_device *pdev) } static const struct of_device_id dw_spi_mmio_of_match[] = { - { .compatible = "snps,dw-apb-ssi", .data = dw_spi_dw_apb_init}, + { .compatible = "snps,dw-apb-ssi", .data = dw_spi_pssi_init}, { .compatible = "mscc,ocelot-spi", .data = dw_spi_mscc_ocelot_init}, { .compatible = "mscc,jaguar2-spi", .data = dw_spi_mscc_jaguar2_init}, { .compatible = "amazon,alpine-dw-apb-ssi", .data = dw_spi_alpine_init}, - { .compatible = "renesas,rzn1-spi", .data = dw_spi_dw_apb_init}, - { .compatible = "snps,dwc-ssi-1.01a", .data = dw_spi_dwc_ssi_init}, + { .compatible = "renesas,rzn1-spi", .data = dw_spi_pssi_init}, + { .compatible = "snps,dwc-ssi-1.01a", .data = dw_spi_hssi_init}, { .compatible = "intel,keembay-ssi", .data = dw_spi_keembay_init}, { .compatible = "microchip,sparx5-spi", dw_spi_mscc_sparx5_init}, { .compatible = "canaan,k210-spi", dw_spi_canaan_k210_init}, @@ -357,7 +357,7 @@ MODULE_DEVICE_TABLE(of, dw_spi_mmio_of_match); #ifdef CONFIG_ACPI static const struct acpi_device_id dw_spi_mmio_acpi_match[] = { - {"HISI0173", (kernel_ulong_t)dw_spi_dw_apb_init}, + {"HISI0173", (kernel_ulong_t)dw_spi_pssi_init}, {}, }; MODULE_DEVICE_TABLE(acpi, dw_spi_mmio_acpi_match); diff --git a/drivers/spi/spi-dw-pci.c b/drivers/spi/spi-dw-pci.c index 5552240fee55..7c8279d13f31 100644 --- a/drivers/spi/spi-dw-pci.c +++ b/drivers/spi/spi-dw-pci.c @@ -24,14 +24,14 @@ #define CLK_SPI_CDIV_MASK 0x00000e00 #define CLK_SPI_DISABLE_OFFSET 8 -struct spi_pci_desc { +struct dw_spi_pci_desc { int (*setup)(struct dw_spi *); u16 num_cs; u16 bus_num; u32 max_freq; }; -static int spi_mid_init(struct dw_spi *dws) +static int dw_spi_pci_mid_init(struct dw_spi *dws) { void __iomem *clk_reg; u32 clk_cdiv; @@ -53,36 +53,36 @@ static int spi_mid_init(struct dw_spi *dws) return 0; } -static int spi_generic_init(struct dw_spi *dws) +static int dw_spi_pci_generic_init(struct dw_spi *dws) { dw_spi_dma_setup_generic(dws); return 0; } -static struct spi_pci_desc spi_pci_mid_desc_1 = { - .setup = spi_mid_init, +static struct dw_spi_pci_desc dw_spi_pci_mid_desc_1 = { + .setup = dw_spi_pci_mid_init, .num_cs = 5, .bus_num = 0, }; -static struct spi_pci_desc spi_pci_mid_desc_2 = { - .setup = spi_mid_init, +static struct dw_spi_pci_desc dw_spi_pci_mid_desc_2 = { + .setup = dw_spi_pci_mid_init, .num_cs = 2, .bus_num = 1, }; -static struct spi_pci_desc spi_pci_ehl_desc = { - .setup = spi_generic_init, +static struct dw_spi_pci_desc dw_spi_pci_ehl_desc = { + .setup = dw_spi_pci_generic_init, .num_cs = 2, .bus_num = -1, .max_freq = 100000000, }; -static int spi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +static int dw_spi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { + struct dw_spi_pci_desc *desc = (struct dw_spi_pci_desc *)ent->driver_data; struct dw_spi *dws; - struct spi_pci_desc *desc = (struct spi_pci_desc *)ent->driver_data; int pci_bar = 0; int ret; @@ -150,7 +150,7 @@ err_free_irq_vectors: return ret; } -static void spi_pci_remove(struct pci_dev *pdev) +static void dw_spi_pci_remove(struct pci_dev *pdev) { struct dw_spi *dws = pci_get_drvdata(pdev); @@ -162,14 +162,14 @@ static void spi_pci_remove(struct pci_dev *pdev) } #ifdef CONFIG_PM_SLEEP -static int spi_suspend(struct device *dev) +static int dw_spi_pci_suspend(struct device *dev) { struct dw_spi *dws = dev_get_drvdata(dev); return dw_spi_suspend_host(dws); } -static int spi_resume(struct device *dev) +static int dw_spi_pci_resume(struct device *dev) { struct dw_spi *dws = dev_get_drvdata(dev); @@ -177,38 +177,37 @@ static int spi_resume(struct device *dev) } #endif -static SIMPLE_DEV_PM_OPS(dw_spi_pm_ops, spi_suspend, spi_resume); +static SIMPLE_DEV_PM_OPS(dw_spi_pci_pm_ops, dw_spi_pci_suspend, dw_spi_pci_resume); -static const struct pci_device_id pci_ids[] = { +static const struct pci_device_id dw_spi_pci_ids[] = { /* Intel MID platform SPI controller 0 */ /* * The access to the device 8086:0801 is disabled by HW, since it's * exclusively used by SCU to communicate with MSIC. */ /* Intel MID platform SPI controller 1 */ - { PCI_VDEVICE(INTEL, 0x0800), (kernel_ulong_t)&spi_pci_mid_desc_1}, + { PCI_VDEVICE(INTEL, 0x0800), (kernel_ulong_t)&dw_spi_pci_mid_desc_1}, /* Intel MID platform SPI controller 2 */ - { PCI_VDEVICE(INTEL, 0x0812), (kernel_ulong_t)&spi_pci_mid_desc_2}, + { PCI_VDEVICE(INTEL, 0x0812), (kernel_ulong_t)&dw_spi_pci_mid_desc_2}, /* Intel Elkhart Lake PSE SPI controllers */ - { PCI_VDEVICE(INTEL, 0x4b84), (kernel_ulong_t)&spi_pci_ehl_desc}, - { PCI_VDEVICE(INTEL, 0x4b85), (kernel_ulong_t)&spi_pci_ehl_desc}, - { PCI_VDEVICE(INTEL, 0x4b86), (kernel_ulong_t)&spi_pci_ehl_desc}, - { PCI_VDEVICE(INTEL, 0x4b87), (kernel_ulong_t)&spi_pci_ehl_desc}, + { PCI_VDEVICE(INTEL, 0x4b84), (kernel_ulong_t)&dw_spi_pci_ehl_desc}, + { PCI_VDEVICE(INTEL, 0x4b85), (kernel_ulong_t)&dw_spi_pci_ehl_desc}, + { PCI_VDEVICE(INTEL, 0x4b86), (kernel_ulong_t)&dw_spi_pci_ehl_desc}, + { PCI_VDEVICE(INTEL, 0x4b87), (kernel_ulong_t)&dw_spi_pci_ehl_desc}, {}, }; -MODULE_DEVICE_TABLE(pci, pci_ids); +MODULE_DEVICE_TABLE(pci, dw_spi_pci_ids); -static struct pci_driver dw_spi_driver = { +static struct pci_driver dw_spi_pci_driver = { .name = DRIVER_NAME, - .id_table = pci_ids, - .probe = spi_pci_probe, - .remove = spi_pci_remove, + .id_table = dw_spi_pci_ids, + .probe = dw_spi_pci_probe, + .remove = dw_spi_pci_remove, .driver = { - .pm = &dw_spi_pm_ops, + .pm = &dw_spi_pci_pm_ops, }, }; - -module_pci_driver(dw_spi_driver); +module_pci_driver(dw_spi_pci_driver); MODULE_AUTHOR("Feng Tang "); MODULE_DESCRIPTION("PCI interface driver for DW SPI Core"); diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 467c342bfe56..893b78c43a50 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#ifndef DW_SPI_HEADER_H -#define DW_SPI_HEADER_H +#ifndef __SPI_DW_H__ +#define __SPI_DW_H__ #include #include @@ -11,7 +11,7 @@ #include #include -/* Register offsets */ +/* Register offsets (Generic for both DWC APB SSI and DWC SSI IP-cores) */ #define DW_SPI_CTRLR0 0x00 #define DW_SPI_CTRLR1 0x04 #define DW_SPI_SSIENR 0x08 @@ -40,84 +40,85 @@ #define DW_SPI_RX_SAMPLE_DLY 0xf0 #define DW_SPI_CS_OVERRIDE 0xf4 -/* Bit fields in CTRLR0 */ -#define SPI_DFS_OFFSET 0 -#define SPI_DFS_MASK GENMASK(3, 0) -#define SPI_DFS32_OFFSET 16 - -#define SPI_FRF_OFFSET 4 -#define SPI_FRF_MOTO_SPI 0x0 -#define SPI_FRF_TI_SSP 0x1 -#define SPI_FRF_NS_MICROWIRE 0x2 -#define SPI_FRF_RESV 0x3 - -#define SPI_MODE_OFFSET 6 -#define SPI_SCPH_OFFSET 6 -#define SPI_SCOL_OFFSET 7 - -#define SPI_TMOD_OFFSET 8 -#define SPI_TMOD_MASK (0x3 << SPI_TMOD_OFFSET) -#define SPI_TMOD_TR 0x0 /* xmit & recv */ -#define SPI_TMOD_TO 0x1 /* xmit only */ -#define SPI_TMOD_RO 0x2 /* recv only */ -#define SPI_TMOD_EPROMREAD 0x3 /* eeprom read mode */ - -#define SPI_SLVOE_OFFSET 10 -#define SPI_SRL_OFFSET 11 -#define SPI_CFS_OFFSET 12 - -/* Bit fields in CTRLR0 based on DWC_ssi_databook.pdf v1.01a */ -#define DWC_SSI_CTRLR0_SRL_OFFSET 13 -#define DWC_SSI_CTRLR0_TMOD_OFFSET 10 -#define DWC_SSI_CTRLR0_TMOD_MASK GENMASK(11, 10) -#define DWC_SSI_CTRLR0_SCPOL_OFFSET 9 -#define DWC_SSI_CTRLR0_SCPH_OFFSET 8 -#define DWC_SSI_CTRLR0_FRF_OFFSET 6 -#define DWC_SSI_CTRLR0_DFS_OFFSET 0 +/* Bit fields in CTRLR0 (DWC APB SSI) */ +#define DW_PSSI_CTRLR0_DFS_OFFSET 0 +#define DW_PSSI_CTRLR0_DFS_MASK GENMASK(3, 0) +#define DW_PSSI_CTRLR0_DFS32_OFFSET 16 + +#define DW_PSSI_CTRLR0_FRF_OFFSET 4 +#define DW_SPI_CTRLR0_FRF_MOTO_SPI 0x0 +#define DW_SPI_CTRLR0_FRF_TI_SSP 0x1 +#define DW_SPI_CTRLR0_FRF_NS_MICROWIRE 0x2 +#define DW_SPI_CTRLR0_FRF_RESV 0x3 + +#define DW_PSSI_CTRLR0_MODE_OFFSET 6 +#define DW_PSSI_CTRLR0_SCPH_OFFSET 6 +#define DW_PSSI_CTRLR0_SCOL_OFFSET 7 + +#define DW_PSSI_CTRLR0_TMOD_OFFSET 8 +#define DW_PSSI_CTRLR0_TMOD_MASK (0x3 << DW_PSSI_CTRLR0_TMOD_OFFSET) +#define DW_SPI_CTRLR0_TMOD_TR 0x0 /* xmit & recv */ +#define DW_SPI_CTRLR0_TMOD_TO 0x1 /* xmit only */ +#define DW_SPI_CTRLR0_TMOD_RO 0x2 /* recv only */ +#define DW_SPI_CTRLR0_TMOD_EPROMREAD 0x3 /* eeprom read mode */ + +#define DW_PSSI_CTRLR0_SLVOE_OFFSET 10 +#define DW_PSSI_CTRLR0_SRL_OFFSET 11 +#define DW_PSSI_CTRLR0_CFS_OFFSET 12 + +/* Bit fields in CTRLR0 (DWC SSI with AHB interface) */ +#define DW_HSSI_CTRLR0_SRL_OFFSET 13 +#define DW_HSSI_CTRLR0_TMOD_OFFSET 10 +#define DW_HSSI_CTRLR0_TMOD_MASK GENMASK(11, 10) +#define DW_HSSI_CTRLR0_SCPOL_OFFSET 9 +#define DW_HSSI_CTRLR0_SCPH_OFFSET 8 +#define DW_HSSI_CTRLR0_FRF_OFFSET 6 +#define DW_HSSI_CTRLR0_DFS_OFFSET 0 /* * For Keem Bay, CTRLR0[31] is used to select controller mode. * 0: SSI is slave * 1: SSI is master */ -#define DWC_SSI_CTRLR0_KEEMBAY_MST BIT(31) +#define DW_HSSI_CTRLR0_KEEMBAY_MST BIT(31) /* Bit fields in CTRLR1 */ -#define SPI_NDF_MASK GENMASK(15, 0) +#define DW_SPI_NDF_MASK GENMASK(15, 0) /* Bit fields in SR, 7 bits */ -#define SR_MASK 0x7f /* cover 7 bits */ -#define SR_BUSY (1 << 0) -#define SR_TF_NOT_FULL (1 << 1) -#define SR_TF_EMPT (1 << 2) -#define SR_RF_NOT_EMPT (1 << 3) -#define SR_RF_FULL (1 << 4) -#define SR_TX_ERR (1 << 5) -#define SR_DCOL (1 << 6) +#define DW_SPI_SR_MASK 0x7f /* cover 7 bits */ +#define DW_SPI_SR_BUSY (1 << 0) +#define DW_SPI_SR_TF_NOT_FULL (1 << 1) +#define DW_SPI_SR_TF_EMPT (1 << 2) +#define DW_SPI_SR_RF_NOT_EMPT (1 << 3) +#define DW_SPI_SR_RF_FULL (1 << 4) +#define DW_SPI_SR_TX_ERR (1 << 5) +#define DW_SPI_SR_DCOL (1 << 6) /* Bit fields in ISR, IMR, RISR, 7 bits */ -#define SPI_INT_TXEI (1 << 0) -#define SPI_INT_TXOI (1 << 1) -#define SPI_INT_RXUI (1 << 2) -#define SPI_INT_RXOI (1 << 3) -#define SPI_INT_RXFI (1 << 4) -#define SPI_INT_MSTI (1 << 5) +#define DW_SPI_INT_TXEI (1 << 0) +#define DW_SPI_INT_TXOI (1 << 1) +#define DW_SPI_INT_RXUI (1 << 2) +#define DW_SPI_INT_RXOI (1 << 3) +#define DW_SPI_INT_RXFI (1 << 4) +#define DW_SPI_INT_MSTI (1 << 5) /* Bit fields in DMACR */ -#define SPI_DMA_RDMAE (1 << 0) -#define SPI_DMA_TDMAE (1 << 1) +#define DW_SPI_DMACR_RDMAE (1 << 0) +#define DW_SPI_DMACR_TDMAE (1 << 1) -#define SPI_WAIT_RETRIES 5 -#define SPI_BUF_SIZE \ +/* Mem/DMA operations helpers */ +#define DW_SPI_WAIT_RETRIES 5 +#define DW_SPI_BUF_SIZE \ (sizeof_field(struct spi_mem_op, cmd.opcode) + \ sizeof_field(struct spi_mem_op, addr.val) + 256) -#define SPI_GET_BYTE(_val, _idx) \ +#define DW_SPI_GET_BYTE(_val, _idx) \ ((_val) >> (BITS_PER_BYTE * (_idx)) & 0xff) /* DW SPI capabilities */ #define DW_SPI_CAP_CS_OVERRIDE BIT(0) #define DW_SPI_CAP_KEEMBAY_MST BIT(1) -#define DW_SPI_CAP_DWC_SSI BIT(2) +#define DW_SPI_CAP_DWC_HSSI BIT(2) #define DW_SPI_CAP_DFS32 BIT(3) /* Slave spi_transfer/spi_mem_op related */ @@ -162,7 +163,7 @@ struct dw_spi { unsigned int tx_len; void *rx; unsigned int rx_len; - u8 buf[SPI_BUF_SIZE]; + u8 buf[DW_SPI_BUF_SIZE]; int dma_mapped; u8 n_bytes; /* current is a 1/2 bytes op */ irqreturn_t (*transfer_handler)(struct dw_spi *dws); @@ -224,18 +225,18 @@ static inline void dw_write_io_reg(struct dw_spi *dws, u32 offset, u32 val) } } -static inline void spi_enable_chip(struct dw_spi *dws, int enable) +static inline void dw_spi_enable_chip(struct dw_spi *dws, int enable) { dw_writel(dws, DW_SPI_SSIENR, (enable ? 1 : 0)); } -static inline void spi_set_clk(struct dw_spi *dws, u16 div) +static inline void dw_spi_set_clk(struct dw_spi *dws, u16 div) { dw_writel(dws, DW_SPI_BAUDR, div); } /* Disable IRQ bits */ -static inline void spi_mask_intr(struct dw_spi *dws, u32 mask) +static inline void dw_spi_mask_intr(struct dw_spi *dws, u32 mask) { u32 new_mask; @@ -244,7 +245,7 @@ static inline void spi_mask_intr(struct dw_spi *dws, u32 mask) } /* Enable IRQ bits */ -static inline void spi_umask_intr(struct dw_spi *dws, u32 mask) +static inline void dw_spi_umask_intr(struct dw_spi *dws, u32 mask) { u32 new_mask; @@ -257,19 +258,19 @@ static inline void spi_umask_intr(struct dw_spi *dws, u32 mask) * and CS, then re-enables the controller back. Transmit and receive FIFO * buffers are cleared when the device is disabled. */ -static inline void spi_reset_chip(struct dw_spi *dws) +static inline void dw_spi_reset_chip(struct dw_spi *dws) { - spi_enable_chip(dws, 0); - spi_mask_intr(dws, 0xff); + dw_spi_enable_chip(dws, 0); + dw_spi_mask_intr(dws, 0xff); dw_readl(dws, DW_SPI_ICR); dw_writel(dws, DW_SPI_SER, 0); - spi_enable_chip(dws, 1); + dw_spi_enable_chip(dws, 1); } -static inline void spi_shutdown_chip(struct dw_spi *dws) +static inline void dw_spi_shutdown_chip(struct dw_spi *dws) { - spi_enable_chip(dws, 0); - spi_set_clk(dws, 0); + dw_spi_enable_chip(dws, 0); + dw_spi_set_clk(dws, 0); } extern void dw_spi_set_cs(struct spi_device *spi, bool enable); @@ -293,4 +294,4 @@ static inline void dw_spi_dma_setup_generic(struct dw_spi *dws) {} #endif /* !CONFIG_SPI_DW_DMA */ -#endif /* DW_SPI_HEADER_H */ +#endif /* __SPI_DW_H__ */ -- cgit v1.2.3 From ec77c086dc5b2eb422ff588f91cc011137fa9ea3 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Mon, 15 Nov 2021 21:19:14 +0300 Subject: spi: dw: Convert to using the Bitfield access macros The driver has been using the offset/bitwise-shift-based approach for the CSR fields R/W operations since it was merged into the kernel. It can be simplified by using the macros defined in the linux/bitfield.h and linux/bit.h header files like BIT(), GENMASK(), FIELD_PREP(), FIELD_GET(), etc where it is required, for instance in the cached cr0 preparation method. Thus in order to have the FIELD_*()-macros utilized we just need to convert the macros with the CSR-fields offsets to the masks with the corresponding registers fields definition. That's where the GENMASK() and BIT() macros come in handy. After that the masks can be used in the FIELD_*()-macros where it's appropriate. We also need to convert the macros with the CRS-bit flags using the manual bitwise shift operations (x << y) to using the BIT() macro. Thus we'll have a more coherent set of the CSR-related macros. Signed-off-by: Serge Semin Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20211115181917.7521-5-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown --- drivers/spi/spi-dw-core.c | 31 ++++++++++++++--------- drivers/spi/spi-dw.h | 64 +++++++++++++++++++++++------------------------ 2 files changed, 50 insertions(+), 45 deletions(-) diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index 57bbffe6d6f9..b9f809989fda 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -5,6 +5,7 @@ * Copyright (c) 2009, Intel Corporation. */ +#include #include #include #include @@ -254,7 +255,7 @@ static irqreturn_t dw_spi_irq(int irq, void *dev_id) { struct spi_controller *master = dev_id; struct dw_spi *dws = spi_controller_get_devdata(master); - u16 irq_status = dw_readl(dws, DW_SPI_ISR) & 0x3f; + u16 irq_status = dw_readl(dws, DW_SPI_ISR) & DW_SPI_INT_MASK; if (!irq_status) return IRQ_NONE; @@ -273,32 +274,38 @@ static u32 dw_spi_prepare_cr0(struct dw_spi *dws, struct spi_device *spi) if (!(dws->caps & DW_SPI_CAP_DWC_HSSI)) { /* CTRLR0[ 5: 4] Frame Format */ - cr0 |= DW_SPI_CTRLR0_FRF_MOTO_SPI << DW_PSSI_CTRLR0_FRF_OFFSET; + cr0 |= FIELD_PREP(DW_PSSI_CTRLR0_FRF_MASK, DW_SPI_CTRLR0_FRF_MOTO_SPI); /* * SPI mode (SCPOL|SCPH) * CTRLR0[ 6] Serial Clock Phase * CTRLR0[ 7] Serial Clock Polarity */ - cr0 |= ((spi->mode & SPI_CPOL) ? 1 : 0) << DW_PSSI_CTRLR0_SCOL_OFFSET; - cr0 |= ((spi->mode & SPI_CPHA) ? 1 : 0) << DW_PSSI_CTRLR0_SCPH_OFFSET; + if (spi->mode & SPI_CPOL) + cr0 |= DW_PSSI_CTRLR0_SCPOL; + if (spi->mode & SPI_CPHA) + cr0 |= DW_PSSI_CTRLR0_SCPHA; /* CTRLR0[11] Shift Register Loop */ - cr0 |= ((spi->mode & SPI_LOOP) ? 1 : 0) << DW_PSSI_CTRLR0_SRL_OFFSET; + if (spi->mode & SPI_LOOP) + cr0 |= DW_PSSI_CTRLR0_SRL; } else { /* CTRLR0[ 7: 6] Frame Format */ - cr0 |= DW_SPI_CTRLR0_FRF_MOTO_SPI << DW_HSSI_CTRLR0_FRF_OFFSET; + cr0 |= FIELD_PREP(DW_HSSI_CTRLR0_FRF_MASK, DW_SPI_CTRLR0_FRF_MOTO_SPI); /* * SPI mode (SCPOL|SCPH) * CTRLR0[ 8] Serial Clock Phase * CTRLR0[ 9] Serial Clock Polarity */ - cr0 |= ((spi->mode & SPI_CPOL) ? 1 : 0) << DW_HSSI_CTRLR0_SCPOL_OFFSET; - cr0 |= ((spi->mode & SPI_CPHA) ? 1 : 0) << DW_HSSI_CTRLR0_SCPH_OFFSET; + if (spi->mode & SPI_CPOL) + cr0 |= DW_HSSI_CTRLR0_SCPOL; + if (spi->mode & SPI_CPHA) + cr0 |= DW_HSSI_CTRLR0_SCPHA; /* CTRLR0[13] Shift Register Loop */ - cr0 |= ((spi->mode & SPI_LOOP) ? 1 : 0) << DW_HSSI_CTRLR0_SRL_OFFSET; + if (spi->mode & SPI_LOOP) + cr0 |= DW_HSSI_CTRLR0_SRL; if (dws->caps & DW_SPI_CAP_KEEMBAY_MST) cr0 |= DW_HSSI_CTRLR0_KEEMBAY_MST; @@ -320,10 +327,10 @@ void dw_spi_update_config(struct dw_spi *dws, struct spi_device *spi, if (!(dws->caps & DW_SPI_CAP_DWC_HSSI)) /* CTRLR0[ 9:8] Transfer Mode */ - cr0 |= cfg->tmode << DW_PSSI_CTRLR0_TMOD_OFFSET; + cr0 |= FIELD_PREP(DW_PSSI_CTRLR0_TMOD_MASK, cfg->tmode); else /* CTRLR0[11:10] Transfer Mode */ - cr0 |= cfg->tmode << DW_HSSI_CTRLR0_TMOD_OFFSET; + cr0 |= FIELD_PREP(DW_HSSI_CTRLR0_TMOD_MASK, cfg->tmode); dw_writel(dws, DW_SPI_CTRLR0, cr0); @@ -850,7 +857,7 @@ static void dw_spi_hw_init(struct device *dev, struct dw_spi *dws) if (!(cr0 & DW_PSSI_CTRLR0_DFS_MASK)) { dws->caps |= DW_SPI_CAP_DFS32; - dws->dfs_offset = DW_PSSI_CTRLR0_DFS32_OFFSET; + dws->dfs_offset = __bf_shf(DW_PSSI_CTRLR0_DFS32_MASK); dev_dbg(dev, "Detected 32-bits max data frame size\n"); } } else { diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 893b78c43a50..634085eadad1 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -41,39 +41,36 @@ #define DW_SPI_CS_OVERRIDE 0xf4 /* Bit fields in CTRLR0 (DWC APB SSI) */ -#define DW_PSSI_CTRLR0_DFS_OFFSET 0 #define DW_PSSI_CTRLR0_DFS_MASK GENMASK(3, 0) -#define DW_PSSI_CTRLR0_DFS32_OFFSET 16 +#define DW_PSSI_CTRLR0_DFS32_MASK GENMASK(20, 16) -#define DW_PSSI_CTRLR0_FRF_OFFSET 4 +#define DW_PSSI_CTRLR0_FRF_MASK GENMASK(5, 4) #define DW_SPI_CTRLR0_FRF_MOTO_SPI 0x0 #define DW_SPI_CTRLR0_FRF_TI_SSP 0x1 #define DW_SPI_CTRLR0_FRF_NS_MICROWIRE 0x2 #define DW_SPI_CTRLR0_FRF_RESV 0x3 -#define DW_PSSI_CTRLR0_MODE_OFFSET 6 -#define DW_PSSI_CTRLR0_SCPH_OFFSET 6 -#define DW_PSSI_CTRLR0_SCOL_OFFSET 7 +#define DW_PSSI_CTRLR0_MODE_MASK GENMASK(7, 6) +#define DW_PSSI_CTRLR0_SCPHA BIT(6) +#define DW_PSSI_CTRLR0_SCPOL BIT(7) -#define DW_PSSI_CTRLR0_TMOD_OFFSET 8 -#define DW_PSSI_CTRLR0_TMOD_MASK (0x3 << DW_PSSI_CTRLR0_TMOD_OFFSET) +#define DW_PSSI_CTRLR0_TMOD_MASK GENMASK(9, 8) #define DW_SPI_CTRLR0_TMOD_TR 0x0 /* xmit & recv */ #define DW_SPI_CTRLR0_TMOD_TO 0x1 /* xmit only */ #define DW_SPI_CTRLR0_TMOD_RO 0x2 /* recv only */ #define DW_SPI_CTRLR0_TMOD_EPROMREAD 0x3 /* eeprom read mode */ -#define DW_PSSI_CTRLR0_SLVOE_OFFSET 10 -#define DW_PSSI_CTRLR0_SRL_OFFSET 11 -#define DW_PSSI_CTRLR0_CFS_OFFSET 12 +#define DW_PSSI_CTRLR0_SLV_OE BIT(10) +#define DW_PSSI_CTRLR0_SRL BIT(11) +#define DW_PSSI_CTRLR0_CFS BIT(12) /* Bit fields in CTRLR0 (DWC SSI with AHB interface) */ -#define DW_HSSI_CTRLR0_SRL_OFFSET 13 -#define DW_HSSI_CTRLR0_TMOD_OFFSET 10 +#define DW_HSSI_CTRLR0_DFS_MASK GENMASK(4, 0) +#define DW_HSSI_CTRLR0_FRF_MASK GENMASK(7, 6) +#define DW_HSSI_CTRLR0_SCPHA BIT(8) +#define DW_HSSI_CTRLR0_SCPOL BIT(9) #define DW_HSSI_CTRLR0_TMOD_MASK GENMASK(11, 10) -#define DW_HSSI_CTRLR0_SCPOL_OFFSET 9 -#define DW_HSSI_CTRLR0_SCPH_OFFSET 8 -#define DW_HSSI_CTRLR0_FRF_OFFSET 6 -#define DW_HSSI_CTRLR0_DFS_OFFSET 0 +#define DW_HSSI_CTRLR0_SRL BIT(13) /* * For Keem Bay, CTRLR0[31] is used to select controller mode. @@ -86,26 +83,27 @@ #define DW_SPI_NDF_MASK GENMASK(15, 0) /* Bit fields in SR, 7 bits */ -#define DW_SPI_SR_MASK 0x7f /* cover 7 bits */ -#define DW_SPI_SR_BUSY (1 << 0) -#define DW_SPI_SR_TF_NOT_FULL (1 << 1) -#define DW_SPI_SR_TF_EMPT (1 << 2) -#define DW_SPI_SR_RF_NOT_EMPT (1 << 3) -#define DW_SPI_SR_RF_FULL (1 << 4) -#define DW_SPI_SR_TX_ERR (1 << 5) -#define DW_SPI_SR_DCOL (1 << 6) +#define DW_SPI_SR_MASK GENMASK(6, 0) +#define DW_SPI_SR_BUSY BIT(0) +#define DW_SPI_SR_TF_NOT_FULL BIT(1) +#define DW_SPI_SR_TF_EMPT BIT(2) +#define DW_SPI_SR_RF_NOT_EMPT BIT(3) +#define DW_SPI_SR_RF_FULL BIT(4) +#define DW_SPI_SR_TX_ERR BIT(5) +#define DW_SPI_SR_DCOL BIT(6) /* Bit fields in ISR, IMR, RISR, 7 bits */ -#define DW_SPI_INT_TXEI (1 << 0) -#define DW_SPI_INT_TXOI (1 << 1) -#define DW_SPI_INT_RXUI (1 << 2) -#define DW_SPI_INT_RXOI (1 << 3) -#define DW_SPI_INT_RXFI (1 << 4) -#define DW_SPI_INT_MSTI (1 << 5) +#define DW_SPI_INT_MASK GENMASK(5, 0) +#define DW_SPI_INT_TXEI BIT(0) +#define DW_SPI_INT_TXOI BIT(1) +#define DW_SPI_INT_RXUI BIT(2) +#define DW_SPI_INT_RXOI BIT(3) +#define DW_SPI_INT_RXFI BIT(4) +#define DW_SPI_INT_MSTI BIT(5) /* Bit fields in DMACR */ -#define DW_SPI_DMACR_RDMAE (1 << 0) -#define DW_SPI_DMACR_TDMAE (1 << 1) +#define DW_SPI_DMACR_RDMAE BIT(0) +#define DW_SPI_DMACR_TDMAE BIT(1) /* Mem/DMA operations helpers */ #define DW_SPI_WAIT_RETRIES 5 -- cgit v1.2.3 From 2cc8d9227bbba7d6f3790a86f1ff0d665a75f3b8 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Mon, 15 Nov 2021 21:19:15 +0300 Subject: spi: dw: Introduce Synopsys IP-core versions interface The driver currently supports two IP-core versions. It's DW APB SSI which is older version of the controller with APB system bus interface, and DW SSI controller with AHB bus interface. The later one is supposed to be a new generation high-speed SSI. Even though both of these IP-cores have got an almost identical registers space there are some differences. The driver differentiates these distinctions by the DW_SPI_CAP_DWC_HSSI capability flag. In addition to that each DW SSI IP-core is equipped with a Synopsys Component version register, which encodes the IP-core release ID the has been synthesized from. Seeing we are going to need the later one to differentiate some controller peculiarities it would be better to have a unified interface for both IP-core line and release versions instead of using each of them separately. Introduced here IP-core versioning interface consists of two parts: 1) IDs of the IP-core (virtual) and component versions. 2) a set of macro helpers to identify current IP-core and component versions. So the platform code is supposed to assign a proper IP-core version based on it's platform -knowledge. The main driver initialization method reads the IP-core release ID from the SSI component version register. That data is used by the helpers to distinguish one IP-core release from another. Thus the rest of the driver can use these macros to implement the conditional code execution based on the specified IP-core and version IDs. Collect the IP-core versions interface and the defined capabilities at the top of the header file since they represent a common device description data and so to immediately available for the driver hackers. Signed-off-by: Serge Semin Suggested-by: Andy Shevchenko Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20211115181917.7521-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown --- drivers/spi/spi-dw-core.c | 14 ++++++++++++++ drivers/spi/spi-dw.h | 36 ++++++++++++++++++++++++++++-------- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index b9f809989fda..42536b448ddd 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -823,6 +823,20 @@ static void dw_spi_hw_init(struct device *dev, struct dw_spi *dws) { dw_spi_reset_chip(dws); + /* + * Retrieve the Synopsys component version if it hasn't been specified + * by the platform. CoreKit version ID is encoded as a 3-chars ASCII + * code enclosed with '*' (typical for the most of Synopsys IP-cores). + */ + if (!dws->ver) { + dws->ver = dw_readl(dws, DW_SPI_VERSION); + + dev_dbg(dev, "Synopsys DWC%sSSI v%c.%c%c\n", + (dws->caps & DW_SPI_CAP_DWC_HSSI) ? " " : " APB ", + DW_SPI_GET_BYTE(dws->ver, 3), DW_SPI_GET_BYTE(dws->ver, 2), + DW_SPI_GET_BYTE(dws->ver, 1)); + } + /* * Try to detect the FIFO depth if not set by interface driver, * the depth could be from 2 to 256 from HW spec diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 634085eadad1..2f7d77024b48 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -11,6 +11,30 @@ #include #include +/* Synopsys DW SSI IP-core virtual IDs */ +#define DW_PSSI_ID 0 +#define DW_HSSI_ID 1 + +/* Synopsys DW SSI component versions (FourCC sequence) */ +#define DW_HSSI_102A 0x3130322a + +/* DW SSI IP-core ID and version check helpers */ +#define dw_spi_ip_is(_dws, _ip) \ + ((_dws)->ip == DW_ ## _ip ## _ID) + +#define __dw_spi_ver_cmp(_dws, _ip, _ver, _op) \ + (dw_spi_ip_is(_dws, _ip) && (_dws)->ver _op DW_ ## _ip ## _ver) + +#define dw_spi_ver_is(_dws, _ip, _ver) __dw_spi_ver_cmp(_dws, _ip, _ver, ==) + +#define dw_spi_ver_is_ge(_dws, _ip, _ver) __dw_spi_ver_cmp(_dws, _ip, _ver, >=) + +/* DW SPI controller capabilities */ +#define DW_SPI_CAP_CS_OVERRIDE BIT(0) +#define DW_SPI_CAP_KEEMBAY_MST BIT(1) +#define DW_SPI_CAP_DWC_HSSI BIT(2) +#define DW_SPI_CAP_DFS32 BIT(3) + /* Register offsets (Generic for both DWC APB SSI and DWC SSI IP-cores) */ #define DW_SPI_CTRLR0 0x00 #define DW_SPI_CTRLR1 0x04 @@ -113,12 +137,6 @@ #define DW_SPI_GET_BYTE(_val, _idx) \ ((_val) >> (BITS_PER_BYTE * (_idx)) & 0xff) -/* DW SPI capabilities */ -#define DW_SPI_CAP_CS_OVERRIDE BIT(0) -#define DW_SPI_CAP_KEEMBAY_MST BIT(1) -#define DW_SPI_CAP_DWC_HSSI BIT(2) -#define DW_SPI_CAP_DFS32 BIT(3) - /* Slave spi_transfer/spi_mem_op related */ struct dw_spi_cfg { u8 tmode; @@ -141,6 +159,10 @@ struct dw_spi_dma_ops { struct dw_spi { struct spi_controller *master; + u32 ip; /* Synopsys DW SSI IP-core ID */ + u32 ver; /* Synopsys component version */ + u32 caps; /* DW SPI capabilities */ + void __iomem *regs; unsigned long paddr; int irq; @@ -149,8 +171,6 @@ struct dw_spi { u32 max_mem_freq; /* max mem-ops bus freq */ u32 max_freq; /* max bus freq supported */ - u32 caps; /* DW SPI capabilities */ - u32 reg_io_width; /* DR I/O width in bytes */ u16 bus_num; u16 num_cs; /* supported slave numbers */ -- cgit v1.2.3 From 2b8a47e0b6984b9795baa20ddcbd37e9ea9b2a91 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Mon, 15 Nov 2021 21:19:16 +0300 Subject: spi: dw: Replace DWC_HSSI capability with IP-core version checker Since there is a common IP-core and component versions interface available we can use it to differentiate the DW HSSI device features in the code. Let's remove the corresponding DWC_HSSI capability flag then and use the dw_spi_ip_is() macro instead. Signed-off-by: Serge Semin Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20211115181917.7521-7-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown --- drivers/spi/spi-dw-core.c | 8 ++++---- drivers/spi/spi-dw-mmio.c | 5 +++-- drivers/spi/spi-dw.h | 1 - 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index 42536b448ddd..934cc7a922e8 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -272,7 +272,7 @@ static u32 dw_spi_prepare_cr0(struct dw_spi *dws, struct spi_device *spi) { u32 cr0 = 0; - if (!(dws->caps & DW_SPI_CAP_DWC_HSSI)) { + if (dw_spi_ip_is(dws, PSSI)) { /* CTRLR0[ 5: 4] Frame Format */ cr0 |= FIELD_PREP(DW_PSSI_CTRLR0_FRF_MASK, DW_SPI_CTRLR0_FRF_MOTO_SPI); @@ -325,7 +325,7 @@ void dw_spi_update_config(struct dw_spi *dws, struct spi_device *spi, /* CTRLR0[ 4/3: 0] or CTRLR0[ 20: 16] Data Frame Size */ cr0 |= (cfg->dfs - 1) << dws->dfs_offset; - if (!(dws->caps & DW_SPI_CAP_DWC_HSSI)) + if (dw_spi_ip_is(dws, PSSI)) /* CTRLR0[ 9:8] Transfer Mode */ cr0 |= FIELD_PREP(DW_PSSI_CTRLR0_TMOD_MASK, cfg->tmode); else @@ -832,7 +832,7 @@ static void dw_spi_hw_init(struct device *dev, struct dw_spi *dws) dws->ver = dw_readl(dws, DW_SPI_VERSION); dev_dbg(dev, "Synopsys DWC%sSSI v%c.%c%c\n", - (dws->caps & DW_SPI_CAP_DWC_HSSI) ? " " : " APB ", + dw_spi_ip_is(dws, PSSI) ? " APB " : " ", DW_SPI_GET_BYTE(dws->ver, 3), DW_SPI_GET_BYTE(dws->ver, 2), DW_SPI_GET_BYTE(dws->ver, 1)); } @@ -860,7 +860,7 @@ static void dw_spi_hw_init(struct device *dev, struct dw_spi *dws) * writability. Note DWC SSI controller also has the extended DFS, but * with zero offset. */ - if (!(dws->caps & DW_SPI_CAP_DWC_HSSI)) { + if (dw_spi_ip_is(dws, PSSI)) { u32 cr0, tmp = dw_readl(dws, DW_SPI_CTRLR0); dw_spi_enable_chip(dws, 0); diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c index 2193c2550e74..5101c4c6017b 100644 --- a/drivers/spi/spi-dw-mmio.c +++ b/drivers/spi/spi-dw-mmio.c @@ -207,7 +207,7 @@ static int dw_spi_pssi_init(struct platform_device *pdev, static int dw_spi_hssi_init(struct platform_device *pdev, struct dw_spi_mmio *dwsmmio) { - dwsmmio->dws.caps = DW_SPI_CAP_DWC_HSSI; + dwsmmio->dws.ip = DW_HSSI_ID; dw_spi_dma_setup_generic(&dwsmmio->dws); @@ -217,7 +217,8 @@ static int dw_spi_hssi_init(struct platform_device *pdev, static int dw_spi_keembay_init(struct platform_device *pdev, struct dw_spi_mmio *dwsmmio) { - dwsmmio->dws.caps = DW_SPI_CAP_KEEMBAY_MST | DW_SPI_CAP_DWC_HSSI; + dwsmmio->dws.ip = DW_HSSI_ID; + dwsmmio->dws.caps = DW_SPI_CAP_KEEMBAY_MST; return 0; } diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 2f7d77024b48..8334e6b35f89 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -32,7 +32,6 @@ /* DW SPI controller capabilities */ #define DW_SPI_CAP_CS_OVERRIDE BIT(0) #define DW_SPI_CAP_KEEMBAY_MST BIT(1) -#define DW_SPI_CAP_DWC_HSSI BIT(2) #define DW_SPI_CAP_DFS32 BIT(3) /* Register offsets (Generic for both DWC APB SSI and DWC SSI IP-cores) */ -- cgit v1.2.3 From 44ebcb44584f81d1d38fafb45cf57d651f44616e Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Mon, 15 Nov 2021 21:19:17 +0300 Subject: spi: dw: Define the capabilities in a continuous bit-flags set Since the DW_SPI_CAP_DWC_HSSI capability has just been replaced with using the DW SSI IP-core versions interface, the DW SPI capability flags are now represented with a gap. Let's fix it by redefining the DW_SPI_CAP_DFS32 macro to setting BIT(2) of the capabilities field. Signed-off-by: Serge Semin Suggested-by: Andy Shevchenko Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20211115181917.7521-8-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown --- drivers/spi/spi-dw.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 8334e6b35f89..d5ee5130601e 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -32,7 +32,7 @@ /* DW SPI controller capabilities */ #define DW_SPI_CAP_CS_OVERRIDE BIT(0) #define DW_SPI_CAP_KEEMBAY_MST BIT(1) -#define DW_SPI_CAP_DFS32 BIT(3) +#define DW_SPI_CAP_DFS32 BIT(2) /* Register offsets (Generic for both DWC APB SSI and DWC SSI IP-cores) */ #define DW_SPI_CTRLR0 0x00 -- cgit v1.2.3 From 40fafc8eca3f0d41b9dade5c10afb2dad723aad7 Mon Sep 17 00:00:00 2001 From: oujiefeng Date: Wed, 17 Nov 2021 09:21:19 +0800 Subject: spi: hisi-kunpeng: Fix the debugfs directory name incorrect Change the debugfs directory name from hisi_spi65535 to hisi_spi0. Fixes: 2b2142f247eb ("spi: hisi-kunpeng: Add debugfs support") Signed-off-by: oujiefeng Signed-off-by: Jay Fang Link: https://lore.kernel.org/r/20211117012119.55558-1-f.fangjian@huawei.com Signed-off-by: Mark Brown --- drivers/spi/spi-hisi-kunpeng.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi-hisi-kunpeng.c b/drivers/spi/spi-hisi-kunpeng.c index 58b823a16fc4..525cc0143a30 100644 --- a/drivers/spi/spi-hisi-kunpeng.c +++ b/drivers/spi/spi-hisi-kunpeng.c @@ -127,7 +127,6 @@ struct hisi_spi { void __iomem *regs; int irq; u32 fifo_len; /* depth of the FIFO buffer */ - u16 bus_num; /* Current message transfer state info */ const void *tx; @@ -165,7 +164,10 @@ static int hisi_spi_debugfs_init(struct hisi_spi *hs) { char name[32]; - snprintf(name, 32, "hisi_spi%d", hs->bus_num); + struct spi_controller *master; + + master = container_of(hs->dev, struct spi_controller, dev); + snprintf(name, 32, "hisi_spi%d", master->bus_num); hs->debugfs = debugfs_create_dir(name, NULL); if (!hs->debugfs) return -ENOMEM; @@ -467,7 +469,6 @@ static int hisi_spi_probe(struct platform_device *pdev) hs = spi_controller_get_devdata(master); hs->dev = dev; hs->irq = irq; - hs->bus_num = pdev->id; hs->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(hs->regs)) @@ -490,7 +491,7 @@ static int hisi_spi_probe(struct platform_device *pdev) master->use_gpio_descriptors = true; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP; master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); - master->bus_num = hs->bus_num; + master->bus_num = pdev->id; master->setup = hisi_spi_setup; master->cleanup = hisi_spi_cleanup; master->transfer_one = hisi_spi_transfer_one; @@ -506,15 +507,15 @@ static int hisi_spi_probe(struct platform_device *pdev) return ret; } - if (hisi_spi_debugfs_init(hs)) - dev_info(dev, "failed to create debugfs dir\n"); - ret = spi_register_controller(master); if (ret) { dev_err(dev, "failed to register spi master, ret=%d\n", ret); return ret; } + if (hisi_spi_debugfs_init(hs)) + dev_info(dev, "failed to create debugfs dir\n"); + dev_info(dev, "hw version:0x%x max-freq:%u kHz\n", readl(hs->regs + HISI_SPI_VERSION), master->max_speed_hz / 1000); -- cgit v1.2.3 From 5a8f8542e34b6469cd5c5a3d075fa5977d90775e Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Thu, 18 Nov 2021 03:10:39 +0000 Subject: spi: dt-bindings: renesas,rspi: Document RZ/G2L SoC Add RSPI binding documentation for Renesas RZ/G2L SoC. RSPI block is identical to one found on RZ/A, so no driver changes are required. The fallback compatible string "renesas,rspi-rz" will be used on RZ/G2L. Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20211118031041.2312-2-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/renesas,rspi.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/spi/renesas,rspi.yaml b/Documentation/devicetree/bindings/spi/renesas,rspi.yaml index 8397f60d80a2..76e6d9e52fc7 100644 --- a/Documentation/devicetree/bindings/spi/renesas,rspi.yaml +++ b/Documentation/devicetree/bindings/spi/renesas,rspi.yaml @@ -21,7 +21,8 @@ properties: - enum: - renesas,rspi-r7s72100 # RZ/A1H - renesas,rspi-r7s9210 # RZ/A2 - - const: renesas,rspi-rz # RZ/A + - renesas,r9a07g044-rspi # RZ/G2{L,LC} + - const: renesas,rspi-rz # RZ/A and RZ/G2{L,LC} - items: - enum: @@ -122,6 +123,7 @@ allOf: contains: enum: - renesas,qspi + - renesas,r9a07g044-rspi then: required: - resets -- cgit v1.2.3 From aadbff4af5c90919cbe67e2c4d77c68cdefa454e Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Thu, 18 Nov 2021 03:10:40 +0000 Subject: spi: spi-rspi: Add support to deassert/assert reset line On RZ/G2L SoC we need to explicitly deassert the reset line for the device to work, use this opportunity to deassert/assert reset line in spi-rspi driver. This patch adds support to read the "resets" property (if available) from DT and perform deassert/assert when required. Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20211118031041.2312-3-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Mark Brown --- drivers/spi/spi-rspi.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 41761f0d892a..b7df49a57e5f 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -1225,8 +1226,14 @@ static const struct of_device_id rspi_of_match[] = { MODULE_DEVICE_TABLE(of, rspi_of_match); +static void rspi_reset_control_assert(void *data) +{ + reset_control_assert(data); +} + static int rspi_parse_dt(struct device *dev, struct spi_controller *ctlr) { + struct reset_control *rstc; u32 num_cs; int error; @@ -1238,6 +1245,24 @@ static int rspi_parse_dt(struct device *dev, struct spi_controller *ctlr) } ctlr->num_chipselect = num_cs; + + rstc = devm_reset_control_get_optional_exclusive(dev, NULL); + if (IS_ERR(rstc)) + return dev_err_probe(dev, PTR_ERR(rstc), + "failed to get reset ctrl\n"); + + error = reset_control_deassert(rstc); + if (error) { + dev_err(dev, "failed to deassert reset %d\n", error); + return error; + } + + error = devm_add_action_or_reset(dev, rspi_reset_control_assert, rstc); + if (error) { + dev_err(dev, "failed to register assert devm action, %d\n", error); + return error; + } + return 0; } #else -- cgit v1.2.3 From 1d734f592e1a1d41af80e90001d109cec1c98fb4 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Thu, 18 Nov 2021 03:10:41 +0000 Subject: spi: spi-rspi: Drop redeclaring ret variable in qspi_transfer_in() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "ret" variable is already declared in qspi_transfer_in() at the beginning of function, drop redeclaring ret in the if block, fixing below: spi-rspi.c: In function ‘qspi_transfer_in’: spi-rspi.c:838:7: warning: declaration of ‘ret’ shadows a previous local 838 | int ret = rspi_dma_transfer(rspi, NULL, &xfer->rx_sg); | ^~~ spi-rspi.c:835:6: note: shadowed declaration is here 835 | int ret; Fixes: db30083813b55 ("spi: rspi: avoid uninitialized variable access") Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20211118031041.2312-4-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Mark Brown --- drivers/spi/spi-rspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index b7df49a57e5f..bd5708d7e5a1 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -835,7 +835,7 @@ static int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer) int ret; if (rspi->ctlr->can_dma && __rspi_can_dma(rspi, xfer)) { - int ret = rspi_dma_transfer(rspi, NULL, &xfer->rx_sg); + ret = rspi_dma_transfer(rspi, NULL, &xfer->rx_sg); if (ret != -EAGAIN) return ret; } -- cgit v1.2.3 From 61f6e38ae8b6cbe140cfd320b3003a52147edef0 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Wed, 17 Nov 2021 19:01:08 +0530 Subject: spi: qcom: geni: remove unused defines Commit b59c122484ec ("spi: spi-geni-qcom: Add support for GPI dma") added GPI support but also added unused defines, so remove them Signed-off-by: Vinod Koul Reviewed-by: Douglas Anderson Link: https://lore.kernel.org/r/20211117133110.2682631-1-vkoul@kernel.org Signed-off-by: Mark Brown --- drivers/spi/spi-geni-qcom.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c index e2affaee4e76..413fa1a7a936 100644 --- a/drivers/spi/spi-geni-qcom.c +++ b/drivers/spi/spi-geni-qcom.c @@ -71,10 +71,6 @@ #define GSI_CPHA BIT(4) #define GSI_CPOL BIT(5) -#define MAX_TX_SG 3 -#define NUM_SPI_XFER 8 -#define SPI_XFER_TIMEOUT_MS 250 - struct spi_geni_master { struct geni_se se; struct device *dev; -- cgit v1.2.3 From f6f6a6320eeeb3e80e1393f727f898f8ca976bfd Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 19 Nov 2021 13:11:39 +0100 Subject: spi: docs: improve the SPI userspace API documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This doc is fairly outdated and only uses legacy device instantiation terminology. Let us update it and also mention the OF and ACPI device tables, to make easier for users to figure out how should be defined. Also, mention that devices bind could be done in user-space now using the "driver_override" sysfs entry. Suggested-by: Ralph Siemsen Signed-off-by: Javier Martinez Canillas Acked-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20211119121139.2412761-1-javierm@redhat.com Signed-off-by: Mark Brown --- Documentation/spi/spidev.rst | 58 ++++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/Documentation/spi/spidev.rst b/Documentation/spi/spidev.rst index f05dbc5ccdbc..369c657ba435 100644 --- a/Documentation/spi/spidev.rst +++ b/Documentation/spi/spidev.rst @@ -29,21 +29,49 @@ of the driver stack) that are not accessible to userspace. DEVICE CREATION, DRIVER BINDING =============================== -The simplest way to arrange to use this driver is to just list it in the -spi_board_info for a device as the driver it should use: the "modalias" -entry is "spidev", matching the name of the driver exposing this API. -Set up the other device characteristics (bits per word, SPI clocking, -chipselect polarity, etc) as usual, so you won't always need to override -them later. - -(Sysfs also supports userspace driven binding/unbinding of drivers to -devices. That mechanism might be supported here in the future.) - -When you do that, the sysfs node for the SPI device will include a child -device node with a "dev" attribute that will be understood by udev or mdev. -(Larger systems will have "udev". Smaller ones may configure "mdev" into -busybox; it's less featureful, but often enough.) For a SPI device with -chipselect C on bus B, you should see: + +The spidev driver contains lists of SPI devices that are supported for +the different hardware topology representations. + +The following are the SPI device tables supported by the spidev driver: + + - struct spi_device_id spidev_spi_ids[]: list of devices that can be + bound when these are defined using a struct spi_board_info with a + .modalias field matching one of the entries in the table. + + - struct of_device_id spidev_dt_ids[]: list of devices that can be + bound when these are defined using a Device Tree node that has a + compatible string matching one of the entries in the table. + + - struct acpi_device_id spidev_acpi_ids[]: list of devices that can + be bound when these are defined using a ACPI device object with a + _HID matching one of the entries in the table. + +You are encouraged to add an entry for your SPI device name to relevant +tables, if these don't already have an entry for the device. To do that, +post a patch for spidev to the linux-spi@vger.kernel.org mailing list. + +It used to be supported to define an SPI device using the "spidev" name. +For example, as .modalias = "spidev" or compatible = "spidev". But this +is no longer supported by the Linux kernel and instead a real SPI device +name as listed in one of the tables must be used. + +Not having a real SPI device name will lead to an error being printed and +the spidev driver failing to probe. + +Sysfs also supports userspace driven binding/unbinding of drivers to +devices that do not bind automatically using one of the tables above. +To make the spidev driver bind to such a device, use the following: + + echo spidev > /sys/bus/spi/devices/spiB.C/driver_override + echo spiB.C > /sys/bus/spi/drivers/spidev/bind + +When the spidev driver is bound to a SPI device, the sysfs node for the +device will include a child device node with a "dev" attribute that will +be understood by udev or mdev (udev replacement from BusyBox; it's less +featureful, but often enough). + +For a SPI device with chipselect C on bus B, you should see: /dev/spidevB.C ... character special device, major number 153 with -- cgit v1.2.3 From d94758b344e3b6f16d31cb5b51b93e3e5a4c3567 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sat, 20 Nov 2021 02:17:15 +0100 Subject: spi: Add resets to the PL022 bindings Some PL022 implementations provide a reset line to the silicon IP block, add a device tree property for this. Cc: devicetree@vger.kernel.org Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20211120011715.2630873-1-linus.walleij@linaro.org Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/spi-pl022.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/spi/spi-pl022.yaml b/Documentation/devicetree/bindings/spi/spi-pl022.yaml index a91d868e40c5..6d633728fc2b 100644 --- a/Documentation/devicetree/bindings/spi/spi-pl022.yaml +++ b/Documentation/devicetree/bindings/spi/spi-pl022.yaml @@ -72,6 +72,9 @@ properties: - const: rx - const: tx + resets: + maxItems: 1 + patternProperties: "^[a-zA-Z][a-zA-Z0-9,+\\-._]{0,63}@[0-9a-f]+$": type: object -- cgit v1.2.3 From 3f07657506df363709a37f99db04e9e0d0b1bce7 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 19 Nov 2021 19:37:17 +0200 Subject: spi: deduplicate spi_match_id() in __spi_register_driver() The same logic is used in spi_match_id() and in the __spi_register_driver(). By switching the former from taking struct spi_device * to const char * as the second parameter we may deduplicate the code. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20211119173718.52938-1-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown --- drivers/spi/spi.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index fdd530b150a7..9d19d9bae253 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -315,11 +315,10 @@ static void spi_statistics_add_transfer_stats(struct spi_statistics *stats, * and the sysfs version makes coldplug work too. */ -static const struct spi_device_id *spi_match_id(const struct spi_device_id *id, - const struct spi_device *sdev) +static const struct spi_device_id *spi_match_id(const struct spi_device_id *id, const char *name) { while (id->name[0]) { - if (!strcmp(sdev->modalias, id->name)) + if (!strcmp(name, id->name)) return id; id++; } @@ -330,7 +329,7 @@ const struct spi_device_id *spi_get_device_id(const struct spi_device *sdev) { const struct spi_driver *sdrv = to_spi_driver(sdev->dev.driver); - return spi_match_id(sdrv->id_table, sdev); + return spi_match_id(sdrv->id_table, sdev->modalias); } EXPORT_SYMBOL_GPL(spi_get_device_id); @@ -352,7 +351,7 @@ static int spi_match_device(struct device *dev, struct device_driver *drv) return 1; if (sdrv->id_table) - return !!spi_match_id(sdrv->id_table, spi); + return !!spi_match_id(sdrv->id_table, spi->modalias); return strcmp(spi->modalias, drv->name) == 0; } @@ -474,12 +473,8 @@ int __spi_register_driver(struct module *owner, struct spi_driver *sdrv) if (sdrv->id_table) { const struct spi_device_id *spi_id; - for (spi_id = sdrv->id_table; spi_id->name[0]; - spi_id++) - if (strcmp(spi_id->name, of_name) == 0) - break; - - if (spi_id->name[0]) + spi_id = spi_match_id(sdrv->id_table, of_name); + if (!spi_id) continue; } else { if (strcmp(sdrv->driver.name, of_name) == 0) -- cgit v1.2.3 From 49cd1eb37b487036f51bd57b591f7b5760a10e02 Mon Sep 17 00:00:00 2001 From: Jacky Bai Date: Sat, 20 Nov 2021 19:34:49 +0800 Subject: spi: fsl-lpspi: Add imx8ulp compatible string The lpspi on i.MX8ULP is derived from i.MX7ULP, it uses two compatible strings, so update the comaptible string for i.MX8ULP. Signed-off-by: Jacky Bai Reviewed-by: Dong Aisheng Acked-by: Rob Herring Link: https://lore.kernel.org/r/20211120113454.785997-4-peng.fan@oss.nxp.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/spi-fsl-lpspi.yaml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.yaml b/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.yaml index 312d8fee9dbb..1d46877fe46a 100644 --- a/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.yaml +++ b/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.yaml @@ -14,10 +14,13 @@ allOf: properties: compatible: - enum: - - fsl,imx7ulp-spi - - fsl,imx8qxp-spi - + oneOf: + - enum: + - fsl,imx7ulp-spi + - fsl,imx8qxp-spi + - items: + - const: fsl,imx8ulp-spi + - const: fsl,imx7ulp-spi reg: maxItems: 1 -- cgit v1.2.3 From b00bab9d48bbb6446a5cf366f5f8e501a16031a1 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 22 Nov 2021 19:17:20 +0200 Subject: spi: Replace memset() with __GFP_ZERO krealloc() as any other kernel memory allocation calls accepts GFP flags, one of which is __GFP_ZERO. Hence, no need to call memset() explicitly on the reallocated buffer. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20211122171721.61553-2-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown --- drivers/spi/spi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 9d19d9bae253..3b9010a67397 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1222,11 +1222,10 @@ static int spi_map_msg(struct spi_controller *ctlr, struct spi_message *msg) if (max_tx) { tmp = krealloc(ctlr->dummy_tx, max_tx, - GFP_KERNEL | GFP_DMA); + GFP_KERNEL | GFP_DMA | __GFP_ZERO); if (!tmp) return -ENOMEM; ctlr->dummy_tx = tmp; - memset(tmp, 0, max_tx); } if (max_rx) { -- cgit v1.2.3 From 350de7ce26caba5c7ec0dd4ef1802c9a50a5d85d Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 22 Nov 2021 19:17:21 +0200 Subject: spi: Fix multi-line comment style /* * Fix multi-line comment style as in this short example. Pay attention * to the capitalization, period and starting line of the text. */ While at it, split the (supposedly short) description of couple of functions to summary (short description) and (long) description. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20211122171721.61553-3-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown --- drivers/spi/spi.c | 160 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 89 insertions(+), 71 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 3b9010a67397..5bf680fcb170 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -311,10 +311,10 @@ static void spi_statistics_add_transfer_stats(struct spi_statistics *stats, spin_unlock_irqrestore(&stats->lock, flags); } -/* modalias support makes "modprobe $MODALIAS" new-style hotplug work, +/* + * modalias support makes "modprobe $MODALIAS" new-style hotplug work, * and the sysfs version makes coldplug work too. */ - static const struct spi_device_id *spi_match_id(const struct spi_device_id *id, const char *name) { while (id->name[0]) { @@ -492,7 +492,8 @@ EXPORT_SYMBOL_GPL(__spi_register_driver); /*-------------------------------------------------------------------------*/ -/* SPI devices should normally not be created by SPI device drivers; that +/* + * SPI devices should normally not be created by SPI device drivers; that * would make them board-specific. Similarly with SPI controller drivers. * Device registration normally goes into like arch/.../mach.../board-YYY.c * with other readonly (flashable) information about mainboard devices. @@ -508,8 +509,8 @@ static LIST_HEAD(spi_controller_list); /* * Used to protect add/del operation for board_info list and - * spi_controller list, and their matching process - * also used to protect object of type struct idr + * spi_controller list, and their matching process also used + * to protect object of type struct idr. */ static DEFINE_MUTEX(board_lock); @@ -616,7 +617,8 @@ static int __spi_add_device(struct spi_device *spi) else if (ctlr->cs_gpios) spi->cs_gpio = ctlr->cs_gpios[spi->chip_select]; - /* Drivers may modify this initial i/o setup, but will + /* + * Drivers may modify this initial i/o setup, but will * normally rely on the device being setup. Devices * using SPI_CS_HIGH can't coexist well otherwise... */ @@ -710,7 +712,8 @@ struct spi_device *spi_new_device(struct spi_controller *ctlr, struct spi_device *proxy; int status; - /* NOTE: caller did any chip->bus_num checks necessary. + /* + * NOTE: caller did any chip->bus_num checks necessary. * * Also, unless we change the return value convention to use * error-or-pointer (not NULL-or-pointer), troubleshootability @@ -878,7 +881,6 @@ static void *spi_res_alloc(struct spi_device *spi, spi_res_release_t release, /** * spi_res_free - free an spi resource * @res: pointer to the custom data of a resource - * */ static void spi_res_free(void *res) { @@ -973,7 +975,7 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force) gpiod_set_value_cansleep(spi->cs_gpiod, activate); } else { /* - * invert the enable line, as active low is + * Invert the enable line, as active low is * default for SPI. */ gpio_set_value_cansleep(spi->cs_gpio, !enable); @@ -1711,16 +1713,7 @@ static void spi_pump_messages(struct kthread_work *work) } /** - * spi_take_timestamp_pre - helper for drivers to collect the beginning of the - * TX timestamp for the requested byte from the SPI - * transfer. The frequency with which this function - * must be called (once per word, once for the whole - * transfer, once per batch of words etc) is arbitrary - * as long as the @tx buffer offset is greater than or - * equal to the requested byte at the time of the - * call. The timestamp is only taken once, at the - * first such call. It is assumed that the driver - * advances its @tx buffer pointer monotonically. + * spi_take_timestamp_pre - helper to collect the beginning of the TX timestamp * @ctlr: Pointer to the spi_controller structure of the driver * @xfer: Pointer to the transfer being timestamped * @progress: How many words (not bytes) have been transferred so far @@ -1730,6 +1723,14 @@ static void spi_pump_messages(struct kthread_work *work) * spi_take_timestamp_post or otherwise system will crash. * WARNING: for fully predictable results, the CPU frequency must * also be under control (governor). + * + * This is a helper for drivers to collect the beginning of the TX timestamp + * for the requested byte from the SPI transfer. The frequency with which this + * function must be called (once per word, once for the whole transfer, once + * per batch of words etc) is arbitrary as long as the @tx buffer offset is + * greater than or equal to the requested byte at the time of the call. The + * timestamp is only taken once, at the first such call. It is assumed that + * the driver advances its @tx buffer pointer monotonically. */ void spi_take_timestamp_pre(struct spi_controller *ctlr, struct spi_transfer *xfer, @@ -1757,16 +1758,16 @@ void spi_take_timestamp_pre(struct spi_controller *ctlr, EXPORT_SYMBOL_GPL(spi_take_timestamp_pre); /** - * spi_take_timestamp_post - helper for drivers to collect the end of the - * TX timestamp for the requested byte from the SPI - * transfer. Can be called with an arbitrary - * frequency: only the first call where @tx exceeds - * or is equal to the requested word will be - * timestamped. + * spi_take_timestamp_post - helper to collect the end of the TX timestamp * @ctlr: Pointer to the spi_controller structure of the driver * @xfer: Pointer to the transfer being timestamped * @progress: How many words (not bytes) have been transferred so far * @irqs_off: If true, will re-enable IRQs and preemption for the local CPU. + * + * This is a helper for drivers to collect the end of the TX timestamp for + * the requested byte from the SPI transfer. Can be called with an arbitrary + * frequency: only the first call where @tx exceeds or is equal to the + * requested word will be timestamped. */ void spi_take_timestamp_post(struct spi_controller *ctlr, struct spi_transfer *xfer, @@ -1899,10 +1900,12 @@ void spi_finalize_current_message(struct spi_controller *ctlr) spi_unmap_msg(ctlr, mesg); - /* In the prepare_messages callback the spi bus has the opportunity to - * split a transfer to smaller chunks. - * Release splited transfers here since spi_map_msg is done on the - * splited transfers. + /* + * In the prepare_messages callback the SPI bus has the opportunity + * to split a transfer to smaller chunks. + * + * Release the split transfers here since spi_map_msg() is done on + * the split transfers. */ spi_res_release(ctlr, mesg); @@ -2944,8 +2947,9 @@ int spi_register_controller(struct spi_controller *ctlr) if (!ctlr->max_dma_len) ctlr->max_dma_len = INT_MAX; - /* register the device, then userspace will see it. - * registration fails if the bus ID is in use. + /* + * Register the device, then userspace will see it. + * Registration fails if the bus ID is in use. */ dev_set_name(&ctlr->dev, "spi%u", ctlr->bus_num); @@ -3211,16 +3215,18 @@ static struct spi_replaced_transfers *spi_replace_transfers( /* init the replaced_transfers list */ INIT_LIST_HEAD(&rxfer->replaced_transfers); - /* assign the list_entry after which we should reinsert + /* + * Assign the list_entry after which we should reinsert * the @replaced_transfers - it may be spi_message.messages! */ rxfer->replaced_after = xfer_first->transfer_list.prev; /* remove the requested number of transfers */ for (i = 0; i < remove; i++) { - /* if the entry after replaced_after it is msg->transfers + /* + * If the entry after replaced_after it is msg->transfers * then we have been requested to remove more transfers - * than are in the list + * than are in the list. */ if (rxfer->replaced_after->next == &msg->transfers) { dev_err(&msg->spi->dev, @@ -3236,15 +3242,17 @@ static struct spi_replaced_transfers *spi_replace_transfers( return ERR_PTR(-EINVAL); } - /* remove the entry after replaced_after from list of - * transfers and add it to list of replaced_transfers + /* + * Remove the entry after replaced_after from list of + * transfers and add it to list of replaced_transfers. */ list_move_tail(rxfer->replaced_after->next, &rxfer->replaced_transfers); } - /* create copy of the given xfer with identical settings - * based on the first transfer to get removed + /* + * Create copy of the given xfer with identical settings + * based on the first transfer to get removed. */ for (i = 0; i < insert; i++) { /* we need to run in reverse order */ @@ -3292,18 +3300,20 @@ static int __spi_split_transfer_maxsize(struct spi_controller *ctlr, return PTR_ERR(srt); xfers = srt->inserted_transfers; - /* now handle each of those newly inserted spi_transfers - * note that the replacements spi_transfers all are preset + /* + * Now handle each of those newly inserted spi_transfers. + * Note that the replacements spi_transfers all are preset * to the same values as *xferp, so tx_buf, rx_buf and len * are all identical (as well as most others) * so we just have to fix up len and the pointers. * - * this also includes support for the depreciated - * spi_message.is_dma_mapped interface + * This also includes support for the depreciated + * spi_message.is_dma_mapped interface. */ - /* the first transfer just needs the length modified, so we - * run it outside the loop + /* + * The first transfer just needs the length modified, so we + * run it outside the loop. */ xfers[0].len = min_t(size_t, maxsize, xfer[0].len); @@ -3323,8 +3333,9 @@ static int __spi_split_transfer_maxsize(struct spi_controller *ctlr, xfers[i].len = min(maxsize, xfers[i].len - offset); } - /* we set up xferp to the last entry we have inserted, - * so that we skip those already split transfers + /* + * We set up xferp to the last entry we have inserted, + * so that we skip those already split transfers. */ *xferp = &xfers[count - 1]; @@ -3356,11 +3367,12 @@ int spi_split_transfers_maxsize(struct spi_controller *ctlr, struct spi_transfer *xfer; int ret; - /* iterate over the transfer_list, + /* + * 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 - * potentiall belong to a different list by the time the - * replacement has happened + * potentially belong to a different list by the time the + * replacement has happened). */ list_for_each_entry(xfer, &msg->transfers, transfer_list) { if (xfer->len > maxsize) { @@ -3421,8 +3433,8 @@ int spi_setup(struct spi_device *spi) int status; /* - * check mode to prevent that any two of DUAL, QUAD and NO_MOSI/MISO - * are set at the same time + * Check mode to prevent that any two of DUAL, QUAD and NO_MOSI/MISO + * are set at the same time. */ if ((hweight_long(spi->mode & (SPI_TX_DUAL | SPI_TX_QUAD | SPI_NO_TX)) > 1) || @@ -3432,20 +3444,21 @@ int spi_setup(struct spi_device *spi) "setup: can not select any two of dual, quad and no-rx/tx at the same time\n"); return -EINVAL; } - /* if it is SPI_3WIRE mode, DUAL and QUAD should be forbidden - */ + /* If it is SPI_3WIRE mode, DUAL and QUAD should be forbidden */ if ((spi->mode & SPI_3WIRE) && (spi->mode & (SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_OCTAL | SPI_RX_DUAL | SPI_RX_QUAD | SPI_RX_OCTAL))) return -EINVAL; - /* help drivers fail *cleanly* when they need options - * that aren't supported with their current controller + /* + * Help drivers fail *cleanly* when they need options + * that aren't supported with their current controller. * SPI_CS_WORD has a fallback software implementation, * so it is ignored here. */ bad_bits = spi->mode & ~(spi->controller->mode_bits | SPI_CS_WORD | SPI_NO_TX | SPI_NO_RX); - /* nothing prevents from working with active-high CS in case if it + /* + * Nothing prevents from working with active-high CS in case if it * is driven by GPIO. */ if (gpio_is_valid(spi->cs_gpio)) @@ -3567,7 +3580,8 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) if (list_empty(&message->transfers)) return -EINVAL; - /* If an SPI controller does not support toggling the CS line on each + /* + * If an SPI controller does not support toggling the CS line on each * transfer (indicated by the SPI_CS_WORD flag) or we are using a GPIO * for the CS line, we can emulate the CS-per-word hardware function by * splitting transfers into one-word transfers and ensuring that @@ -3597,7 +3611,8 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) } } - /* Half-duplex links include original MicroWire, and ones with + /* + * Half-duplex links include original MicroWire, and ones with * only one data pin like SPI_3WIRE (switches direction) or where * either MOSI or MISO is missing. They can also be caused by * software limitations. @@ -3616,7 +3631,7 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) } } - /** + /* * Set transfer bits_per_word and max speed as spi device default if * it is not set for this transfer. * Set transfer tx_nbits and rx_nbits as single transfer default @@ -3642,7 +3657,7 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) /* * SPI transfer length should be multiple of SPI word size - * where SPI word size should be power-of-two multiple + * where SPI word size should be power-of-two multiple. */ if (xfer->bits_per_word <= 8) w_size = 1; @@ -3663,7 +3678,8 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) xfer->tx_nbits = SPI_NBITS_SINGLE; if (xfer->rx_buf && !xfer->rx_nbits) xfer->rx_nbits = SPI_NBITS_SINGLE; - /* check transfer tx/rx_nbits: + /* + * Check transfer tx/rx_nbits: * 1. check the value matches one of single, dual and quad * 2. check tx/rx_nbits match the mode in spi_device */ @@ -3842,7 +3858,8 @@ static int spi_async_locked(struct spi_device *spi, struct spi_message *message) /*-------------------------------------------------------------------------*/ -/* Utility methods for SPI protocol drivers, layered on +/* + * Utility methods for SPI protocol drivers, layered on * top of the core. Some other utility methods are defined as * inline functions. */ @@ -3870,7 +3887,8 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message) SPI_STATISTICS_INCREMENT_FIELD(&ctlr->statistics, spi_sync); SPI_STATISTICS_INCREMENT_FIELD(&spi->statistics, spi_sync); - /* If we're not using the legacy transfer method then we will + /* + * If we're not using the legacy transfer method then we will * try to transfer in the calling context so special case. * This code would be less tricky if we could remove the * support for driver implemented message queues. @@ -3888,9 +3906,7 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message) } if (status == 0) { - /* Push out the messages in the calling context if we - * can. - */ + /* Push out the messages in the calling context if we can */ if (ctlr->transfer == spi_queued_transfer) { SPI_STATISTICS_INCREMENT_FIELD(&ctlr->statistics, spi_sync_immediate); @@ -4051,7 +4067,8 @@ int spi_write_then_read(struct spi_device *spi, struct spi_transfer x[2]; u8 *local_buf; - /* Use preallocated DMA-safe buffer if we can. We can't avoid + /* + * Use preallocated DMA-safe buffer if we can. We can't avoid * copying here, (as a pure convenience thing), but we can * keep heap costs out of the hot path unless someone else is * using the pre-allocated buffer or the transfer is too large. @@ -4287,11 +4304,12 @@ err0: return status; } -/* board_info is normally registered in arch_initcall(), - * but even essential drivers wait till later +/* + * A board_info is normally registered in arch_initcall(), + * but even essential drivers wait till later. * - * REVISIT only boardinfo really needs static linking. the rest (device and - * driver registration) _could_ be dynamically linked (modular) ... costs + * REVISIT only boardinfo really needs static linking. The rest (device and + * driver registration) _could_ be dynamically linked (modular) ... Costs * include needing to have boardinfo data structures be much more public. */ postcore_initcall(spi_init); -- cgit v1.2.3 From dd06a0c6b6f64f6610c0bb8f7651df3ebfb0f990 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 22 Nov 2021 19:52:45 +0200 Subject: spi: spidev: Use SPI_MODE_USER_MASK instead of casting Currently the 16-bit mode is what being used in user space. However assuming that is not fully correct. Instead we should use the respective mask, i.e. SPI_MODE_USER_MASK, which precisely defines what bits are available for user space apps. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20211122175245.84691-1-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown --- drivers/spi/spidev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 1bd73e322b7b..968dab2f5e3d 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -415,7 +415,7 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) tmp |= SPI_CS_HIGH; tmp |= spi->mode & ~SPI_MODE_MASK; - spi->mode = (u16)tmp; + spi->mode = tmp & SPI_MODE_USER_MASK; retval = spi_setup(spi); if (retval < 0) spi->mode = save; -- cgit v1.2.3 From 44ec41b7f7831f91c79a06de5e45f2d7ce6e4fbd Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 22 Nov 2021 22:06:22 +0200 Subject: spi: pxa2xx: Remove redundant ->read() and ->write() in struct chip_data Since the commit 196b0e2cf237 ("spi: pxa2xx: Remove if statement that is always true in pump_transfers()") the ->read() and ->write() methods in the struct driver_data are reconfigured for each transfer. Hence no need to keep the intermediate state in the struct chip_data. The same applies to n_bytes member of the same data structure. Get rid of unneeded storage for good. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20211122200622.43305-1-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx.c | 35 ++++++----------------------------- drivers/spi/spi-pxa2xx.h | 4 ---- 2 files changed, 6 insertions(+), 33 deletions(-) diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 1573f6d8eb48..ee3297dd532e 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -994,13 +994,10 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller, dev_err(&spi->dev, "Flush failed\n"); return -EIO; } - drv_data->n_bytes = chip->n_bytes; drv_data->tx = (void *)transfer->tx_buf; drv_data->tx_end = drv_data->tx + transfer->len; drv_data->rx = transfer->rx_buf; drv_data->rx_end = drv_data->rx + transfer->len; - drv_data->write = drv_data->tx ? chip->write : null_writer; - drv_data->read = drv_data->rx ? chip->read : null_reader; /* Change speed and bit per word on a per transfer */ bits = transfer->bits_per_word; @@ -1010,22 +1007,16 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller, if (bits <= 8) { drv_data->n_bytes = 1; - drv_data->read = drv_data->read != null_reader ? - u8_reader : null_reader; - drv_data->write = drv_data->write != null_writer ? - u8_writer : null_writer; + drv_data->read = drv_data->rx ? u8_reader : null_reader; + drv_data->write = drv_data->tx ? u8_writer : null_writer; } else if (bits <= 16) { drv_data->n_bytes = 2; - drv_data->read = drv_data->read != null_reader ? - u16_reader : null_reader; - drv_data->write = drv_data->write != null_writer ? - u16_writer : null_writer; + drv_data->read = drv_data->rx ? u16_reader : null_reader; + drv_data->write = drv_data->tx ? u16_writer : null_writer; } else if (bits <= 32) { drv_data->n_bytes = 4; - drv_data->read = drv_data->read != null_reader ? - u32_reader : null_reader; - drv_data->write = drv_data->write != null_writer ? - u32_writer : null_writer; + drv_data->read = drv_data->rx ? u32_reader : null_reader; + drv_data->write = drv_data->tx ? u32_writer : null_writer; } /* * If bits per word is changed in DMA mode, then must check @@ -1391,20 +1382,6 @@ static int setup(struct spi_device *spi) if (spi->mode & SPI_LOOP) chip->cr1 |= SSCR1_LBM; - if (spi->bits_per_word <= 8) { - chip->n_bytes = 1; - chip->read = u8_reader; - chip->write = u8_writer; - } else if (spi->bits_per_word <= 16) { - chip->n_bytes = 2; - chip->read = u16_reader; - chip->write = u16_writer; - } else if (spi->bits_per_word <= 32) { - chip->n_bytes = 4; - chip->read = u32_reader; - chip->write = u32_writer; - } - spi_set_ctldata(spi, chip); if (drv_data->ssp_type == CE4100_SSP) diff --git a/drivers/spi/spi-pxa2xx.h b/drivers/spi/spi-pxa2xx.h index 9a20fb88e50f..4d77f4de6eda 100644 --- a/drivers/spi/spi-pxa2xx.h +++ b/drivers/spi/spi-pxa2xx.h @@ -61,7 +61,6 @@ struct chip_data { u32 cr1; u32 dds_rate; u32 timeout; - u8 n_bytes; u8 enable_dma; u32 dma_burst_size; u32 dma_threshold; @@ -69,9 +68,6 @@ struct chip_data { u16 lpss_rx_threshold; u16 lpss_tx_threshold; - int (*write)(struct driver_data *drv_data); - int (*read)(struct driver_data *drv_data); - void (*cs_control)(u32 command); }; -- cgit v1.2.3 From fffc84fd87d963a2ea77a125b8a6f5a3c9f3192d Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 9 Nov 2021 23:59:20 +0100 Subject: spi: spidev: Make probe to fail early if a spidev compatible is used Some Device Trees don't use a real device name in the compatible string for SPI devices nodes, abusing the fact that the spidev driver name is used to match as a fallback when a SPI device ID table is not defined. But since commit 6840615f85f6 ("spi: spidev: Add SPI ID table") a table for SPI device IDs was added to the driver breaking the assumption that these DTs were relying on. There has been a warning message for some time since commit 956b200a846e ("spi: spidev: Warn loudly if instantiated from DT as "spidev""), making quite clear that this case is not really supported by the spidev driver. Since these devices won't match anyways after the mentioned commit, there is no point to continue if an spidev compatible is used. Let's just make the driver probe to fail early. Signed-off-by: Javier Martinez Canillas Link: https://lore.kernel.org/r/20211109225920.1158920-1-javierm@redhat.com Signed-off-by: Mark Brown --- drivers/spi/spidev.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 968dab2f5e3d..a5cceca8b82b 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -751,9 +751,10 @@ static int spidev_probe(struct spi_device *spi) * compatible string, it is a Linux implementation thing * rather than a description of the hardware. */ - WARN(spi->dev.of_node && - of_device_is_compatible(spi->dev.of_node, "spidev"), - "%pOF: buggy DT: spidev listed directly in DT\n", spi->dev.of_node); + if (spi->dev.of_node && of_device_is_compatible(spi->dev.of_node, "spidev")) { + dev_err(&spi->dev, "spidev listed directly in DT is not supported\n"); + return -EINVAL; + } spidev_probe_acpi(spi); -- cgit v1.2.3 From b79332ef9d61513d0ccda74a5161bb7c31851e9c Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 23 Nov 2021 19:00:32 +0200 Subject: spi: Fix condition in the __spi_register_driver() The recent commit 3f07657506df ("spi: deduplicate spi_match_id() in __spi_register_driver()") inadvertently inverted a condition that provokes a (harmless) warning: WARNING KERN SPI driver mtd_dataflash has no spi_device_id for atmel,at45 Restore logic to avoid such warning to be issued. Fixes: 3f07657506df ("spi: deduplicate spi_match_id() in __spi_register_driver()") Reported-by: Jon Hunter Signed-off-by: Andy Shevchenko Tested-by: Jon Hunter Link: https://lore.kernel.org/r/20211123170034.41253-1-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown --- drivers/spi/spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 5bf680fcb170..8726309b3eaf 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -474,7 +474,7 @@ int __spi_register_driver(struct module *owner, struct spi_driver *sdrv) const struct spi_device_id *spi_id; spi_id = spi_match_id(sdrv->id_table, of_name); - if (!spi_id) + if (spi_id) continue; } else { if (strcmp(sdrv->driver.name, of_name) == 0) -- cgit v1.2.3 From c74526f947ab946273939757c72499c0a5b09826 Mon Sep 17 00:00:00 2001 From: Kamal Dasu Date: Wed, 24 Nov 2021 14:33:52 -0500 Subject: spi: bcm-qspi: choose sysclk setting based on requested speed Check requested speed for a given transfer before setting 27MHz or 108Mhz sysclk on SoCs that support both. This way for baud rates below 212Khz we can use 27Mhz clock. Signed-off-by: Kamal Dasu Link: https://lore.kernel.org/r/20211124193353.32311-2-kdasu.kdev@gmail.com Signed-off-by: Mark Brown --- drivers/spi/spi-bcm-qspi.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c index f3de3305d0f5..38e6e2cb62ca 100644 --- a/drivers/spi/spi-bcm-qspi.c +++ b/drivers/spi/spi-bcm-qspi.c @@ -287,6 +287,18 @@ static inline int bcm_qspi_spbr_min(struct bcm_qspi *qspi) return 8; } +static u32 bcm_qspi_calc_spbr(u32 clk_speed_hz, + const struct bcm_qspi_parms *xp) +{ + u32 spbr = 0; + + /* SPBR = System Clock/(2 * SCK Baud Rate) */ + if (xp->speed_hz) + spbr = clk_speed_hz / (xp->speed_hz * 2); + + return spbr; +} + /* Read qspi controller register*/ static inline u32 bcm_qspi_read(struct bcm_qspi *qspi, enum base_type type, unsigned int offset) @@ -621,9 +633,17 @@ static void bcm_qspi_hw_set_parms(struct bcm_qspi *qspi, spcr |= MSPI_SPCR3_HALFDUPLEX | MSPI_SPCR3_HDOUTTYPE; if (bcm_qspi_has_sysclk_108(qspi)) { - /* SYSCLK_108 */ - spcr |= MSPI_SPCR3_SYSCLKSEL_108; - qspi->base_clk = MSPI_BASE_FREQ * 4; + /* check requested baud rate before moving to 108Mhz */ + spbr = bcm_qspi_calc_spbr(MSPI_BASE_FREQ * 4, xp); + if (spbr > QSPI_SPBR_MAX) { + /* use SYSCLK_27Mhz for slower baud rates */ + spcr &= ~MSPI_SPCR3_SYSCLKSEL_MASK; + qspi->base_clk = MSPI_BASE_FREQ; + } else { + /* SYSCLK_108Mhz */ + spcr |= MSPI_SPCR3_SYSCLKSEL_108; + qspi->base_clk = MSPI_BASE_FREQ * 4; + } } if (xp->bits_per_word > 16) { @@ -649,9 +669,9 @@ static void bcm_qspi_hw_set_parms(struct bcm_qspi *qspi, bcm_qspi_write(qspi, MSPI, MSPI_SPCR3, spcr); } - if (xp->speed_hz) - spbr = qspi->base_clk / (2 * xp->speed_hz); - + /* SCK Baud Rate = System Clock/(2 * SPBR) */ + qspi->max_speed_hz = qspi->base_clk / (bcm_qspi_spbr_min(qspi) * 2); + spbr = bcm_qspi_calc_spbr(qspi->base_clk, xp); spbr = clamp_val(spbr, bcm_qspi_spbr_min(qspi), QSPI_SPBR_MAX); bcm_qspi_write(qspi, MSPI, MSPI_SPCR0_LSB, spbr); -- cgit v1.2.3 From e10a6bb5f52de70c7798b720d16632d4042d2552 Mon Sep 17 00:00:00 2001 From: Kamal Dasu Date: Wed, 24 Nov 2021 14:33:53 -0500 Subject: spi: bcm-qspi: set transfer parameter only if they change Check if the transfer parameters have changed from previous settings before applying new parameters. Signed-off-by: Kamal Dasu Link: https://lore.kernel.org/r/20211124193353.32311-3-kdasu.kdev@gmail.com Signed-off-by: Mark Brown --- drivers/spi/spi-bcm-qspi.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c index 38e6e2cb62ca..c9a769b8594b 100644 --- a/drivers/spi/spi-bcm-qspi.c +++ b/drivers/spi/spi-bcm-qspi.c @@ -598,12 +598,24 @@ static void bcm_qspi_chip_select(struct bcm_qspi *qspi, int cs) qspi->curr_cs = cs; } +static bool bcmspi_parms_did_change(const struct bcm_qspi_parms * const cur, + const struct bcm_qspi_parms * const prev) +{ + return (cur->speed_hz != prev->speed_hz) || + (cur->mode != prev->mode) || + (cur->bits_per_word != prev->bits_per_word); +} + + /* MSPI helpers */ static void bcm_qspi_hw_set_parms(struct bcm_qspi *qspi, const struct bcm_qspi_parms *xp) { u32 spcr, spbr = 0; + if (!bcmspi_parms_did_change(xp, &qspi->last_parms)) + return; + if (!qspi->mspi_maj_rev) /* legacy controller */ spcr = MSPI_MASTER_BIT; -- cgit v1.2.3 From c1b00674aab0c6950970e52c0f059756064a9e8c Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Thu, 25 Nov 2021 14:41:09 +0200 Subject: spi: atmel: Drop slave_config argument in atmel_spi_dma_slave_config() The callers passed a pointer to slave_config as an argument of atmel_spi_dma_slave_config(), but they did not use it afterwards. Use instead a local variable in atmel_spi_dma_slave_config(), and stop passing arguments that are not needed in the callers. Signed-off-by: Tudor Ambarus Link: https://lore.kernel.org/r/20211125124110.838037-2-tudor.ambarus@microchip.com Signed-off-by: Mark Brown --- drivers/spi/spi-atmel.c | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index f872cf196c2f..22c7239aff75 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -433,26 +433,25 @@ static bool atmel_spi_can_dma(struct spi_master *master, } -static int atmel_spi_dma_slave_config(struct atmel_spi *as, - struct dma_slave_config *slave_config, - u8 bits_per_word) +static int atmel_spi_dma_slave_config(struct atmel_spi *as, u8 bits_per_word) { struct spi_master *master = platform_get_drvdata(as->pdev); + struct dma_slave_config slave_config; int err = 0; if (bits_per_word > 8) { - slave_config->dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; - slave_config->src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; + slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; + slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; } else { - slave_config->dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; - slave_config->src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; } - slave_config->dst_addr = (dma_addr_t)as->phybase + SPI_TDR; - slave_config->src_addr = (dma_addr_t)as->phybase + SPI_RDR; - slave_config->src_maxburst = 1; - slave_config->dst_maxburst = 1; - slave_config->device_fc = false; + slave_config.dst_addr = (dma_addr_t)as->phybase + SPI_TDR; + slave_config.src_addr = (dma_addr_t)as->phybase + SPI_RDR; + slave_config.src_maxburst = 1; + slave_config.dst_maxburst = 1; + slave_config.device_fc = false; /* * This driver uses fixed peripheral select mode (PS bit set to '0' in @@ -468,8 +467,8 @@ static int atmel_spi_dma_slave_config(struct atmel_spi *as, * So we'd rather write only one data at the time. Hence the transmit * path works the same whether FIFOs are available (and enabled) or not. */ - slave_config->direction = DMA_MEM_TO_DEV; - if (dmaengine_slave_config(master->dma_tx, slave_config)) { + slave_config.direction = DMA_MEM_TO_DEV; + if (dmaengine_slave_config(master->dma_tx, &slave_config)) { dev_err(&as->pdev->dev, "failed to configure tx dma channel\n"); err = -EINVAL; @@ -483,8 +482,8 @@ static int atmel_spi_dma_slave_config(struct atmel_spi *as, * So the receive path works the same whether FIFOs are available (and * enabled) or not. */ - slave_config->direction = DMA_DEV_TO_MEM; - if (dmaengine_slave_config(master->dma_rx, slave_config)) { + slave_config.direction = DMA_DEV_TO_MEM; + if (dmaengine_slave_config(master->dma_rx, &slave_config)) { dev_err(&as->pdev->dev, "failed to configure rx dma channel\n"); err = -EINVAL; @@ -496,7 +495,6 @@ static int atmel_spi_dma_slave_config(struct atmel_spi *as, static int atmel_spi_configure_dma(struct spi_master *master, struct atmel_spi *as) { - struct dma_slave_config slave_config; struct device *dev = &as->pdev->dev; int err; @@ -518,7 +516,7 @@ static int atmel_spi_configure_dma(struct spi_master *master, goto error; } - err = atmel_spi_dma_slave_config(as, &slave_config, 8); + err = atmel_spi_dma_slave_config(as, 8); if (err) goto error; @@ -700,7 +698,6 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master, struct dma_chan *txchan = master->dma_tx; struct dma_async_tx_descriptor *rxdesc; struct dma_async_tx_descriptor *txdesc; - struct dma_slave_config slave_config; dma_cookie_t cookie; dev_vdbg(master->dev.parent, "atmel_spi_next_xfer_dma_submit\n"); @@ -712,8 +709,7 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master, *plen = xfer->len; - if (atmel_spi_dma_slave_config(as, &slave_config, - xfer->bits_per_word)) + if (atmel_spi_dma_slave_config(as, xfer->bits_per_word)) goto err_exit; /* Send both scatterlists */ -- cgit v1.2.3 From f44a29ceb99fc99832ee1d55d7fe9c4dbf594660 Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Thu, 25 Nov 2021 14:41:10 +0200 Subject: spi: atmel: Remove setting of deprecated member of struct dma_slave_config The 'direction' member of 'struct dma_slave_config' is deprecated. Instead, drivers should use the direction argument to the device_prep_slave_sg and device_prep_dma_cyclic functions or the dir field in the dma_interleaved_template structure. spi-atmel uses the direction argument to dmaengine_prep_slave_sg. slave_config.direction is not used in neither of the DMA controller drivers (at_h/xdmac) that spi-atmel is using, we can just remove the setting of slave_config.direction and live with whatever stack value is there. Signed-off-by: Tudor Ambarus Link: https://lore.kernel.org/r/20211125124110.838037-3-tudor.ambarus@microchip.com Signed-off-by: Mark Brown --- drivers/spi/spi-atmel.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 22c7239aff75..f6626be4d4f7 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -467,7 +467,6 @@ static int atmel_spi_dma_slave_config(struct atmel_spi *as, u8 bits_per_word) * So we'd rather write only one data at the time. Hence the transmit * path works the same whether FIFOs are available (and enabled) or not. */ - slave_config.direction = DMA_MEM_TO_DEV; if (dmaengine_slave_config(master->dma_tx, &slave_config)) { dev_err(&as->pdev->dev, "failed to configure tx dma channel\n"); @@ -482,7 +481,6 @@ static int atmel_spi_dma_slave_config(struct atmel_spi *as, u8 bits_per_word) * So the receive path works the same whether FIFOs are available (and * enabled) or not. */ - slave_config.direction = DMA_DEV_TO_MEM; if (dmaengine_slave_config(master->dma_rx, &slave_config)) { dev_err(&as->pdev->dev, "failed to configure rx dma channel\n"); -- cgit v1.2.3 From f89d2cc3967af9948ffc58e4cc9a1331f1c4971a Mon Sep 17 00:00:00 2001 From: Krishna Yarlagadda Date: Thu, 25 Nov 2021 15:25:51 +0530 Subject: spi: tegra210-quad: use devm call for cdata memory Use devm alloc call to allocate memory for spi controller data and remove free calls from cleanup. Signed-off-by: Krishna Yarlagadda Link: https://lore.kernel.org/r/1637834152-32093-1-git-send-email-kyarlagadda@nvidia.com Signed-off-by: Mark Brown --- drivers/spi/spi-tegra210-quad.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c index c0f9a75b44b5..ce1bdb4767ea 100644 --- a/drivers/spi/spi-tegra210-quad.c +++ b/drivers/spi/spi-tegra210-quad.c @@ -877,7 +877,7 @@ static struct tegra_qspi_client_data *tegra_qspi_parse_cdata_dt(struct spi_devic struct tegra_qspi_client_data *cdata; struct device_node *slave_np = spi->dev.of_node; - cdata = kzalloc(sizeof(*cdata), GFP_KERNEL); + cdata = devm_kzalloc(&spi->dev, sizeof(*cdata), GFP_KERNEL); if (!cdata) return NULL; @@ -888,14 +888,6 @@ static struct tegra_qspi_client_data *tegra_qspi_parse_cdata_dt(struct spi_devic return cdata; } -static void tegra_qspi_cleanup(struct spi_device *spi) -{ - struct tegra_qspi_client_data *cdata = spi->controller_data; - - spi->controller_data = NULL; - kfree(cdata); -} - static int tegra_qspi_setup(struct spi_device *spi) { struct tegra_qspi *tqspi = spi_master_get_devdata(spi->master); @@ -1229,7 +1221,6 @@ static int tegra_qspi_probe(struct platform_device *pdev) SPI_TX_DUAL | SPI_RX_DUAL | SPI_TX_QUAD | SPI_RX_QUAD; master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) | SPI_BPW_MASK(8); master->setup = tegra_qspi_setup; - master->cleanup = tegra_qspi_cleanup; master->transfer_one_message = tegra_qspi_transfer_one_message; master->num_chipselect = 1; master->auto_runtime_pm = true; -- cgit v1.2.3 From 342e3ce0f6f4691b31b1c7c9c3ae37160c4a82d2 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 23 Nov 2021 21:27:21 +0200 Subject: ARM: pxa/lubbock: Replace custom ->cs_control() by GPIO lookup table SPI PXA2xx driver supports GPIO chipselect by querying for known GPIO connection ID. Replace custom ->cs_control() by GPIO table, so the driver will use generic approach on this platform. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20211123192723.44537-1-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown --- arch/arm/mach-pxa/lubbock.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 742d18a1f7dc..e2411971422d 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -211,16 +211,17 @@ static struct ads7846_platform_data ads_info = { // .y_plate_ohms = 500, /* GUESS! */ }; -static void ads7846_cs(u32 command) -{ - static const unsigned TS_nCS = 1 << 11; - lubbock_set_misc_wr(TS_nCS, (command == PXA2XX_CS_ASSERT) ? 0 : TS_nCS); -} +static struct gpiod_lookup_table ads7846_cs_gpios = { + .dev_id = "ads7846", + .table = { + GPIO_LOOKUP("lubbock", 11, "cs", GPIO_ACTIVE_LOW), + {} + }, +}; static struct pxa2xx_spi_chip ads_hw = { .tx_threshold = 1, .rx_threshold = 2, - .cs_control = ads7846_cs, }; static struct spi_board_info spi_board_info[] __initdata = { { @@ -512,6 +513,8 @@ static void __init lubbock_init(void) lubbock_flash_data[flashboot].name = "boot-rom"; (void) platform_add_devices(devices, ARRAY_SIZE(devices)); + gpiod_add_lookup_table(&ads7846_cs_gpios); + pxa2xx_set_spi_info(1, &pxa_ssp_master_info); spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); } -- cgit v1.2.3 From a9c8f68ce2c37ced2f7a8667eda71b7753ede398 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 23 Nov 2021 21:27:22 +0200 Subject: spi: pxa2xx: Get rid of unused ->cs_control() Since the last user of the custom ->cs_control() gone, we may get rid of this legacy API completely. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20211123192723.44537-2-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown --- Documentation/spi/pxa2xx.rst | 29 +++-------------------------- arch/arm/mach-pxa/stargate2.c | 2 +- drivers/spi/spi-pxa2xx.c | 18 ------------------ drivers/spi/spi-pxa2xx.h | 3 --- include/linux/spi/pxa2xx_spi.h | 4 ---- 5 files changed, 4 insertions(+), 52 deletions(-) diff --git a/Documentation/spi/pxa2xx.rst b/Documentation/spi/pxa2xx.rst index 6312968acfe9..dfc7673ed15d 100644 --- a/Documentation/spi/pxa2xx.rst +++ b/Documentation/spi/pxa2xx.rst @@ -102,7 +102,7 @@ device. All fields are optional. u8 dma_burst_size; u32 timeout; u8 enable_loopback; - void (*cs_control)(u32 command); + int gpio_cs; }; The "pxa2xx_spi_chip.tx_threshold" and "pxa2xx_spi_chip.rx_threshold" fields are @@ -133,11 +133,6 @@ into internal loopback mode. In this mode the SSP controller internally connects the SSPTX pin to the SSPRX pin. This is useful for initial setup testing. -The "pxa2xx_spi_chip.cs_control" field is used to point to a board specific -function for asserting/deasserting a slave device chip select. If the field is -NULL, the pxa2xx_spi master controller driver assumes that the SSP port is -configured to use GPIO or SSPFRM instead. - NOTE: the SPI driver cannot control the chip select if SSPFRM is used, so the chipselect is dropped after each spi_transfer. Most devices need chip select asserted around the complete message. Use SSPFRM as a GPIO (through a descriptor) @@ -152,30 +147,12 @@ field. Below is a sample configuration using the PXA255 NSSP. :: - /* Chip Select control for the CS8415A SPI slave device */ - static void cs8415a_cs_control(u32 command) - { - if (command & PXA2XX_CS_ASSERT) - GPCR(2) = GPIO_bit(2); - else - GPSR(2) = GPIO_bit(2); - } - - /* Chip Select control for the CS8405A SPI slave device */ - static void cs8405a_cs_control(u32 command) - { - if (command & PXA2XX_CS_ASSERT) - GPCR(3) = GPIO_bit(3); - else - GPSR(3) = GPIO_bit(3); - } - static struct pxa2xx_spi_chip cs8415a_chip_info = { .tx_threshold = 8, /* SSP hardward FIFO threshold */ .rx_threshold = 8, /* SSP hardward FIFO threshold */ .dma_burst_size = 8, /* Byte wide transfers used so 8 byte bursts */ .timeout = 235, /* See Intel documentation */ - .cs_control = cs8415a_cs_control, /* Use external chip select */ + .gpio_cs = 2, /* Use external chip select */ }; static struct pxa2xx_spi_chip cs8405a_chip_info = { @@ -183,7 +160,7 @@ field. Below is a sample configuration using the PXA255 NSSP. .rx_threshold = 8, /* SSP hardward FIFO threshold */ .dma_burst_size = 8, /* Byte wide transfers used so 8 byte bursts */ .timeout = 235, /* See Intel documentation */ - .cs_control = cs8405a_cs_control, /* Use external chip select */ + .gpio_cs = 3, /* Use external chip select */ }; static struct spi_board_info streetracer_spi_board_info[] __initdata = { diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c index 7ad627465768..8ca02ec1d44c 100644 --- a/arch/arm/mach-pxa/stargate2.c +++ b/arch/arm/mach-pxa/stargate2.c @@ -347,7 +347,7 @@ static struct pxa2xx_spi_controller pxa_ssp_master_2_info = { }; /* An upcoming kernel change will scrap SFRM usage so these - * drivers have been moved to use gpio's via cs_control */ + * drivers have been moved to use GPIOs */ static struct pxa2xx_spi_chip staccel_chip_info = { .tx_threshold = 8, .rx_threshold = 8, diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index ee3297dd532e..24196156c609 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -427,7 +427,6 @@ static void lpss_ssp_cs_control(struct spi_device *spi, bool enable) static void cs_assert(struct spi_device *spi) { - struct chip_data *chip = spi_get_ctldata(spi); struct driver_data *drv_data = spi_controller_get_devdata(spi->controller); @@ -436,18 +435,12 @@ static void cs_assert(struct spi_device *spi) return; } - if (chip->cs_control) { - chip->cs_control(PXA2XX_CS_ASSERT); - return; - } - if (is_lpss_ssp(drv_data)) lpss_ssp_cs_control(spi, true); } static void cs_deassert(struct spi_device *spi) { - struct chip_data *chip = spi_get_ctldata(spi); struct driver_data *drv_data = spi_controller_get_devdata(spi->controller); unsigned long timeout; @@ -461,11 +454,6 @@ static void cs_deassert(struct spi_device *spi) !time_after(jiffies, timeout)) cpu_relax(); - if (chip->cs_control) { - chip->cs_control(PXA2XX_CS_DEASSERT); - return; - } - if (is_lpss_ssp(drv_data)) lpss_ssp_cs_control(spi, false); } @@ -1204,12 +1192,6 @@ static int setup_cs(struct spi_device *spi, struct chip_data *chip, */ cleanup_cs(spi); - /* If ->cs_control() is provided, ignore GPIO chip select */ - if (chip_info->cs_control) { - chip->cs_control = chip_info->cs_control; - return 0; - } - if (gpio_is_valid(chip_info->gpio_cs)) { int gpio = chip_info->gpio_cs; int err; diff --git a/drivers/spi/spi-pxa2xx.h b/drivers/spi/spi-pxa2xx.h index 4d77f4de6eda..45cdbbc71c4b 100644 --- a/drivers/spi/spi-pxa2xx.h +++ b/drivers/spi/spi-pxa2xx.h @@ -49,7 +49,6 @@ struct driver_data { int (*write)(struct driver_data *drv_data); int (*read)(struct driver_data *drv_data); irqreturn_t (*transfer_handler)(struct driver_data *drv_data); - void (*cs_control)(u32 command); void __iomem *lpss_base; @@ -67,8 +66,6 @@ struct chip_data { u32 threshold; u16 lpss_rx_threshold; u16 lpss_tx_threshold; - - void (*cs_control)(u32 command); }; static inline u32 pxa2xx_spi_read(const struct driver_data *drv_data, u32 reg) diff --git a/include/linux/spi/pxa2xx_spi.h b/include/linux/spi/pxa2xx_spi.h index eaab121ee575..42e06bfbc2a4 100644 --- a/include/linux/spi/pxa2xx_spi.h +++ b/include/linux/spi/pxa2xx_spi.h @@ -9,9 +9,6 @@ #include -#define PXA2XX_CS_ASSERT (0x01) -#define PXA2XX_CS_DEASSERT (0x02) - struct dma_chan; /* @@ -47,7 +44,6 @@ struct pxa2xx_spi_chip { u32 timeout; u8 enable_loopback; int gpio_cs; - void (*cs_control)(u32 command); }; #if defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP) -- cgit v1.2.3 From 8393961c53b31078cfc877bc00eb0f67e1474edd Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 23 Nov 2021 21:27:23 +0200 Subject: spi: pxa2xx: Get rid of unused enable_loopback member There is no user of the enable_loopback member in the struct pxa2xx_spi_chip. Remote this legacy member completely. The mentioned in the documentation the testing phase can be performed with spidev_test tool. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20211123192723.44537-3-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown --- Documentation/spi/pxa2xx.rst | 6 ------ drivers/spi/spi-pxa2xx.c | 5 ++--- include/linux/spi/pxa2xx_spi.h | 1 - 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/Documentation/spi/pxa2xx.rst b/Documentation/spi/pxa2xx.rst index dfc7673ed15d..6347580826be 100644 --- a/Documentation/spi/pxa2xx.rst +++ b/Documentation/spi/pxa2xx.rst @@ -101,7 +101,6 @@ device. All fields are optional. u8 rx_threshold; u8 dma_burst_size; u32 timeout; - u8 enable_loopback; int gpio_cs; }; @@ -128,11 +127,6 @@ dependent on the SPI bus speed ("spi_board_info.max_speed_hz") and the specific slave device. Please note that the PXA2xx SSP 1 does not support trailing byte timeouts and must busy-wait any trailing bytes. -The "pxa2xx_spi_chip.enable_loopback" field is used to place the SSP porting -into internal loopback mode. In this mode the SSP controller internally -connects the SSPTX pin to the SSPRX pin. This is useful for initial setup -testing. - NOTE: the SPI driver cannot control the chip select if SSPFRM is used, so the chipselect is dropped after each spi_transfer. Most devices need chip select asserted around the complete message. Use SSPFRM as a GPIO (through a descriptor) diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 24196156c609..b3186bd0c2a8 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1289,7 +1289,6 @@ static int setup(struct spi_device *spi) chip_info = spi->controller_data; /* chip_info isn't always needed */ - chip->cr1 = 0; if (chip_info) { if (chip_info->timeout) chip->timeout = chip_info->timeout; @@ -1300,9 +1299,9 @@ static int setup(struct spi_device *spi) if (chip_info->rx_threshold) rx_thres = chip_info->rx_threshold; chip->dma_threshold = 0; - if (chip_info->enable_loopback) - chip->cr1 = SSCR1_LBM; } + + chip->cr1 = 0; if (spi_controller_is_slave(drv_data->controller)) { chip->cr1 |= SSCR1_SCFR; chip->cr1 |= SSCR1_SCLKDIR; diff --git a/include/linux/spi/pxa2xx_spi.h b/include/linux/spi/pxa2xx_spi.h index 42e06bfbc2a4..ca74dce36706 100644 --- a/include/linux/spi/pxa2xx_spi.h +++ b/include/linux/spi/pxa2xx_spi.h @@ -42,7 +42,6 @@ struct pxa2xx_spi_chip { u8 rx_threshold; u8 dma_burst_size; u32 timeout; - u8 enable_loopback; int gpio_cs; }; -- cgit v1.2.3 From 8762b07c95c18fbbe1c6b3eb1e8e686091c346b5 Mon Sep 17 00:00:00 2001 From: Pratyush Yadav Date: Tue, 9 Nov 2021 23:49:09 +0530 Subject: spi: dt-bindings: add schema listing peripheral-specific properties Many SPI controllers need to add properties to peripheral devices. This could be the delay in clock or data lines, etc. These properties are controller specific but need to be defined in the peripheral node because they are per-peripheral and there can be multiple peripherals attached to a controller. If these properties are not added to the peripheral binding, then the dtbs check emits a warning. But these properties do not make much sense in the peripheral binding because they are controller-specific and they will just pollute every peripheral binding. So this binding is added to collect all such properties from all such controllers. Peripheral bindings should simply refer to this binding and they should be rid of the warnings. There are some limitations with this approach. Firstly, there is no way to specify required properties. The schema contains properties for all controllers and there is no way to know which controller is being used. Secondly, there is no way to restrict additional properties. Since this schema will be used with an allOf operator, additionalProperties needs to be true. In addition, the peripheral schema will have to set unevaluatedProperties: false. Despite these limitations, this appears to be the best solution to this problem that doesn't involve modifying existing tools or schema specs. Signed-off-by: Pratyush Yadav Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20211109181911.2251-2-p.yadav@ti.com Signed-off-by: Mark Brown --- .../devicetree/bindings/spi/spi-controller.yaml | 69 +---------------- .../bindings/spi/spi-peripheral-props.yaml | 87 ++++++++++++++++++++++ 2 files changed, 89 insertions(+), 67 deletions(-) create mode 100644 Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml diff --git a/Documentation/devicetree/bindings/spi/spi-controller.yaml b/Documentation/devicetree/bindings/spi/spi-controller.yaml index 8246891602e7..36b72518f565 100644 --- a/Documentation/devicetree/bindings/spi/spi-controller.yaml +++ b/Documentation/devicetree/bindings/spi/spi-controller.yaml @@ -94,73 +94,8 @@ patternProperties: "^.*@[0-9a-f]+$": type: object - properties: - compatible: - description: - Compatible of the SPI device. - - reg: - minItems: 1 - maxItems: 256 - items: - minimum: 0 - maximum: 256 - description: - Chip select used by the device. - - spi-3wire: - $ref: /schemas/types.yaml#/definitions/flag - description: - The device requires 3-wire mode. - - spi-cpha: - $ref: /schemas/types.yaml#/definitions/flag - description: - The device requires shifted clock phase (CPHA) mode. - - spi-cpol: - $ref: /schemas/types.yaml#/definitions/flag - description: - The device requires inverse clock polarity (CPOL) mode. - - spi-cs-high: - $ref: /schemas/types.yaml#/definitions/flag - description: - The device requires the chip select active high. - - spi-lsb-first: - $ref: /schemas/types.yaml#/definitions/flag - description: - The device requires the LSB first mode. - - spi-max-frequency: - $ref: /schemas/types.yaml#/definitions/uint32 - description: - Maximum SPI clocking speed of the device in Hz. - - spi-rx-bus-width: - description: - Bus width to the SPI bus used for read transfers. - If 0 is provided, then no RX will be possible on this device. - $ref: /schemas/types.yaml#/definitions/uint32 - enum: [0, 1, 2, 4, 8] - default: 1 - - spi-rx-delay-us: - description: - Delay, in microseconds, after a read transfer. - - spi-tx-bus-width: - description: - Bus width to the SPI bus used for write transfers. - If 0 is provided, then no TX will be possible on this device. - $ref: /schemas/types.yaml#/definitions/uint32 - enum: [0, 1, 2, 4, 8] - default: 1 - - spi-tx-delay-us: - description: - Delay, in microseconds, after a write transfer. + allOf: + - $ref: spi-peripheral-props.yaml required: - compatible diff --git a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml new file mode 100644 index 000000000000..105fa2840e72 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml @@ -0,0 +1,87 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spi/spi-peripheral-props.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Peripheral-specific properties for a SPI bus. + +description: + Many SPI controllers need to add properties to peripheral devices. They could + be common properties like spi-max-frequency, spi-cpha, etc. or they could be + controller specific like delay in clock or data lines, etc. These properties + need to be defined in the peripheral node because they are per-peripheral and + there can be multiple peripherals attached to a controller. All those + properties are listed here. The controller specific properties should go in + their own separate schema that should be referenced from here. + +maintainers: + - Pratyush Yadav + +properties: + reg: + minItems: 1 + maxItems: 256 + items: + minimum: 0 + maximum: 256 + description: + Chip select used by the device. + + spi-3wire: + $ref: /schemas/types.yaml#/definitions/flag + description: + The device requires 3-wire mode. + + spi-cpha: + $ref: /schemas/types.yaml#/definitions/flag + description: + The device requires shifted clock phase (CPHA) mode. + + spi-cpol: + $ref: /schemas/types.yaml#/definitions/flag + description: + The device requires inverse clock polarity (CPOL) mode. + + spi-cs-high: + $ref: /schemas/types.yaml#/definitions/flag + description: + The device requires the chip select active high. + + spi-lsb-first: + $ref: /schemas/types.yaml#/definitions/flag + description: + The device requires the LSB first mode. + + spi-max-frequency: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Maximum SPI clocking speed of the device in Hz. + + spi-rx-bus-width: + description: + Bus width to the SPI bus used for read transfers. + If 0 is provided, then no RX will be possible on this device. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2, 4, 8] + default: 1 + + spi-rx-delay-us: + description: + Delay, in microseconds, after a read transfer. + + spi-tx-bus-width: + description: + Bus width to the SPI bus used for write transfers. + If 0 is provided, then no TX will be possible on this device. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2, 4, 8] + default: 1 + + spi-tx-delay-us: + description: + Delay, in microseconds, after a write transfer. + +# The controller specific properties go here. + +additionalProperties: true -- cgit v1.2.3 From b6bdc6e043906c70e949b2747772e6aa1d36f2a3 Mon Sep 17 00:00:00 2001 From: Pratyush Yadav Date: Tue, 9 Nov 2021 23:49:10 +0530 Subject: spi: dt-bindings: cdns,qspi-nor: Move peripheral-specific properties out The spi-peripheral-props.yaml schema contains peripheral-specific properties for SPI controllers that should be present in the peripheral node. Move peripheral-specific properties to a separate file and refer to it in spi-peripheral-props.yaml. Signed-off-by: Pratyush Yadav Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20211109181911.2251-3-p.yadav@ti.com Signed-off-by: Mark Brown --- .../spi/cdns,qspi-nor-peripheral-props.yaml | 42 ++++++++++++++++++++++ .../devicetree/bindings/spi/cdns,qspi-nor.yaml | 33 ----------------- .../bindings/spi/spi-peripheral-props.yaml | 2 ++ 3 files changed, 44 insertions(+), 33 deletions(-) create mode 100644 Documentation/devicetree/bindings/spi/cdns,qspi-nor-peripheral-props.yaml diff --git a/Documentation/devicetree/bindings/spi/cdns,qspi-nor-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/cdns,qspi-nor-peripheral-props.yaml new file mode 100644 index 000000000000..553601a441a7 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/cdns,qspi-nor-peripheral-props.yaml @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spi/cdns,qspi-nor-peripheral-props.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Peripheral-specific properties for the Cadence QSPI controller. + +description: + See spi-peripheral-props.yaml for more info. + +maintainers: + - Pratyush Yadav + +properties: + # cdns,qspi-nor.yaml + cdns,read-delay: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Delay for read capture logic, in clock cycles. + + cdns,tshsl-ns: + description: + Delay in nanoseconds for the length that the master mode chip select + outputs are de-asserted between transactions. + + cdns,tsd2d-ns: + description: + Delay in nanoseconds between one chip select being de-activated + and the activation of another. + + cdns,tchsh-ns: + description: + Delay in nanoseconds between last bit of current transaction and + deasserting the device chip select (qspi_n_ss_out). + + cdns,tslch-ns: + description: + Delay in nanoseconds between setting qspi_n_ss_out low and + first bit transfer. + +additionalProperties: true diff --git a/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml b/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml index ca155abbda7a..a439e3ed753f 100644 --- a/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml +++ b/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml @@ -86,39 +86,6 @@ properties: items: enum: [ qspi, qspi-ocp ] -# subnode's properties -patternProperties: - "@[0-9a-f]+$": - type: object - description: - Flash device uses the below defined properties in the subnode. - - properties: - cdns,read-delay: - $ref: /schemas/types.yaml#/definitions/uint32 - description: - Delay for read capture logic, in clock cycles. - - cdns,tshsl-ns: - description: - Delay in nanoseconds for the length that the master mode chip select - outputs are de-asserted between transactions. - - cdns,tsd2d-ns: - description: - Delay in nanoseconds between one chip select being de-activated - and the activation of another. - - cdns,tchsh-ns: - description: - Delay in nanoseconds between last bit of current transaction and - deasserting the device chip select (qspi_n_ss_out). - - cdns,tslch-ns: - description: - Delay in nanoseconds between setting qspi_n_ss_out low and - first bit transfer. - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml index 105fa2840e72..5dd209206e88 100644 --- a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml +++ b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml @@ -83,5 +83,7 @@ properties: Delay, in microseconds, after a write transfer. # The controller specific properties go here. +allOf: + - $ref: cdns,qspi-nor-peripheral-props.yaml# additionalProperties: true -- cgit v1.2.3 From e9d7c323cfbbd07c365a419b4ce3dc2f161442c7 Mon Sep 17 00:00:00 2001 From: Pratyush Yadav Date: Tue, 9 Nov 2021 23:49:11 +0530 Subject: dt-bindings: mtd: spi-nor: Add a reference to spi-peripheral-props.yaml The spi-peripheral-props.yaml schema contains peripheral-specific properties for SPI controllers that should be present in the peripheral node. Add a reference to that so its constraints are followed. additionalProperties: false cannot be used since it marks the controller properties as unknown. Use unevaluatedProperties: false instead. This has the side effect of allowing extra properties that are not specified in the schema. The alternative is to list all the controller properties in this schema but that would mean every peripheral binding would have to repeat the same set of properties for each controller. Signed-off-by: Pratyush Yadav Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20211109181911.2251-4-p.yadav@ti.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml index ed590d7c6e37..39421f7233e4 100644 --- a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml +++ b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml @@ -11,6 +11,7 @@ maintainers: allOf: - $ref: "mtd.yaml#" + - $ref: /schemas/spi/spi-peripheral-props.yaml# properties: compatible: @@ -88,7 +89,7 @@ patternProperties: "^otp(-[0-9]+)?$": type: object -additionalProperties: false +unevaluatedProperties: false examples: - | -- cgit v1.2.3 From 95c07247399536f83b89dc60cfe7b279d17e69f6 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sat, 11 Dec 2021 02:05:34 +0900 Subject: spi: Fix incorrect cs_setup delay handling Move the cs_setup delay to the end of spi_set_cs. From include/linux/spi/spi.h: * @cs_setup: delay to be introduced by the controller after CS is asserted The cs_setup delay needs to happen *after* CS is asserted, that is, at the end of spi_set_cs, not at the beginning. Otherwise we're just delaying before the SPI transaction starts at all, which isn't very useful. No drivers use this right now, but that is likely to change soon with an upcoming Apple SPI HID transport driver. Fixes: 25093bdeb6bc ("spi: implement SW control for CS times") Signed-off-by: Hector Martin Link: https://lore.kernel.org/r/20211210170534.177139-1-marcan@marcan.st Signed-off-by: Mark Brown --- drivers/spi/spi.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 8726309b3eaf..7c790858547c 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -944,12 +944,9 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force) spi->controller->last_cs_enable = enable; spi->controller->last_cs_mode_high = spi->mode & SPI_CS_HIGH; - if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) || - !spi->controller->set_cs_timing) { - if (activate) - spi_delay_exec(&spi->cs_setup, NULL); - else - spi_delay_exec(&spi->cs_hold, NULL); + if ((spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) || + !spi->controller->set_cs_timing) && !activate) { + spi_delay_exec(&spi->cs_hold, NULL); } if (spi->mode & SPI_CS_HIGH) @@ -991,7 +988,9 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force) if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) || !spi->controller->set_cs_timing) { - if (!activate) + if (activate) + spi_delay_exec(&spi->cs_setup, NULL); + else spi_delay_exec(&spi->cs_inactive, NULL); } } -- cgit v1.2.3 From 001a41d2a7061694fa31accdbc2013bb5c5d83b5 Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Thu, 9 Dec 2021 14:29:38 +0200 Subject: spi: atmel,quadspi: Convert to json-schema Convert the Atmel QuadSPI controller Device Tree binding documentation to json-schema. Signed-off-by: Tudor Ambarus Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20211209122939.339810-2-tudor.ambarus@microchip.com Signed-off-by: Mark Brown --- .../devicetree/bindings/spi/atmel,quadspi.yaml | 87 ++++++++++++++++++++++ .../devicetree/bindings/spi/atmel-quadspi.txt | 37 --------- 2 files changed, 87 insertions(+), 37 deletions(-) create mode 100644 Documentation/devicetree/bindings/spi/atmel,quadspi.yaml delete mode 100644 Documentation/devicetree/bindings/spi/atmel-quadspi.txt diff --git a/Documentation/devicetree/bindings/spi/atmel,quadspi.yaml b/Documentation/devicetree/bindings/spi/atmel,quadspi.yaml new file mode 100644 index 000000000000..7d0408f53c5f --- /dev/null +++ b/Documentation/devicetree/bindings/spi/atmel,quadspi.yaml @@ -0,0 +1,87 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spi/atmel,quadspi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Atmel Quad Serial Peripheral Interface (QSPI) + +maintainers: + - Tudor Ambarus + +allOf: + - $ref: spi-controller.yaml# + +properties: + compatible: + enum: + - atmel,sama5d2-qspi + - microchip,sam9x60-qspi + + reg: + items: + - description: base registers + - description: mapped memory + + reg-names: + items: + - const: qspi_base + - const: qspi_mmap + + clocks: + minItems: 1 + items: + - description: peripheral clock + - description: system clock, if available + + clock-names: + minItems: 1 + items: + - const: pclk + - const: qspick + + interrupts: + maxItems: 1 + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + +required: + - compatible + - reg + - reg-names + - interrupts + - clocks + - clock-names + - '#address-cells' + - '#size-cells' + +unevaluatedProperties: false + +examples: + - | + #include + #include + spi@f0020000 { + compatible = "atmel,sama5d2-qspi"; + reg = <0xf0020000 0x100>, <0xd0000000 0x8000000>; + reg-names = "qspi_base", "qspi_mmap"; + interrupts = <52 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 52>; + clock-names = "pclk"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi0_default>; + + flash@0 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <50000000>; + reg = <0>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; + }; + }; diff --git a/Documentation/devicetree/bindings/spi/atmel-quadspi.txt b/Documentation/devicetree/bindings/spi/atmel-quadspi.txt deleted file mode 100644 index 7c40ea694352..000000000000 --- a/Documentation/devicetree/bindings/spi/atmel-quadspi.txt +++ /dev/null @@ -1,37 +0,0 @@ -* Atmel Quad Serial Peripheral Interface (QSPI) - -Required properties: -- compatible: Should be one of the following: - - "atmel,sama5d2-qspi" - - "microchip,sam9x60-qspi" -- reg: Should contain the locations and lengths of the base registers - and the mapped memory. -- reg-names: Should contain the resource reg names: - - qspi_base: configuration register address space - - qspi_mmap: memory mapped address space -- interrupts: Should contain the interrupt for the device. -- clocks: Should reference the peripheral clock and the QSPI system - clock if available. -- clock-names: Should contain "pclk" for the peripheral clock and "qspick" - for the system clock when available. -- #address-cells: Should be <1>. -- #size-cells: Should be <0>. - -Example: - -spi@f0020000 { - compatible = "atmel,sama5d2-qspi"; - reg = <0xf0020000 0x100>, <0xd0000000 0x8000000>; - reg-names = "qspi_base", "qspi_mmap"; - interrupts = <52 IRQ_TYPE_LEVEL_HIGH 7>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 52>; - clock-names = "pclk"; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_spi0_default>; - - m25p80@0 { - ... - }; -}; -- cgit v1.2.3 From 77850bda360dd9b389d5064c64b79467d613c3d6 Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Thu, 9 Dec 2021 14:29:39 +0200 Subject: spi: atmel,quadspi: Define sama7g5 QSPI sama7g5 embedds 2 instances of the QSPI controller: 1/ One Octal Serial Peripheral Interface (QSPI0) Supporting up to 200 MHz DDR. Octal, TwinQuad, HyperFlash and OctaFlash Protocols Supported 2/ One Quad Serial Peripheral Interface (QSPI1) Supporting Up to 90 MHz DDR/133 MHz SDR Signed-off-by: Tudor Ambarus Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20211209122939.339810-3-tudor.ambarus@microchip.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/atmel,quadspi.yaml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/atmel,quadspi.yaml b/Documentation/devicetree/bindings/spi/atmel,quadspi.yaml index 7d0408f53c5f..1d493add4053 100644 --- a/Documentation/devicetree/bindings/spi/atmel,quadspi.yaml +++ b/Documentation/devicetree/bindings/spi/atmel,quadspi.yaml @@ -17,6 +17,8 @@ properties: enum: - atmel,sama5d2-qspi - microchip,sam9x60-qspi + - microchip,sama7g5-qspi + - microchip,sama7g5-ospi reg: items: @@ -32,17 +34,27 @@ properties: minItems: 1 items: - description: peripheral clock - - description: system clock, if available + - description: system clock or generic clock, if available clock-names: minItems: 1 items: - const: pclk - - const: qspick + - enum: [ qspick, gclk ] interrupts: maxItems: 1 + dmas: + items: + - description: tx DMA channel + - description: rx DMA channel + + dma-names: + items: + - const: tx + - const: rx + '#address-cells': const: 1 -- cgit v1.2.3 From 6008cb4c98d935a844edf2f3c13639104f533e30 Mon Sep 17 00:00:00 2001 From: Tinghan Shen Date: Mon, 20 Dec 2021 20:18:23 +0800 Subject: spi: spi-mtk-nor: add new clock name 'axi' for spi nor Some mtk spi nor has dedicated dma(s) inside. Add a new clock name, axi, for spi nor dma bus clock. Signed-off-by: Tinghan Shen Link: https://lore.kernel.org/r/20211220121825.6446-3-tinghan.shen@mediatek.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/mediatek,spi-mtk-nor.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-nor.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-nor.yaml index 7393f30535df..4fe929bfcec9 100644 --- a/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-nor.yaml +++ b/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-nor.yaml @@ -43,14 +43,19 @@ properties: maxItems: 1 clocks: + minItems: 2 items: - description: clock used for spi bus - description: clock used for controller + - description: clock used for nor dma bus. this depends on hardware + design, so this is optional. clock-names: + minItems: 2 items: - const: spi - const: sf + - const: axi required: - compatible @@ -84,4 +89,3 @@ examples: }; }; }; - -- cgit v1.2.3 From 80bb73a9fbcde4ecc55e12f10c73fabbe68a24d1 Mon Sep 17 00:00:00 2001 From: Kunihiko Hayashi Date: Wed, 22 Dec 2021 13:48:12 +0900 Subject: spi: uniphier: Fix a bug that doesn't point to private data correctly In uniphier_spi_remove(), there is a wrong code to get private data from the platform device, so the driver can't be removed properly. The driver should get spi_master from the platform device and retrieve the private data from it. Cc: Fixes: 5ba155a4d4cc ("spi: add SPI controller driver for UniPhier SoC") Signed-off-by: Kunihiko Hayashi Link: https://lore.kernel.org/r/1640148492-32178-1-git-send-email-hayashi.kunihiko@socionext.com Signed-off-by: Mark Brown --- drivers/spi/spi-uniphier.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi-uniphier.c b/drivers/spi/spi-uniphier.c index 8900e51e1a1c..342ee8d2c476 100644 --- a/drivers/spi/spi-uniphier.c +++ b/drivers/spi/spi-uniphier.c @@ -767,12 +767,13 @@ out_master_put: static int uniphier_spi_remove(struct platform_device *pdev) { - struct uniphier_spi_priv *priv = platform_get_drvdata(pdev); + struct spi_master *master = platform_get_drvdata(pdev); + struct uniphier_spi_priv *priv = spi_master_get_devdata(master); - if (priv->master->dma_tx) - dma_release_channel(priv->master->dma_tx); - if (priv->master->dma_rx) - dma_release_channel(priv->master->dma_rx); + if (master->dma_tx) + dma_release_channel(master->dma_tx); + if (master->dma_rx) + dma_release_channel(master->dma_rx); clk_disable_unprepare(priv->clk); -- cgit v1.2.3 From c70282457c380db7deb57c81a6894debc8f88efa Mon Sep 17 00:00:00 2001 From: Oskari Lemmela Date: Wed, 22 Dec 2021 07:59:58 +0200 Subject: spi: ar934x: fix transfer and word delays Add missing delay between transferred messages and words. Signed-off-by: Oskari Lemmela Link: https://lore.kernel.org/r/20211222055958.1383233-3-oskari@lemmela.net Signed-off-by: Mark Brown --- drivers/spi/spi-ar934x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/spi/spi-ar934x.c b/drivers/spi/spi-ar934x.c index def32e0aaefe..e1b64e35900c 100644 --- a/drivers/spi/spi-ar934x.c +++ b/drivers/spi/spi-ar934x.c @@ -137,8 +137,10 @@ static int ar934x_spi_transfer_one_message(struct spi_controller *master, reg >>= 8; } } + spi_delay_exec(&t->word_delay, t); } m->actual_length += t->len; + spi_transfer_delay_exec(t); } msg_done: -- cgit v1.2.3 From e6609c26b3ab71aa3ef2f7f9524a066a863a7f18 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 22 Dec 2021 17:57:37 +0200 Subject: spi: dln2: Propagate firmware node Propagate firmware node by using a specific API call, i.e. device_set_node(). Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20211222155739.7699-1-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown --- drivers/spi/spi-dln2.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-dln2.c b/drivers/spi/spi-dln2.c index 3ff63ab82f4f..0a1fb2bc9e54 100644 --- a/drivers/spi/spi-dln2.c +++ b/drivers/spi/spi-dln2.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -688,6 +689,8 @@ static int dln2_spi_probe(struct platform_device *pdev) if (!master) return -ENOMEM; + device_set_node(&master->dev, dev_fwnode(dev)); + platform_set_drvdata(pdev, master); dln2 = spi_master_get_devdata(master); @@ -699,7 +702,6 @@ static int dln2_spi_probe(struct platform_device *pdev) } dln2->master = master; - dln2->master->dev.of_node = dev->of_node; dln2->pdev = pdev; dln2->port = pdata->port; /* cs/mode can never be 0xff, so the first transfer will set them */ -- cgit v1.2.3 From 27b6965ccb72e658eb2235f564a04d2775c956cf Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 22 Dec 2021 17:57:38 +0200 Subject: spi: dw: Propagate firmware node Propagate firmware node by using a specific API call, i.e. device_set_node(). Signed-off-by: Andy Shevchenko Tested-by: Serge Semin Acked-by: Serge Semin Link: https://lore.kernel.org/r/20211222155739.7699-2-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown --- drivers/spi/spi-dw-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index 934cc7a922e8..ecea471ff42c 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -895,6 +895,8 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) if (!master) return -ENOMEM; + device_set_node(&master->dev, dev_fwnode(dev)); + dws->master = master; dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR); @@ -931,8 +933,6 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) if (dws->mem_ops.exec_op) master->mem_ops = &dws->mem_ops; master->max_speed_hz = dws->max_freq; - master->dev.of_node = dev->of_node; - master->dev.fwnode = dev->fwnode; master->flags = SPI_MASTER_GPIO_SS; master->auto_runtime_pm = true; -- cgit v1.2.3 From 12baee68b2df6847f9a26ee82f30aa5f52c6d0d2 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 22 Dec 2021 17:57:39 +0200 Subject: spi: pxa2xx: Propagate firmware node Propagate firmware node by using a specific API call, i.e. device_set_node(). Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20211222155739.7699-3-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index b3186bd0c2a8..e88f86274eeb 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1664,8 +1664,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) drv_data->controller_info = platform_info; drv_data->ssp = ssp; - controller->dev.of_node = dev->of_node; - controller->dev.fwnode = dev->fwnode; + device_set_node(&controller->dev, dev_fwnode(dev)); /* The spi->mode bits understood by this driver: */ controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP; -- cgit v1.2.3 From ebe33e5a98dcf14a9630845f3f10c193584ac054 Mon Sep 17 00:00:00 2001 From: Oskari Lemmela Date: Wed, 22 Dec 2021 07:59:57 +0200 Subject: spi: ar934x: fix transfer size If bits_per_word is configured, transfer only word amount of data per iteration. Signed-off-by: Oskari Lemmela Link: https://lore.kernel.org/r/20211222055958.1383233-2-oskari@lemmela.net Signed-off-by: Mark Brown --- drivers/spi/spi-ar934x.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi-ar934x.c b/drivers/spi/spi-ar934x.c index e1b64e35900c..ec7250c4c810 100644 --- a/drivers/spi/spi-ar934x.c +++ b/drivers/spi/spi-ar934x.c @@ -82,7 +82,7 @@ static int ar934x_spi_transfer_one_message(struct spi_controller *master, struct spi_device *spi = m->spi; unsigned long trx_done, trx_cur; int stat = 0; - u8 term = 0; + u8 bpw, term = 0; int div, i; u32 reg; const u8 *tx_buf; @@ -90,6 +90,11 @@ static int ar934x_spi_transfer_one_message(struct spi_controller *master, m->actual_length = 0; list_for_each_entry(t, &m->transfers, transfer_list) { + if (t->bits_per_word >= 8 && t->bits_per_word < 32) + bpw = t->bits_per_word >> 3; + else + bpw = 4; + if (t->speed_hz) div = ar934x_spi_clk_div(sp, t->speed_hz); else @@ -105,10 +110,10 @@ static int ar934x_spi_transfer_one_message(struct spi_controller *master, iowrite32(reg, sp->base + AR934X_SPI_REG_CTRL); iowrite32(0, sp->base + AR934X_SPI_DATAOUT); - for (trx_done = 0; trx_done < t->len; trx_done += 4) { + for (trx_done = 0; trx_done < t->len; trx_done += bpw) { trx_cur = t->len - trx_done; - if (trx_cur > 4) - trx_cur = 4; + if (trx_cur > bpw) + trx_cur = bpw; else if (list_is_last(&t->transfer_list, &m->transfers)) term = 1; @@ -193,7 +198,8 @@ static int ar934x_spi_probe(struct platform_device *pdev) ctlr->mode_bits = SPI_LSB_FIRST; ctlr->setup = ar934x_spi_setup; ctlr->transfer_one_message = ar934x_spi_transfer_one_message; - ctlr->bits_per_word_mask = SPI_BPW_MASK(8); + ctlr->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(24) | + SPI_BPW_MASK(16) | SPI_BPW_MASK(8); ctlr->dev.of_node = pdev->dev.of_node; ctlr->num_chipselect = 3; -- cgit v1.2.3 From 709c81b55c6aa74a6cdad27bdc224f50962b6ad9 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 5 Jan 2022 12:32:33 -0600 Subject: spi: spi-mux: Add reference to spi-peripheral-props.yaml schema The spi-mux serves as both a SPI peripheral and controller, so add a reference to spi-peripheral-props.yaml in addition to spi-controller.yaml. This is necessary to avoid unevaluatedProperties warnings once those are fully enabled. Signed-off-by: Rob Herring Reviewed-by: Chris Packham Link: https://lore.kernel.org/r/20220105183234.3426649-1-robh@kernel.org Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/spi-mux.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/spi/spi-mux.yaml b/Documentation/devicetree/bindings/spi/spi-mux.yaml index 51c7622dc20b..7ea79f6d33f3 100644 --- a/Documentation/devicetree/bindings/spi/spi-mux.yaml +++ b/Documentation/devicetree/bindings/spi/spi-mux.yaml @@ -31,6 +31,7 @@ description: | allOf: - $ref: "/schemas/spi/spi-controller.yaml#" + - $ref: "/schemas/spi/spi-peripheral-props.yaml#" maintainers: - Chris Packham -- cgit v1.2.3 From 74b86d6af81be73bb74995ebeba74417e84b6b6f Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 3 Jan 2022 12:41:17 +0530 Subject: spi: qcom: geni: set the error code for gpi transfer Before we invoke spi_finalize_current_transfer() in spi_gsi_callback_result() we should set the spi->cur_msg->status as appropriate (0 for success, error otherwise). The helps to return error on transfer and not wait till it timesout on error Fixes: b59c122484ec ("spi: spi-geni-qcom: Add support for GPI dma") Signed-off-by: Vinod Koul Reviewed-by: Douglas Anderson Link: https://lore.kernel.org/r/20220103071118.27220-1-vkoul@kernel.org Signed-off-by: Mark Brown --- drivers/spi/spi-geni-qcom.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c index 413fa1a7a936..b82f3ddff0f4 100644 --- a/drivers/spi/spi-geni-qcom.c +++ b/drivers/spi/spi-geni-qcom.c @@ -346,17 +346,21 @@ spi_gsi_callback_result(void *cb, const struct dmaengine_result *result) { struct spi_master *spi = cb; + spi->cur_msg->status = -EIO; if (result->result != DMA_TRANS_NOERROR) { dev_err(&spi->dev, "DMA txn failed: %d\n", result->result); + spi_finalize_current_transfer(spi); return; } if (!result->residue) { + spi->cur_msg->status = 0; dev_dbg(&spi->dev, "DMA txn completed\n"); - spi_finalize_current_transfer(spi); } else { dev_err(&spi->dev, "DMA xfer has pending: %d\n", result->residue); } + + spi_finalize_current_transfer(spi); } static int setup_gsi_xfer(struct spi_transfer *xfer, struct spi_geni_master *mas, -- cgit v1.2.3 From f8039ea55d4ccac2238a247a574f0acb3bc1dc4b Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 3 Jan 2022 12:41:18 +0530 Subject: spi: qcom: geni: handle timeout for gpi mode We missed adding handle_err for gpi mode, so add a new function spi_geni_handle_err() which would call handle_fifo_timeout() or newly added handle_gpi_timeout() based on mode Fixes: b59c122484ec ("spi: spi-geni-qcom: Add support for GPI dma") Reported-by: Douglas Anderson Reviewed-by: Douglas Anderson Signed-off-by: Vinod Koul Link: https://lore.kernel.org/r/20220103071118.27220-2-vkoul@kernel.org Signed-off-by: Mark Brown --- drivers/spi/spi-geni-qcom.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c index b82f3ddff0f4..f7d905d2a90f 100644 --- a/drivers/spi/spi-geni-qcom.c +++ b/drivers/spi/spi-geni-qcom.c @@ -164,6 +164,30 @@ static void handle_fifo_timeout(struct spi_master *spi, } } +static void handle_gpi_timeout(struct spi_master *spi, struct spi_message *msg) +{ + struct spi_geni_master *mas = spi_master_get_devdata(spi); + + dmaengine_terminate_sync(mas->tx); + dmaengine_terminate_sync(mas->rx); +} + +static void spi_geni_handle_err(struct spi_master *spi, struct spi_message *msg) +{ + struct spi_geni_master *mas = spi_master_get_devdata(spi); + + switch (mas->cur_xfer_mode) { + case GENI_SE_FIFO: + handle_fifo_timeout(spi, msg); + break; + case GENI_GPI_DMA: + handle_gpi_timeout(spi, msg); + break; + default: + dev_err(mas->dev, "Abort on Mode:%d not supported", mas->cur_xfer_mode); + } +} + static bool spi_geni_is_abort_still_pending(struct spi_geni_master *mas) { struct geni_se *se = &mas->se; @@ -922,7 +946,7 @@ static int spi_geni_probe(struct platform_device *pdev) spi->can_dma = geni_can_dma; spi->dma_map_dev = dev->parent; spi->auto_runtime_pm = true; - spi->handle_err = handle_fifo_timeout; + spi->handle_err = spi_geni_handle_err; spi->use_gpio_descriptors = true; init_completion(&mas->cs_done); -- cgit v1.2.3 From 3e718b44756e2829e7189a9504aa7a6d7f394d6c Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 6 Jan 2022 12:25:17 -0600 Subject: spi: dt-bindings: mediatek,spi-mtk-nor: Fix example 'interrupts' property A phandle for 'interrupts' value is wrong and should be one or more numbers. Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220106182518.1435497-9-robh@kernel.org Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/mediatek,spi-mtk-nor.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-nor.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-nor.yaml index 4fe929bfcec9..4e4694e3d539 100644 --- a/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-nor.yaml +++ b/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-nor.yaml @@ -77,7 +77,7 @@ examples: nor_flash: spi@1100d000 { compatible = "mediatek,mt8173-nor"; reg = <0 0x1100d000 0 0xe0>; - interrupts = <&spi_flash_irq>; + interrupts = <1>; clocks = <&pericfg CLK_PERI_SPI>, <&topckgen CLK_TOP_SPINFI_IFR_SEL>; clock-names = "spi", "sf"; #address-cells = <1>; -- cgit v1.2.3 From c8c9cb6d9fbeace1c5509f4bb2f3c32095cda0d0 Mon Sep 17 00:00:00 2001 From: Qinghua Jin Date: Fri, 7 Jan 2022 10:46:31 +0800 Subject: spi: atmel: Fix typo Change 'actualy' to 'actually' Signed-off-by: Qinghua Jin Link: https://lore.kernel.org/r/20220107024631.396862-1-qhjin.dev@gmail.com Signed-off-by: Mark Brown --- drivers/spi/spi-atmel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index f6626be4d4f7..9e300a932699 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -463,7 +463,7 @@ static int atmel_spi_dma_slave_config(struct atmel_spi *as, u8 bits_per_word) * However, the first data has to be written into the lowest 16 bits and * the second data into the highest 16 bits of the Transmit * Data Register. For 8bit data (the most frequent case), it would - * require to rework tx_buf so each data would actualy fit 16 bits. + * require to rework tx_buf so each data would actually fit 16 bits. * So we'd rather write only one data at the time. Hence the transmit * path works the same whether FIFOs are available (and enabled) or not. */ -- cgit v1.2.3 From 69c1b87516e327a60b39f96b778fe683259408bf Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Fri, 7 Jan 2022 07:54:24 +0000 Subject: spi: spi-meson-spifc: Add missing pm_runtime_disable() in meson_spifc_probe If the probe fails, we should use pm_runtime_disable() to balance pm_runtime_enable(). Add missing pm_runtime_disable() for meson_spifc_probe. Fixes: c3e4bc5434d2 ("spi: meson: Add support for Amlogic Meson SPIFC") Signed-off-by: Miaoqian Lin Link: https://lore.kernel.org/r/20220107075424.7774-1-linmq006@gmail.com Signed-off-by: Mark Brown --- drivers/spi/spi-meson-spifc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/spi/spi-meson-spifc.c b/drivers/spi/spi-meson-spifc.c index 8eca6f24cb79..c8ed7815c4ba 100644 --- a/drivers/spi/spi-meson-spifc.c +++ b/drivers/spi/spi-meson-spifc.c @@ -349,6 +349,7 @@ static int meson_spifc_probe(struct platform_device *pdev) return 0; out_clk: clk_disable_unprepare(spifc->clk); + pm_runtime_disable(spifc->dev); out_err: spi_master_put(master); return ret; -- cgit v1.2.3 From 44ea62813f0ab3d718de480504f4dfd0bdd01858 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Fri, 3 Sep 2021 18:31:40 -0700 Subject: spi: don't include ptp_clock_kernel.h in spi.h Commit b42faeee718c ("spi: Add a PTP system timestamp to the transfer structure") added an include of ptp_clock_kernel.h to spi.h for struct ptp_system_timestamp but a forward declaration is enough. Let's use that to limit the number of objects we have to rebuild every time we touch networking headers. Signed-off-by: Jakub Kicinski Tested-by: Vladimir Oltean Link: https://lore.kernel.org/r/20210904013140.2377609-1-kuba@kernel.org Signed-off-by: Mark Brown --- drivers/spi/spi.c | 1 + include/linux/spi/spi.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 7c790858547c..4599b121d744 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -33,6 +33,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index eb7ac8a1e03c..7ab3fed7b804 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -14,12 +14,12 @@ #include #include #include -#include #include struct dma_chan; struct software_node; +struct ptp_system_timestamp; struct spi_controller; struct spi_transfer; struct spi_controller_mem_ops; -- cgit v1.2.3