[PATCH v5 3/9] spi: support controllers with multiple data lanes

David Lechner posted 9 patches 3 weeks, 6 days ago
There is a newer version of this series
[PATCH v5 3/9] spi: support controllers with multiple data lanes
Posted by David Lechner 3 weeks, 6 days ago
Add support for SPI controllers with multiple physical SPI data lanes.
(A data lane in this context means lines connected to a serializer, so a
controller with two data lanes would have two serializers in a single
controller).

This is common in the type of controller that can be used with parallel
flash memories, but can be used for general purpose SPI as well.

To indicate support, a controller just needs to set ctlr->num_data_lanes
to something greater than 1. Peripherals indicate which lane they are
connected to via device tree (ACPI support can be added if needed).

The spi-{tx,rx}-bus-width DT properties can now be arrays. The length of
the array indicates the number of data lanes, and each element indicates
the bus width of that lane. For now, we restrict all lanes to have the
same bus width to keep things simple. Support for an optional controller
lane mapping property is also implemented.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v5 changes:
- Use of_property_read_variable_u32_array() for lane maps.

v4 changes:
- Update for changes in devicetree bindings.
- Don't put new fields in the middle of CS fields.
- Dropped acks since this was a significant rework.

v3 changes:
* Renamed "buses" to "lanes" to reflect devicetree property name change.

This patch has been seen in a different series [1] by Sean before:

[1]: https://lore.kernel.org/linux-spi/20250616220054.3968946-4-sean.anderson@linux.dev/

Changes:
* Use u8 array instead of bitfield so that the order of the mapping is
  preserved. (Now looks very much like chip select mapping.)
* Added doc strings for added fields.
* Tweaked the comments.
---
 drivers/spi/spi.c       | 116 +++++++++++++++++++++++++++++++++++++++++++++++-
 include/linux/spi/spi.h |  22 +++++++++
 2 files changed, 136 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index e25df9990f82..5c3f9ba3f606 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -2370,7 +2370,53 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
 		spi->mode |= SPI_CS_HIGH;
 
 	/* Device DUAL/QUAD mode */
