Skip to content

Commit aa9db10

Browse files
committed
spi: dw: Auto-detect number of native CS
Merge series from Serge Semin <[email protected]>: The main goal of the short series is to provide a procedure implementing the auto-detection of the number of native Chip-Select signals supported by the controller. The suggested algorithm is straightforward. It relies on the fact that the SER register writable flags reflects the actual number of available native chip-select signals. So the DW APB/AHB SSI driver now tests the SER register for having the writable bits, calculates the number of CS signals based on the number of set flags and then initializes the num_cs private data field based on that, which then will be passed to the SPI-core subsystem indicating the number of supported hardware chip-selects. The implemented procedure will be useful for the DW SSI device nodes not having the explicitly set "num-cs" property. In case if the property is specified it will be utilized instead of the auto-detection procedure. Besides of that a small cleanup patch is introduced in the head of the series. It converts the driver to using the BITS_TO_BYTES() macro instead of the hard-coded DIV_ROUND_UP()-based calculation of the number of bytes-per-transfer-word.
2 parents c24d340 + 98d75b9 commit aa9db10

File tree

3 files changed

+19
-11
lines changed

3 files changed

+19
-11
lines changed

drivers/spi/spi-dw-core.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
#include <linux/bitfield.h>
9+
#include <linux/bitops.h>
910
#include <linux/dma-mapping.h>
1011
#include <linux/interrupt.h>
1112
#include <linux/module.h>
@@ -421,10 +422,7 @@ static int dw_spi_transfer_one(struct spi_controller *host,
421422
int ret;
422423

423424
dws->dma_mapped = 0;
424-
dws->n_bytes =
425-
roundup_pow_of_two(DIV_ROUND_UP(transfer->bits_per_word,
426-
BITS_PER_BYTE));
427-
425+
dws->n_bytes = roundup_pow_of_two(BITS_TO_BYTES(transfer->bits_per_word));
428426
dws->tx = (void *)transfer->tx_buf;
429427
dws->tx_len = transfer->len / dws->n_bytes;
430428
dws->rx = transfer->rx_buf;
@@ -836,6 +834,20 @@ static void dw_spi_hw_init(struct device *dev, struct dw_spi *dws)
836834
DW_SPI_GET_BYTE(dws->ver, 1));
837835
}
838836

837+
/*
838+
* Try to detect the number of native chip-selects if the platform
839+
* driver didn't set it up. There can be up to 16 lines configured.
840+
*/
841+
if (!dws->num_cs) {
842+
u32 ser;
843+
844+
dw_writel(dws, DW_SPI_SER, 0xffff);
845+
ser = dw_readl(dws, DW_SPI_SER);
846+
dw_writel(dws, DW_SPI_SER, 0);
847+
848+
dws->num_cs = hweight16(ser);
849+
}
850+
839851
/*
840852
* Try to detect the FIFO depth if not set by interface driver,
841853
* the depth could be from 2 to 256 from HW spec

drivers/spi/spi-dw-mmio.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,6 @@ static int dw_spi_mmio_probe(struct platform_device *pdev)
320320
struct resource *mem;
321321
struct dw_spi *dws;
322322
int ret;
323-
int num_cs;
324323

325324
dwsmmio = devm_kzalloc(&pdev->dev, sizeof(struct dw_spi_mmio),
326325
GFP_KERNEL);
@@ -364,11 +363,8 @@ static int dw_spi_mmio_probe(struct platform_device *pdev)
364363
&dws->reg_io_width))
365364
dws->reg_io_width = 4;
366365

367-
num_cs = 4;
368-
369-
device_property_read_u32(&pdev->dev, "num-cs", &num_cs);
370-
371-
dws->num_cs = num_cs;
366+
/* Rely on the auto-detection if no property specified */
367+
device_property_read_u32(&pdev->dev, "num-cs", &dws->num_cs);
372368

373369
init_func = device_get_match_data(&pdev->dev);
374370
if (init_func) {

drivers/spi/spi-dw.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,8 @@ struct dw_spi {
164164
u32 max_freq; /* max bus freq supported */
165165

166166
u32 reg_io_width; /* DR I/O width in bytes */
167+
u32 num_cs; /* chip select lines */
167168
u16 bus_num;
168-
u16 num_cs; /* supported slave numbers */
169169
void (*set_cs)(struct spi_device *spi, bool enable);
170170

171171
/* Current message transfer state info */

0 commit comments

Comments
 (0)