aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/spi/Kconfig4
-rw-r--r--drivers/spi/spi-bitbang.c23
-rw-r--r--drivers/spi/spi-dw-core.c20
-rw-r--r--drivers/spi/spi-dw-mmio.c8
-rw-r--r--drivers/spi/spi-dw.h2
5 files changed, 33 insertions, 24 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index e2d2f011f973..a2c99ff33e0a 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -226,11 +226,11 @@ config SPI_BCMBCA_HSSPI
explicitly.
config SPI_BITBANG
- tristate "Utilities for Bitbanging SPI masters"
+ tristate "Utilities for Bitbanging SPI host controllers"
help
With a few GPIO pins, your system can bitbang the SPI protocol.
Select this to get SPI support through I/O pins (GPIO, parallel
- port, etc). Or, some systems' SPI master controller drivers use
+ port, etc). Or, some systems' SPI host controller drivers use
this code to manage the per-word or per-transfer accesses to the
hardware shift registers.
diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c
index a0e2204fc039..ca5cc67555c5 100644
--- a/drivers/spi/spi-bitbang.c
+++ b/drivers/spi/spi-bitbang.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * polling/bitbanging SPI master controller driver utilities
+ * Polling/bitbanging SPI host controller controller driver utilities
*/
#include <linux/spinlock.h>
@@ -11,6 +11,7 @@
#include <linux/errno.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
+#include <linux/time64.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
@@ -168,8 +169,8 @@ int spi_bitbang_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
if (!hz)
hz = spi->max_speed_hz;
if (hz) {
- cs->nsecs = (1000000000/2) / hz;
- if (cs->nsecs > (MAX_UDELAY_MS * 1000 * 1000))
+ cs->nsecs = (NSEC_PER_SEC / 2) / hz;
+ if (cs->nsecs > (MAX_UDELAY_MS * NSEC_PER_MSEC))
return -EINVAL;
}
@@ -393,12 +394,12 @@ int spi_bitbang_init(struct spi_bitbang *bitbang)
EXPORT_SYMBOL_GPL(spi_bitbang_init);
/**
- * spi_bitbang_start - start up a polled/bitbanging SPI master driver
+ * spi_bitbang_start - start up a polled/bitbanging SPI host controller driver
* @bitbang: driver handle
*
* Caller should have zero-initialized all parts of the structure, and then
- * provided callbacks for chip selection and I/O loops. If the master has
- * a transfer method, its final step should call spi_bitbang_transfer; or,
+ * provided callbacks for chip selection and I/O loops. If the host controller has
+ * a transfer method, its final step should call spi_bitbang_transfer(); or,
* that's the default if the transfer routine is not initialized. It should
* also set up the bus number and number of chipselects.
*
@@ -406,9 +407,9 @@ EXPORT_SYMBOL_GPL(spi_bitbang_init);
* hardware that basically exposes a shift register) or per-spi_transfer
* (which takes better advantage of hardware like fifos or DMA engines).
*
- * Drivers using per-word I/O loops should use (or call) spi_bitbang_setup,
- * spi_bitbang_cleanup and spi_bitbang_setup_transfer to handle those spi
- * master methods. Those methods are the defaults if the bitbang->txrx_bufs
+ * Drivers using per-word I/O loops should use (or call) spi_bitbang_setup(),
+ * spi_bitbang_cleanup() and spi_bitbang_setup_transfer() to handle those SPI
+ * host controller methods. Those methods are the defaults if the bitbang->txrx_bufs
* routine isn't initialized.
*
* This routine registers the spi_controller, which will process requests in a
@@ -417,7 +418,7 @@ EXPORT_SYMBOL_GPL(spi_bitbang_init);
*
* On success, this routine will take a reference to the controller. The caller
* is responsible for calling spi_bitbang_stop() to decrement the reference and
- * spi_controller_put() as counterpart of spi_alloc_master() to prevent a memory
+ * spi_controller_put() as counterpart of spi_alloc_host() to prevent a memory
* leak.
*/
int spi_bitbang_start(struct spi_bitbang *bitbang)
@@ -450,4 +451,4 @@ void spi_bitbang_stop(struct spi_bitbang *bitbang)
EXPORT_SYMBOL_GPL(spi_bitbang_stop);
MODULE_LICENSE("GPL");
-
+MODULE_DESCRIPTION("Utilities for Bitbanging SPI host controllers");
diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c
index 0274c9295514..ddfdb903047a 100644
--- a/drivers/spi/spi-dw-core.c
+++ b/drivers/spi/spi-dw-core.c
@@ -6,6 +6,7 @@
*/
#include <linux/bitfield.h>
+#include <linux/bitops.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/module.h>
@@ -421,10 +422,7 @@ static int dw_spi_transfer_one(struct spi_controller *host,
int ret;
dws->dma_mapped = 0;
- dws->n_bytes =
- roundup_pow_of_two(DIV_ROUND_UP(transfer->bits_per_word,
- BITS_PER_BYTE));
-
+ dws->n_bytes = roundup_pow_of_two(BITS_TO_BYTES(transfer->bits_per_word));
dws->tx = (void *)transfer->tx_buf;
dws->tx_len = transfer->len / dws->n_bytes;
dws->rx = transfer->rx_buf;
@@ -837,6 +835,20 @@ static void dw_spi_hw_init(struct device *dev, struct dw_spi *dws)
}
/*
+ * Try to detect the number of native chip-selects if the platform
+ * driver didn't set it up. There can be up to 16 lines configured.
+ */
+ if (!dws->num_cs) {
+ u32 ser;
+
+ dw_writel(dws, DW_SPI_SER, 0xffff);
+ ser = dw_readl(dws, DW_SPI_SER);
+ dw_writel(dws, DW_SPI_SER, 0);
+
+ dws->num_cs = hweight16(ser);
+ }
+
+ /*
* 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-mmio.c b/drivers/spi/spi-dw-mmio.c
index cc74cbe03431..c56de35eca98 100644
--- a/drivers/spi/spi-dw-mmio.c
+++ b/drivers/spi/spi-dw-mmio.c
@@ -320,7 +320,6 @@ static int dw_spi_mmio_probe(struct platform_device *pdev)
struct resource *mem;
struct dw_spi *dws;
int ret;
- int num_cs;
dwsmmio = devm_kzalloc(&pdev->dev, sizeof(struct dw_spi_mmio),
GFP_KERNEL);
@@ -364,11 +363,8 @@ static int dw_spi_mmio_probe(struct platform_device *pdev)
&dws->reg_io_width))
dws->reg_io_width = 4;
- num_cs = 4;
-
- device_property_read_u32(&pdev->dev, "num-cs", &num_cs);
-
- dws->num_cs = num_cs;
+ /* Rely on the auto-detection if no property specified */
+ device_property_read_u32(&pdev->dev, "num-cs", &dws->num_cs);
init_func = device_get_match_data(&pdev->dev);
if (init_func) {
diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h
index 6cafeee8ee2a..fc267c6437ae 100644
--- a/drivers/spi/spi-dw.h
+++ b/drivers/spi/spi-dw.h
@@ -164,8 +164,8 @@ struct dw_spi {
u32 max_freq; /* max bus freq supported */
u32 reg_io_width; /* DR I/O width in bytes */
+ u32 num_cs; /* chip select lines */
u16 bus_num;
- u16 num_cs; /* supported slave numbers */
void (*set_cs)(struct spi_device *spi, bool enable);
/* Current message transfer state info */