[U-Boot] [PATCH v3 19/26] dm: i2c: Move slave details to child platdata

Simon Glass sjg at chromium.org
Sun Jan 25 16:27:13 CET 2015


At present we go through various contortions to store the I2C's chip
address in its private data. This only exists when the chip is active so
must be set up when it is probed. Until the device is probed we don't
actually record what address it will appear on.

However, now that we can support per-child platform data, we can use that
instead. This allows us to set up the address when the child is bound,
and avoid the messy contortions.

Unfortunately this is a fairly large change and it seems to be difficult to
break it down further.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

Changes in v3:
- Add missing 'static' to two functions
- Remove unnecessary per_child_auto_alloc_size value

Changes in v2: None

 drivers/i2c/i2c-uclass-compat.c |  2 +-
 drivers/i2c/i2c-uclass.c        | 54 ++++++++++++++++++++++++-----------------
 drivers/i2c/i2c-uniphier-f.c    | 12 ---------
 drivers/i2c/i2c-uniphier.c      | 12 ---------
 drivers/i2c/s3c24x0_i2c.c       | 12 ---------
 drivers/i2c/sandbox_i2c.c       | 28 +++++----------------
 drivers/i2c/tegra_i2c.c         | 18 --------------
 include/i2c.h                   |  4 +--
 8 files changed, 41 insertions(+), 101 deletions(-)

