[U-Boot] [PATCH] dm: allow setting driver_data before/during bind

Stephen Warren swarren at wwwdotorg.org
Fri Apr 29 01:08:42 CEST 2016


From: Stephen Warren <swarren at nvidia.com>

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.

Signed-off-by: Stephen Warren <swarren at nvidia.com>
---
 drivers/core/device.c            | 7 ++++---
 drivers/core/lists.c             | 6 +++---
 drivers/gpio/dwapb_gpio.c        | 2 +-
 drivers/gpio/s5p_gpio.c          | 2 +-
 drivers/gpio/sunxi_gpio.c        | 2 +-
 drivers/gpio/tegra_gpio.c        | 2 +-
 drivers/mtd/spi/sandbox.c        | 2 +-
 drivers/net/mvpp2.c              | 3 ++-
 drivers/pci/pci-uclass.c         | 5 ++---
 drivers/power/pmic/pmic-uclass.c | 2 +-
 drivers/usb/host/usb-uclass.c    | 5 ++---
 include/dm/device-internal.h     | 5 +++--
 12 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index 74688dc95075..dc66e2400de6 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -27,8 +27,8 @@
 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)
+		const char *name, void *platdata, ulong driver_data,
+		int of_offset, struct udevice **devp)
 {
 	struct udevice *dev, *dev2;
 	struct uclass *uc;
@@ -56,6 +56,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;
@@ -227,7 +228,7 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
 		return -EPERM;
 
 	return device_bind(parent, drv, info->name, (void *)info->platdata,
-			   -1, devp);
+			   0, -1, devp);
 }
 
 static void *alloc_priv(int size, uint flags)
diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index a72db13a119a..ac5a788e7e2b 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -89,7 +89,7 @@ int device_bind_driver_to_node(struct udevice *parent, const char *drv_name,
 		debug("Cannot find driver '%s'\n", drv_name);
 		return -ENOENT;
 	}
-	ret = device_bind(parent, drv, dev_name, NULL, node, devp);
+	ret = device_bind(parent, drv, dev_name, NULL, 0, node, devp);
 	if (ret) {
 		debug("Cannot create device named '%s' (err=%d)\n",
 		      dev_name, ret);
@@ -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(parent, entry, name, NULL, 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;
diff --git a/drivers/gpio/dwapb_gpio.c b/drivers/gpio/dwapb_gpio.c
index 72cec4880095..dcbf4c7b0877 100644
--- a/drivers/gpio/dwapb_gpio.c
+++ b/drivers/gpio/dwapb_gpio.c
@@ -137,7 +137,7 @@ static int gpio_dwapb_bind(struct udevice *dev)
 			goto err;
 
 		ret = device_bind(dev, dev->driver, plat->name,
-				  plat, -1, &subdev);
+				  plat, 0, -1, &subdev);
 		if (ret)
 			goto err;
 
diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c
index 0f22b238ba99..d4e1822c3646 100644
--- a/drivers/gpio/s5p_gpio.c
+++ b/drivers/gpio/s5p_gpio.c
@@ -344,7 +344,7 @@ static int gpio_exynos_bind(struct udevice *parent)
 
 		plat->bank_name = fdt_get_name(blob, node, NULL);
 		ret = device_bind(parent, parent->driver,
-				  plat->bank_name, plat, -1, &dev);
+				  plat->bank_name, plat, 0, -1, &dev);
 		if (ret)
 			return ret;
 
diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
index a7cec18d57fb..715239dae38e 100644
--- a/drivers/gpio/sunxi_gpio.c
+++ b/drivers/gpio/sunxi_gpio.c
@@ -306,7 +306,7 @@ static int gpio_sunxi_bind(struct udevice *parent)
 		plat->gpio_count = SUNXI_GPIOS_PER_BANK;
 
 		ret = device_bind(parent, parent->driver,
-					plat->bank_name, plat, -1, &dev);
+					plat->bank_name, plat, 0, -1, &dev);
 		if (ret)
 			return ret;
 		dev->of_offset = parent->of_offset;
diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c
index 5a031159ca37..1949029d8978 100644
--- a/drivers/gpio/tegra_gpio.c
+++ b/drivers/gpio/tegra_gpio.c
@@ -360,7 +360,7 @@ static int gpio_tegra_bind(struct udevice *parent)
 			plat->port_name = gpio_port_name(base_port);
 
 			ret = device_bind(parent, parent->driver,
-					  plat->port_name, plat, -1, &dev);
+					  plat->port_name, plat, 0, -1, &dev);
 			if (ret)
 				return ret;
 			dev->of_offset = parent->of_offset;
diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c
index 53470b90ce87..4244b8b8e6e7 100644
--- a/drivers/mtd/spi/sandbox.c
+++ b/drivers/mtd/spi/sandbox.c
@@ -581,7 +581,7 @@ int sandbox_sf_bind_emul(struct sandbox_state *state, int busnum, int cs,
 		puts("Cannot find sandbox_sf_emul driver\n");
 		return -ENOENT;
 	}
-	ret = device_bind(bus, drv, str, NULL, of_offset, &emul);
+	ret = device_bind(bus, drv, str, NULL, 0, of_offset, &emul);
 	if (ret) {
 		printf("Cannot create emul device for spec '%s' (err=%d)\n",
 		       spec, ret);
diff --git a/drivers/net/mvpp2.c b/drivers/net/mvpp2.c
index 900a04c0eeeb..5ca5ee10f50c 100644
--- a/drivers/net/mvpp2.c
+++ b/drivers/net/mvpp2.c
@@ -4168,7 +4168,8 @@ static int mvpp2_base_bind(struct udevice *parent)
 		sprintf(name, "mvpp2-%d", id);
 
 		/* Create child device UCLASS_ETH and bind it */
-		device_bind(parent, &mvpp2_driver, name, plat, subnode, &dev);
+		device_bind(parent, &mvpp2_driver, name, plat, 0, subnode,
+			    &dev);
 		dev->of_offset = subnode;
 	}
 
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index 32590ce498a7..6b9d56b3de25 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -629,12 +629,11 @@ static int pci_find_and_bind_driver(struct udevice *parent,
 			 * find another driver. For now this doesn't seem
 			 * necesssary, so just bind the first match.
 			 */
-			ret = device_bind(parent, drv, drv->name, NULL, -1,
-					  &dev);
+			ret = device_bind(parent, drv, drv->name, NULL,
+					  find_id->driver_data, -1, &dev);
 			if (ret)
 				goto error;
 			debug("%s: Match found: %s\n", __func__, drv->name);
-			dev->driver_data = find_id->driver_data;
 			*devp = dev;
 			return 0;
 		}
diff --git a/drivers/power/pmic/pmic-uclass.c b/drivers/power/pmic/pmic-uclass.c
index 7211026aecbe..d85c62a2dc0e 100644
--- a/drivers/power/pmic/pmic-uclass.c
+++ b/drivers/power/pmic/pmic-uclass.c
@@ -60,7 +60,7 @@ int pmic_bind_children(struct udevice *pmic, int offset,
 
 			debug("  - found child driver: '%s'\n", drv->name);
 
-			ret = device_bind(pmic, drv, node_name, NULL,
+			ret = device_bind(pmic, drv, node_name, NULL, 0,
 					  node, &child);
 			if (ret) {
 				debug("  - child binding error: %d\n", ret);
diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
index 69c9a504ebb8..bb88ef0e6b14 100644
--- a/drivers/usb/host/usb-uclass.c
+++ b/drivers/usb/host/usb-uclass.c
@@ -501,12 +501,11 @@ static int usb_find_and_bind_driver(struct udevice *parent,
 			 * find another driver. For now this doesn't seem
 			 * necesssary, so just bind the first match.
 			 */
-			ret = device_bind(parent, drv, drv->name, NULL, -1,
-					  &dev);
+			ret = device_bind(parent, drv, drv->name, NULL,
+					  id->driver_info, -1, &dev);
 			if (ret)
 				goto error;
 			debug("%s: Match found: %s\n", __func__, drv->name);
-			dev->driver_data = id->driver_info;
 			plat = dev_get_parent_platdata(dev);
 			plat->id = *id;
 			*devp = dev;
diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h
index b348ad5231bd..8ce11bf04186 100644
--- a/include/dm/device-internal.h
+++ b/include/dm/device-internal.h
@@ -29,14 +29,15 @@ struct udevice;
  * @platdata: Pointer to data for this device - the structure is device-
  * specific but may include the device's I/O address, etc.. This is NULL for
  * devices which use device tree.
+ * @driver_data: The value to be stored in the device's driver_data field.
  * @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(struct udevice *parent, const struct driver *drv,
-		const char *name, void *platdata, int of_offset,
-		struct udevice **devp);
+		const char *name, void *platdata, ulong driver_data,
+		int of_offset, struct udevice **devp);
 
 /**
  * device_bind_by_name: Create a device and bind it to a driver
-- 
2.8.1



More information about the U-Boot mailing list