Skip to contentSkip to conversation

dm: allow setting driver_data before/during bind

PATCH New Stephen Warren 3 participants 10 messages May 11, 2016 – May 23, 2016

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH v2 1/2 dm: allow setting driver_data before/during bind

From: Stephen Warren <[email protected]>

This will allow a driver's bind function to use the driver data. One example is the Tegra186 GPIO driver, which instantiates child devices for each of its GPIO ports, yet supports two different HW instances each with a different set of ports, and identified by the udevice_id .data field.

---
v2:
* Introduce a separate function for the new functionality, rather than modifying device_bind().

This patch is a dependency for the upcoming Tegra186 GPIO driver too.

---
 doc/driver-model/README.txt  | 23 ++++++++++++++---------
 drivers/core/device.c        | 25 ++++++++++++++++++++++---
 drivers/core/lists.c         |  4 ++--
 include/dm/device-internal.h | 24 ++++++++++++++++++++++++
 4 files changed, 62 insertions(+), 14 deletions(-)
doc/driver-model/README.txt +14 -9
index 7a24552560d5..1b5ccec4b2e5 100644
@@ -606,19 +606,24 @@ methods actually defined.
 
 1. Bind stage
 
-A device and its driver are bound using one of these two methods:
+U-Boot discovers devices using one of these two methods:
 
-   - Scan the U_BOOT_DEVICE() definitions. U-Boot It looks up the
-name specified by each, to find the appropriate driver. It then calls
-device_bind() to create a new device and bind' it to its driver. This will
-call the device's bind() method.
+   - Scan the U_BOOT_DEVICE() definitions. U-Boot looks up the name specified
+by each, to find the appropriate U_BOOT_DRIVER() definition. In this case,
+there is no path by which driver_data may be provided, but the U_BOOT_DEVICE()
+may provide platdata.
 
    - Scan through the device tree definitions. U-Boot looks at top-level
 nodes in the the device tree. It looks at the compatible string in each node
-and uses the of_match part of the U_BOOT_DRIVER() structure to find the
-right driver for each node. It then calls device_bind() to bind the
-newly-created device to its driver (thereby creating a device structure).
-This will also call the device's bind() method.
+and uses the of_match table of the U_BOOT_DRIVER() structure to find the
+right driver for each node. In this case, the of_match table may provide a
+driver_data value, but platdata cannot be provided until later.
+
+For each device that is discovered, U-Boot then calls device_bind() to create a
+new device, initializes various core fields of the device object such as name,
+uclass & driver, initializes any optional fields of the device object that are
+applicable such as of_offset, driver_data & platdata, and finally calls the
+driver's bind() method if one is defined.
 
 At this point all the devices are known, and bound to their drivers. There
 is a 'struct udevice' allocated for all devices. However, nothing has been
drivers/core/device.c +22 -3
index 2b12ce7835f0..a8f2380e4676 100644
@@ -26,9 +26,10 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-int device_bind(struct udevice *parent, const struct driver *drv,
-		const char *name, void *platdata, int of_offset,
-		struct udevice **devp)
+static int device_bind_common(struct udevice *parent, const struct driver *drv,
+			      const char *name, void *platdata,
+			      ulong driver_data, int of_offset,
+			      struct udevice **devp)
 {
 	struct udevice *dev;
 	struct uclass *uc;
@@ -56,6 +57,7 @@ int device_bind(struct udevice *parent, const struct driver *drv,
 	INIT_LIST_HEAD(&dev->devres_head);
 #endif
 	dev->platdata = platdata;
+	dev->driver_data = driver_data;
 	dev->name = name;
 	dev->of_offset = of_offset;
 	dev->parent = parent;
@@ -193,6 +195,23 @@ fail_alloc1:
 	return ret;
 }
 
+int device_bind_with_driver_data(struct udevice *parent,
+				 const struct driver *drv, const char *name,
+				 ulong driver_data, int of_offset,
+				 struct udevice **devp)
+{
+	return device_bind_common(parent, drv, name, NULL, driver_data,
+				  of_offset, devp);
+}
+
+int device_bind(struct udevice *parent, const struct driver *drv,
+		const char *name, void *platdata, int of_offset,
+		struct udevice **devp)
+{
+	return device_bind_common(parent, drv, name, platdata, 0, of_offset,
+				  devp);
+}
+
 int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
 			const struct driver_info *info, struct udevice **devp)
 {
drivers/core/lists.c +2 -2
index a72db13a119a..0c2771779096 100644
@@ -170,7 +170,8 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
 		}
 
 		dm_dbg("   - found match at '%s'\n", entry->name);
