Skip to content

Commit

Permalink
spi: Introduce SPI_INVALID_CS and is_valid_cs()
Browse files Browse the repository at this point in the history
The SPI core inconsistently uses the marker value for unused chip select
pin. Define a constant (with appropriate type) and introduce is_valid_cs()
helper function to avoid spreading this inconsistency in the future.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://msgid.link/r/20240307150256.3789138-4-andriy.shevchenko@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Andy Shevchenko authored and Mark Brown committed Mar 7, 2024
1 parent 14fe5a9 commit be84be4
Showing 1 changed file with 23 additions and 16 deletions.
39 changes: 23 additions & 16 deletions drivers/spi/spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,22 @@ static void spi_dev_set_name(struct spi_device *spi)
spi_get_chipselect(spi, 0));
}

/*
* Zero(0) is a valid physical CS value and can be located at any
* logical CS in the spi->chip_select[]. If all the physical CS
* are initialized to 0 then It would be difficult to differentiate
* between a valid physical CS 0 & an unused logical CS whose physical
* CS can be 0. As a solution to this issue initialize all the CS to -1.
* Now all the unused logical CS will have -1 physical CS value & can be
* ignored while performing physical CS validity checks.
*/
#define SPI_INVALID_CS ((s8)-1)

static inline bool is_valid_cs(s8 chip_select)
{
return chip_select != SPI_INVALID_CS;
}

static inline int spi_dev_check_cs(struct device *dev,
struct spi_device *spi, u8 idx,
struct spi_device *new_spi, u8 new_idx)
Expand All @@ -618,7 +634,7 @@ static inline int spi_dev_check_cs(struct device *dev,
cs = spi_get_chipselect(spi, idx);
for (idx_new = new_idx; idx_new < SPI_CS_CNT_MAX; idx_new++) {
cs_new = spi_get_chipselect(new_spi, idx_new);
if (cs != 0xFF && cs_new != 0xFF && cs == cs_new) {
if (is_valid_cs(cs) && is_valid_cs(cs_new) && cs == cs_new) {
dev_err(dev, "chipselect %u already in use\n", cs_new);
return -EBUSY;
}
Expand Down Expand Up @@ -658,7 +674,7 @@ static int __spi_add_device(struct spi_device *spi)
for (idx = 0; idx < SPI_CS_CNT_MAX; idx++) {
/* Chipselects are numbered 0..max; validate. */
cs = spi_get_chipselect(spi, idx);
if (cs != 0xFF && cs >= ctlr->num_chipselect) {
if (is_valid_cs(cs) && cs >= ctlr->num_chipselect) {
dev_err(dev, "cs%d >= max %d\n", spi_get_chipselect(spi, idx),
ctlr->num_chipselect);
return -EINVAL;
Expand Down Expand Up @@ -698,7 +714,7 @@ static int __spi_add_device(struct spi_device *spi)

for (idx = 0; idx < SPI_CS_CNT_MAX; idx++) {
cs = spi_get_chipselect(spi, idx);
if (cs != 0xFF)
if (is_valid_cs(cs))
spi_set_csgpiod(spi, idx, ctlr->cs_gpiods[cs]);
}
}
Expand Down Expand Up @@ -756,17 +772,8 @@ static void spi_set_all_cs_unused(struct spi_device *spi)
{
u8 idx;

/*
* Zero(0) is a valid physical CS value and can be located at any
* logical CS in the spi->chip_select[]. If all the physical CS
* are initialized to 0 then It would be difficult to differentiate
* between a valid physical CS 0 & an unused logical CS whose physical
* CS can be 0. As a solution to this issue initialize all the CS to 0xFF.
* Now all the unused logical CS will have 0xFF physical CS value & can be
* ignore while performing physical CS validity checks.
*/
for (idx = 0; idx < SPI_CS_CNT_MAX; idx++)
spi_set_chipselect(spi, idx, 0xFF);
spi_set_chipselect(spi, idx, SPI_INVALID_CS);
}

/**
Expand Down Expand Up @@ -1050,7 +1057,7 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force)

spi->controller->last_cs_index_mask = spi->cs_index_mask;
for (idx = 0; idx < SPI_CS_CNT_MAX; idx++)
spi->controller->last_cs[idx] = enable ? spi_get_chipselect(spi, 0) : -1;
spi->controller->last_cs[idx] = enable ? spi_get_chipselect(spi, 0) : SPI_INVALID_CS;
spi->controller->last_cs_mode_high = spi->mode & SPI_CS_HIGH;

if (spi->mode & SPI_CS_HIGH)
Expand Down Expand Up @@ -3333,9 +3340,9 @@ int spi_register_controller(struct spi_controller *ctlr)
goto free_bus_id;
}

/* Setting last_cs to -1 means no chip selected */
/* Setting last_cs to SPI_INVALID_CS means no chip selected */
for (idx = 0; idx < SPI_CS_CNT_MAX; idx++)
ctlr->last_cs[idx] = -1;
ctlr->last_cs[idx] = SPI_INVALID_CS;

status = device_add(&ctlr->dev);
if (status < 0)
Expand Down

0 comments on commit be84be4

Please sign in to comment.