From patchwork Tue Jan 20 03:12:48 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 430794 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 8A5F114017F for ; Tue, 20 Jan 2015 14:15:03 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 483CB4B6B4; Tue, 20 Jan 2015 04:14:25 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ri12TrHHJE-p; Tue, 20 Jan 2015 04:14:25 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id B89FB4B6DA; Tue, 20 Jan 2015 04:13:44 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 5ED234B66F for ; Tue, 20 Jan 2015 04:13:20 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6xuK7+cEI2I8 for ; Tue, 20 Jan 2015 04:13:20 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-ig0-f202.google.com (mail-ig0-f202.google.com [209.85.213.202]) by theia.denx.de (Postfix) with ESMTPS id DC1654B675 for ; Tue, 20 Jan 2015 04:13:15 +0100 (CET) Received: by mail-ig0-f202.google.com with SMTP id a13so1909833igq.1 for ; Mon, 19 Jan 2015 19:13:14 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=2f3HURjvXCS0iTV3zHpE11su3k4peH/mI1u+qc3j7hA=; b=XcG30GilUiuEyEOBtNzaRG6mCjRRjWgqKylx3AvR5S6qVjHSRdk1E3cb1NMocfTUtT G582vvRCD3aO8XKrSMdIsltobf6IIoWrdZc90gR8N1bYlp67eS/J7LHMCGFQ1R+zCL5o tIBsBhgc6ghhRjnYOAZrZrNA2Hqg0DI0phTyudhcRMK2rShxiZlHaJxpXueKWRgIFLOv lcX1OUq4TG7Qev3IFDf4a5RQULeQIn1hjGKWMe059rNtPDaAgcY08v7jR8lq2q2GLSg5 qwu+oD39Bm4PXjUIHB6O/5htO19RHq3uLZOuVTkHk6HThk3XVubMxQTv4qZsaNo2tsjz AOKg== X-Gm-Message-State: ALoCoQnM29X6LL/eh1Vrrc2FOGwj4M9G+QPZccgl3sLiPy2UV7NnboserwMwAc00rJhtwmBBkdVj X-Received: by 10.182.168.114 with SMTP id zv18mr26989641obb.3.1421723594825; Mon, 19 Jan 2015 19:13:14 -0800 (PST) Received: from corpmail-nozzle1-1.hot.corp.google.com ([100.108.1.104]) by gmr-mx.google.com with ESMTPS id r4si1943384qca.0.2015.01.19.19.13.14 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 19 Jan 2015 19:13:14 -0800 (PST) Received: from kaki.bld.corp.google.com ([172.29.216.32]) by corpmail-nozzle1-1.hot.corp.google.com with ESMTP id YxdiHXbO.2; Mon, 19 Jan 2015 19:13:14 -0800 Received: by kaki.bld.corp.google.com (Postfix, from userid 121222) id 1F786220D78; Mon, 19 Jan 2015 20:13:14 -0700 (MST) From: Simon Glass To: U-Boot Mailing List Date: Mon, 19 Jan 2015 20:12:48 -0700 Message-Id: <1421723575-4532-20-git-send-email-sjg@chromium.org> X-Mailer: git-send-email 2.2.0.rc0.207.ga3a616c In-Reply-To: <1421723575-4532-1-git-send-email-sjg@chromium.org> References: <1421723575-4532-1-git-send-email-sjg@chromium.org> Subject: [U-Boot] [PATCH v2 19/26] dm: i2c: Move slave details to child platdata X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.13 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de 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 --- Changes in v2: None drivers/i2c/i2c-uclass-compat.c | 2 +- drivers/i2c/i2c-uclass.c | 53 +++++++++++++++++++++++++---------------- 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(+), 100 deletions(-) diff --git a/drivers/i2c/i2c-uclass-compat.c b/drivers/i2c/i2c-uclass-compat.c index d8de46a..223f238 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, alen, devp); if (ret) return ret; - chip = dev_get_parentdata(*devp); + chip = dev_get_parent_platdata(*devp); if (chip->offset_len != alen) { printf("I2C chip %x: requested alen %d does not match chip offset_len %d\n", chip_addr, alen, chip->offset_len); diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c index 94b49df..83c7a04 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; @@ -450,13 +448,26 @@ int i2c_post_bind(struct udevice *dev) return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); } +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_auto_alloc_size = sizeof(struct dm_i2c_chip), + .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 616c974..27fe00f 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