linux-spi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 0/3] spi: Add more consistency to CS handle
@ 2024-03-07 15:00 Andy Shevchenko
  2024-03-07 15:00 ` [PATCH v1 1/3] spi: Consistently use BIT for cs_index_mask Andy Shevchenko
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Andy Shevchenko @ 2024-03-07 15:00 UTC (permalink / raw)
  To: Mark Brown, Andy Shevchenko, linux-spi, linux-kernel

There are the following issues with the current code:
- inconsistent use of 0xFF and -1 for invalid chip select pin
- inconsistent plain or BIT() use with a hard-to-understand comment
- wrong types used for last_cs_* fields

Fix all of these here.

Andy Shevchenko (3):
  spi: Consistently use BIT for cs_index_mask
  spi: Fix types of the last chip select storage variables
  spi: Introduce SPI_INVALID_CS and is_valid_cs()

 drivers/spi/spi.c       | 74 +++++++++++++++++++----------------------
 include/linux/spi/spi.h | 12 +++----
 2 files changed, 40 insertions(+), 46 deletions(-)

-- 
2.43.0.rc1.1.gbec44491f096


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v1 1/3] spi: Consistently use BIT for cs_index_mask
  2024-03-07 15:00 [PATCH v1 0/3] spi: Add more consistency to CS handle Andy Shevchenko
@ 2024-03-07 15:00 ` Andy Shevchenko
  2024-03-07 15:01 ` [PATCH v1 2/3] spi: Fix types of the last chip select storage variables Andy Shevchenko
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Andy Shevchenko @ 2024-03-07 15:00 UTC (permalink / raw)
  To: Mark Brown, Andy Shevchenko, linux-spi, linux-kernel

Some of the parts related to the chip select are using BIT() macro
the rest are using plain numbers. Unify all of them to use BIT().

While at it, make the (repetitive) comment clearer when assigning
cs_index_mask during SPI target device enumeration.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/spi/spi.c | 35 +++++++++++------------------------
 1 file changed, 11 insertions(+), 24 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index eb7e3ddf909b..4ab155f698c8 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1021,7 +1021,7 @@ static inline bool spi_is_last_cs(struct spi_device *spi)
 	bool last = false;
 
 	for (idx = 0; idx < SPI_CS_CNT_MAX; idx++) {
-		if ((spi->cs_index_mask >> idx) & 0x01) {
+		if (spi->cs_index_mask & BIT(idx)) {
 			if (spi->controller->last_cs[idx] == spi_get_chipselect(spi, idx))
 				last = true;
 		}
@@ -1072,8 +1072,7 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
 			 * into account.
 			 */
 			for (idx = 0; idx < SPI_CS_CNT_MAX; idx++) {
-				if (((spi->cs_index_mask >> idx) & 0x01) &&
-				    spi_get_csgpiod(spi, idx)) {
+				if ((spi->cs_index_mask & BIT(idx)) && spi_get_csgpiod(spi, idx)) {
 					if (has_acpi_companion(&spi->dev))
 						gpiod_set_value_cansleep(spi_get_csgpiod(spi, idx),
 									 !enable);
@@ -2456,14 +2455,10 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
 		spi_set_chipselect(spi, idx, cs[idx]);
 
 	/*
-	 * spi->chip_select[i] gives the corresponding physical CS for logical CS i
-	 * logical CS number is represented by setting the ith bit in spi->cs_index_mask
-	 * So, for example, if spi->cs_index_mask = 0x01 then logical CS number is 0 and
-	 * spi->chip_select[0] will give the physical CS.
-	 * By default spi->chip_select[0] will hold the physical CS number so, set
-	 * spi->cs_index_mask as 0x01.
+	 * By default spi->chip_select[0] will hold the physical CS number,
+	 * so set bit 0 in spi->cs_index_mask.
 	 */
-	spi->cs_index_mask = 0x01;
+	spi->cs_index_mask = BIT(0);
 
 	/* Device speed */
 	if (!of_property_read_u32(nc, "spi-max-frequency", &value))
@@ -2587,14 +2582,10 @@ struct spi_device *spi_new_ancillary_device(struct spi_device *spi,
 	ancillary->max_speed_hz = spi->max_speed_hz;
 	ancillary->mode = spi->mode;
 	/*
-	 * spi->chip_select[i] gives the corresponding physical CS for logical CS i
-	 * logical CS number is represented by setting the ith bit in spi->cs_index_mask
-	 * So, for example, if spi->cs_index_mask = 0x01 then logical CS number is 0 and
-	 * spi->chip_select[0] will give the physical CS.
-	 * By default spi->chip_select[0] will hold the physical CS number so, set
-	 * spi->cs_index_mask as 0x01.
+	 * By default spi->chip_select[0] will hold the physical CS number,
+	 * so set bit 0 in spi->cs_index_mask.
 	 */
-	ancillary->cs_index_mask = 0x01;
+	ancillary->cs_index_mask = BIT(0);
 
 	WARN_ON(!mutex_is_locked(&ctlr->add_lock));
 
@@ -2841,14 +2832,10 @@ struct spi_device *acpi_spi_device_alloc(struct spi_controller *ctlr,
 	spi->irq		= lookup.irq;
 	spi->bits_per_word	= lookup.bits_per_word;
 	/*
-	 * spi->chip_select[i] gives the corresponding physical CS for logical CS i
-	 * logical CS number is represented by setting the ith bit in spi->cs_index_mask
-	 * So, for example, if spi->cs_index_mask = 0x01 then logical CS number is 0 and
-	 * spi->chip_select[0] will give the physical CS.
-	 * By default spi->chip_select[0] will hold the physical CS number so, set
-	 * spi->cs_index_mask as 0x01.
+	 * By default spi->chip_select[0] will hold the physical CS number,
+	 * so set bit 0 in spi->cs_index_mask.
 	 */
-	spi->cs_index_mask	= 0x01;
+	spi->cs_index_mask	= BIT(0);
 
 	return spi;
 }
-- 
2.43.0.rc1.1.gbec44491f096


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v1 2/3] spi: Fix types of the last chip select storage variables
  2024-03-07 15:00 [PATCH v1 0/3] spi: Add more consistency to CS handle Andy Shevchenko
  2024-03-07 15:00 ` [PATCH v1 1/3] spi: Consistently use BIT for cs_index_mask Andy Shevchenko
