From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CCAC5C433F5 for ; Sat, 23 Oct 2021 23:38:07 +0000 (UTC) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 527E060F4F for ; Sat, 23 Oct 2021 23:38:07 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 527E060F4F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=chromium.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=lists.denx.de Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id E858C833D8; Sun, 24 Oct 2021 01:37:48 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="IEI8H3Gd"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id D93E58352E; Sun, 24 Oct 2021 01:27:18 +0200 (CEST) Received: from mail-oi1-x231.google.com (mail-oi1-x231.google.com [IPv6:2607:f8b0:4864:20::231]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 14E5E83531 for ; Sun, 24 Oct 2021 01:27:00 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-oi1-x231.google.com with SMTP id n63so10031843oif.7 for ; Sat, 23 Oct 2021 16:26:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=X4hSSnM4QuA5eUhw4ZvAkHY9fsuC/7u2OK9Sst/M250=; b=IEI8H3Gd/mBQQLiPrz8qZkhhE48TBEjkFBK3OiH0vcmK7h1hhtzW/zi182mZyRcMZ4 /cJ+kgdxDaUAnm1PZZ+RUsbNGp3xpJbhx9cCZUNxWC3alLAbDyAG8R8iI/j3MM+1drg0 ngPQt9zt8RiZmmBRz08SbMM3RPLOhr8lBPR3c= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=X4hSSnM4QuA5eUhw4ZvAkHY9fsuC/7u2OK9Sst/M250=; b=d1yzxhBlKYxp1u1vQSooq9mVDPjXifhVloLQRndKhdEDPASDtrdmcd5Pp+FqNW9AS9 Ir/aJ2f3mySd1xqlLAwU7tMtspKWWh0Lsrx86zzMuq/ljcv/NSdLpLFFw7uhNUwTW9eo FP8wG2PWPlYxMhBKo7BZq7yyy4p7I/idoTjkB7WYzPudnRFcYm5C0eaqr73gGklf//PJ REkA02zJJZSodb0ErRGDRzLvnlrt6z/6DTIiyleMz8anLfc7+fIck5BbDFvxkDhWjm38 ZtFxjH9KEon6+7QuDyZKhg9vYiRsZD8EeDjJPs8eWjseqtG8Pt70rX3j8xnBA7NNOYa1 j/9Q== X-Gm-Message-State: AOAM533jcL9izBH/nYGNhB4oR2fvOdp3P0djoM7nfEOGgrz5Okm0KvuE Jnc3VvotpNnzDEQORNItSVpQ/1CLg2ovrg== X-Google-Smtp-Source: ABdhPJxuRbFEG9O1A9QTmtHV7eANpOyqMpYrij5jpm/XME67a+3PD3D0nm0ULBDqrbphycQvJBu92Q== X-Received: by 2002:a05:6808:230a:: with SMTP id bn10mr6189791oib.179.1635031618475; Sat, 23 Oct 2021 16:26:58 -0700 (PDT) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id l24sm2253885oop.4.2021.10.23.16.26.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 23 Oct 2021 16:26:58 -0700 (PDT) From: Simon Glass To: U-Boot Mailing List Cc: Michal Simek , Heinrich Schuchardt , Tom Rini , Ilias Apalodimas , Daniel Schwierzeck , Steffen Jaeckel , =?UTF-8?q?Marek=20Beh=C3=BAn?= , Lukas Auer , Dennis Gilmore , Simon Glass , Marek Vasut , Pavel Herrmann Subject: [PATCH v2 13/41] dm: core: Add a way to obtain a string list Date: Sat, 23 Oct 2021 17:26:07 -0600 Message-Id: <20211023232635.9195-12-sjg@chromium.org> X-Mailer: git-send-email 2.33.0.1079.g6e70778dc9-goog In-Reply-To: <20211023232635.9195-1-sjg@chromium.org> References: <20211023232635.9195-1-sjg@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean At present we support reading a string list a string at a time. Apart from being inefficient, this makes it impossible to separate reading of the devicetree into the of_to_plat() method where it belongs, since any code which needs access to the string must read it from the devicetree. Add a function which returns the string property as an array of pointers to the strings, which is easily used by clients. Signed-off-by: Simon Glass --- (no changes since v1) drivers/core/ofnode.c | 26 ++++++++++++++++++++++++++ drivers/core/read.c | 6 ++++++ include/dm/ofnode.h | 20 ++++++++++++++++++++ include/dm/read.h | 28 ++++++++++++++++++++++++++++ test/dm/ofnode.c | 20 ++++++++++++++++++++ 5 files changed, 100 insertions(+) diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 08705ef8d99..709bea272a6 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -456,6 +456,32 @@ int ofnode_read_string_count(ofnode node, const char *property) } } +int ofnode_read_string_list(ofnode node, const char *property, + const char ***listp) +{ + const char **prop; + int count; + int i; + + *listp = NULL; + count = ofnode_read_string_count(node, property); + if (count < 0) + return count; + if (!count) + return 0; + + prop = calloc(count + 1, sizeof(char *)); + if (!prop) + return -ENOMEM; + + for (i = 0; i < count; i++) + ofnode_read_string_index(node, property, i, &prop[i]); + prop[count] = NULL; + *listp = prop; + + return count; +} + static void ofnode_from_fdtdec_phandle_args(struct fdtdec_phandle_args *in, struct ofnode_phandle_args *out) { diff --git a/drivers/core/read.c b/drivers/core/read.c index 4307ca45799..31f9e78a062 100644 --- a/drivers/core/read.c +++ b/drivers/core/read.c @@ -205,6 +205,12 @@ int dev_read_string_count(const struct udevice *dev, const char *propname) return ofnode_read_string_count(dev_ofnode(dev), propname); } +int dev_read_string_list(const struct udevice *dev, const char *propname, + const char ***listp) +{ + return ofnode_read_string_list(dev_ofnode(dev), propname, listp); +} + int dev_read_phandle_with_args(const struct udevice *dev, const char *list_name, const char *cells_name, int cell_count, int index, struct ofnode_phandle_args *out_args) diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 4faa9bfa563..f2b5b9c2d33 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -609,6 +609,26 @@ int ofnode_read_string_index(ofnode node, const char *propname, int index, */ int ofnode_read_string_count(ofnode node, const char *property); +/** + * ofnode_read_string_list() - read a list of strings + * + * This produces a list of string pointers with each one pointing to a string + * in the string list. If the property does not exist, it returns {NULL}. + * + * The data is allocated and the caller is reponsible for freeing the return + * value (the list of string pointers). The strings themselves may not be + * changed as they point directly into the devicetree property. + * + * @node: node to check + * @listp: returns an allocated, NULL-terminated list of strings if the return + * value is > 0, else is set to NULL + * @return number of strings in list, 0 if none, -ENOMEM if out of memory, + * -EINVAL if no such property, -EENODATA if property is empty + * @return: NULL-terminated list of strings (NULL if no property or empty) + */ +int ofnode_read_string_list(ofnode node, const char *property, + const char ***listp); + /** * ofnode_parse_phandle_with_args() - Find a node pointed by phandle in a list * diff --git a/include/dm/read.h b/include/dm/read.h index 890bf3d8472..75c6ad6ee49 100644 --- a/include/dm/read.h +++ b/include/dm/read.h @@ -371,6 +371,27 @@ int dev_read_string_index(const struct udevice *dev, const char *propname, * number of strings in the list, or -ve error value if not found */ int dev_read_string_count(const struct udevice *dev, const char *propname); + +/** + * dev_read_string_list() - read a list of strings + * + * This produces a list of string pointers with each one pointing to a string + * in the string list. If the property does not exist, it returns {NULL}. + * + * The data is allocated and the caller is reponsible for freeing the return + * value (the list of string pointers). The strings themselves may not be + * changed as they point directly into the devicetree property. + * + * @dev: device to examine + * @propname: name of the property containing the string list + * @listp: returns an allocated, NULL-terminated list of strings if the return + * value is > 0, else is set to NULL + * @return number of strings in list, 0 if none, -ENOMEM if out of memory, + * -ENOENT if no such property + */ +int dev_read_string_list(const struct udevice *dev, const char *propname, + const char ***listp); + /** * dev_read_phandle_with_args() - Find a node pointed by phandle in a list * @@ -906,6 +927,13 @@ static inline int dev_read_string_count(const struct udevice *dev, return ofnode_read_string_count(dev_ofnode(dev), propname); } +static inline int dev_read_string_list(const struct udevice *dev, + const char *propname, + const char ***listp) +{ + return ofnode_read_string_list(dev_ofnode(dev), propname, listp); +} + static inline int dev_read_phandle_with_args(const struct udevice *dev, const char *list_name, const char *cells_name, int cell_count, int index, struct ofnode_phandle_args *out_args) diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index 537028ca8fc..470cbce4c2e 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -336,6 +336,7 @@ DM_TEST(dm_test_ofnode_conf, 0); static int dm_test_ofnode_string(struct unit_test_state *uts) { + const char **val; const char *out; ofnode node; @@ -348,6 +349,10 @@ static int dm_test_ofnode_string(struct unit_test_state *uts) ut_asserteq_str("test string", out); ut_asserteq(0, ofnode_stringlist_search(node, "str-value", "test string")); + ut_asserteq(1, ofnode_read_string_list(node, "str-value", &val)); + ut_asserteq_str("test string", val[0]); + ut_assertnull(val[1]); + free(val); /* list of strings */ ut_asserteq(5, ofnode_read_string_count(node, "mux-control-names")); @@ -356,6 +361,15 @@ static int dm_test_ofnode_string(struct unit_test_state *uts) ut_asserteq_str("mux0", out); ut_asserteq(0, ofnode_stringlist_search(node, "mux-control-names", "mux0")); + ut_asserteq(5, ofnode_read_string_list(node, "mux-control-names", + &val)); + ut_asserteq_str("mux0", val[0]); + ut_asserteq_str("mux1", val[1]); + ut_asserteq_str("mux2", val[2]); + ut_asserteq_str("mux3", val[3]); + ut_asserteq_str("mux4", val[4]); + ut_assertnull(val[5]); + free(val); ut_assertok(ofnode_read_string_index(node, "mux-control-names", 4, &out)); @@ -369,6 +383,7 @@ DM_TEST(dm_test_ofnode_string, 0); static int dm_test_ofnode_string_err(struct unit_test_state *uts) { + const char **val; const char *out; ofnode node; @@ -383,16 +398,21 @@ static int dm_test_ofnode_string_err(struct unit_test_state *uts) ut_asserteq(-EINVAL, ofnode_read_string_count(node, "missing")); ut_asserteq(-EINVAL, ofnode_read_string_index(node, "missing", 0, &out)); + ut_asserteq(-EINVAL, ofnode_read_string_list(node, "missing", &val)); /* empty property */ ut_asserteq(-ENODATA, ofnode_read_string_count(node, "bool-value")); ut_asserteq(-ENODATA, ofnode_read_string_index(node, "bool-value", 0, &out)); + ut_asserteq(-ENODATA, ofnode_read_string_list(node, "bool-value", + &val)); /* badly formatted string list */ ut_asserteq(-EILSEQ, ofnode_read_string_count(node, "int64-value")); ut_asserteq(-EILSEQ, ofnode_read_string_index(node, "int64-value", 0, &out)); + ut_asserteq(-EILSEQ, ofnode_read_string_list(node, "int64-value", + &val)); /* out of range / not found */ ut_asserteq(-ENODATA, ofnode_read_string_index(node, "str-value", 1, -- 2.33.0.1079.g6e70778dc9-goog