-		ret = device_bind(parent, entry, name, NULL, offset, &dev);
+		ret = device_bind_with_driver_data(parent, entry, name,
+						   id->data, offset, &dev);
 		if (ret == -ENODEV) {
 			dm_dbg("Driver '%s' refuses to bind\n", entry->name);
 			continue;
@@ -180,7 +181,6 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
 				ret);
 			return ret;
 		} else {
-			dev->driver_data = id->data;
 			found = true;
 			if (devp)
 				*devp = dev;
include/dm/device-internal.h +24 -0
index b348ad5231bd..0bf8707493a9 100644
@@ -39,6 +39,30 @@ int device_bind(struct udevice *parent, const struct driver *drv,
 		struct udevice **devp);
 
 /**
+ * device_bind_with_driver_data() - Create a device and bind it to a driver
+ *
+ * Called to set up a new device attached to a driver, in the case where the
+ * driver was matched to the device by means of a match table that provides
+ * driver_data.
+ *
+ * Once bound a device exists but is not yet active until device_probe() is
+ * called.
+ *
+ * @parent: Pointer to device's parent, under which this driver will exist
+ * @drv: Device's driver
+ * @name: Name of device (e.g. device tree node name)
+ * @driver_data: The driver_data field from the driver's match table.
+ * @of_offset: Offset of device tree node for this device. This is -1 for
+ * devices which don't use device tree.
+ * @devp: if non-NULL, returns a pointer to the bound device
+ * @return 0 if OK, -ve on error
+ */
+int device_bind_with_driver_data(struct udevice *parent,
+				 const struct driver *drv, const char *name,
+				 ulong driver_data, int of_offset,
+				 struct udevice **devp);
+
+/**
  * device_bind_by_name: Create a device and bind it to a driver
  *
  * This is a helper function used to bind devices which do not use device
Signature · 1 line
2.8.2
#1 lore raw

PATCH v2 2/2 sunxi: gpio: convert bind() to use driver data

From: Stephen Warren <[email protected]>

Now that the DM core sets driver_data before calling bind(), this driver can make use of driver_data to determine the set of child devices to create, rather than manually re-implementing the matching logic in code.

---
v2: New patch.

---
 drivers/gpio/sunxi_gpio.c | 90 ++++++++++++++++++++++++++---------------------
 1 file changed, 50 insertions(+), 40 deletions(-)
drivers/gpio/sunxi_gpio.c +50 -40
index a7cec18d57fb..94abbeb39adc 100644
@@ -258,43 +258,30 @@ static int gpio_sunxi_probe(struct udevice *dev)
 
 	return 0;
 }
+
+struct sunxi_gpio_soc_data {
+	int start;
+	int no_banks;
+};
+
 /**
  * We have a top-level GPIO device with no actual GPIOs. It has a child
  * device for each Sunxi bank.
  */
 static int gpio_sunxi_bind(struct udevice *parent)
 {
+	struct sunxi_gpio_soc_data *soc_data =
+		(struct sunxi_gpio_soc_data *)dev_get_driver_data(parent);
 	struct sunxi_gpio_platdata *plat = parent->platdata;
 	struct sunxi_gpio_reg *ctlr;
-	int bank, no_banks, ret, start;
+	int bank, ret;
 
 	/* If this is a child device, there is nothing to do here */
 	if (plat)
 		return 0;
 
-	if (fdt_node_check_compatible(gd->fdt_blob, parent->of_offset,
-				"allwinner,sun6i-a31-r-pinctrl") == 0) {
-		start = 'L' - 'A';
-		no_banks = 2; /* L & M */
-	} else if (fdt_node_check_compatible(gd->fdt_blob, parent->of_offset,
-				"allwinner,sun8i-a23-r-pinctrl") == 0 ||
-		   fdt_node_check_compatible(gd->fdt_blob, parent->of_offset,
-				"allwinner,sun8i-a83t-r-pinctrl") == 0 ||
-		   fdt_node_check_compatible(gd->fdt_blob, parent->of_offset,
-				"allwinner,sun8i-h3-r-pinctrl") == 0) {
-		start = 'L' - 'A';
-		no_banks = 1; /* L only */
-	} else if (fdt_node_check_compatible(gd->fdt_blob, parent->of_offset,
-				"allwinner,sun9i-a80-r-pinctrl") == 0) {
-		start = 'L' - 'A';
-		no_banks = 3; /* L, M & N */
-	} else {
-		start = 0;
-		no_banks = SUNXI_GPIO_BANKS;
-	}
-
 	ctlr = (struct sunxi_gpio_reg *)dev_get_addr(parent);
-	for (bank = 0; bank < no_banks; bank++) {
+	for (bank = 0; bank < soc_data->no_banks; bank++) {
 		struct sunxi_gpio_platdata *plat;
 		struct udevice *dev;
 
@@ -302,7 +289,7 @@ static int gpio_sunxi_bind(struct udevice *parent)
 		if (!plat)
 			return -ENOMEM;
 		plat->regs = &ctlr->gpio_bank[bank];
-		plat->bank_name = gpio_bank_name(start + bank);
+		plat->bank_name = gpio_bank_name(soc_data->start + bank);
 		plat->gpio_count = SUNXI_GPIOS_PER_BANK;
 
 		ret = device_bind(parent, parent->driver,
@@ -315,23 +302,46 @@ static int gpio_sunxi_bind(struct udevice *parent)
 	return 0;
 }
 
+static const struct sunxi_gpio_soc_data soc_data_a_all = {
+	.start = 0,
+	.no_banks = SUNXI_GPIO_BANKS,
+};
+
+static const struct sunxi_gpio_soc_data soc_data_l_1 = {
+	.start = 'L' - 'A',
+	.no_banks = 1,
+};
+
+static const struct sunxi_gpio_soc_data soc_data_l_2 = {
+	.start = 'L' - 'A',
+	.no_banks = 2,
+};
+
+static const struct sunxi_gpio_soc_data soc_data_l_3 = {
+	.start = 'L' - 'A',
+	.no_banks = 3,
+};
+
+#define ID(_compat_, _soc_data_) \
+	{ .compatible = _compat_, .data = (ulong)&soc_data_##_soc_data_ }
+
 static const struct udevice_id sunxi_gpio_ids[] = {
-	{ .compatible = "allwinner,sun4i-a10-pinctrl" },
-	{ .compatible = "allwinner,sun5i-a10s-pinctrl" },
-	{ .compatible = "allwinner,sun5i-a13-pinctrl" },
-	{ .compatible = "allwinner,sun6i-a31-pinctrl" },
-	{ .compatible = "allwinner,sun6i-a31s-pinctrl" },
-	{ .compatible = "allwinner,sun7i-a20-pinctrl" },
-	{ .compatible = "allwinner,sun8i-a23-pinctrl" },
-	{ .compatible = "allwinner,sun8i-a33-pinctrl" },
-	{ .compatible = "allwinner,sun8i-a83t-pinctrl", },
-	{ .compatible = "allwinner,sun8i-h3-pinctrl" },
-	{ .compatible = "allwinner,sun9i-a80-pinctrl" },
-	{ .compatible = "allwinner,sun6i-a31-r-pinctrl" },
-	{ .compatible = "allwinner,sun8i-a23-r-pinctrl" },
-	{ .compatible = "allwinner,sun8i-a83t-r-pinctrl" },
-	{ .compatible = "allwinner,sun8i-h3-r-pinctrl", },
-	{ .compatible = "allwinner,sun9i-a80-r-pinctrl", },
+	ID("allwinner,sun4i-a10-pinctrl",	a_all),
+	ID("allwinner,sun5i-a10s-pinctrl",	a_all),
+	ID("allwinner,sun5i-a13-pinctrl",	a_all),
+	ID("allwinner,sun6i-a31-pinctrl",	a_all),
+	ID("allwinner,sun6i-a31s-pinctrl",	a_all),
+	ID("allwinner,sun7i-a20-pinctrl",	a_all),
+	ID("allwinner,sun8i-a23-pinctrl",	a_all),
+	ID("allwinner,sun8i-a33-pinctrl",	a_all),
+	ID("allwinner,sun8i-a83t-pinctrl",	a_all),
+	ID("allwinner,sun8i-h3-pinctrl",	a_all),
+	ID("allwinner,sun9i-a80-pinctrl",	a_all),
+	ID("allwinner,sun6i-a31-r-pinctrl",	l_2),
+	ID("allwinner,sun8i-a23-r-pinctrl",	l_1),
+	ID("allwinner,sun8i-a83t-r-pinctrl",	l_1),
+	ID("allwinner,sun8i-h3-r-pinctrl",	l_1),
+	ID("allwinner,sun9i-a80-r-pinctrl",	l_3),
 	{ }
 };
 
Signature · 1 line
2.8.2
#2 lore raw

PATCH v2 2/2 sunxi: gpio: convert bind() to use driver data

Hi Stephen,

Quoted 6 lines · Stephen Warren

From: Stephen Warren <[email protected]>

Now that the DM core sets driver_data before calling bind(), this driver can make use of driver_data to determine the set of child devices to create, rather than manually re-implementing the matching logic in code.

Quoted 7 lines

---
v2: New patch.

---
 drivers/gpio/sunxi_gpio.c | 90 ++++++++++++++++++++++++++---------------------
 1 file changed, 50 insertions(+), 40 deletions(-)

Comment below.

Quoted 118 lines
drivers/gpio/sunxi_gpio.c +40 -40
index a7cec18d57fb..94abbeb39adc 100644
@@ -258,43 +258,30 @@ static int gpio_sunxi_probe(struct udevice *dev)
 
        return 0;
 }
+
+struct sunxi_gpio_soc_data {
+       int start;
+       int no_banks;
+};
+
 /**
  * We have a top-level GPIO device with no actual GPIOs. It has a child
  * device for each Sunxi bank.
  */
 static int gpio_sunxi_bind(struct udevice *parent)
 {
+       struct sunxi_gpio_soc_data *soc_data =
+               (struct sunxi_gpio_soc_data *)dev_get_driver_data(parent);
        struct sunxi_gpio_platdata *plat = parent->platdata;
        struct sunxi_gpio_reg *ctlr;
-       int bank, no_banks, ret, start;
+       int bank, ret;
 
        /* If this is a child device, there is nothing to do here */
        if (plat)
                return 0;
 
-       if (fdt_node_check_compatible(gd->fdt_blob, parent->of_offset,
-                               "allwinner,sun6i-a31-r-pinctrl") == 0) {
-               start = 'L' - 'A';
-               no_banks = 2; /* L & M */
-       } else if (fdt_node_check_compatible(gd->fdt_blob, parent->of_offset,
-                               "allwinner,sun8i-a23-r-pinctrl") == 0 ||
-                  fdt_node_check_compatible(gd->fdt_blob, parent->of_offset,
-                               "allwinner,sun8i-a83t-r-pinctrl") == 0 ||
-                  fdt_node_check_compatible(gd->fdt_blob, parent->of_offset,
-                               "allwinner,sun8i-h3-r-pinctrl") == 0) {
-               start = 'L' - 'A';
-               no_banks = 1; /* L only */
-       } else if (fdt_node_check_compatible(gd->fdt_blob, parent->of_offset,
-                               "allwinner,sun9i-a80-r-pinctrl") == 0) {
-               start = 'L' - 'A';
-               no_banks = 3; /* L, M & N */
-       } else {
-               start = 0;
-               no_banks = SUNXI_GPIO_BANKS;
-       }
-
        ctlr = (struct sunxi_gpio_reg *)dev_get_addr(parent);
-       for (bank = 0; bank < no_banks; bank++) {
+       for (bank = 0; bank < soc_data->no_banks; bank++) {
                struct sunxi_gpio_platdata *plat;
                struct udevice *dev;
 
@@ -302,7 +289,7 @@ static int gpio_sunxi_bind(struct udevice *parent)
                if (!plat)
                        return -ENOMEM;
                plat->regs = &ctlr->gpio_bank[bank];
-               plat->bank_name = gpio_bank_name(start + bank);
+               plat->bank_name = gpio_bank_name(soc_data->start + bank);
                plat->gpio_count = SUNXI_GPIOS_PER_BANK;
 
                ret = device_bind(parent, parent->driver,
@@ -315,23 +302,46 @@ static int gpio_sunxi_bind(struct udevice *parent)
        return 0;
 }
 
+static const struct sunxi_gpio_soc_data soc_data_a_all = {
+       .start = 0,
+       .no_banks = SUNXI_GPIO_BANKS,
+};
+
+static const struct sunxi_gpio_soc_data soc_data_l_1 = {
+       .start = 'L' - 'A',
+       .no_banks = 1,
+};
+
+static const struct sunxi_gpio_soc_data soc_data_l_2 = {
+       .start = 'L' - 'A',
+       .no_banks = 2,
+};
+
+static const struct sunxi_gpio_soc_data soc_data_l_3 = {
+       .start = 'L' - 'A',
+       .no_banks = 3,
+};
+
+#define ID(_compat_, _soc_data_) \
+       { .compatible = _compat_, .data = (ulong)&soc_data_##_soc_data_ }
+
 static const struct udevice_id sunxi_gpio_ids[] = {
-       { .compatible = "allwinner,sun4i-a10-pinctrl" },
-       { .compatible = "allwinner,sun5i-a10s-pinctrl" },
-       { .compatible = "allwinner,sun5i-a13-pinctrl" },
-       { .compatible = "allwinner,sun6i-a31-pinctrl" },
-       { .compatible = "allwinner,sun6i-a31s-pinctrl" },
-       { .compatible = "allwinner,sun7i-a20-pinctrl" },
-       { .compatible = "allwinner,sun8i-a23-pinctrl" },
-       { .compatible = "allwinner,sun8i-a33-pinctrl" },
-       { .compatible = "allwinner,sun8i-a83t-pinctrl", },
-       { .compatible = "allwinner,sun8i-h3-pinctrl" },
-       { .compatible = "allwinner,sun9i-a80-pinctrl" },
-       { .compatible = "allwinner,sun6i-a31-r-pinctrl" },
-       { .compatible = "allwinner,sun8i-a23-r-pinctrl" },
-       { .compatible = "allwinner,sun8i-a83t-r-pinctrl" },
-       { .compatible = "allwinner,sun8i-h3-r-pinctrl", },
-       { .compatible = "allwinner,sun9i-a80-r-pinctrl", },
+       ID("allwinner,sun4i-a10-pinctrl",       a_all),
+       ID("allwinner,sun5i-a10s-pinctrl",      a_all),
+       ID("allwinner,sun5i-a13-pinctrl",       a_all),
+       ID("allwinner,sun6i-a31-pinctrl",       a_all),
+       ID("allwinner,sun6i-a31s-pinctrl",      a_all),
+       ID("allwinner,sun7i-a20-pinctrl",       a_all),

drivers/gpio/sunxi_gpio.c static int gpio_sunxi_bind(struct udevice *parent) · line 344

Quoted 10 lines
drivers/gpio/sunxi_gpio.c +10 -0
+       ID("allwinner,sun8i-a23-pinctrl",       a_all),
+       ID("allwinner,sun8i-a33-pinctrl",       a_all),
+       ID("allwinner,sun8i-a83t-pinctrl",      a_all),
+       ID("allwinner,sun8i-h3-pinctrl",        a_all),
+       ID("allwinner,sun9i-a80-pinctrl",       a_all),
+       ID("allwinner,sun6i-a31-r-pinctrl",     l_2),
+       ID("allwinner,sun8i-a23-r-pinctrl",     l_1),
+       ID("allwinner,sun8i-a83t-r-pinctrl",    l_1),
+       ID("allwinner,sun8i-h3-r-pinctrl",      l_1),
+       ID("allwinner,sun9i-a80-r-pinctrl",     l_3),

I don't think the #define adds a lot of value - consider removing it an writing things out in full?

Quoted 6 lines
drivers/gpio/sunxi_gpio.c +0 -1
        { }
 };
 
--

2.8.2

Regards,
Simon

#3 lore raw

PATCH v2 2/2 sunxi: gpio: convert bind() to use driver data

Quoted 18 lines · Simon Glass

Hi Stephen,

Quoted 15 lines · Stephen Warren

From: Stephen Warren <[email protected]>

Now that the DM core sets driver_data before calling bind(), this driver can make use of driver_data to determine the set of child devices to create, rather than manually re-implementing the matching logic in code.

drivers/gpio/sunxi_gpio.c +3 -3
 
+#define ID(_compat_, _soc_data_) \
+       { .compatible = _compat_, .data = (ulong)&soc_data_##_soc_data_ }
+
  static const struct udevice_id sunxi_gpio_ids[] = {
-       { .compatible = "allwinner,sun4i-a10-pinctrl" },
-       { .compatible = "allwinner,sun5i-a10s-pinctrl" },
-       { .compatible = "allwinner,sun5i-a13-pinctrl" },

...

Quoted 5 lines

drivers/gpio/sunxi_gpio.c static int gpio_sunxi_bind(struct udevice *parent) · line 330

Quoted 2 lines
drivers/gpio/sunxi_gpio.c +2 -0
+       ID("allwinner,sun4i-a10-pinctrl",       a_all),
+       ID("allwinner,sun5i-a10s-pinctrl",      a_all),

I don't think the #define adds a lot of value - consider removing it an writing things out in full?

I originally did that, but you either end up with lines over 80 columns which checkpatch complains about, or multiple lines per entry which makes it harder to read for such a large table. Still, I can convert it if you want.

#4 lore raw

PATCH v2 2/2 sunxi: gpio: convert bind() to use driver data

Hi Stephen,

Quoted 30 lines · Stephen Warren
Quoted 22 lines · Simon Glass

Hi Stephen,

Quoted 18 lines · Stephen Warren

From: Stephen Warren <[email protected]>

Now that the DM core sets driver_data before calling bind(), this driver can make use of driver_data to determine the set of child devices to create, rather than manually re-implementing the matching logic in code.

drivers/gpio/sunxi_gpio.c +3 -3
 
 
+#define ID(_compat_, _soc_data_) \
+       { .compatible = _compat_, .data = (ulong)&soc_data_##_soc_data_ }
+
  static const struct udevice_id sunxi_gpio_ids[] = {
-       { .compatible = "allwinner,sun4i-a10-pinctrl" },
-       { .compatible = "allwinner,sun5i-a10s-pinctrl" },
-       { .compatible = "allwinner,sun5i-a13-pinctrl" },

...

Quoted 5 lines
Quoted 3 lines
drivers/gpio/sunxi_gpio.c +2 -0
+       ID("allwinner,sun4i-a10-pinctrl",       a_all),
+       ID("allwinner,sun5i-a10s-pinctrl",      a_all),
Quoted 7 lines
Quoted 2 lines

I don't think the #define adds a lot of value - consider removing it an writing things out in full?

I originally did that, but you either end up with lines over 80 columns which checkpatch complains about, or multiple lines per entry which makes it harder to read for such a large table. Still, I can convert it if you want.

I don't mind. See what Hans thinks.

Regards,
Simon

#5 lore raw

PATCH v2 2/2 sunxi: gpio: convert bind() to use driver data

In reply to Stephen Warren

Hi,

Quoted 20 lines · Stephen Warren
Quoted 18 lines · Simon Glass

Hi Stephen,

Quoted 15 lines · Stephen Warren

From: Stephen Warren <[email protected]>

Now that the DM core sets driver_data before calling bind(), this driver can make use of driver_data to determine the set of child devices to create, rather than manually re-implementing the matching logic in code.

drivers/gpio/sunxi_gpio.c +3 -3
 
+#define ID(_compat_, _soc_data_) \
+       { .compatible = _compat_, .data = (ulong)&soc_data_##_soc_data_ }
+
  static const struct udevice_id sunxi_gpio_ids[] = {
-       { .compatible = "allwinner,sun4i-a10-pinctrl" },
-       { .compatible = "allwinner,sun5i-a10s-pinctrl" },
-       { .compatible = "allwinner,sun5i-a13-pinctrl" },

...

Quoted 7 lines
Quoted 5 lines

drivers/gpio/sunxi_gpio.c static int gpio_sunxi_bind(struct udevice *parent) · line 330

Quoted 2 lines
drivers/gpio/sunxi_gpio.c +2 -0
+       ID("allwinner,sun4i-a10-pinctrl",       a_all),
+       ID("allwinner,sun5i-a10s-pinctrl",      a_all),

I don't think the #define adds a lot of value - consider removing it an writing things out in full?

I originally did that, but you either end up with lines over 80 columns which checkpatch complains about, or multiple lines per entry which makes it harder to read for such a large table. Still, I can convert it if you want.

I'm fine with keeping the ID define:

Simon, I assume that you will upstream this one through your tree ?

Regards,

Hans

#6 lore raw

PATCH v2 2/2 sunxi: gpio: convert bind() to use driver data

Hi Hans,

Quoted 45 lines · Hans de Goede

Hi,

Quoted 32 lines · Stephen Warren
Quoted 23 lines · Simon Glass

Hi Stephen,

Quoted 19 lines · Stephen Warren

From: Stephen Warren <[email protected]>

Now that the DM core sets driver_data before calling bind(), this driver can make use of driver_data to determine the set of child devices to create, rather than manually re-implementing the matching logic in code.

drivers/gpio/sunxi_gpio.c +2 -0
 
 
+#define ID(_compat_, _soc_data_) \
+       { .compatible = _compat_, .data = (ulong)&soc_data_##_soc_data_

}

drivers/gpio/sunxi_gpio.c +1 -3
+
  static const struct udevice_id sunxi_gpio_ids[] = {
-       { .compatible = "allwinner,sun4i-a10-pinctrl" },
-       { .compatible = "allwinner,sun5i-a10s-pinctrl" },
-       { .compatible = "allwinner,sun5i-a13-pinctrl" },

...

Quoted 5 lines
Quoted 3 lines
drivers/gpio/sunxi_gpio.c +2 -0
+       ID("allwinner,sun4i-a10-pinctrl",       a_all),
+       ID("allwinner,sun5i-a10s-pinctrl",      a_all),
Quoted 7 lines
Quoted 2 lines

I don't think the #define adds a lot of value - consider removing it an writing things out in full?

I originally did that, but you either end up with lines over 80 columns which checkpatch complains about, or multiple lines per entry which makes it harder to read for such a large table. Still, I can convert it if you want.

Quoted 6 lines

I'm fine with keeping the ID define:

Simon, I assume that you will upstream this one through your tree ?

Yes, thanks.

Regards,
Simon

#7 lore raw

PATCH v2 2/2 sunxi: gpio: convert bind() to use driver data

Quoted 52 lines · Simon Glass

Hi Hans,

Quoted 49 lines · Hans de Goede

Hi,

Quoted 32 lines · Stephen Warren
Quoted 23 lines · Simon Glass

Hi Stephen,

Quoted 19 lines · Stephen Warren

From: Stephen Warren <[email protected]>

Now that the DM core sets driver_data before calling bind(), this driver can make use of driver_data to determine the set of child devices to create, rather than manually re-implementing the matching logic in code.

drivers/gpio/sunxi_gpio.c +2 -0
 
 
+#define ID(_compat_, _soc_data_) \
+       { .compatible = _compat_, .data = (ulong)&soc_data_##_soc_data_

}

drivers/gpio/sunxi_gpio.c +1 -3
+
  static const struct udevice_id sunxi_gpio_ids[] = {
-       { .compatible = "allwinner,sun4i-a10-pinctrl" },
-       { .compatible = "allwinner,sun5i-a10s-pinctrl" },
-       { .compatible = "allwinner,sun5i-a13-pinctrl" },

...

Quoted 5 lines
Quoted 3 lines
drivers/gpio/sunxi_gpio.c +2 -0
+       ID("allwinner,sun4i-a10-pinctrl",       a_all),
+       ID("allwinner,sun5i-a10s-pinctrl",      a_all),
Quoted 7 lines
Quoted 2 lines

I don't think the #define adds a lot of value - consider removing it an writing things out in full?

I originally did that, but you either end up with lines over 80 columns which checkpatch complains about, or multiple lines per entry which makes it harder to read for such a large table. Still, I can convert it if you want.

I'm fine with keeping the ID define:

Quoted 7 lines
Quoted 2 lines

Simon, I assume that you will upstream this one through your tree ?

Yes, thanks.

Regards,
Simon

Applied to u-boot-dm, thanks!

#8 lore raw

PATCH v2 1/2 dm: allow setting driver_data before/during bind

In reply to Stephen Warren
Quoted 14 lines · Stephen Warren

From: Stephen Warren <[email protected]>

This will allow a driver's bind function to use the driver data. One example is the Tegra186 GPIO driver, which instantiates child devices for each of its GPIO ports, yet supports two different HW instances each with a different set of ports, and identified by the udevice_id .data field.

---
v2:
* Introduce a separate function for the new functionality, rather than modifying device_bind().

Quoted 7 lines

This patch is a dependency for the upcoming Tegra186 GPIO driver too.

---
 doc/driver-model/README.txt  | 23 ++++++++++++++---------
 drivers/core/device.c        | 25 ++++++++++++++++++++++---
 drivers/core/lists.c         |  4 ++--
 include/dm/device-internal.h | 24 ++++++++++++++++++++++++
 4 files changed, 62 insertions(+), 14 deletions(-)

Thanks.

#9 lore raw

PATCH v2 1/2 dm: allow setting driver_data before/during bind

Quoted 23 lines · Simon Glass
Quoted 14 lines · Stephen Warren

From: Stephen Warren <[email protected]>

This will allow a driver's bind function to use the driver data. One example is the Tegra186 GPIO driver, which instantiates child devices for each of its GPIO ports, yet supports two different HW instances each with a different set of ports, and identified by the udevice_id .data field.

---
v2:
* Introduce a separate function for the new functionality, rather than modifying device_bind().

Quoted 7 lines

This patch is a dependency for the upcoming Tegra186 GPIO driver too.

---
 doc/driver-model/README.txt  | 23 ++++++++++++++---------
 drivers/core/device.c        | 25 ++++++++++++++++++++++---
 drivers/core/lists.c         |  4 ++--
 include/dm/device-internal.h | 24 ++++++++++++++++++++++++
 4 files changed, 62 insertions(+), 14 deletions(-)
Quoted 3 lines

Thanks.

Applied to u-boot-dm, thanks!