dm: i2c: Move slave details to child platdata
authorSimon Glass <sjg@chromium.org>
Sun, 25 Jan 2015 15:27:13 +0000 (08:27 -0700)
committerSimon Glass <sjg@chromium.org>
Fri, 30 Jan 2015 00:09:56 +0000 (17:09 -0700)
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@chromium.org>
Reviewed-by: Masahiro Yamada <yamada.m@jp.panasonic.com>
drivers/i2c/i2c-uclass-compat.c
drivers/i2c/i2c-uclass.c
drivers/i2c/i2c-uniphier-f.c
drivers/i2c/i2c-uniphier.c
drivers/i2c/sandbox_i2c.c
drivers/i2c/tegra_i2c.c
include/i2c.h

index c29fc89e048b4eed31255af68c12eb5121f81c8e..11239da2b997d9568fa3dac488689a5c39fd271c 100644 (file)
@@ -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);
index 94b49dfe52beed7b225dcc7d2b5bb505e9326a20..393cd6f583aac9dfde86d63726e9e9e6ab0d4c2e 100644 (file)
@@ -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) = {
index b0d30f76c61f11ad150d9f0abdd4f196615ffc78..6707edd9ef498364f1493d5787adf914be2f53d6 100644 (file)
@@ -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,
 };
index bdac1f90799910b56fc78cc73fb6c13196864fbc..64a9ed81d2530b601edd2b29b234f8461c107ac6 100644 (file)
@@ -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,
 };
index e2f6c3b9bb50b790d57073fe0e4416def84081d5..a943aa6382142b4ebf411bc7c11ad7a9dbd9d80a 100644 (file)
@@ -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,
 };
index 87290c3127612c3369f8e98c383118f0e3229563..f4142870b304037273cb405f36e9ad2a39819d4b 100644 (file)
@@ -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,
 };
index 76090b7a93ac5d0c92f9a3fbf09936ef1f012fe0..95d6f28771995a3fc2af553cfd05a279c523e6ec 100644 (file)
@@ -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