From eeaceb8b7d1fb64b6030249ca0dd1d902ef3069e Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Thu, 16 Aug 2018 20:54:49 +0800 Subject: spi: Introduce one new field to set word delay For some SPI controllers, after each word size (specified by bits_per_word) transimission, the hardware need some delay to make sure the slave has enough time to receive the whole data. So introducing one new 'word_delay' field of struct spi_tansfer for slave devices to set this inter word delay time. Signed-off-by: Baolin Wang Signed-off-by: Mark Brown --- include/linux/spi/spi.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index a64235e05321..d698f9db3484 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -711,6 +711,8 @@ extern void spi_res_release(struct spi_controller *ctlr, * @delay_usecs: microseconds to delay after this transfer before * (optionally) changing the chipselect status, then starting * the next transfer or completing this @spi_message. + * @word_delay: clock cycles to inter word delay after each word size + * (set by bits_per_word) transmission. * @transfer_list: transfers are sequenced through @spi_message.transfers * @tx_sg: Scatterlist for transmit, currently not for client use * @rx_sg: Scatterlist for receive, currently not for client use @@ -793,6 +795,7 @@ struct spi_transfer { u8 bits_per_word; u16 delay_usecs; u32 speed_hz; + u16 word_delay; struct list_head transfer_list; }; -- cgit v1.2.3 From 56df612afb606dcefba8ab38ab32e052218b6050 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 4 Sep 2018 14:41:28 +0200 Subject: spi: davinci: Remove chip select GPIO pdata The DaVinci SPI can use either: - Internal chip selects (inside the SPI host) - External chip selects (using GPIO) - External chip selects passed in pdata The last way of passing external chip selects through platform data is not used in the kernel. Delete it to make the code simpler when refactoring GPIO. Cc: Sekhar Nori Cc: Kevin Hilman Cc: Michele Dionisio Cc: Frode Isaksen Signed-off-by: Linus Walleij Signed-off-by: Mark Brown --- drivers/spi/spi-davinci.c | 7 ------- include/linux/platform_data/spi-davinci.h | 4 ---- 2 files changed, 11 deletions(-) (limited to 'include') diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 3dabc20b68a1..d502cf504deb 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -432,13 +432,6 @@ static int davinci_spi_setup(struct spi_device *spi) retval = gpio_direction_output( spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); internal_cs = false; - } else if (pdata->chip_sel && - spi->chip_select < pdata->num_chipselect && - pdata->chip_sel[spi->chip_select] != SPI_INTERN_CS) { - spi->cs_gpio = pdata->chip_sel[spi->chip_select]; - retval = gpio_direction_output( - spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); - internal_cs = false; } if (retval) { diff --git a/include/linux/platform_data/spi-davinci.h b/include/linux/platform_data/spi-davinci.h index f4edcb03c40c..0638fb6353bc 100644 --- a/include/linux/platform_data/spi-davinci.h +++ b/include/linux/platform_data/spi-davinci.h @@ -36,9 +36,6 @@ enum { * @num_chipselect: number of chipselects supported by this SPI master * @intr_line: interrupt line used to connect the SPI IP to the ARM interrupt * controller withn the SoC. Possible values are 0 and 1. - * @chip_sel: list of GPIOs which can act as chip-selects for the SPI. - * SPI_INTERN_CS denotes internal SPI chip-select. Not necessary - * to populate if all chip-selects are internal. * @cshold_bug: set this to true if the SPI controller on your chip requires * a write to CSHOLD bit in between transfers (like in DM355). * @dma_event_q: DMA event queue to use if SPI_IO_TYPE_DMA is used for any @@ -48,7 +45,6 @@ struct davinci_spi_platform_data { u8 version; u8 num_chipselect; u8 intr_line; - u8 *chip_sel; u8 prescaler_limit; bool cshold_bug; enum dma_event_q dma_event_q; -- cgit v1.2.3 From 0baf9eb25572eea0cf48249c1d152d8373956a7c Mon Sep 17 00:00:00 2001 From: David Lechner Date: Wed, 12 Sep 2018 19:39:17 -0500 Subject: spi: add new SPI_CS_WORD flag This adds a new SPI mode flag, SPI_CS_WORD, that is used to indicate that a SPI device requires the chip select to be toggled after each word that is transferred. Signed-off-by: David Lechner Signed-off-by: Mark Brown --- include/linux/spi/spi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index a64235e05321..7cc1466111f5 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -163,6 +163,7 @@ struct spi_device { #define SPI_TX_QUAD 0x200 /* transmit with 4 wires */ #define SPI_RX_DUAL 0x400 /* receive with 2 wires */ #define SPI_RX_QUAD 0x800 /* receive with 4 wires */ +#define SPI_CS_WORD 0x1000 /* toggle cs after each word */ int irq; void *controller_state; void *controller_data; @@ -177,7 +178,6 @@ struct spi_device { * the controller talks to each chip, like: * - memory packing (12 bit samples into low bits, others zeroed) * - priority - * - drop chipselect after each word * - chipselect delays * - ... */ -- cgit v1.2.3 From 65a272642ce13aab911f68279c8994cde3282b0a Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 18 May 2018 15:47:50 -0700 Subject: soc: qcom: geni: Make version macros simpler This macro doesn't work, because it hides a local variable inside of the macro to hold the version and that variable name is called 'ver' and 'version' sometimes. Let's change this to be more explicit. Introduce three macros for the major, minor, and step of the version, and require callers to pass the version in to get the part of the version out. This way we don't hide local variables inside macros and things are less evil overall. Cc: Karthikeyan Ramasubramanian Cc: Sagar Dharia Cc: Girish Mahadevan Signed-off-by: Stephen Boyd Reviewed-by: Douglas Anderson Reviewed-by: Bjorn Andersson Signed-off-by: Andy Gross --- include/linux/qcom-geni-se.h | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/include/linux/qcom-geni-se.h b/include/linux/qcom-geni-se.h index 5d6144977828..3bcd67fd5548 100644 --- a/include/linux/qcom-geni-se.h +++ b/include/linux/qcom-geni-se.h @@ -225,19 +225,14 @@ struct geni_se { #define HW_VER_MINOR_SHFT 16 #define HW_VER_STEP_MASK GENMASK(15, 0) +#define GENI_SE_VERSION_MAJOR(ver) ((ver & HW_VER_MAJOR_MASK) >> HW_VER_MAJOR_SHFT) +#define GENI_SE_VERSION_MINOR(ver) ((ver & HW_VER_MINOR_MASK) >> HW_VER_MINOR_SHFT) +#define GENI_SE_VERSION_STEP(ver) (ver & HW_VER_STEP_MASK) + #if IS_ENABLED(CONFIG_QCOM_GENI_SE) u32 geni_se_get_qup_hw_version(struct geni_se *se); -#define geni_se_get_wrapper_version(se, major, minor, step) do { \ - u32 ver; \ -\ - ver = geni_se_get_qup_hw_version(se); \ - major = (ver & HW_VER_MAJOR_MASK) >> HW_VER_MAJOR_SHFT; \ - minor = (ver & HW_VER_MINOR_MASK) >> HW_VER_MINOR_SHFT; \ - step = version & HW_VER_STEP_MASK; \ -} while (0) - /** * geni_se_read_proto() - Read the protocol configured for a serial engine * @se: Pointer to the concerned serial engine. -- cgit v1.2.3 From b445bfcb9081ae90fec90b828f3aacc565776901 Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Tue, 25 Sep 2018 11:42:28 +0200 Subject: spi: switch to SPDX license identifier Use the appropriate SPDX license identifier and drop the previous license text. Signed-off-by: Marco Felsch Signed-off-by: Mark Brown --- drivers/spi/spi.c | 11 +---------- include/linux/spi/spi.h | 13 ++----------- 2 files changed, 3 insertions(+), 21 deletions(-) (limited to 'include') diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index a358acdd98d3..2cfc3df821f6 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * SPI init/core code * * Copyright (C) 2005 David Brownell * Copyright (C) 2008 Secret Lab Technologies Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 7bb36145e2ba..f08824ea1968 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -1,15 +1,6 @@ -/* - * Copyright (C) 2005 David Brownell +/* SPDX-License-Identifier: GPL-2.0-or-later * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Copyright (C) 2005 David Brownell */ #ifndef __LINUX_SPI_H -- cgit v1.2.3 From 5039563e7c25eccd7fec1de6706011009d1c5665 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Thu, 20 Sep 2018 19:18:32 +0000 Subject: spi: Add driver_override SPI device attribute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This attribute works the same was as the identically named attribute for PCI, AMBA, and platform devices. For reference, see: commit 3cf385713460 ("ARM: 8256/1: driver coamba: add device binding path 'driver_override'") commit 3d713e0e382e ("driver core: platform: add device binding path 'driver_override'") commit 782a985d7af2 ("PCI: Introduce new device binding path using pci_dev.driver_override") If the name of a driver is written to this attribute, then the device will bind to the named driver and only the named driver. The device will bind to the driver even if the driver does not list the device in its id table. This behavior is different than the driver's bind attribute, which only allows binding to devices that are listed as supported by the driver. It can be used to bind a generic driver, like spidev, to a device. Signed-off-by: Trent Piepho Reviewed-by: Jan Kundrát Tested-by: Jan Kundrát Reviewed-by: Geert Uytterhoeven Signed-off-by: Mark Brown --- drivers/spi/spi.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/spi/spi.h | 1 + 2 files changed, 52 insertions(+) (limited to 'include') diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 2cfc3df821f6..fcbd4cfd2818 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -51,6 +51,7 @@ static void spidev_release(struct device *dev) spi->controller->cleanup(spi); spi_controller_put(spi->controller); + kfree(spi->driver_override); kfree(spi); } @@ -68,6 +69,51 @@ modalias_show(struct device *dev, struct device_attribute *a, char *buf) } static DEVICE_ATTR_RO(modalias); +static ssize_t driver_override_store(struct device *dev, + struct device_attribute *a, + const char *buf, size_t count) +{ + struct spi_device *spi = to_spi_device(dev); + const char *end = memchr(buf, '\n', count); + const size_t len = end ? end - buf : count; + const char *driver_override, *old; + + /* We need to keep extra room for a newline when displaying value */ + if (len >= (PAGE_SIZE - 1)) + return -EINVAL; + + driver_override = kstrndup(buf, len, GFP_KERNEL); + if (!driver_override) + return -ENOMEM; + + device_lock(dev); + old = spi->driver_override; + if (len) { + spi->driver_override = driver_override; + } else { + /* Emptry string, disable driver override */ + spi->driver_override = NULL; + kfree(driver_override); + } + device_unlock(dev); + kfree(old); + + return count; +} + +static ssize_t driver_override_show(struct device *dev, + struct device_attribute *a, char *buf) +{ + const struct spi_device *spi = to_spi_device(dev); + ssize_t len; + + device_lock(dev); + len = snprintf(buf, PAGE_SIZE, "%s\n", spi->driver_override ? : ""); + device_unlock(dev); + return len; +} +static DEVICE_ATTR_RW(driver_override); + #define SPI_STATISTICS_ATTRS(field, file) \ static ssize_t spi_controller_##field##_show(struct device *dev, \ struct device_attribute *attr, \ @@ -149,6 +195,7 @@ SPI_STATISTICS_SHOW(transfers_split_maxsize, "%lu"); static struct attribute *spi_dev_attrs[] = { &dev_attr_modalias.attr, + &dev_attr_driver_override.attr, NULL, }; @@ -296,6 +343,10 @@ static int spi_match_device(struct device *dev, struct device_driver *drv) const struct spi_device *spi = to_spi_device(dev); const struct spi_driver *sdrv = to_spi_driver(drv); + /* Check override first, and if set, only use the named driver */ + if (spi->driver_override) + return strcmp(spi->driver_override, drv->name) == 0; + /* Attempt an OF style match */ if (of_driver_match_device(dev, drv)) return 1; diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index f08824ea1968..3de9958ca28b 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -159,6 +159,7 @@ struct spi_device { void *controller_state; void *controller_data; char modalias[SPI_NAME_SIZE]; + const char *driver_override; int cs_gpio; /* chip select gpio */ /* the statistics */ -- cgit v1.2.3 From 55ef8262f2b1b31762b045b14182db3cc8f607d1 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Wed, 10 Oct 2018 19:09:28 +0200 Subject: spi: pxa2xx: Use an enum for type That seems to be the correct type. Signed-off-by: Lubomir Rintel Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx.c | 6 +++--- include/linux/pxa2xx_ssp.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index d68f511a9ef1..8baa5b038f15 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1431,7 +1431,7 @@ pxa2xx_spi_init_pdata(struct platform_device *pdev) struct resource *res; const struct acpi_device_id *adev_id = NULL; const struct pci_device_id *pcidev_id = NULL; - int type; + enum pxa_ssp_type type; adev = ACPI_COMPANION(&pdev->dev); @@ -1445,9 +1445,9 @@ pxa2xx_spi_init_pdata(struct platform_device *pdev) return NULL; if (adev_id) - type = (int)adev_id->driver_data; + type = (enum pxa_ssp_type)adev_id->driver_data; else if (pcidev_id) - type = (int)pcidev_id->driver_data; + type = (enum pxa_ssp_type)pcidev_id->driver_data; else return NULL; diff --git a/include/linux/pxa2xx_ssp.h b/include/linux/pxa2xx_ssp.h index 13b4244d44c1..262e1f318836 100644 --- a/include/linux/pxa2xx_ssp.h +++ b/include/linux/pxa2xx_ssp.h @@ -217,7 +217,7 @@ struct ssp_device { const char *label; int port_id; - int type; + enum pxa_ssp_type type; int use_count; int irq; -- cgit v1.2.3 From 87ae1d2d70772d661162de03e56c8d1cc5f12650 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Wed, 10 Oct 2018 19:09:29 +0200 Subject: spi: pxa2xx: Add devicetree support The MMP2 platform, that uses device tree, has this controller. Let's add devicetree alongside platform & PCI. Signed-off-by: Lubomir Rintel Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx.c | 73 ++++++++++++++++++++++++++++------------------ include/linux/pxa2xx_ssp.h | 1 + 2 files changed, 45 insertions(+), 29 deletions(-) (limited to 'include') diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 8baa5b038f15..612cc49db28f 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "spi-pxa2xx.h" @@ -1335,9 +1336,6 @@ static void cleanup(struct spi_device *spi) kfree(chip); } -#ifdef CONFIG_PCI -#ifdef CONFIG_ACPI - static const struct acpi_device_id pxa2xx_spi_acpi_match[] = { { "INT33C0", LPSS_LPT_SSP }, { "INT33C1", LPSS_LPT_SSP }, @@ -1349,23 +1347,6 @@ static const struct acpi_device_id pxa2xx_spi_acpi_match[] = { }; MODULE_DEVICE_TABLE(acpi, pxa2xx_spi_acpi_match); -static int pxa2xx_spi_get_port_id(struct acpi_device *adev) -{ - unsigned int devid; - int port_id = -1; - - if (adev && adev->pnp.unique_id && - !kstrtouint(adev->pnp.unique_id, 0, &devid)) - port_id = devid; - return port_id; -} -#else /* !CONFIG_ACPI */ -static int pxa2xx_spi_get_port_id(struct acpi_device *adev) -{ - return -1; -} -#endif - /* * PCI IDs of compound devices that integrate both host controller and private * integrated DMA engine. Please note these are not used in module @@ -1412,6 +1393,37 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = { { }, }; +static const struct of_device_id pxa2xx_spi_of_match[] = { + { .compatible = "marvell,mmp2-ssp", .data = (void *)MMP2_SSP }, + {}, +}; +MODULE_DEVICE_TABLE(of, pxa2xx_spi_of_match); + +#ifdef CONFIG_ACPI + +static int pxa2xx_spi_get_port_id(struct acpi_device *adev) +{ + unsigned int devid; + int port_id = -1; + + if (adev && adev->pnp.unique_id && + !kstrtouint(adev->pnp.unique_id, 0, &devid)) + port_id = devid; + return port_id; +} + +#else /* !CONFIG_ACPI */ + +static int pxa2xx_spi_get_port_id(struct acpi_device *adev) +{ + return -1; +} + +#endif /* CONFIG_ACPI */ + + +#ifdef CONFIG_PCI + static bool pxa2xx_spi_idma_filter(struct dma_chan *chan, void *param) { struct device *dev = param; @@ -1422,6 +1434,8 @@ static bool pxa2xx_spi_idma_filter(struct dma_chan *chan, void *param) return true; } +#endif /* CONFIG_PCI */ + static struct pxa2xx_spi_master * pxa2xx_spi_init_pdata(struct platform_device *pdev) { @@ -1431,11 +1445,15 @@ pxa2xx_spi_init_pdata(struct platform_device *pdev) struct resource *res; const struct acpi_device_id *adev_id = NULL; const struct pci_device_id *pcidev_id = NULL; + const struct of_device_id *of_id = NULL; enum pxa_ssp_type type; adev = ACPI_COMPANION(&pdev->dev); - if (dev_is_pci(pdev->dev.parent)) + if (pdev->dev.of_node) + of_id = of_match_device(pdev->dev.driver->of_match_table, + &pdev->dev); + else if (dev_is_pci(pdev->dev.parent)) pcidev_id = pci_match_id(pxa2xx_spi_pci_compound_match, to_pci_dev(pdev->dev.parent)); else if (adev) @@ -1448,6 +1466,8 @@ pxa2xx_spi_init_pdata(struct platform_device *pdev) type = (enum pxa_ssp_type)adev_id->driver_data; else if (pcidev_id) type = (enum pxa_ssp_type)pcidev_id->driver_data; + else if (of_id) + type = (enum pxa_ssp_type)of_id->data; else return NULL; @@ -1466,11 +1486,13 @@ pxa2xx_spi_init_pdata(struct platform_device *pdev) if (IS_ERR(ssp->mmio_base)) return NULL; +#ifdef CONFIG_PCI if (pcidev_id) { pdata->tx_param = pdev->dev.parent; pdata->rx_param = pdev->dev.parent; pdata->dma_filter = pxa2xx_spi_idma_filter; } +#endif ssp->clk = devm_clk_get(&pdev->dev, NULL); ssp->irq = platform_get_irq(pdev, 0); @@ -1484,14 +1506,6 @@ pxa2xx_spi_init_pdata(struct platform_device *pdev) return pdata; } -#else /* !CONFIG_PCI */ -static inline struct pxa2xx_spi_master * -pxa2xx_spi_init_pdata(struct platform_device *pdev) -{ - return NULL; -} -#endif - static int pxa2xx_spi_fw_translate_cs(struct spi_controller *master, unsigned int cs) { @@ -1836,6 +1850,7 @@ static struct platform_driver driver = { .name = "pxa2xx-spi", .pm = &pxa2xx_spi_pm_ops, .acpi_match_table = ACPI_PTR(pxa2xx_spi_acpi_match), + .of_match_table = of_match_ptr(pxa2xx_spi_of_match), }, .probe = pxa2xx_spi_probe, .remove = pxa2xx_spi_remove, diff --git a/include/linux/pxa2xx_ssp.h b/include/linux/pxa2xx_ssp.h index 262e1f318836..979087e021f3 100644 --- a/include/linux/pxa2xx_ssp.h +++ b/include/linux/pxa2xx_ssp.h @@ -196,6 +196,7 @@ enum pxa_ssp_type { PXA27x_SSP, PXA3xx_SSP, PXA168_SSP, + MMP2_SSP, PXA910_SSP, CE4100_SSP, QUARK_X1000_SSP, -- cgit v1.2.3 From 9c2120090586d7e509faa885988d4eb2441fabc2 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Wed, 10 Oct 2018 19:09:27 +0200 Subject: PCI: Provide pci_match_id() with CONFIG_PCI=n This spares drivers from #ifdef-ing on CONFIG_PCI if the driver can be optionally built on machines without PCI bus. Consistent with acpi_driver_match_device() and similar. Acked-by: Bjorn Helgaas Signed-off-by: Lubomir Rintel Signed-off-by: Mark Brown --- include/linux/pci.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/pci.h b/include/linux/pci.h index e72ca8dd6241..d2f14eb23ea4 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1702,6 +1702,10 @@ static inline int pci_irqd_intx_xlate(struct irq_domain *d, unsigned long *out_hwirq, unsigned int *out_type) { return -EINVAL; } + +static inline const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, + struct pci_dev *dev) +{ return NULL; } #endif /* CONFIG_PCI */ /* Include architecture-dependent settings and functions */ -- cgit v1.2.3