@ 2024-03-07 15:01 ` Andy Shevchenko
  2024-03-07 15:01 ` [PATCH v1 3/3] spi: Introduce SPI_INVALID_CS and is_valid_cs() Andy Shevchenko
  2024-03-07 17:56 ` [PATCH v1 0/3] spi: Add more consistency to CS handle Mark Brown
  3 siblings, 0 replies; 5+ messages in thread
From: Andy Shevchenko @ 2024-03-07 15:01 UTC (permalink / raw)
  To: Mark Brown, Andy Shevchenko, linux-spi, linux-kernel

First of all, last_cs_index_mask should be aligned with the original
cs_index_mask, which is 16-bit (for now) wide. Use the same pattern
for the last_cs_index_mask.

Second, last_cs can be negative and since 'char' is equal to 'unsigned
char' in the kernel, it's incorrect, strictly speaking, to assign
signed number to it. Use s8 type as it's done for *_native_cs ones.

With this change, regroup a bit the ordering to avoid too much memory
space to be wasted due to paddings. Shuffle kernel documentation
accordignly.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 include/linux/spi/spi.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index e400d454b3f0..c459809efee4 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -448,9 +448,11 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch
  *	the @cur_msg_completion. This flag is used to signal the context that
  *	is running spi_finalize_current_message() that it needs to complete()
  * @cur_msg_mapped: message has been mapped for DMA
+ * @fallback: fallback to PIO if DMA transfer return failure with
+ *	SPI_TRANS_FAIL_NO_START.
+ * @last_cs_mode_high: was (mode & SPI_CS_HIGH) true on the last call to set_cs.
  * @last_cs: the last chip_select that is recorded by set_cs, -1 on non chip
  *           selected
- * @last_cs_mode_high: was (mode & SPI_CS_HIGH) true on the last call to set_cs.
  * @xfer_completion: used by core transfer_one_message()
  * @busy: message pump is busy
  * @running: message pump is running
@@ -527,8 +529,6 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch
  *	If the driver does not set this, the SPI core takes the snapshot as
  *	close to the driver hand-over as possible.
  * @irq_flags: Interrupt enable state during PTP system timestamping
- * @fallback: fallback to PIO if DMA transfer return failure with
- *	SPI_TRANS_FAIL_NO_START.
  * @queue_empty: signal green light for opportunistically skipping the queue
  *	for spi_sync transfers.
  * @must_async: disable all fast paths in the core
@@ -708,10 +708,10 @@ struct spi_controller {
 	bool				rt;
 	bool				auto_runtime_pm;
 	bool				cur_msg_mapped;
-	char				last_cs[SPI_CS_CNT_MAX];
-	char				last_cs_index_mask;
-	bool				last_cs_mode_high;
 	bool                            fallback;
+	bool				last_cs_mode_high;
+	s8				last_cs[SPI_CS_CNT_MAX];
+	u32				last_cs_index_mask : SPI_CS_CNT_MAX;
 	struct completion               xfer_completion;
 	size_t				max_dma_len;
 
-- 
2.43.0.rc1.1.gbec44491f096


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v1 3/3] spi: Introduce SPI_INVALID_CS and is_valid_cs()
  2024-03-07 15:00 [PATCH v1 0/3] spi: Add more consistency to CS handle Andy Shevchenko
  2024-03-07 15:00 ` [PATCH v1 1/3] spi: Consistently use BIT for cs_index_mask Andy Shevchenko
  2024-03-07 15:01 ` [PATCH v1 2/3] spi: Fix types of the last chip select storage variables Andy Shevchenko
@ 2024-03-07 15:01 ` Andy Shevchenko
  2024-03-07 17:56 ` [PATCH v1 0/3] spi: Add more consistency to CS handle Mark Brown
  3 siblings, 0 replies; 5+ messages in thread
From: Andy Shevchenko @ 2024-03-07 15:01 UTC (permalink / raw)
  To: Mark Brown, Andy Shevchenko, linux-spi, linux-kernel

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>
---
 drivers/spi/spi.c | 39 +++++++++++++++++++++++----------------
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 4ab155f698c8..f18738ae95f8 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -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)
@@ -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;
 		}
@@ -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;
@@ -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]);
 		}
 	}
@@ -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);
 }
 
 /**
@@ -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)
@@ -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)
-- 
2.43.0.rc1.1.gbec44491f096


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v1 0/3] spi: Add more consistency to CS handle
  2024-03-07 15:00 [PATCH v1 0/3] spi: Add more consistency to CS handle Andy Shevchenko
                   ` (2 preceding siblings ...)
  2024-03-07 15:01 ` [PATCH v1 3/3] spi: Introduce SPI_INVALID_CS and is_valid_cs() Andy Shevchenko
@ 2024-03-07 17:56 ` Mark Brown
  3 siblings, 0 replies; 5+ messages in thread