diff --git a/drivers/i2c/i2c-uclass-compat.c b/drivers/i2c/i2c-uclass-compat.c
index c29fc89..11239da 100644
--- a/drivers/i2c/i2c-uclass-compat.c
+++ b/drivers/i2c/i2c-uclass-compat.c
@@ -20,7 +20,7 @@ static int i2c_compat_get_device(uint chip_addr, int alen,
 	ret = i2c_get_chip_for_busnum(cur_busnum, chip_addr, devp);
 	if (ret)
 		return ret;
-	chip = dev_get_parentdata(*devp);
+	chip = dev_get_parent_platdata(*devp);
 	if (chip->offset_len != alen) {
 		printf("Requested alen %d does not match chip offset_len %d\n",
 		       alen, chip->offset_len);
diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c
index 94b49df..393cd6f 100644
--- a/drivers/i2c/i2c-uclass.c
+++ b/drivers/i2c/i2c-uclass.c
@@ -50,7 +50,7 @@ static int i2c_setup_offset(struct dm_i2c_chip *chip, uint offset,
 static int i2c_read_bytewise(struct udevice *dev, uint offset,
 			     uint8_t *buffer, int len)
 {
-	struct dm_i2c_chip *chip = dev_get_parentdata(dev);
+	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
 	struct udevice *bus = dev_get_parent(dev);
 	struct dm_i2c_ops *ops = i2c_get_ops(bus);
 	struct i2c_msg msg[2], *ptr;
@@ -79,7 +79,7 @@ static int i2c_read_bytewise(struct udevice *dev, uint offset,
 static int i2c_write_bytewise(struct udevice *dev, uint offset,
 			     const uint8_t *buffer, int len)
 {
-	struct dm_i2c_chip *chip = dev_get_parentdata(dev);
+	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
 	struct udevice *bus = dev_get_parent(dev);
 	struct dm_i2c_ops *ops = i2c_get_ops(bus);
 	struct i2c_msg msg[1];
@@ -102,7 +102,7 @@ static int i2c_write_bytewise(struct udevice *dev, uint offset,
 
 int dm_i2c_read(struct udevice *dev, uint offset, uint8_t *buffer, int len)
 {
-	struct dm_i2c_chip *chip = dev_get_parentdata(dev);
+	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
 	struct udevice *bus = dev_get_parent(dev);
 	struct dm_i2c_ops *ops = i2c_get_ops(bus);
 	struct i2c_msg msg[2], *ptr;
@@ -133,7 +133,7 @@ int dm_i2c_read(struct udevice *dev, uint offset, uint8_t *buffer, int len)
 int dm_i2c_write(struct udevice *dev, uint offset, const uint8_t *buffer,
 		 int len)
 {
-	struct dm_i2c_chip *chip = dev_get_parentdata(dev);
+	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
 	struct udevice *bus = dev_get_parent(dev);
 	struct dm_i2c_ops *ops = i2c_get_ops(bus);
 	struct i2c_msg msg[1];
@@ -223,7 +223,7 @@ static int i2c_probe_chip(struct udevice *bus, uint chip_addr,
 static int i2c_bind_driver(struct udevice *bus, uint chip_addr, uint offset_len,
 			   struct udevice **devp)
 {
-	struct dm_i2c_chip chip;
+	struct dm_i2c_chip *chip;
 	char name[30], *str;
 	struct udevice *dev;
 	int ret;
@@ -236,11 +236,11 @@ static int i2c_bind_driver(struct udevice *bus, uint chip_addr, uint offset_len,
 		goto err_bind;
 
 	/* Tell the device what we know about it */
-	memset(&chip, '\0', sizeof(chip));
-	chip.chip_addr = chip_addr;
-	chip.offset_len = offset_len;
-	ret = device_probe_child(dev, &chip);
-	debug("%s:  device_probe_child: ret=%d\n", __func__, ret);
+	chip = dev_get_parent_platdata(dev);
+	chip->chip_addr = chip_addr;
+	chip->offset_len = offset_len;
+	ret = device_probe(dev);
+	debug("%s:  device_probe: ret=%d\n", __func__, ret);
 	if (ret)
 		goto err_probe;
 
@@ -248,6 +248,10 @@ static int i2c_bind_driver(struct udevice *bus, uint chip_addr, uint offset_len,
 	return 0;
 
 err_probe:
+	/*
+	 * If the device failed to probe, unbind it. There is nothing there
+	 * on the bus so we don't want to leave it lying around
+	 */
 	device_unbind(dev);
 err_bind:
 	free(str);
@@ -263,15 +267,9 @@ int i2c_get_chip(struct udevice *bus, uint chip_addr, uint offset_len,
 	      bus->name, chip_addr);
 	for (device_find_first_child(bus, &dev); dev;
 			device_find_next_child(&dev)) {
-		struct dm_i2c_chip store;
-		struct dm_i2c_chip *chip = dev_get_parentdata(dev);
+		struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
 		int ret;
 
-		if (!chip) {
-			chip = &store;
-			i2c_chip_ofdata_to_platdata(gd->fdt_blob,
-						    dev->of_offset, chip);
-		}
 		if (chip->chip_addr == chip_addr) {
 			ret = device_probe(dev);
 			debug("found, ret=%d\n", ret);
@@ -367,7 +365,7 @@ int i2c_get_bus_speed(struct udevice *bus)
 int i2c_set_chip_flags(struct udevice *dev, uint flags)
 {
 	struct udevice *bus = dev->parent;
-	struct dm_i2c_chip *chip = dev_get_parentdata(dev);
+	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
 	struct dm_i2c_ops *ops = i2c_get_ops(bus);
 	int ret;
 
@@ -383,7 +381,7 @@ int i2c_set_chip_flags(struct udevice *dev, uint flags)
 
 int i2c_get_chip_flags(struct udevice *dev, uint *flagsp)
 {
-	struct dm_i2c_chip *chip = dev_get_parentdata(dev);
+	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
 
 	*flagsp = chip->flags;
 
@@ -392,7 +390,7 @@ int i2c_get_chip_flags(struct udevice *dev, uint *flagsp)
 
 int i2c_set_chip_offset_len(struct udevice *dev, uint offset_len)
 {
-	struct dm_i2c_chip *chip = dev_get_parentdata(dev);
+	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
 
 	if (offset_len > I2C_MAX_OFFSET_LEN)
 		return -EINVAL;
@@ -444,19 +442,31 @@ static int i2c_post_probe(struct udevice *dev)
 	return i2c_set_bus_speed(dev, i2c->speed_hz);
 }
 
-int i2c_post_bind(struct udevice *dev)
+static int i2c_post_bind(struct udevice *dev)
 {
 	/* Scan the bus for devices */
 	return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
 }
 
+static int i2c_child_post_bind(struct udevice *dev)
+{
+	struct dm_i2c_chip *plat = dev_get_parent_platdata(dev);
+
+	if (dev->of_offset == -1)
+		return 0;
+
+	return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, plat);
+}
+
 UCLASS_DRIVER(i2c) = {
 	.id		= UCLASS_I2C,
 	.name		= "i2c",
 	.flags		= DM_UC_FLAG_SEQ_ALIAS,
-	.per_device_auto_alloc_size = sizeof(struct dm_i2c_bus),
 	.post_bind	= i2c_post_bind,
 	.post_probe	= i2c_post_probe,
+	.per_device_auto_alloc_size = sizeof(struct dm_i2c_bus),
+	.per_child_platdata_auto_alloc_size = sizeof(struct dm_i2c_chip),
+	.child_post_bind = i2c_child_post_bind,
 };
 
 UCLASS_DRIVER(i2c_generic) = {
diff --git a/drivers/i2c/i2c-uniphier-f.c b/drivers/i2c/i2c-uniphier-f.c
index b0d30f7..6707edd 100644
--- a/drivers/i2c/i2c-uniphier-f.c
+++ b/drivers/i2c/i2c-uniphier-f.c
@@ -145,16 +145,6 @@ static int uniphier_fi2c_remove(struct udevice *dev)
 	return 0;
 }
 
-static int uniphier_fi2c_child_pre_probe(struct udevice *dev)
-{
-	struct dm_i2c_chip *i2c_chip = dev_get_parentdata(dev);
-
-	if (dev->of_offset == -1)
-		return 0;
-	return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset,
-					   i2c_chip);
-}
-
 static int wait_for_irq(struct uniphier_fi2c_dev *dev, u32 flags,
 			bool *stop)
 {
@@ -372,8 +362,6 @@ U_BOOT_DRIVER(uniphier_fi2c) = {
 	.of_match = uniphier_fi2c_of_match,
 	.probe = uniphier_fi2c_probe,
 	.remove = uniphier_fi2c_remove,
-	.per_child_auto_alloc_size = sizeof(struct dm_i2c_chip),
-	.child_pre_probe = uniphier_fi2c_child_pre_probe,
 	.priv_auto_alloc_size = sizeof(struct uniphier_fi2c_dev),
 	.ops = &uniphier_fi2c_ops,
 };
diff --git a/drivers/i2c/i2c-uniphier.c b/drivers/i2c/i2c-uniphier.c
index bdac1f9..64a9ed8 100644
--- a/drivers/i2c/i2c-uniphier.c
+++ b/drivers/i2c/i2c-uniphier.c
@@ -75,16 +75,6 @@ static int uniphier_i2c_remove(struct udevice *dev)
 	return 0;
 }
 
-static int uniphier_i2c_child_pre_probe(struct udevice *dev)
-{
-	struct dm_i2c_chip *i2c_chip = dev_get_parentdata(dev);
-
-	if (dev->of_offset == -1)
-		return 0;
-	return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset,
-					   i2c_chip);
-}
-
 static int send_and_recv_byte(struct uniphier_i2c_dev *dev, u32 dtrm)
 {
 	writel(dtrm, &dev->regs->dtrm);
@@ -232,8 +222,6 @@ U_BOOT_DRIVER(uniphier_i2c) = {
 	.of_match = uniphier_i2c_of_match,
 	.probe = uniphier_i2c_probe,
 	.remove = uniphier_i2c_remove,
-	.per_child_auto_alloc_size = sizeof(struct dm_i2c_chip),
-	.child_pre_probe = uniphier_i2c_child_pre_probe,
 	.priv_auto_alloc_size = sizeof(struct uniphier_i2c_dev),
 	.ops = &uniphier_i2c_ops,
 };
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c
index c21d479..4002972 100644
--- a/drivers/i2c/s3c24x0_i2c.c
+++ b/drivers/i2c/s3c24x0_i2c.c
@@ -1404,16 +1404,6 @@ static int s3c_i2c_ofdata_to_platdata(struct udevice *dev)
 	return 0;
 }
 
-static int s3c_i2c_child_pre_probe(struct udevice *dev)
-{
-	struct dm_i2c_chip *i2c_chip = dev_get_parentdata(dev);
-
-	if (dev->of_offset == -1)
-		return 0;
-	return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset,
-					   i2c_chip);
-}
-
 static const struct dm_i2c_ops s3c_i2c_ops = {
 	.xfer		= s3c24x0_i2c_xfer,
 	.probe_chip	= s3c24x0_i2c_probe,
@@ -1431,8 +1421,6 @@ U_BOOT_DRIVER(i2c_s3c) = {
 	.id	= UCLASS_I2C,
 	.of_match = s3c_i2c_ids,
 	.ofdata_to_platdata = s3c_i2c_ofdata_to_platdata,
-	.per_child_auto_alloc_size = sizeof(struct dm_i2c_chip),
-	.child_pre_probe = s3c_i2c_child_pre_probe,
 	.priv_auto_alloc_size = sizeof(struct s3c24x0_i2c_bus),
 	.ops	= &s3c_i2c_ops,
 };
diff --git a/drivers/i2c/sandbox_i2c.c b/drivers/i2c/sandbox_i2c.c
index e2f6c3b..a943aa6 100644
--- a/drivers/i2c/sandbox_i2c.c
+++ b/drivers/i2c/sandbox_i2c.c
@@ -25,24 +25,24 @@ struct dm_sandbox_i2c_emul_priv {
 static int get_emul(struct udevice *dev, struct udevice **devp,
 		    struct dm_i2c_ops **opsp)
 {
-	struct dm_i2c_chip *priv;
+	struct dm_i2c_chip *plat;
 	int ret;
 
 	*devp = NULL;
 	*opsp = NULL;
-	priv = dev_get_parentdata(dev);
-	if (!priv->emul) {
+	plat = dev_get_parent_platdata(dev);
+	if (!plat->emul) {
 		ret = dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset,
 				       false);
 		if (ret)
 			return ret;
 
-		ret = device_get_child(dev, 0, &priv->emul);
+		ret = device_get_child(dev, 0, &plat->emul);
 		if (ret)
 			return ret;
 	}
-	*devp = priv->emul;
-	*opsp = i2c_get_ops(priv->emul);
+	*devp = plat->emul;
+	*opsp = i2c_get_ops(plat->emul);
 
 	return 0;
 }
@@ -82,20 +82,6 @@ static const struct dm_i2c_ops sandbox_i2c_ops = {
 	.xfer		= sandbox_i2c_xfer,
 };
 
-static int sandbox_i2c_child_pre_probe(struct udevice *dev)
-{
-	struct dm_i2c_chip *i2c_chip = dev_get_parentdata(dev);
-
-	/* Ignore our test address */
-	if (i2c_chip->chip_addr == SANDBOX_I2C_TEST_ADDR)
-		return 0;
-	if (dev->of_offset == -1)
-		return 0;
-
-	return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset,
-					   i2c_chip);
-}
-
 static const struct udevice_id sandbox_i2c_ids[] = {
 	{ .compatible = "sandbox,i2c" },
 	{ }
@@ -105,7 +91,5 @@ U_BOOT_DRIVER(i2c_sandbox) = {
 	.name	= "i2c_sandbox",
 	.id	= UCLASS_I2C,
 	.of_match = sandbox_i2c_ids,
-	.per_child_auto_alloc_size = sizeof(struct dm_i2c_chip),
-	.child_pre_probe = sandbox_i2c_child_pre_probe,
 	.ops	= &sandbox_i2c_ops,
 };
diff --git a/drivers/i2c/tegra_i2c.c b/drivers/i2c/tegra_i2c.c
index 87290c3..f414287 100644
--- a/drivers/i2c/tegra_i2c.c
+++ b/drivers/i2c/tegra_i2c.c
@@ -484,21 +484,6 @@ static const struct dm_i2c_ops tegra_i2c_ops = {
 	.set_bus_speed	= tegra_i2c_set_bus_speed,
 };
 
-static int tegra_i2c_child_pre_probe(struct udevice *dev)
-{
-	struct dm_i2c_chip *i2c_chip = dev_get_parentdata(dev);
-
-	if (dev->of_offset == -1)
-		return 0;
-	return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset,
-					   i2c_chip);
-}
-
-static int tegra_i2c_ofdata_to_platdata(struct udevice *dev)
-{
-	return 0;
-}
-
 static const struct udevice_id tegra_i2c_ids[] = {
 	{ .compatible = "nvidia,tegra114-i2c", .data = TYPE_114 },
 	{ .compatible = "nvidia,tegra20-i2c", .data = TYPE_STD },
@@ -510,10 +495,7 @@ U_BOOT_DRIVER(i2c_tegra) = {
 	.name	= "i2c_tegra",
 	.id	= UCLASS_I2C,
 	.of_match = tegra_i2c_ids,
-	.ofdata_to_platdata = tegra_i2c_ofdata_to_platdata,
 	.probe	= tegra_i2c_probe,
-	.per_child_auto_alloc_size = sizeof(struct dm_i2c_chip),
-	.child_pre_probe = tegra_i2c_child_pre_probe,
 	.priv_auto_alloc_size = sizeof(struct i2c_bus),
 	.ops	= &tegra_i2c_ops,
 };
diff --git a/include/i2c.h b/include/i2c.h
index 76090b7..95d6f28 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -39,8 +39,8 @@ enum dm_i2c_chip_flags {
  * An I2C chip is a device on the I2C bus. It sits at a particular address
  * and normally supports 7-bit or 10-bit addressing.
  *
- * To obtain this structure, use dev_get_parentdata(dev) where dev is the
- * chip to examine.
+ * To obtain this structure, use dev_get_parent_platdata(dev) where dev is
+ * the chip to examine.
  *
  * @chip_addr:	Chip address on bus
  * @offset_len: Length of offset in bytes. A single byte offset can
-- 
2.2.0.rc0.207.ga3a616c



More information about the U-Boot mailing list