-	if (!of_property_read_u32(nc, "spi-tx-bus-width", &value)) {
+
+	rc = of_property_read_variable_u32_array(nc, "spi-tx-lane-map",
+						 spi->tx_lane_map, 1,
+						 ARRAY_SIZE(spi->tx_lane_map));
+	if (rc == -EINVAL) {
+		/* Default lane map */
+		for (idx = 0; idx < ARRAY_SIZE(spi->tx_lane_map); idx++)
+			spi->tx_lane_map[idx] = idx;
+	} else if (rc < 0) {
+		dev_err(&ctlr->dev,
+			"failed to read spi-tx-lane-map property: %d\n", rc);
+		return rc;
+	}
+
+	rc = of_property_count_u32_elems(nc, "spi-tx-bus-width");
+	if (rc < 0 && rc != -EINVAL) {
+		dev_err(&ctlr->dev,
+			"failed to read spi-tx-bus-width property: %d\n", rc);
+		return rc;
+	}
+
+	if (rc == -EINVAL) {
+		/* Default when property is not present. */
+		spi->num_tx_lanes = 1;
+	} else {
+		u32 first_value;
+
+		spi->num_tx_lanes = rc;
+
+		for (idx = 0; idx < spi->num_tx_lanes; idx++) {
+			of_property_read_u32_index(nc, "spi-tx-bus-width", idx,
+						   &value);
+
+			/*
+			 * For now, we only support all lanes having the same
+			 * width so we can keep using the existing mode flags.
+			 */
+			if (!idx)
+				first_value = value;
+			else if (first_value != value) {
+				dev_err(&ctlr->dev,
+					"spi-tx-bus-width has inconsistent values: first %d vs later %d\n",
+					first_value, value);
+				return -EINVAL;
+			}
+		}
+
 		switch (value) {
 		case 0:
 			spi->mode |= SPI_NO_TX;
@@ -2394,7 +2440,62 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
 		}
 	}
 
-	if (!of_property_read_u32(nc, "spi-rx-bus-width", &value)) {
+	for (idx = 0; idx < spi->num_tx_lanes; idx++) {
+		if (spi->tx_lane_map[idx] >= spi->controller->num_data_lanes) {
+			dev_err(&ctlr->dev,
+				"spi-tx-lane-map has invalid value %d (num_data_lanes=%d)\n",
+				spi->tx_lane_map[idx],
+				spi->controller->num_data_lanes);
+			return -EINVAL;
+		}
+	}
+
+	rc = of_property_read_variable_u32_array(nc, "spi-rx-lane-map",
+						 spi->rx_lane_map, 1,
+						 ARRAY_SIZE(spi->rx_lane_map));
+	if (rc == -EINVAL) {
+		/* Default lane map */
+		for (idx = 0; idx < ARRAY_SIZE(spi->rx_lane_map); idx++)
+			spi->rx_lane_map[idx] = idx;
+	} else if (rc < 0) {
+		dev_err(&ctlr->dev,
+			"failed to read spi-rx-lane-map property: %d\n", rc);
+		return rc;
+	}
+
+	rc = of_property_count_u32_elems(nc, "spi-rx-bus-width");
+	if (rc < 0 && rc != -EINVAL) {
+		dev_err(&ctlr->dev,
+			"failed to read spi-rx-bus-width property: %d\n", rc);
+		return rc;
+	}
+
+	if (rc == -EINVAL) {
+		/* Default when property is not present. */
+		spi->num_rx_lanes = 1;
+	} else {
+		u32 first_value;
+
+		spi->num_rx_lanes = rc;
+
+		for (idx = 0; idx < spi->num_rx_lanes; idx++) {
+			of_property_read_u32_index(nc, "spi-rx-bus-width", idx,
+						   &value);
+
+			/*
+			 * For now, we only support all lanes having the same
+			 * width so we can keep using the existing mode flags.
+			 */
+			if (!idx)
+				first_value = value;
+			else if (first_value != value) {
+				dev_err(&ctlr->dev,
+					"spi-rx-bus-width has inconsistent values: first %d vs later %d\n",
+					first_value, value);
+				return -EINVAL;
+			}
+		}
+
 		switch (value) {
 		case 0:
 			spi->mode |= SPI_NO_RX;
@@ -2418,6 +2519,16 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
 		}
 	}
 
+	for (idx = 0; idx < spi->num_rx_lanes; idx++) {
+		if (spi->rx_lane_map[idx] >= spi->controller->num_data_lanes) {
+			dev_err(&ctlr->dev,
+				"spi-rx-lane-map has invalid value %d (num_data_lanes=%d)\n",
+				spi->rx_lane_map[idx],
+				spi->controller->num_data_lanes);
+			return -EINVAL;
+		}
+	}
+
 	if (spi_controller_is_target(ctlr)) {
 		if (!of_node_name_eq(nc, "slave")) {
 			dev_err(&ctlr->dev, "%pOF is not called 'slave'\n",
@@ -3066,6 +3177,7 @@ struct spi_controller *__spi_alloc_controller(struct device *dev,
 	mutex_init(&ctlr->add_lock);
 	ctlr->bus_num = -1;
 	ctlr->num_chipselect = 1;
+	ctlr->num_data_lanes = 1;
 	ctlr->target = target;
 	if (IS_ENABLED(CONFIG_SPI_SLAVE) && target)
 		ctlr->dev.class = &spi_target_class;
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index cb2c2df31089..7aff60ab257e 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -23,6 +23,9 @@
 /* Max no. of CS supported per spi device */
 #define SPI_DEVICE_CS_CNT_MAX 4
 
+/* Max no. of data lanes supported per spi device */
+#define SPI_DEVICE_DATA_LANE_CNT_MAX 8
+
 struct dma_chan;
 struct software_node;
 struct ptp_system_timestamp;
@@ -174,6 +177,10 @@ extern void spi_transfer_cs_change_delay_exec(struct spi_message *msg,
  * @cs_index_mask: Bit mask of the active chipselect(s) in the chipselect array
  * @cs_gpiod: Array of GPIO descriptors of the corresponding chipselect lines
  *	(optional, NULL when not using a GPIO line)
+ * @tx_lane_map: Map of peripheral lanes (index) to controller lanes (value).
+ * @num_tx_lanes: Number of transmit lanes wired up.
+ * @rx_lane_map: Map of peripheral lanes (index) to controller lanes (value).
+ * @num_rx_lanes: Number of receive lanes wired up.
  *
  * A @spi_device is used to interchange data between an SPI target device
  * (usually a discrete chip) and CPU memory.
@@ -242,6 +249,12 @@ struct spi_device {
 
 	struct gpio_desc	*cs_gpiod[SPI_DEVICE_CS_CNT_MAX];	/* Chip select gpio desc */
 
+	/* Multi-lane SPI controller support. */
+	u32			tx_lane_map[SPI_DEVICE_DATA_LANE_CNT_MAX];
+	u32			num_tx_lanes;
+	u32			rx_lane_map[SPI_DEVICE_DATA_LANE_CNT_MAX];
+	u32			num_rx_lanes;
+
 	/*
 	 * Likely need more hooks for more protocol options affecting how
 	 * the controller talks to each chip, like:
@@ -401,6 +414,7 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch
  *	SPI targets, and are numbered from zero to num_chipselects.
  *	each target has a chipselect signal, but it's common that not
  *	every chipselect is connected to a target.
+ * @num_data_lanes: Number of data lanes supported by this controller. Default is 1.
  * @dma_alignment: SPI controller constraint on DMA buffers alignment.
  * @mode_bits: flags understood by this controller driver
  * @buswidth_override_bits: flags to override for this controller driver
@@ -576,6 +590,14 @@ struct spi_controller {
 	 */
 	u16			num_chipselect;
 
+	/*
+	 * Some specialized SPI controllers can have more than one physical
+	 * data lane interface per controller (each having it's own serializer).
+	 * This specifies the number of data lanes in that case. Other
+	 * controllers do not need to set this (defaults to 1).
+	 */
+	u16			num_data_lanes;
+
 	/* Some SPI controllers pose alignment requirements on DMAable
 	 * buffers; let protocol drivers know about these requirements.
 	 */

-- 
2.43.0
Re: [PATCH v5 3/9] spi: support controllers with multiple data lanes
Posted by Jonathan Cameron 3 weeks, 5 days ago
On Mon, 12 Jan 2026 11:45:21 -0600
David Lechner <dlechner@baylibre.com> wrote:

> Add support for SPI controllers with multiple physical SPI data lanes.
> (A data lane in this context means lines connected to a serializer, so a
> controller with two data lanes would have two serializers in a single
> controller).
> 
> This is common in the type of controller that can be used with parallel
> flash memories, but can be used for general purpose SPI as well.
> 
> To indicate support, a controller just needs to set ctlr->num_data_lanes
> to something greater than 1. Peripherals indicate which lane they are
> connected to via device tree (ACPI support can be added if needed).
> 
> The spi-{tx,rx}-bus-width DT properties can now be arrays. The length of
> the array indicates the number of data lanes, and each element indicates
> the bus width of that lane. For now, we restrict all lanes to have the
> same bus width to keep things simple. Support for an optional controller
> lane mapping property is also implemented.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>
> ---
> 
> v5 changes:
> - Use of_property_read_variable_u32_array() for lane maps.
For this, I think you need to check for short maps.
> 
> v4 changes:
> - Update for changes in devicetree bindings.
> - Don't put new fields in the middle of CS fields.
> - Dropped acks since this was a significant rework.
> 
> v3 changes:
> * Renamed "buses" to "lanes" to reflect devicetree property name change.
> 
> This patch has been seen in a different series [1] by Sean before:
> 
> [1]: https://lore.kernel.org/linux-spi/20250616220054.3968946-4-sean.anderson@linux.dev/
> 
> Changes:
> * Use u8 array instead of bitfield so that the order of the mapping is
>   preserved. (Now looks very much like chip select mapping.)
> * Added doc strings for added fields.
> * Tweaked the comments.
> ---
>  drivers/spi/spi.c       | 116 +++++++++++++++++++++++++++++++++++++++++++++++-
>  include/linux/spi/spi.h |  22 +++++++++
>  2 files changed, 136 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> index e25df9990f82..5c3f9ba3f606 100644
> --- a/drivers/spi/spi.c
> +++ b/drivers/spi/spi.c
> @@ -2370,7 +2370,53 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
>  		spi->mode |= SPI_CS_HIGH;
>  
>  	/* Device DUAL/QUAD mode */
> -	if (!of_property_read_u32(nc, "spi-tx-bus-width", &value)) {
> +
> +	rc = of_property_read_variable_u32_array(nc, "spi-tx-lane-map",
> +						 spi->tx_lane_map, 1,
> +						 ARRAY_SIZE(spi->tx_lane_map));

This reads 'up to' the ARRAY_SIZE(spi->tx_lane_map)
If it is short, what is the right thing to do?  I'd either expect a check
for that or for rc to be stashed somewhere if positive for later use.
If the intent is for short the default of 0 is fine, then if it's a lot
short we'll end up with repeated mappings to 0 which makes little sense.


> +	if (rc == -EINVAL) {
> +		/* Default lane map */
> +		for (idx = 0; idx < ARRAY_SIZE(spi->tx_lane_map); idx++)
> +			spi->tx_lane_map[idx] = idx;
> +	} else if (rc < 0) {
> +		dev_err(&ctlr->dev,
> +			"failed to read spi-tx-lane-map property: %d\n", rc);
> +		return rc;
> +	}
> +
> +	rc = of_property_count_u32_elems(nc, "spi-tx-bus-width");
> +	if (rc < 0 && rc != -EINVAL) {
> +		dev_err(&ctlr->dev,
> +			"failed to read spi-tx-bus-width property: %d\n", rc);
> +		return rc;
> +	}
> +
> +	if (rc == -EINVAL) {
> +		/* Default when property is not present. */
> +		spi->num_tx_lanes = 1;
> +	} else {
> +		u32 first_value;
> +
> +		spi->num_tx_lanes = rc;
> +
> +		for (idx = 0; idx < spi->num_tx_lanes; idx++) {
> +			of_property_read_u32_index(nc, "spi-tx-bus-width", idx,
> +						   &value);

Probably want a sanity check on return value of that even though we are fairly sure
it won't fail.

> +
> +			/*
> +			 * For now, we only support all lanes having the same
> +			 * width so we can keep using the existing mode flags.
> +			 */
> +			if (!idx)
> +				first_value = value;
> +			else if (first_value != value) {
> +				dev_err(&ctlr->dev,
> +					"spi-tx-bus-width has inconsistent values: first %d vs later %d\n",
> +					first_value, value);
> +				return -EINVAL;
> +			}
> +		}
Re: [PATCH v5 3/9] spi: support controllers with multiple data lanes
Posted by David Lechner 3 weeks, 2 days ago
On 1/14/26 3:05 AM, Jonathan Cameron wrote:
> On Mon, 12 Jan 2026 11:45:21 -0600
> David Lechner <dlechner@baylibre.com> wrote:
> 
>> Add support for SPI controllers with multiple physical SPI data lanes.
>> (A data lane in this context means lines connected to a serializer, so a
>> controller with two data lanes would have two serializers in a single
>> controller).
>>
>> This is common in the type of controller that can be used with parallel
>> flash memories, but can be used for general purpose SPI as well.
>>
>> To indicate support, a controller just needs to set ctlr->num_data_lanes
>> to something greater than 1. Peripherals indicate which lane they are
>> connected to via device tree (ACPI support can be added if needed).
>>
>> The spi-{tx,rx}-bus-width DT properties can now be arrays. The length of
>> the array indicates the number of data lanes, and each element indicates
>> the bus width of that lane. For now, we restrict all lanes to have the
>> same bus width to keep things simple. Support for an optional controller
>> lane mapping property is also implemented.
>>
>> Signed-off-by: David Lechner <dlechner@baylibre.com>
>> ---
>>
>> v5 changes:
>> - Use of_property_read_variable_u32_array() for lane maps.
> For this, I think you need to check for short maps.
>>
>> v4 changes:
>> - Update for changes in devicetree bindings.
>> - Don't put new fields in the middle of CS fields.
>> - Dropped acks since this was a significant rework.
>>
>> v3 changes:
>> * Renamed "buses" to "lanes" to reflect devicetree property name change.
>>
>> This patch has been seen in a different series [1] by Sean before:
>>
>> [1]: https://lore.kernel.org/linux-spi/20250616220054.3968946-4-sean.anderson@linux.dev/
>>
>> Changes:
>> * Use u8 array instead of bitfield so that the order of the mapping is
>>   preserved. (Now looks very much like chip select mapping.)
>> * Added doc strings for added fields.
>> * Tweaked the comments.
>> ---
>>  drivers/spi/spi.c       | 116 +++++++++++++++++++++++++++++++++++++++++++++++-
>>  include/linux/spi/spi.h |  22 +++++++++
>>  2 files changed, 136 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
>> index e25df9990f82..5c3f9ba3f606 100644
>> --- a/drivers/spi/spi.c
>> +++ b/drivers/spi/spi.c
>> @@ -2370,7 +2370,53 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
>>  		spi->mode |= SPI_CS_HIGH;
>>  
>>  	/* Device DUAL/QUAD mode */
>> -	if (!of_property_read_u32(nc, "spi-tx-bus-width", &value)) {
>> +
>> +	rc = of_property_read_variable_u32_array(nc, "spi-tx-lane-map",
>> +						 spi->tx_lane_map, 1,
>> +						 ARRAY_SIZE(spi->tx_lane_map));
> 
> This reads 'up to' the ARRAY_SIZE(spi->tx_lane_map)
> If it is short, what is the right thing to do?  I'd either expect a check
> for that or for rc to be stashed somewhere if positive for later use.
> If the intent is for short the default of 0 is fine, then if it's a lot
> short we'll end up with repeated mappings to 0 which makes little sense.

The right thing would be to make sure that spi-tx-lane-map and
spi-tx-bus-width are the same size. I suppose we could reorder it
and call of_property_count_u32_elems(nc, "spi-tx-bus-width") first
to avoid needing to do the variable read.

> 
> 
>> +	if (rc == -EINVAL) {
>> +		/* Default lane map */
>> +		for (idx = 0; idx < ARRAY_SIZE(spi->tx_lane_map); idx++)
>> +			spi->tx_lane_map[idx] = idx;
>> +	} else if (rc < 0) {
>> +		dev_err(&ctlr->dev,
>> +			"failed to read spi-tx-lane-map property: %d\n", rc);
>> +		return rc;
>> +	}
>> +
>> +	rc = of_property_count_u32_elems(nc, "spi-tx-bus-width");
>> +	if (rc < 0 && rc != -EINVAL) {
>> +		dev_err(&ctlr->dev,
>> +			"failed to read spi-tx-bus-width property: %d\n", rc);
>> +		return rc;
>> +	}
>> +
>> +	if (rc == -EINVAL) {
>> +		/* Default when property is not present. */
>> +		spi->num_tx_lanes = 1;
>> +	} else {
>> +		u32 first_value;
>> +
>> +		spi->num_tx_lanes = rc;
>> +
>> +		for (idx = 0; idx < spi->num_tx_lanes; idx++) {
>> +			of_property_read_u32_index(nc, "spi-tx-bus-width", idx,
>> +						   &value);
> 
> Probably want a sanity check on return value of that even though we are fairly sure
> it won't fail.

I figured that if of_property_count_u32_elems() succeeded then this could not
possibly fail. But OK, why not be extra careful.

> 
>> +
>> +			/*
>> +			 * For now, we only support all lanes having the same
>> +			 * width so we can keep using the existing mode flags.
>> +			 */
>> +			if (!idx)
>> +				first_value = value;
>> +			else if (first_value != value) {
>> +				dev_err(&ctlr->dev,
>> +					"spi-tx-bus-width has inconsistent values: first %d vs later %d\n",
>> +					first_value, value);
>> +				return -EINVAL;
>> +			}
>> +		}
>
Re: [PATCH v5 3/9] spi: support controllers with multiple data lanes
Posted by Andy Shevchenko 3 weeks, 6 days ago
On Mon, Jan 12, 2026 at 11:45:21AM -0600, David Lechner wrote:
> Add support for SPI controllers with multiple physical SPI data lanes.
> (A data lane in this context means lines connected to a serializer, so a
> controller with two data lanes would have two serializers in a single
> controller).
> 
> This is common in the type of controller that can be used with parallel
> flash memories, but can be used for general purpose SPI as well.
> 
> To indicate support, a controller just needs to set ctlr->num_data_lanes
> to something greater than 1. Peripherals indicate which lane they are
> connected to via device tree (ACPI support can be added if needed).
> 
> The spi-{tx,rx}-bus-width DT properties can now be arrays. The length of
> the array indicates the number of data lanes, and each element indicates
> the bus width of that lane. For now, we restrict all lanes to have the
> same bus width to keep things simple. Support for an optional controller
> lane mapping property is also implemented.

...

> struct spi_device {

> +	/* Multi-lane SPI controller support. */
> +	u32			tx_lane_map[SPI_DEVICE_DATA_LANE_CNT_MAX];
> +	u32			num_tx_lanes;
> +	u32			rx_lane_map[SPI_DEVICE_DATA_LANE_CNT_MAX];
> +	u32			num_rx_lanes;

This adds 72 bytes in _each_ instance of spi_device on the platforms that do
not use the feature and might not ever use it. Can we move to the pointer
and allocate the mentioned fields separately, please?

-- 
With Best Regards,
Andy Shevchenko
Re: [PATCH v5 3/9] spi: support controllers with multiple data lanes
Posted by Mark Brown 3 weeks, 6 days ago
On Mon, Jan 12, 2026 at 09:07:17PM +0200, Andy Shevchenko wrote:
> On Mon, Jan 12, 2026 at 11:45:21AM -0600, David Lechner wrote:

> > +	/* Multi-lane SPI controller support. */
> > +	u32			tx_lane_map[SPI_DEVICE_DATA_LANE_CNT_MAX];
> > +	u32			num_tx_lanes;
> > +	u32			rx_lane_map[SPI_DEVICE_DATA_LANE_CNT_MAX];
> > +	u32			num_rx_lanes;

> This adds 72 bytes in _each_ instance of spi_device on the platforms that do
> not use the feature and might not ever use it. Can we move to the pointer
> and allocate the mentioned fields separately, please?

Do we have real systems where we have enough SPI devices for anyone to
care?
Re: [PATCH v5 3/9] spi: support controllers with multiple data lanes
Posted by Andy Shevchenko 3 weeks, 6 days ago
On Mon, Jan 12, 2026 at 07:11:26PM +0000, Mark Brown wrote:
> On Mon, Jan 12, 2026 at 09:07:17PM +0200, Andy Shevchenko wrote:
> > On Mon, Jan 12, 2026 at 11:45:21AM -0600, David Lechner wrote:

...

> > > +	/* Multi-lane SPI controller support. */
> > > +	u32			tx_lane_map[SPI_DEVICE_DATA_LANE_CNT_MAX];
> > > +	u32			num_tx_lanes;
> > > +	u32			rx_lane_map[SPI_DEVICE_DATA_LANE_CNT_MAX];
> > > +	u32			num_rx_lanes;
> 
> > This adds 72 bytes in _each_ instance of spi_device on the platforms that do
> > not use the feature and might not ever use it. Can we move to the pointer
> > and allocate the mentioned fields separately, please?
> 
> Do we have real systems where we have enough SPI devices for anyone to
> care?

Define "enough" :-) To me even dozen of devices is enough (it gets almost a 1kB
of space) esp. if we are talking about quite low profile embedded systems.

-- 
With Best Regards,
Andy Shevchenko
Re: [PATCH v5 3/9] spi: support controllers with multiple data lanes
Posted by David Lechner 3 weeks, 2 days ago
On 1/12/26 1:35 PM, Andy Shevchenko wrote:
> On Mon, Jan 12, 2026 at 07:11:26PM +0000, Mark Brown wrote:
>> On Mon, Jan 12, 2026 at 09:07:17PM +0200, Andy Shevchenko wrote:
>>> On Mon, Jan 12, 2026 at 11:45:21AM -0600, David Lechner wrote:
> 
> ...
> 
>>>> +	/* Multi-lane SPI controller support. */
>>>> +	u32			tx_lane_map[SPI_DEVICE_DATA_LANE_CNT_MAX];
>>>> +	u32			num_tx_lanes;
>>>> +	u32			rx_lane_map[SPI_DEVICE_DATA_LANE_CNT_MAX];
>>>> +	u32			num_rx_lanes;
>>
>>> This adds 72 bytes in _each_ instance of spi_device on the platforms that do
>>> not use the feature and might not ever use it. Can we move to the pointer
>>> and allocate the mentioned fields separately, please?
>>
>> Do we have real systems where we have enough SPI devices for anyone to
>> care?
> 
> Define "enough" :-) To me even dozen of devices is enough (it gets almost a 1kB
> of space) esp. if we are talking about quite low profile embedded systems.
> 

We could make it u8 and save the same amount (on 64-bit systems) while avoiding
the extra complexity of separate allocation.

I'm not particularly keen on requiring `/bits/ 8` in the devicetree though since
it is unusual and often trips people up.
Re: [PATCH v5 3/9] spi: support controllers with multiple data lanes
Posted by Andy Shevchenko 3 weeks ago
On Fri, Jan 16, 2026 at 05:12:09PM -0600, David Lechner wrote:
> On 1/12/26 1:35 PM, Andy Shevchenko wrote:
> > On Mon, Jan 12, 2026 at 07:11:26PM +0000, Mark Brown wrote:
> >> On Mon, Jan 12, 2026 at 09:07:17PM +0200, Andy Shevchenko wrote:
> >>> On Mon, Jan 12, 2026 at 11:45:21AM -0600, David Lechner wrote:

...

> >>>> +	/* Multi-lane SPI controller support. */
> >>>> +	u32			tx_lane_map[SPI_DEVICE_DATA_LANE_CNT_MAX];
> >>>> +	u32			num_tx_lanes;
> >>>> +	u32			rx_lane_map[SPI_DEVICE_DATA_LANE_CNT_MAX];
> >>>> +	u32			num_rx_lanes;
> >>
> >>> This adds 72 bytes in _each_ instance of spi_device on the platforms that do
> >>> not use the feature and might not ever use it. Can we move to the pointer
> >>> and allocate the mentioned fields separately, please?
> >>
> >> Do we have real systems where we have enough SPI devices for anyone to
> >> care?
> > 
> > Define "enough" :-) To me even dozen of devices is enough (it gets almost a 1kB
> > of space) esp. if we are talking about quite low profile embedded systems.
> 
> We could make it u8 and save the same amount (on 64-bit systems) while avoiding
> the extra complexity of separate allocation.

Have you run `pahole` on this, btw? How big is it right now and do you fit
(aligned) with cache lines with this fields?

> I'm not particularly keen on requiring `/bits/ 8` in the devicetree though since
> it is unusual and often trips people up.

It can be transformed (to a smaller one) after reading
to a local (bigger) array.

-- 
With Best Regards,
Andy Shevchenko