From: Mark Brown @ 2024-03-07 17:56 UTC (permalink / raw)
  To: linux-spi, linux-kernel, Andy Shevchenko

On Thu, 07 Mar 2024 17:00:58 +0200, Andy Shevchenko wrote:
> There are the following issues with the current code:
> - inconsistent use of 0xFF and -1 for invalid chip select pin
> - inconsistent plain or BIT() use with a hard-to-understand comment
> - wrong types used for last_cs_* fields
> 
> Fix all of these here.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/3] spi: Consistently use BIT for cs_index_mask
      commit: 1209c5566f9b244bd047478b7fc90318c9a310f0
[2/3] spi: Fix types of the last chip select storage variables
      commit: 14fe5a98fb24192f73639590d9d3cdb5640d48db
[3/3] spi: Introduce SPI_INVALID_CS and is_valid_cs()
      commit: be84be4a35fa99cca7e81e6dd21516a324cca413

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-03-07 17:56 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-07 15:00 [PATCH v1 0/3] spi: Add more consistency to CS handle Andy Shevchenko
2024-03-07 15:00 ` [PATCH v1 1/3] spi: Consistently use BIT for cs_index_mask Andy Shevchenko
2024-03-07 15:01 ` [PATCH v1 2/3] spi: Fix types of the last chip select storage variables Andy Shevchenko
2024-03-07 15:01 ` [PATCH v1 3/3] spi: Introduce SPI_INVALID_CS and is_valid_cs() Andy Shevchenko
2024-03-07 17:56 ` [PATCH v1 0/3] spi: Add more consistency to CS handle Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).