Skip to contentSkip to conversation

spi: allow attaching device properties to SPI board info

PATCH Superseded Dmitry Torokhov 1 participant 4 messages Feb 28, 2017 SPI

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/3 spi: allow attaching device properties to SPI board info

Generic device properties support statically defined property sets. For them to be usable, we need to attach these property sets before devices are registered and probed. Allowing to attach property list to spi_board_info structure will allow non-ACPI non-DT boards switch to using generic properties and get rid of custom platform data.

---
 drivers/spi/spi.c       | 27 +++++++++++++++++++++++----
 include/linux/spi/spi.h |  4 ++++
 2 files changed, 27 insertions(+), 4 deletions(-)
drivers/spi/spi.c +23 -4
index 656dd3e3220c..b948d8cdbace 100644
@@ -31,6 +31,7 @@
 #include <linux/of_gpio.h>
 #include <linux/pm_runtime.h>
 #include <linux/pm_domain.h>
+#include <linux/property.h>
 #include <linux/export.h>
 #include <linux/sched/rt.h>
 #include <linux/delay.h>
@@ -599,13 +600,25 @@ struct spi_device *spi_new_device(struct spi_master *master,
 	proxy->controller_data = chip->controller_data;
 	proxy->controller_state = NULL;
 
-	status = spi_add_device(proxy);
-	if (status < 0) {
-		spi_dev_put(proxy);
-		return NULL;
+	if (chip->properties) {
+		status = device_add_properties(&proxy->dev, chip->properties);
+		if (status) {
+			dev_err(&master->dev,
+				"failed to add properties to '%s': %d\n",
+				chip->modalias, status);
+			goto err_out;
+		}
 	}
 
+	status = spi_add_device(proxy);
+	if (status < 0)
+		goto err_out;
+
 	return proxy;
+
+err_out:
+	spi_dev_put(proxy);
+	return NULL;
 }
 EXPORT_SYMBOL_GPL(spi_new_device);
 
@@ -661,6 +674,7 @@ static void spi_match_master_to_boardinfo(struct spi_master *master,
  *
  * The board info passed can safely be __initdata ... but be careful of
  * any embedded pointers (platform_data, etc), they're copied as-is.
+ * Device properties are deep-copied though.
  *
  * Return: zero on success, else a negative error code.
  */
@@ -680,6 +694,11 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n)
 		struct spi_master *master;
 
 		memcpy(&bi->board_info, info, sizeof(*info));
+		bi->board_info.properties =
+			property_entries_dup(info->properties);
+		if (IS_ERR(bi->board_info.properties))
+			return PTR_ERR(bi->board_info.properties);
+
 		mutex_lock(&board_lock);
 		list_add_tail(&bi->list, &board_list);
 		list_for_each_entry(master, &spi_master_list, list)
include/linux/spi/spi.h +4 -0
index 75c6bd0ac605..5a8c4b24f2dc 100644
@@ -23,6 +23,7 @@
 #include <linux/scatterlist.h>
 
 struct dma_chan;
+struct property_entry;
 struct spi_master;
 struct spi_transfer;
 struct spi_flash_read_message;
@@ -1209,6 +1210,7 @@ int spi_flash_read(struct spi_device *spi,
  * @modalias: Initializes spi_device.modalias; identifies the driver.
  * @platform_data: Initializes spi_device.platform_data; the particular
  *	data stored there is driver-specific.
+ * @properties: Additional device properties for the device.
  * @controller_data: Initializes spi_device.controller_data; some
  *	controllers need hints about hardware setup, e.g. for DMA.
  * @irq: Initializes spi_device.irq; depends on how the board is wired.
@@ -1241,10 +1243,12 @@ struct spi_board_info {
 	 *
 	 * platform_data goes to spi_device.dev.platform_data,
 	 * controller_data goes to spi_device.controller_data,
+	 * device properties are copied and attached to spi_device,
 	 * irq is copied too
 	 */
 	char		modalias[SPI_NAME_SIZE];
 	const void	*platform_data;
+	const struct property_entry *properties;
 	void		*controller_data;
 	int		irq;
 
Signature · 6 lines
2.11.0.483.g087da7b7c-goog

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#1 lore raw

PATCH 2/3 spi: allocate spi_board_info entries one by one

Lists of spi_board_info entries registered with spi_register_board_info() can be quite long; instead of forcing memory allocator find contagious chunk of memory, let;s allocate them one-by-one, so they can be packed as needed.

---
 drivers/spi/spi.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/spi/spi.c +5 -6
index b948d8cdbace..029864410a5f 100644
@@ -686,14 +686,13 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n)
 	if (!n)
 		return -EINVAL;
 
-	bi = kzalloc(n * sizeof(*bi), GFP_KERNEL);
-	if (!bi)
-		return -ENOMEM;
-
-	for (i = 0; i < n; i++, bi++, info++) {
+	for (i = 0; i < n; i++, info++) {
 		struct spi_master *master;
 
-		memcpy(&bi->board_info, info, sizeof(*info));
+		bi = kmemdup(info, sizeof(*bi), GFP_KERNEL);
+		if (!bi)
+			return -ENOMEM;
+
 		bi->board_info.properties =
 			property_entries_dup(info->properties);
 		if (IS_ERR(bi->board_info.properties))
Signature · 1 line
2.11.0.483.g087da7b7c-goog
#2 lore raw

Re: [PATCH 2/3] spi: allocate spi_board_info entries one by one

Quoted 18 lines · Dmitry Torokhov

Lists of spi_board_info entries registered with spi_register_board_info() can be quite long; instead of forcing memory allocator find contagious chunk of memory, let;s allocate them one-by-one, so they can be packed as needed.

---
 drivers/spi/spi.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/spi/spi.c +0 -0
index b948d8cdbace..029864410a5f 100644
@@ -686,14 +686,13 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n)
 	if (!n)
 		return -EINVAL;
 

drivers/spi/spi.c int spi_register_board_info(struct spi_board_info const *info, unsigned n) · line 692

Quoted 10 lines
drivers/spi/spi.c +2 -6
-	bi = kzalloc(n * sizeof(*bi), GFP_KERNEL);
-	if (!bi)
-		return -ENOMEM;
-
-	for (i = 0; i < n; i++, bi++, info++) {
+	for (i = 0; i < n; i++, info++) {
 		struct spi_master *master;
 
-		memcpy(&bi->board_info, info, sizeof(*info));
+		bi = kmemdup(info, sizeof(*bi), GFP_KERNEL);

Meh, should not have changed to kmemdup at the 11th hour: different types. I'll send v2 in a minute.

Quoted 9 lines
drivers/spi/spi.c +3 -0
+		if (!bi)
+			return -ENOMEM;
+
 		bi->board_info.properties =
 			property_entries_dup(info->properties);
 		if (IS_ERR(bi->board_info.properties))
Signature · 1 line
2.11.0.483.g087da7b7c-goog
Signature · 5 lines
Dmitry
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#3 lore raw

PATCH 3/3 spi: allow registering empty spi_board_info lists

In reply to Dmitry Torokhov

Many boards form list of spi_board_info entries depending on config, and it is possible to end up with empty list. Do not report error in such cases.

---
 drivers/spi/spi.c | 3 ---
 1 file changed, 3 deletions(-)
drivers/spi/spi.c +0 -3
index 029864410a5f..ca6cee37a445 100644
@@ -683,9 +683,6 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n)
 	struct boardinfo *bi;
 	int i;
 
-	if (!n)
-		return -EINVAL;
-
 	for (i = 0; i < n; i++, info++) {
 		struct spi_master *master;
 
Signature · 6 lines
2.11.0.483.g087da7b7c-goog

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html