summaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/Kconfig6
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/altera_spi.c236
-rw-r--r--drivers/spi/ath79_spi.c11
-rw-r--r--drivers/spi/atmel-quadspi.c12
-rw-r--r--drivers/spi/atmel_spi.c17
-rw-r--r--drivers/spi/dspi_spi.c19
-rw-r--r--drivers/spi/gpio_spi.c18
-rw-r--r--drivers/spi/imx_spi.c19
-rw-r--r--drivers/spi/litex_spiflash.c9
-rw-r--r--drivers/spi/mvebu_spi.c7
-rw-r--r--drivers/spi/mxs_spi.c9
-rw-r--r--drivers/spi/omap3_spi.c12
-rw-r--r--drivers/spi/spi-fsl-dspi.c15
-rw-r--r--drivers/spi/spi-fsl-qspi.c11
-rw-r--r--drivers/spi/spi-nxp-fspi.c31
-rw-r--r--drivers/spi/spi-sifive.c11
-rw-r--r--drivers/spi/spi.c62
-rw-r--r--drivers/spi/stm32_spi.c85
-rw-r--r--drivers/spi/zynq_qspi.c9
20 files changed, 220 insertions, 380 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 8935feb97b..445c756a38 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -14,10 +14,6 @@ config SPI_MEM
This extension is meant to simplify interaction with SPI memories
by providing a high-level interface to send memory-like commands.
-config DRIVER_SPI_ALTERA
- bool "Altera SPI Master driver"
- depends on NIOS2
-
config DRIVER_SPI_ATH79
bool "Atheros AR71XX/AR724X/AR913X/AR933X SPI controller driver"
depends on MACH_MIPS_ATH79
@@ -116,7 +112,7 @@ config DRIVER_SPI_STM32
config SPI_NXP_FLEXSPI
tristate "NXP Flex SPI controller"
- depends on ARCH_IMX8M || COMPILE_TEST
+ depends on ARCH_IMX8M || ARCH_IMX93 || COMPILE_TEST
help
This enables support for the Flex SPI controller in master mode.
Up to four slave devices can be connected on two buses with two
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 3455eea869..68a8c4e675 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -8,7 +8,6 @@ obj-$(CONFIG_DRIVER_SPI_IMX) += imx_spi.o
obj-$(CONFIG_DRIVER_SPI_LITEX_SPIFLASH) += litex_spiflash.o
obj-$(CONFIG_DRIVER_SPI_MVEBU) += mvebu_spi.o
obj-$(CONFIG_DRIVER_SPI_MXS) += mxs_spi.o
-obj-$(CONFIG_DRIVER_SPI_ALTERA) += altera_spi.o
obj-$(CONFIG_DRIVER_SPI_ATMEL) += atmel_spi.o
obj-$(CONFIG_SPI_FSL_DSPI) += spi-fsl-dspi.o
obj-$(CONFIG_SPI_ATMEL_QUADSPI) += atmel-quadspi.o
diff --git a/drivers/spi/altera_spi.c b/drivers/spi/altera_spi.c
deleted file mode 100644
index 3db8af5415..0000000000
--- a/drivers/spi/altera_spi.c
+++ /dev/null
@@ -1,236 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * (C) Copyright 2011 - Franck JULLIEN <elec4fun@gmail.com>
- */
-
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <spi/spi.h>
-#include <io.h>
-#include <asm/spi.h>
-#include <asm/nios2-io.h>
-#include <clock.h>
-
-static void altera_spi_cs_inactive(struct spi_device *spi);
-
-static int altera_spi_setup(struct spi_device *spi)
-{
- struct spi_master *master = spi->master;
- struct device_d spi_dev = spi->dev;
- struct altera_spi *altera_spi = container_of(master, struct altera_spi, master);
-
- if (spi->bits_per_word != altera_spi->databits) {
- dev_err(master->dev, " master doesn't support %d bits per word requested by %s\n",
- spi->bits_per_word, spi_dev.name);
- return -EINVAL;
- }
-
- if ((spi->mode & (SPI_CPHA | SPI_CPOL)) != altera_spi->mode) {
- dev_err(master->dev, " master doesn't support SPI_MODE%d requested by %s\n",
- spi->mode & (SPI_CPHA | SPI_CPOL), spi_dev.name);
- return -EINVAL;
- }
-
- if (spi->max_speed_hz < altera_spi->speed) {
- dev_err(master->dev, " frequency is too high for %s\n", spi_dev.name);
- return -EINVAL;
- }
-
- altera_spi_cs_inactive(spi);
-
- dev_dbg(master->dev, " mode 0x%08x, bits_per_word: %d, speed: %d\n",
- spi->mode, spi->bits_per_word, altera_spi->speed);
-
- return 0;
-}
-
-
-static unsigned int altera_spi_xchg_single(struct altera_spi *altera_spi, unsigned int data)
-{
- struct nios_spi *nios_spi = altera_spi->regs;
-
- while (!(readl(&nios_spi->status) & NIOS_SPI_TRDY));
- writel(data, &nios_spi->txdata);
-
- while (!(readl(&nios_spi->status) & NIOS_SPI_RRDY));
-
- return readl(&nios_spi->rxdata);
-}
-
-/*
- * When using SPI_CS_HIGH devices, only one device is allowed to be
- * connected to the Altera SPI master. This limitation is due to the
- * emulation of an active high CS by writing 0 to the slaveselect register
- * (this produce a '1' to all CS pins).
- */
-
-static void altera_spi_cs_active(struct spi_device *spi)
-{
- struct altera_spi *altera_spi = container_of(spi->master, struct altera_spi, master);
- struct nios_spi *nios_spi = altera_spi->regs;
- uint32_t tmp;
-
- if (spi->mode & SPI_CS_HIGH) {
- tmp = readw(&nios_spi->control);
- writew(tmp & ~NIOS_SPI_SSO, &nios_spi->control);
- writel(0, &nios_spi->slaveselect);
- } else {
- writel(1 << spi->chip_select, &nios_spi->slaveselect);
- tmp = readl(&nios_spi->control);
- writel(tmp | NIOS_SPI_SSO, &nios_spi->control);
- }
-}
-
-static void altera_spi_cs_inactive(struct spi_device *spi)
-{
- struct altera_spi *altera_spi = container_of(spi->master, struct altera_spi, master);
- struct nios_spi *nios_spi = altera_spi->regs;
- uint32_t tmp;
-
- if (spi->mode & SPI_CS_HIGH) {
- writel(1 << spi->chip_select, &nios_spi->slaveselect);
- tmp = readl(&nios_spi->control);
- writel(tmp | NIOS_SPI_SSO, &nios_spi->control);
- } else {
- tmp = readw(&nios_spi->control);
- writew(tmp & ~NIOS_SPI_SSO, &nios_spi->control);
- }
-}
-
-static unsigned altera_spi_do_xfer(struct spi_device *spi, struct spi_transfer *t)
-{
- struct altera_spi *altera_spi = container_of(spi->master, struct altera_spi, master);
- int word_len;
- unsigned retval = 0;
- u32 txval;
- u32 rxval;
-
- word_len = spi->bits_per_word;
-
- if (word_len <= 8) {
- const u8 *txbuf = t->tx_buf;
- u8 *rxbuf = t->rx_buf;
- int i = 0;
-
- while (i < t->len) {
- txval = txbuf ? txbuf[i] : 0;
- rxval = altera_spi_xchg_single(altera_spi, txval);
- if (rxbuf)
- rxbuf[i] = rxval;
- i++;
- retval++;
- }
- } else if (word_len <= 16) {
- const u16 *txbuf = t->tx_buf;
- u16 *rxbuf = t->rx_buf;
- int i = 0;
-
- while (i < t->len >> 1) {
- txval = txbuf ? txbuf[i] : 0;
- rxval = altera_spi_xchg_single(altera_spi, txval);
- if (rxbuf)
- rxbuf[i] = rxval;
- i++;
- retval += 2;
- }
- } else if (word_len <= 32) {
- const u32 *txbuf = t->tx_buf;
- u32 *rxbuf = t->rx_buf;
- int i = 0;
-
- while (i < t->len >> 2) {
- txval = txbuf ? txbuf[i] : 0;
- rxval = altera_spi_xchg_single(altera_spi, txval);
- if (rxbuf)
- rxbuf[i] = rxval;
- i++;
- retval += 4;
- }
- }
-
- return retval;
-}
-
-static int altera_spi_transfer(struct spi_device *spi, struct spi_message *mesg)
-{
- struct altera_spi *altera_spi = container_of(spi->master, struct altera_spi, master);
- struct nios_spi *nios_spi = altera_spi->regs;
- struct spi_transfer *t;
- unsigned int cs_change;
- const int nsecs = 50;
-
- altera_spi_cs_active(spi);
-
- cs_change = 0;
-
- mesg->actual_length = 0;
-
- list_for_each_entry(t, &mesg->transfers, transfer_list) {
-
- if (cs_change) {
- ndelay(nsecs);
- altera_spi_cs_inactive(spi);
- ndelay(nsecs);
- altera_spi_cs_active(spi);
- }
-
- cs_change = t->cs_change;
-
- mesg->actual_length += altera_spi_do_xfer(spi, t);
-
- if (cs_change) {
- altera_spi_cs_active(spi);
- }
- }
-
- /* Wait the end of any pending transfer */
- while ((readl(&nios_spi->status) & NIOS_SPI_TMT) == 0);
-
- if (!cs_change)
- altera_spi_cs_inactive(spi);
-
- return 0;
-}
-
-static int altera_spi_probe(struct device_d *dev)
-{
- struct resource *iores;
- struct spi_master *master;
- struct altera_spi *altera_spi;
- struct spi_altera_master *pdata = dev->platform_data;
- struct nios_spi *nios_spi;
-
- altera_spi = xzalloc(sizeof(*altera_spi));
-
- master = &altera_spi->master;
- master->dev = dev;
-
- master->setup = altera_spi_setup;
- master->transfer = altera_spi_transfer;
- master->num_chipselect = pdata->num_chipselect;
- master->bus_num = pdata->bus_num;
-
- iores = dev_request_mem_resource(dev, 0);
- if (IS_ERR(iores))
- return PTR_ERR(iores);
- altera_spi->regs = IOMEM(iores->start);
-
- altera_spi->databits = pdata->databits;
- altera_spi->speed = pdata->speed;
- altera_spi->mode = pdata->spi_mode;
-
- nios_spi = altera_spi->regs;
- writel(0, &nios_spi->slaveselect);
- writel(0, &nios_spi->control);
-
- spi_register_master(master);
-
- return 0;
-}
-
-static struct driver_d altera_spi_driver = {
- .name = "altera_spi",
- .probe = altera_spi_probe,
-};
-device_platform_driver(altera_spi_driver);
diff --git a/drivers/spi/ath79_spi.c b/drivers/spi/ath79_spi.c
index 383570b253..41a31ae922 100644
--- a/drivers/spi/ath79_spi.c
+++ b/drivers/spi/ath79_spi.c
@@ -126,7 +126,7 @@ static inline void ath79_spi_chipselect(struct ath79_spi *sp, int chipselect)
static int ath79_spi_setup(struct spi_device *spi)
{
struct spi_master *master = spi->master;
- struct device_d spi_dev = spi->dev;
+ struct device spi_dev = spi->dev;
if (spi->bits_per_word != 8) {
dev_err(master->dev, "master doesn't support %d bits per word requested by %s\n",
@@ -220,7 +220,7 @@ static void ath79_spi_disable(struct ath79_spi *sp)
ath79_spi_wr(sp, 0, AR71XX_SPI_REG_FS);
}
-static int ath79_spi_probe(struct device_d *dev)
+static int ath79_spi_probe(struct device *dev)
{
struct resource *iores;
struct spi_master *master;
@@ -238,7 +238,7 @@ static int ath79_spi_probe(struct device_d *dev)
master->num_chipselect = 3;
if (IS_ENABLED(CONFIG_OFDEVICE)) {
- struct device_node *node = dev->device_node;
+ struct device_node *node = dev->of_node;
u32 num_cs;
int ret;
@@ -269,7 +269,7 @@ static int ath79_spi_probe(struct device_d *dev)
return 0;
}
-static void ath79_spi_remove(struct device_d *dev)
+static void ath79_spi_remove(struct device *dev)
{
struct ath79_spi *sp = dev->priv;
@@ -284,8 +284,9 @@ static __maybe_unused struct of_device_id ath79_spi_dt_ids[] = {
/* sentinel */
}
};
+MODULE_DEVICE_TABLE(of, ath79_spi_dt_ids);
-static struct driver_d ath79_spi_driver = {
+static struct driver ath79_spi_driver = {
.name = "ath79-spi",
.probe = ath79_spi_probe,
.remove = ath79_spi_remove,
diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c
index 55ebccc877..c680ee15a0 100644
--- a/drivers/spi/atmel-quadspi.c
+++ b/drivers/spi/atmel-quadspi.c
@@ -21,9 +21,9 @@
#include <of_gpio.h>
#include <io.h>
#include <spi/spi.h>
-#include <mach/iomux.h>
-#include <mach/board.h>
-#include <mach/cpu.h>
+#include <mach/at91/iomux.h>
+#include <mach/at91/board.h>
+#include <mach/at91/cpu.h>
#include <linux/clk.h>
#include <linux/err.h>
@@ -157,7 +157,6 @@ struct atmel_qspi {
void __iomem *mem;
struct clk *pclk;
struct clk *qspick;
- struct platform_device *pdev;
const struct atmel_qspi_caps *caps;
u32 mr;
};
@@ -414,7 +413,7 @@ static int atmel_qspi_init(struct atmel_qspi *aq)
return 0;
}
-static int atmel_qspi_probe(struct device_d *dev)
+static int atmel_qspi_probe(struct device *dev)
{
struct spi_controller *ctrl;
struct atmel_qspi *aq;
@@ -527,8 +526,9 @@ static const struct of_device_id atmel_qspi_dt_ids[] = {
},
{ /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, atmel_qspi_dt_ids);
-static struct driver_d atmel_qspi_driver = {
+static struct driver atmel_qspi_driver = {
.name = "atmel_qspi",
.of_compatible = atmel_qspi_dt_ids,
.probe = atmel_qspi_probe,
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index ec90330e53..90f655dc3e 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -21,9 +21,9 @@
#include <of_gpio.h>
#include <io.h>
#include <spi/spi.h>
-#include <mach/iomux.h>
-#include <mach/board.h>
-#include <mach/cpu.h>
+#include <mach/at91/iomux.h>
+#include <mach/at91/board.h>
+#include <mach/at91/cpu.h>
#include <linux/clk.h>
#include <linux/err.h>
@@ -378,18 +378,18 @@ static void atmel_get_caps(struct atmel_spi *as)
unsigned int version;
version = atmel_get_version(as);
- dev_info(as->master.dev, "version: 0x%x\n", version);
+ dev_dbg(as->master.dev, "version: 0x%x\n", version);
as->caps.is_spi2 = version > 0x121;
}
-static int atmel_spi_probe(struct device_d *dev)
+static int atmel_spi_probe(struct device *dev)
{
struct resource *iores;
int ret = 0;
int i;
struct spi_master *master;
- struct device_node *node = dev->device_node;
+ struct device_node *node = dev->of_node;
struct atmel_spi *as;
struct at91_spi_platform_data *pdata = dev->platform_data;
@@ -408,7 +408,7 @@ static int atmel_spi_probe(struct device_d *dev)
master->num_chipselect = pdata->num_chipselect;
as->cs_pins = pdata->chipselect;
} else {
- master->num_chipselect = of_gpio_named_count(node, "cs-gpios");
+ master->num_chipselect = of_gpio_count_csgpios(node);
as->cs_pins = xzalloc(sizeof(u32) * master->num_chipselect);
for (i = 0; i < master->num_chipselect; i++) {
@@ -474,8 +474,9 @@ const static __maybe_unused struct of_device_id atmel_spi_dt_ids[] = {
{ .compatible = "atmel,at91rm9200-spi" },
{ /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, atmel_spi_dt_ids);
-static struct driver_d atmel_spi_driver = {
+static struct driver atmel_spi_driver = {
.name = "atmel_spi",
.probe = atmel_spi_probe,
.of_compatible = DRV_OF_COMPAT(atmel_spi_dt_ids),
diff --git a/drivers/spi/dspi_spi.c b/drivers/spi/dspi_spi.c
index fcfa2a830d..75addfd12c 100644
--- a/drivers/spi/dspi_spi.c
+++ b/drivers/spi/dspi_spi.c
@@ -21,8 +21,8 @@
#include <gpio.h>
#include <of_gpio.h>
#include <of_device.h>
-#include <mach/spi.h>
-#include <mach/generic.h>
+#include <mach/imx/spi.h>
+#include <mach/imx/generic.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <clock.h>
@@ -93,7 +93,7 @@ static struct fsl_dspi *to_dspi(struct spi_master *master)
return container_of(master, struct fsl_dspi, master);
}
-static void hz_to_spi_baud(struct device_d *dev,
+static void hz_to_spi_baud(struct device *dev,
char *pbr, char *br, int speed_hz,
unsigned long clkrate)
{
@@ -132,7 +132,7 @@ static void hz_to_spi_baud(struct device_d *dev,
}
}
-static void ns_delay_scale(struct device_d *dev,
+static void ns_delay_scale(struct device *dev,
char *psc, char *sc, int delay_ns,
unsigned long clkrate)
{
@@ -314,12 +314,12 @@ static int dspi_setup(struct spi_device *spi)
return 0;
}
-static int dspi_probe(struct device_d *dev)
+static int dspi_probe(struct device *dev)
{
struct resource *io;
struct fsl_dspi *dspi;
struct spi_master *master;
- struct device_node *np = dev->device_node;
+ struct device_node *np = dev->of_node;
int ret = 0;
uint32_t bus_num = 0;
@@ -351,9 +351,9 @@ static int dspi_probe(struct device_d *dev)
else
master->bus_num = dev->id;
- of_property_read_u32(dev->device_node, "fsl,spi-cs-sck-delay",
+ of_property_read_u32(dev->of_node, "fsl,spi-cs-sck-delay",
&dspi->cs_sck_delay);
- of_property_read_u32(dev->device_node, "fsl,spi-sck-cs-delay",
+ of_property_read_u32(dev->of_node, "fsl,spi-sck-cs-delay",
&dspi->sck_cs_delay);
io = dev_request_mem_resource(dev, 0);
@@ -400,8 +400,9 @@ static const struct of_device_id dspi_dt_ids[] = {
{ .compatible = "fsl,vf610-dspi", .data = (void *)&vf610_data, },
{ /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, dspi_dt_ids);
-static struct driver_d dspi_spi_driver = {
+static struct driver dspi_spi_driver = {
.name = "fsl-dspi",
.probe = dspi_probe,
.of_compatible = DRV_OF_COMPAT(dspi_dt_ids),
diff --git a/drivers/spi/gpio_spi.c b/drivers/spi/gpio_spi.c
index 1956eed9cc..e5664df3fe 100644
--- a/drivers/spi/gpio_spi.c
+++ b/drivers/spi/gpio_spi.c
@@ -126,9 +126,9 @@ static int gpio_spi_setup(struct spi_device *spi)
return 0;
}
-static int gpio_spi_of_probe(struct device_d *dev)
+static int gpio_spi_of_probe(struct device *dev)
{
- struct device_node *np = dev->device_node;
+ struct device_node *np = dev->of_node;
struct gpio_spi_pdata *pdata;
int n, sck;
@@ -136,12 +136,9 @@ static int gpio_spi_of_probe(struct device_d *dev)
return 0;
sck = of_get_named_gpio(np, "gpio-sck", 0);
- if (sck == -EPROBE_DEFER)
- return sck;
- if (!gpio_is_valid(sck)) {
- dev_err(dev, "missing mandatory SCK gpio\n");
- return sck;
- }
+ if (!gpio_is_valid(sck))
+ return dev_err_probe(dev, sck < 0 ? sck : -EINVAL,
+ "missing mandatory SCK gpio\n");
pdata = xzalloc(sizeof(*pdata));
pdata->sck = sck;
@@ -166,7 +163,7 @@ static int gpio_spi_of_probe(struct device_d *dev)
return 0;
}
-static int gpio_spi_probe(struct device_d *dev)
+static int gpio_spi_probe(struct device *dev)
{
struct gpio_spi *priv;
struct gpio_spi_pdata *pdata;
@@ -222,8 +219,9 @@ static struct of_device_id __maybe_unused gpio_spi_dt_ids[] = {
{ .compatible = "spi-gpio", },
{ }
};
+MODULE_DEVICE_TABLE(of, gpio_spi_dt_ids);
-static struct driver_d gpio_spi_driver = {
+static struct driver gpio_spi_driver = {
.name = "gpio-spi",
.probe = gpio_spi_probe,
.of_compatible = DRV_OF_COMPAT(gpio_spi_dt_ids),
diff --git a/drivers/spi/imx_spi.c b/drivers/spi/imx_spi.c
index ad3e79d54c..5310a2715d 100644
--- a/drivers/spi/imx_spi.c
+++ b/drivers/spi/imx_spi.c
@@ -15,8 +15,8 @@
#include <malloc.h>
#include <gpio.h>
#include <of_gpio.h>
-#include <mach/spi.h>
-#include <mach/generic.h>
+#include <mach/imx/spi.h>
+#include <mach/imx/generic.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <clock.h>
@@ -562,13 +562,13 @@ static __maybe_unused struct spi_imx_devtype_data spi_imx_devtype_data_2_3 = {
static int imx_spi_dt_probe(struct imx_spi *imx)
{
- struct device_node *node = imx->master.dev->device_node;
+ struct device_node *node = imx->master.dev->of_node;
int i;
if (!node)
return -ENODEV;
- imx->master.num_chipselect = of_gpio_named_count(node, "cs-gpios");
+ imx->master.num_chipselect = of_gpio_count_csgpios(node);
imx->cs_array = xzalloc(sizeof(u32) * imx->master.num_chipselect);
for (i = 0; i < imx->master.num_chipselect; i++)
@@ -577,7 +577,7 @@ static int imx_spi_dt_probe(struct imx_spi *imx)
return 0;
}
-static int imx_spi_probe(struct device_d *dev)
+static int imx_spi_probe(struct device *dev)
{
struct resource *iores;
struct spi_master *master;
@@ -603,7 +603,7 @@ static int imx_spi_probe(struct device_d *dev)
master->num_chipselect = pdata->num_chipselect;
imx->cs_array = pdata->chipselect;
} else if (IS_ENABLED(CONFIG_OFDEVICE)) {
- ret = of_alias_get_id(dev->device_node, "spi");
+ ret = of_alias_get_id(dev->of_node, "spi");
if (ret < 0)
goto err_free;
master->bus_num = ret;
@@ -662,11 +662,16 @@ static __maybe_unused struct of_device_id imx_spi_dt_ids[] = {
.compatible = "fsl,imx51-ecspi",
.data = &spi_imx_devtype_data_2_3,
},
+ {
+ .compatible = "fsl,imx6ul-ecspi",
+ .data = &spi_imx_devtype_data_2_3,
+ },
#endif
{
/* sentinel */
}
};
+MODULE_DEVICE_TABLE(of, imx_spi_dt_ids);
static struct platform_device_id imx_spi_ids[] = {
#if IS_ENABLED(CONFIG_DRIVER_SPI_IMX_0_0)
@@ -692,7 +697,7 @@ static struct platform_device_id imx_spi_ids[] = {
}
};
-static struct driver_d imx_spi_driver = {
+static struct driver imx_spi_driver = {
.name = "imx_spi",
.probe = imx_spi_probe,
.of_compatible = DRV_OF_COMPAT(imx_spi_dt_ids),
diff --git a/drivers/spi/litex_spiflash.c b/drivers/spi/litex_spiflash.c
index e1fc5a4d3f..58ce6ad5f5 100644
--- a/drivers/spi/litex_spiflash.c
+++ b/drivers/spi/litex_spiflash.c
@@ -93,7 +93,7 @@ static inline void litex_spiflash_spi_chipselect(struct litex_spiflash_spi *sc,
static int litex_spiflash_spi_setup(struct spi_device *spi)
{
struct spi_master *master = spi->master;
- struct device_d spi_dev = spi->dev;
+ struct device spi_dev = spi->dev;
if (spi->bits_per_word != 8) {
dev_err(master->dev, "master doesn't support %d bits per word requested by %s\n",
@@ -184,7 +184,7 @@ static void litex_spiflash_spi_disable(struct litex_spiflash_spi *sp)
litex_spiflash_spi_wr(sp, 0, SPIFLASH_BITBANG_EN);
}
-static int litex_spiflash_spi_probe(struct device_d *dev)
+static int litex_spiflash_spi_probe(struct device *dev)
{
struct resource *iores;
struct spi_master *master;
@@ -216,7 +216,7 @@ static int litex_spiflash_spi_probe(struct device_d *dev)
return 0;
}
-static void litex_spiflash_spi_remove(struct device_d *dev)
+static void litex_spiflash_spi_remove(struct device *dev)
{
struct litex_spiflash_spi *sp = dev->priv;
@@ -231,8 +231,9 @@ static __maybe_unused struct of_device_id litex_spiflash_spi_dt_ids[] = {
/* sentinel */
}
};
+MODULE_DEVICE_TABLE(of, litex_spiflash_spi_dt_ids);
-static struct driver_d litex_spiflash_spi_driver = {
+static struct driver litex_spiflash_spi_driver = {
.name = "litex-spiflash",
.probe = litex_spiflash_spi_probe,
.remove = litex_spiflash_spi_remove,
diff --git a/drivers/spi/mvebu_spi.c b/drivers/spi/mvebu_spi.c
index 3325138604..e220d1f9ee 100644
--- a/drivers/spi/mvebu_spi.c
+++ b/drivers/spi/mvebu_spi.c
@@ -347,8 +347,9 @@ static struct of_device_id mvebu_spi_dt_ids[] = {
.data = &mvebu_spi_set_baudrate },
{ }
};
+MODULE_DEVICE_TABLE(of, mvebu_spi_dt_ids);
-static int mvebu_spi_probe(struct device_d *dev)
+static int mvebu_spi_probe(struct device *dev)
{
struct resource *iores;
struct spi_master *master;
@@ -356,7 +357,7 @@ static int mvebu_spi_probe(struct device_d *dev)
const struct of_device_id *match;
int ret = 0;
- match = of_match_node(mvebu_spi_dt_ids, dev->device_node);
+ match = of_match_node(mvebu_spi_dt_ids, dev->of_node);
if (!match)
return -EINVAL;
@@ -391,7 +392,7 @@ err_free:
return ret;
}
-static struct driver_d mvebu_spi_driver = {
+static struct driver mvebu_spi_driver = {
.name = "mvebu-spi",
.probe = mvebu_spi_probe,
.of_compatible = DRV_OF_COMPAT(mvebu_spi_dt_ids),
diff --git a/drivers/spi/mxs_spi.c b/drivers/spi/mxs_spi.c
index 071622bd54..d2ec42f064 100644
--- a/drivers/spi/mxs_spi.c
+++ b/drivers/spi/mxs_spi.c
@@ -18,9 +18,8 @@
#include <stmp-device.h>
#include <linux/clk.h>
#include <linux/err.h>
-#include <mach/generic.h>
-#include <mach/clock.h>
-#include <mach/ssp.h>
+#include <mach/mxs/generic.h>
+#include <mach/mxs/ssp.h>
#define MXS_SPI_MAX_TIMEOUT (10 * MSECOND)
@@ -243,7 +242,7 @@ static int mxs_spi_transfer(struct spi_device *spi, struct spi_message *mesg)
return 0;
}
-static int mxs_spi_probe(struct device_d *dev)
+static int mxs_spi_probe(struct device *dev)
{
struct resource *iores;
struct spi_master *master;
@@ -275,7 +274,7 @@ static int mxs_spi_probe(struct device_d *dev)
return 0;
}
-static struct driver_d mxs_spi_driver = {
+static struct driver mxs_spi_driver = {
.name = "mxs_spi",
.probe = mxs_spi_probe,
};
diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c
index 44c35673d8..78c3a82338 100644
--- a/drivers/spi/omap3_spi.c
+++ b/drivers/spi/omap3_spi.c
@@ -332,18 +332,19 @@ static int omap3_spi_setup(struct spi_device *spi)
return 0;
}
-static int omap3_spi_probe_dt(struct device_d *dev, struct omap3_spi_master *omap3_master)
+static int omap3_spi_probe_dt(struct device *dev,
+ struct omap3_spi_master *omap3_master)
{
- if (!IS_ENABLED(CONFIG_OFDEVICE) || !dev->device_node)
+ if (!IS_ENABLED(CONFIG_OFDEVICE) || !dev->of_node)
return -ENODEV;
- if (of_property_read_bool(dev->device_node, "ti,pindir-d0-out-d1-in"))
+ if (of_property_read_bool(dev->of_node, "ti,pindir-d0-out-d1-in"))
omap3_master->swap_miso_mosi = 1;
return 0;
}
-static int omap3_spi_probe(struct device_d *dev)
+static int omap3_spi_probe(struct device *dev)
{
struct resource *iores;
struct spi_master *master;
@@ -421,6 +422,7 @@ static __maybe_unused struct of_device_id omap_spi_dt_ids[] = {
/* sentinel */
}
};
+MODULE_DEVICE_TABLE(of, omap_spi_dt_ids);
static struct platform_device_id omap_spi_ids[] = {
{
@@ -434,7 +436,7 @@ static struct platform_device_id omap_spi_ids[] = {
},
};
-static struct driver_d omap3_spi_driver = {
+static struct driver omap3_spi_driver = {
.name = "omap-spi",
.probe = omap3_spi_probe,
.of_compatible = DRV_OF_COMPAT(omap_spi_dt_ids),
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 21cf84233b..f032e2673e 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -10,7 +10,7 @@
#include <errno.h>
#include <init.h>
#include <io.h>
-#include <regmap.h>
+#include <linux/regmap.h>
#include <spi/spi.h>
#include <linux/clk.h>
#include <linux/math64.h>
@@ -132,7 +132,7 @@ static const struct fsl_dspi_devtype_data ls2085a_data = {
struct fsl_dspi {
struct spi_controller ctlr;
- struct device_d *dev;
+ struct device *dev;
struct regmap *regmap;
struct regmap *regmap_pushr;
@@ -462,10 +462,10 @@ static int dspi_setup(struct spi_device *spi)
return -ENOMEM;
}
- of_property_read_u32(spi->dev.device_node, "fsl,spi-cs-sck-delay",
+ of_property_read_u32(spi->dev.of_node, "fsl,spi-cs-sck-delay",
&cs_sck_delay);
- of_property_read_u32(spi->dev.device_node, "fsl,spi-sck-cs-delay",
+ of_property_read_u32(spi->dev.of_node, "fsl,spi-sck-cs-delay",
&sck_cs_delay);
chip->void_write_data = 0;
@@ -515,6 +515,7 @@ static const struct of_device_id fsl_dspi_dt_ids[] = {
{ .compatible = "fsl,ls2085a-dspi", .data = &ls2085a_data, },
{ /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, fsl_dspi_dt_ids);
static const struct regmap_config dspi_regmap_config = {
.reg_bits = 32,
@@ -553,9 +554,9 @@ static void dspi_init(struct fsl_dspi *dspi)
SPI_CTARE_FMSZE(0) | SPI_CTARE_DTCP(1));
}
-static int dspi_probe(struct device_d *dev)
+static int dspi_probe(struct device *dev)
{
- struct device_node *np = dev->device_node;
+ struct device_node *np = dev->of_node;
const struct regmap_config *regmap_config;
struct spi_master *master;
int ret, cs_num, bus_num = -1;
@@ -647,7 +648,7 @@ out_ctlr_put:
return ret;
}
-static struct driver_d fsl_dspi_driver = {
+static struct driver fsl_dspi_driver = {
.name = "fsl-dspi",
.probe = dspi_probe,
.of_compatible = DRV_OF_COMPAT(fsl_dspi_dt_ids),
diff --git a/drivers/spi/spi-fsl-qspi.c b/drivers/spi/spi-fsl-qspi.c
index f9bf888603..17e6d1df86 100644
--- a/drivers/spi/spi-fsl-qspi.c
+++ b/drivers/spi/spi-fsl-qspi.c
@@ -239,7 +239,7 @@ struct fsl_qspi {
void __iomem *ahb_addr;
u32 memmap_phy;
struct clk *clk, *clk_en;
- struct device_d *dev;
+ struct device *dev;
struct spi_controller ctlr;
const struct fsl_qspi_devtype_data *devtype_data;
struct mutex lock;
@@ -743,7 +743,7 @@ static int fsl_qspi_setup(struct spi_device *spi)
static const char *fsl_qspi_get_name(struct spi_mem *mem)
{
struct fsl_qspi *q = spi_controller_get_devdata(mem->spi->controller);
- struct device_d *dev = &mem->spi->dev;
+ struct device *dev = &mem->spi->dev;
const char *name;
/*
@@ -751,7 +751,7 @@ static const char *fsl_qspi_get_name(struct spi_mem *mem)
* mtd/spi-nor/fsl-quadspi.c, we set a custom name derived from the
* platform_device of the controller.
*/
- if (of_get_available_child_count(q->dev->device_node) == 1)
+ if (of_get_available_child_count(q->dev->of_node) == 1)
return dev_name(q->dev);
name = basprintf("%s-%d", dev_name(q->dev), mem->spi->chip_select);
@@ -770,7 +770,7 @@ static const struct spi_controller_mem_ops fsl_qspi_mem_ops = {
.get_name = fsl_qspi_get_name,
};
-static int fsl_qspi_probe(struct device_d *dev)
+static int fsl_qspi_probe(struct device *dev)
{
struct spi_controller *ctlr;
struct resource *res;
@@ -860,8 +860,9 @@ static const struct of_device_id fsl_qspi_dt_ids[] = {
{ .compatible = "fsl,ls2080a-qspi", .data = &ls2080a_data, },
{ /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, fsl_qspi_dt_ids);
-static struct driver_d fsl_qspi_driver = {
+static struct driver fsl_qspi_driver = {
.name = "fsl-quadspi",
.probe = fsl_qspi_probe,
.of_compatible = DRV_OF_COMPAT(fsl_qspi_dt_ids),
diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
index 673b91d6dc..d8675779da 100644
--- a/drivers/spi/spi-nxp-fspi.c
+++ b/drivers/spi/spi-nxp-fspi.c
@@ -38,7 +38,7 @@
#include <errno.h>
#include <init.h>
#include <io.h>
-#include <regmap.h>
+#include <linux/regmap.h>
#include <linux/types.h>
#include <linux/bitops.h>
#include <linux/clk.h>
@@ -355,7 +355,7 @@ struct nxp_fspi {
u32 memmap_start;
u32 memmap_len;
struct clk *clk, *clk_en;
- struct device_d *dev;
+ struct device *dev;
struct spi_controller ctlr;
const struct nxp_fspi_devtype_data *devtype_data;
struct mutex lock;
@@ -544,7 +544,7 @@ static void nxp_fspi_prepare_lut(struct nxp_fspi *f,
for (i = 0; i < ARRAY_SIZE(lutval); i++)
fspi_writel(f, lutval[i], base + FSPI_LUT_REG(i));
- dev_dbg((const struct device_d *)f->dev,
+ dev_dbg((const struct device *)f->dev,
"CMD[%x] lutval[0:%x \t 1:%x \t 2:%x \t 3:%x], size: 0x%08x\n",
op->cmd.opcode, lutval[0], lutval[1], lutval[2], lutval[3],
op->data.nbytes);
@@ -642,7 +642,8 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi)
fspi_writel(f, size_kb, f->iobase + FSPI_FLSHA1CR0 +
4 * spi->chip_select);
- dev_dbg((const struct device_d *)f->dev, "Slave device [CS:%x] selected\n",
+ dev_dbg((const struct device *)f->dev,
+ "Slave device [CS:%x] selected\n",
spi->chip_select);
nxp_fspi_clk_disable_unprep(f);
@@ -937,12 +938,12 @@ static int nxp_fspi_setup(struct spi_device *spi)
static const char *nxp_fspi_get_name(struct spi_mem *mem)
{
struct nxp_fspi *f = spi_controller_get_devdata(mem->spi->master);
- struct device_d *dev = (struct device_d *)&mem->spi->dev;
+ struct device *dev = (struct device *)&mem->spi->dev;
const char *name;
/* Set custom name derived from the platform_device of the controller.
*/
- if (of_get_available_child_count(f->dev->device_node) == 1)
+ if (of_get_available_child_count(f->dev->of_node) == 1)
return dev_name(f->dev);
name = basprintf("%s-%d", dev_name(f->dev), mem->spi->chip_select);
@@ -961,7 +962,7 @@ static const struct spi_controller_mem_ops nxp_fspi_mem_ops = {
.get_name = nxp_fspi_get_name,
};
-static int nxp_fspi_probe(struct device_d *dev)
+static int nxp_fspi_probe(struct device *dev)
{
struct spi_controller *ctlr;
struct resource *res;
@@ -992,18 +993,19 @@ static int nxp_fspi_probe(struct device_d *dev)
/* find the resources */
res = dev_request_mem_resource(dev, 0);
- f->iobase = IOMEM(res->start);
- if (IS_ERR(f->iobase)) {
- ret = PTR_ERR(f->iobase);
+ if (IS_ERR(res)) {
+ ret = PTR_ERR(res);
goto err_put_ctrl;
}
+ f->iobase = IOMEM(res->start);
+
res = dev_request_mem_resource(dev, 1);
- f->ahb_addr = IOMEM(res->start);
- if (IS_ERR(f->ahb_addr)) {
- ret = PTR_ERR(f->ahb_addr);
+ if (IS_ERR(res)) {
+ ret = PTR_ERR(res);
goto err_put_ctrl;
}
+ f->ahb_addr = IOMEM(res->start);
/* assign memory mapped starting address and mapped size. */
f->memmap_phy = res->start;
@@ -1052,8 +1054,9 @@ static const struct of_device_id nxp_fspi_dt_ids[] = {
{ .compatible = "nxp,imx8dxl-fspi", .data = (void *)&imx8dxl_data, },
{ /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, nxp_fspi_dt_ids);
-static struct driver_d nxp_fspi_driver = {
+static struct driver nxp_fspi_driver = {
.name = "nxp-fspi",
.probe = nxp_fspi_probe,
.of_compatible = DRV_OF_COMPAT(nxp_fspi_dt_ids),
diff --git a/drivers/spi/spi-sifive.c b/drivers/spi/spi-sifive.c
index 713bcc0c3b..fbe80718e4 100644
--- a/drivers/spi/spi-sifive.c
+++ b/drivers/spi/spi-sifive.c
@@ -301,7 +301,7 @@ static int sifive_spi_exec_op(struct spi_mem *mem,
const struct spi_mem_op *op)
{
struct spi_device *spi_dev = mem->spi;
- struct device_d *dev = &spi_dev->dev;
+ struct device *dev = &spi_dev->dev;
struct sifive_spi *spi = spi_controller_get_devdata(spi_dev->controller);
u8 opcode = op->cmd.opcode;
int ret;
@@ -415,7 +415,7 @@ static int sifive_spi_setup(struct spi_device *spi_dev)
static void sifive_spi_init_hw(struct sifive_spi *spi)
{
- struct device_d *dev = spi->ctlr.dev;
+ struct device *dev = spi->ctlr.dev;
u32 cs_bits;
/* probe the number of CS lines */
@@ -457,7 +457,7 @@ static const struct spi_controller_mem_ops sifive_spi_mem_ops = {
static void sifive_spi_dt_probe(struct sifive_spi *spi)
{
- struct device_node *node = spi->ctlr.dev->device_node;
+ struct device_node *node = spi->ctlr.dev->of_node;
spi->fifo_depth = SIFIVE_SPI_DEFAULT_DEPTH;
of_property_read_u32(node, "sifive,fifo-depth", &spi->fifo_depth);
@@ -466,7 +466,7 @@ static void sifive_spi_dt_probe(struct sifive_spi *spi)
of_property_read_u32(node, "sifive,max-bits-per-word", &spi->bits_per_word);
}
-static int sifive_spi_probe(struct device_d *dev)
+static int sifive_spi_probe(struct device *dev)
{
struct sifive_spi *spi;
struct resource *iores;
@@ -512,8 +512,9 @@ static const struct of_device_id sifive_spi_ids[] = {
{ .compatible = "sifive,spi0" },
{ /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, sifive_spi_ids);
-static struct driver_d sifive_spi_driver = {
+static struct driver sifive_spi_driver = {
.name = "sifive_spi",
.probe = sifive_spi_probe,
.of_compatible = sifive_spi_ids,
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index b840dbe286..c627d88954 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -12,6 +12,7 @@
#include <spi/spi.h>
#include <xfuncs.h>
#include <malloc.h>
+#include <slice.h>
#include <errno.h>
#include <init.h>
#include <of.h>
@@ -29,6 +30,7 @@ struct boardinfo {
};
static LIST_HEAD(board_list);
+static LIST_HEAD(spi_controller_list);
/**
* spi_new_device - instantiate one new SPI device
@@ -71,7 +73,7 @@ struct spi_device *spi_new_device(struct spi_controller *ctrl,
/* allocate a free id for this chip */
proxy->dev.id = DEVICE_ID_DYNAMIC;
proxy->dev.type_data = proxy;
- proxy->dev.device_node = chip->device_node;
+ proxy->dev.of_node = chip->device_node;
proxy->dev.parent = ctrl->dev;
proxy->master = proxy->controller = ctrl;
@@ -108,9 +110,8 @@ EXPORT_SYMBOL(spi_new_device);
static void spi_of_register_slaves(struct spi_controller *ctrl)
{
struct device_node *n;
- struct spi_board_info chip;
struct property *reg;
- struct device_node *node = ctrl->dev->device_node;
+ struct device_node *node = ctrl->dev->of_node;
if (!IS_ENABLED(CONFIG_OFDEVICE))
return;
@@ -119,7 +120,14 @@ static void spi_of_register_slaves(struct spi_controller *ctrl)
return;
for_each_available_child_of_node(node, n) {
- memset(&chip, 0, sizeof(chip));
+ struct spi_board_info chip = {};
+
+ if (n->dev) {
+ dev_dbg(ctrl->dev, "skipping already registered %s\n",
+ dev_name(n->dev));
+ continue;
+ }
+
chip.name = xstrdup(n->name);
chip.bus_num = ctrl->bus_num;
/* Mode (clock phase/polarity/etc.) */
@@ -138,7 +146,18 @@ static void spi_of_register_slaves(struct spi_controller *ctrl)
continue;
chip.chip_select = of_read_number(reg->value, 1);
chip.device_node = n;
- spi_register_board_info(&chip, 1);
+ spi_new_device(ctrl, &chip);
+ }
+}
+
+static void spi_controller_rescan(struct device *dev)
+{
+ struct spi_controller *ctrl;
+
+ list_for_each_entry(ctrl, &spi_controller_list, list) {
+ if (ctrl->dev != dev)
+ continue;
+ spi_of_register_slaves(ctrl);
}
}
@@ -196,8 +215,6 @@ static void scan_boardinfo(struct spi_controller *ctrl)
}
}
-static LIST_HEAD(spi_controller_list);
-
static int spi_controller_check_ops(struct spi_controller *ctlr)
{
/*
@@ -253,14 +270,16 @@ int spi_register_controller(struct spi_controller *ctrl)
if (status)
return status;
+ slice_init(&ctrl->slice, dev_name(ctrl->dev));
+
/* even if it's just one always-selected device, there must
* be at least one chipselect
*/
if (ctrl->num_chipselect == 0)
return -EINVAL;
- if ((ctrl->bus_num < 0) && ctrl->dev->device_node)
- ctrl->bus_num = of_alias_get_id(ctrl->dev->device_node, "spi");
+ if ((ctrl->bus_num < 0) && ctrl->dev->of_node)
+ ctrl->bus_num = of_alias_get_id(ctrl->dev->of_node, "spi");
/* convention: dynamically assigned bus IDs count down from the max */
if (ctrl->bus_num < 0)
@@ -274,6 +293,9 @@ int spi_register_controller(struct spi_controller *ctrl)
scan_boardinfo(ctrl);
status = 0;
+ if (!ctrl->dev->rescan)
+ ctrl->dev->rescan = spi_controller_rescan;
+
return status;
}
EXPORT_SYMBOL(spi_register_controller);
@@ -333,12 +355,19 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
int spi_sync(struct spi_device *spi, struct spi_message *message)
{
int status;
+ int ret;
status = __spi_validate(spi, message);
if (status != 0)
return status;
- return spi->controller->transfer(spi, message);
+ slice_acquire(&spi->controller->slice);
+
+ ret = spi->controller->transfer(spi, message);
+
+ slice_release(&spi->controller->slice);
+
+ return ret;
}
/**
@@ -383,22 +412,9 @@ int spi_write_then_read(struct spi_device *spi,
}
EXPORT_SYMBOL(spi_write_then_read);
-static int spi_probe(struct device_d *dev)
-{
- return dev->driver->probe(dev);
-}
-
-static void spi_remove(struct device_d *dev)
-{
- if (dev->driver->remove)
- dev->driver->remove(dev);
-}
-
struct bus_type spi_bus = {
.name = "spi",
.match = device_match_of_modalias,
- .probe = spi_probe,
- .remove = spi_remove,
};
static int spi_bus_init(void)
diff --git a/drivers/spi/stm32_spi.c b/drivers/spi/stm32_spi.c
index 0cb04a968c..9ef405a788 100644
--- a/drivers/spi/stm32_spi.c
+++ b/drivers/spi/stm32_spi.c
@@ -11,6 +11,7 @@
#include <init.h>
#include <errno.h>
#include <linux/reset.h>
+#include <linux/spi/spi-mem.h>
#include <spi/spi.h>
#include <linux/bitops.h>
#include <clock.h>
@@ -110,6 +111,24 @@ static inline struct stm32_spi_priv *to_stm32_spi_priv(struct spi_master *master
return container_of(master, struct stm32_spi_priv, master);
}
+static int stm32_spi_get_bpw_mask(struct stm32_spi_priv *priv)
+{
+ u32 cfg1, max_bpw;
+
+ /*
+ * The most significant bit at DSIZE bit field is reserved when the
+ * maximum data size of periperal instances is limited to 16-bit
+ */
+ setbits_le32(priv->base + STM32_SPI_CFG1, SPI_CFG1_DSIZE);
+
+ cfg1 = readl(priv->base + STM32_SPI_CFG1);
+ max_bpw = FIELD_GET(SPI_CFG1_DSIZE, cfg1) + 1;
+
+ dev_dbg(priv->master.dev, "%d-bit maximum data frame\n", max_bpw);
+
+ return SPI_BPW_RANGE_MASK(4, max_bpw);
+}
+
static void stm32_spi_write_txfifo(struct stm32_spi_priv *priv)
{
while ((priv->tx_len > 0) &&
@@ -189,7 +208,7 @@ static void stm32_spi_disable(struct stm32_spi_priv *priv)
static void stm32_spi_stopxfer(struct stm32_spi_priv *priv)
{
- struct device_d *dev = priv->master.dev;
+ struct device *dev = priv->master.dev;
u32 cr1, sr;
int ret;
@@ -260,19 +279,15 @@ static void stm32_spi_set_mode(struct stm32_spi_priv *priv, unsigned mode)
static void stm32_spi_set_fthlv(struct stm32_spi_priv *priv, u32 xfer_len)
{
- u32 fthlv, half_fifo;
+ u32 fthlv, packet, bpw;
/* data packet should not exceed 1/2 of fifo space */
- half_fifo = (priv->fifo_size / 2);
-
- /* data_packet should not exceed transfer length */
- fthlv = (half_fifo > xfer_len) ? xfer_len : half_fifo;
+ packet = clamp(xfer_len, 1U, priv->fifo_size / 2);
/* align packet size with data registers access */
- fthlv -= (fthlv % 4);
+ bpw = DIV_ROUND_UP(priv->cur_bpw, 8);
+ fthlv = DIV_ROUND_UP(packet, bpw);
- if (!fthlv)
- fthlv = 1;
clrsetbits_le32(priv->base + STM32_SPI_CFG1, SPI_CFG1_FTHLV,
(fthlv - 1) << SPI_CFG1_FTHLV_SHIFT);
}
@@ -338,14 +353,22 @@ out:
static int stm32_spi_transfer_one(struct stm32_spi_priv *priv,
struct spi_transfer *t)
{
- struct device_d *dev = priv->master.dev;
+ struct device *dev = priv->master.dev;
u32 sr;
u32 ifcr = 0;
u32 mode;
int xfer_status = 0;
+ int nb_words;
+
+ if (t->bits_per_word <= 8)
+ nb_words = t->len;
+ else if (t->bits_per_word <= 16)
+ nb_words = DIV_ROUND_UP(t->len * 8, 16);
+ else
+ nb_words = DIV_ROUND_UP(t->len * 8, 32);
- if (t->len <= SPI_CR2_TSIZE)
- writel(t->len, priv->base + STM32_SPI_CR2);
+ if (nb_words <= SPI_CR2_TSIZE)
+ writel(nb_words, priv->base + STM32_SPI_CR2);
else
return -EMSGSIZE;
@@ -360,9 +383,11 @@ static int stm32_spi_transfer_one(struct stm32_spi_priv *priv,
else if (!priv->rx_buf)
mode = SPI_SIMPLEX_TX;
- if (priv->cur_xferlen != t->len || priv->cur_mode != mode) {
+ if (priv->cur_xferlen != t->len || priv->cur_mode != mode ||
+ priv->cur_bpw != t->bits_per_word) {
priv->cur_mode = mode;
priv->cur_xferlen = t->len;
+ priv->cur_bpw = t->bits_per_word;
/* Disable the SPI hardware to unlock CFG1/CFG2 registers */
stm32_spi_disable(priv);
@@ -372,6 +397,9 @@ static int stm32_spi_transfer_one(struct stm32_spi_priv *priv,
stm32_spi_set_fthlv(priv, t->len);
+ clrsetbits_le32(priv->base + STM32_SPI_CFG1, SPI_CFG1_DSIZE,
+ priv->cur_bpw - 1);
+
/* Enable the SPI hardware */
stm32_spi_enable(priv);
}
@@ -474,6 +502,24 @@ out:
return ret;
}
+static int stm32_spi_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
+{
+ if (op->data.nbytes > SPI_CR2_TSIZE)
+ op->data.nbytes = SPI_CR2_TSIZE;
+
+ return 0;
+}
+
+static int stm32_spi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
+{
+ return -ENOTSUPP;
+}
+
+static const struct spi_controller_mem_ops stm32_spi_mem_ops = {
+ .adjust_op_size = stm32_spi_adjust_op_size,
+ .exec_op = stm32_spi_exec_op,
+};
+
static int stm32_spi_get_fifo_size(struct stm32_spi_priv *priv)
{
u32 count = 0;
@@ -492,17 +538,17 @@ static int stm32_spi_get_fifo_size(struct stm32_spi_priv *priv)
static void stm32_spi_dt_probe(struct stm32_spi_priv *priv)
{
- struct device_node *node = priv->master.dev->device_node;
+ struct device_node *node = priv->master.dev->of_node;
int i;
- priv->master.num_chipselect = of_gpio_named_count(node, "cs-gpios");
+ priv->master.num_chipselect = of_gpio_count_csgpios(node);
priv->cs_gpios = xzalloc(sizeof(u32) * priv->master.num_chipselect);
for (i = 0; i < priv->master.num_chipselect; i++)
priv->cs_gpios[i] = of_get_named_gpio(node, "cs-gpios", i);
}
-static int stm32_spi_probe(struct device_d *dev)
+static int stm32_spi_probe(struct device *dev)
{
struct resource *iores;
struct spi_master *master;
@@ -522,6 +568,7 @@ static int stm32_spi_probe(struct device_d *dev)
master->setup = stm32_spi_setup;
master->transfer = stm32_spi_transfer;
+ master->mem_ops = &stm32_spi_mem_ops;
master->bus_num = -1;
stm32_spi_dt_probe(priv);
@@ -540,6 +587,7 @@ static int stm32_spi_probe(struct device_d *dev)
if (ret)
return ret;
+ master->bits_per_word_mask = stm32_spi_get_bpw_mask(priv);
priv->fifo_size = stm32_spi_get_fifo_size(priv);
priv->cur_mode = SPI_FULL_DUPLEX;
@@ -568,7 +616,7 @@ static int stm32_spi_probe(struct device_d *dev)
return spi_register_master(master);
}
-static void stm32_spi_remove(struct device_d *dev)
+static void stm32_spi_remove(struct device *dev)
{
struct stm32_spi_priv *priv = dev->priv;
@@ -580,8 +628,9 @@ static const struct of_device_id stm32_spi_ids[] = {
{ .compatible = "st,stm32h7-spi", },
{ /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, stm32_spi_ids);
-static struct driver_d stm32_spi_driver = {
+static struct driver stm32_spi_driver = {
.name = "stm32_spi",
.probe = stm32_spi_probe,
.remove = stm32_spi_remove,
diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c
index f0edc41c37..3da245feb7 100644
--- a/drivers/spi/zynq_qspi.c
+++ b/drivers/spi/zynq_qspi.c
@@ -125,7 +125,7 @@
*/
struct zynq_qspi {
struct spi_controller ctlr;
- struct device_d *dev;
+ struct device *dev;
void __iomem *regs;
struct clk *refclk;
struct clk *pclk;
@@ -539,9 +539,9 @@ static const struct spi_controller_mem_ops zynq_qspi_mem_ops = {
.exec_op = zynq_qspi_exec_mem_op,
};
-static int zynq_qspi_probe(struct device_d *dev)
+static int zynq_qspi_probe(struct device *dev)
{
- struct device_node *np = dev->device_node;
+ struct device_node *np = dev->of_node;
struct spi_controller *ctlr;
struct zynq_qspi *xqspi;
struct resource *iores;
@@ -603,8 +603,9 @@ static const struct of_device_id zynq_qspi_of_match[] = {
{ .compatible = "xlnx,zynq-qspi-1.0", },
{ /* end of table */ }
};
+MODULE_DEVICE_TABLE(of, zynq_qspi_of_match);
-static struct driver_d zynq_qspi_driver = {
+static struct driver zynq_qspi_driver = {
.name = "zynq-qspi",
.probe = zynq_qspi_probe,
.of_compatible = DRV_OF_COMPAT(zynq_qspi_of_match),