From patchwork Mon Oct 1 18:22:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 977370 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=chromium.org Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 42P9jR00t6z9s3l for ; Tue, 2 Oct 2018 04:26:50 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 98ECFC21FAB; Mon, 1 Oct 2018 18:24:51 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RCVD_IN_DNSWL_BLOCKED, RCVD_IN_MSPIKE_H2 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id C0DEAC21FC1; Mon, 1 Oct 2018 18:23:19 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 7B77EC21F04; Mon, 1 Oct 2018 18:23:18 +0000 (UTC) Received: from mail-vk1-f201.google.com (mail-vk1-f201.google.com [209.85.221.201]) by lists.denx.de (Postfix) with ESMTPS id A0604C21FAE for ; Mon, 1 Oct 2018 18:23:10 +0000 (UTC) Received: by mail-vk1-f201.google.com with SMTP id x78-v6so1988972vkx.17 for ; Mon, 01 Oct 2018 11:23:10 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=8bekBk1cdpxPGC/a3LqCM1w1zCorEM7uEOGWMrh4GCA=; b=bfbFr062Z+LUtxjofwAZzixJnO9nLmw2eLrPP9Yva3hRkZ+cAvCzPjzLfQNpEi7lnU 96Yg3ejhocURTNU92GP/+0PAZqlikHcMLv9nQuYxkCb0SustlXwzbPYeDxxu+nf2i/yq oR4RC6ZvdkTpQ5CbJdqPuI/1tDUirvJQISl0A/JpynW1kYbR1O6UptAi8vCHAA3Ghpjp iizBn8OoOZ3EM8yrdhUW4VnYxD2MotOfaa55wKt9NHeYwC4BAF3w2eXhgkyZMJHFluKt gBTHHlRfdshp/fs4mp5+XamQICzpzpmVqcflg5R/FUn0UdRWk5joCATcOOi7Y+5hf40t IQvA== X-Gm-Message-State: ABuFfogDseHFn/RibMgZTRg4ZeBcRzYf96SYnkrIb4CKkzuKHq7XKocx ESx8U/x7zy7hQ8PzSqZCaVzKuEk= X-Google-Smtp-Source: ACcGV60DR46yt8dT15vPKPpNhatiTLixnLAkhKh2YeHgalcAQv/+wOwjDb7rAT1pZyAzv++rBwcUPrI= X-Received: by 2002:a1f:3605:: with SMTP id d5-v6mr11216794vka.24.1538418189778; Mon, 01 Oct 2018 11:23:09 -0700 (PDT) Date: Mon, 1 Oct 2018 12:22:07 -0600 In-Reply-To: <20181001182249.129565-1-sjg@chromium.org> Message-Id: <20181001182249.129565-4-sjg@chromium.org> Mime-Version: 1.0 References: <20181001182249.129565-1-sjg@chromium.org> X-Mailer: git-send-email 2.19.0.605.g01d371f741-goog From: Simon Glass To: U-Boot Mailing List Subject: [U-Boot] [PATCH 03/45] dm: core: Add a function to find the first inactive child X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Some devices have children and want to press an existing inactive child into service when needed. Add a function to help with this. Signed-off-by: Simon Glass Signed-off-by: Simon Glass --- drivers/core/device.c | 18 ++++++++++++++++++ include/dm/device.h | 15 +++++++++++++++ test/dm/core.c | 31 +++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/drivers/core/device.c b/drivers/core/device.c index a9e5906e7cd..5176aa3f866 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -681,6 +681,24 @@ int device_find_next_child(struct udevice **devp) return 0; } +int device_find_first_inactive_child(struct udevice *parent, + enum uclass_id uclass_id, + struct udevice **devp) +{ + struct udevice *dev; + + *devp = NULL; + list_for_each_entry(dev, &parent->child_head, sibling_node) { + if (!device_active(dev) && + device_get_uclass_id(dev) == uclass_id) { + *devp = dev; + return 0; + } + } + + return -ENODEV; +} + struct udevice *dev_get_parent(const struct udevice *child) { return child->parent; diff --git a/include/dm/device.h b/include/dm/device.h index f873fc66e12..847934425bb 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -519,6 +519,21 @@ int device_find_first_child(struct udevice *parent, struct udevice **devp); */ int device_find_next_child(struct udevice **devp); +/** + * device_find_first_inactive_child() - Find the first inactive child + * + * This is used to locate an existing child of a device which is of a given + * uclass. + * + * @parent: Parent device to search + * @uclass_id: Uclass to look for + * @devp: Returns device found, if any + * @return 0 if found, else -ENODEV + */ +int device_find_first_inactive_child(struct udevice *parent, + enum uclass_id uclass_id, + struct udevice **devp); + /** * device_has_children() - check if a device has any children * diff --git a/test/dm/core.c b/test/dm/core.c index c15a8406c09..260f6494a2e 100644 --- a/test/dm/core.c +++ b/test/dm/core.c @@ -870,3 +870,34 @@ static int dm_test_uclass_names(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_uclass_names, DM_TESTF_SCAN_PDATA); + +static int dm_test_inactive_child(struct unit_test_state *uts) +{ + struct dm_test_state *dms = uts->priv; + struct udevice *parent, *dev1, *dev2; + + /* Skip the behaviour in test_post_probe() */ + dms->skip_post_probe = 1; + + ut_assertok(uclass_first_device_err(UCLASS_TEST, &parent)); + + /* + * Create a child but do not activate it. Calling the function again + * should return the same child. + */ + ut_asserteq(-ENODEV, device_find_first_inactive_child(parent, + UCLASS_TEST, &dev1)); + ut_assertok(device_bind_ofnode(parent, DM_GET_DRIVER(test_drv), + "test_child", 0, ofnode_null(), &dev1)); + + ut_assertok(device_find_first_inactive_child(parent, UCLASS_TEST, + &dev2)); + ut_asserteq_ptr(dev1, dev2); + + ut_assertok(device_probe(dev1)); + ut_asserteq(-ENODEV, device_find_first_inactive_child(parent, + UCLASS_TEST, &dev2)); + + return 0; +} +DM_TEST(dm_test_inactive_child, DM_TESTF_SCAN_PDATA);