From patchwork Wed Jun 22 16:22:23 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Thomas Abraham X-Patchwork-Id: 906292 Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p5MGMn4o015621 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 22 Jun 2011 16:23:11 GMT Received: from canuck.infradead.org ([2001:4978:20e::1]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1QZQCL-0005r8-AW; Wed, 22 Jun 2011 16:22:37 +0000 Received: from localhost ([127.0.0.1] helo=canuck.infradead.org) by canuck.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1QZQCJ-0004Wy-Po; Wed, 22 Jun 2011 16:22:35 +0000 Received: from mail-qy0-f170.google.com ([209.85.216.170]) by canuck.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1QZQCF-0004Wf-Um for linux-arm-kernel@lists.infradead.org; Wed, 22 Jun 2011 16:22:33 +0000 Received: by qyg14 with SMTP id 14so2616110qyg.15 for ; Wed, 22 Jun 2011 09:22:23 -0700 (PDT) MIME-Version: 1.0 Received: by 10.224.195.193 with SMTP id ed1mr642388qab.231.1308759743767; Wed, 22 Jun 2011 09:22:23 -0700 (PDT) Received: by 10.224.60.71 with HTTP; Wed, 22 Jun 2011 09:22:23 -0700 (PDT) In-Reply-To: References: <1308567752-13451-1-git-send-email-thomas.abraham@linaro.org> <1308567752-13451-3-git-send-email-thomas.abraham@linaro.org> Date: Wed, 22 Jun 2011 21:52:23 +0530 Message-ID: Subject: Re: [PATCH 2/6] serial: samsung: Add device tree support for s5pv210 uart driver From: Thomas Abraham To: Grant Likely X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20110622_122232_283270_8256998C X-CRM114-Status: GOOD ( 23.68 ) X-Spam-Score: -0.7 (/) X-Spam-Report: SpamAssassin version 3.3.1 on canuck.infradead.org summary: Content analysis details: (-0.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.216.170 listed in list.dnswl.org] Cc: linux-samsung-soc@vger.kernel.org, linaro-dev@lists.linaro.org, patches@linaro.org, devicetree-discuss@lists.ozlabs.org, kgene.kim@samsung.com, ben-linux@fluff.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Wed, 22 Jun 2011 16:23:11 +0000 (UTC) X-MIME-Autoconverted: from quoted-printable to 8bit by demeter2.kernel.org id p5MGMn4o015621 Hi Grant, On 20 June 2011 22:13, Grant Likely wrote: > Okay, this is getting ugly (not your fault, but this pattern has > become too common.  Can you craft and post a patch that adds the > following functions to drivers/of/base.c and include/linux/of.h > > /* offset in cells, not bytes */ > int dt_decode_u32(struct *property, int offset, u32 *out_val) > { >        if (!property || !property->value) >                return -EINVAL; >        if ((offset + 1) * 4 > property->length) >                return -EINVAL; >        *out_val = of_read_number(property->value + (offset * 4), 1); >        return 0; > } > int dt_decode_u64(struct *property, int offset, u64 *out_val) > { > ... > } > int dt_decode_string(struct *property, int index, char **out_string); > { > ... > } > > Plus a set of companion functions: > int dt_getprop_u32(struct device_node *np, char *propname, int offset, > u32 *out_val) > { >        return dt_decode_u32(of_find_property(np, propname, NULL), > offset, out_val); > } > int dt_getprop_u64(struct *device_node, char *propname, int offset, > u64 *out_val); > { > ... > } > int dt_getprop_string(struct *device_node, char *propname, int index, > char **out_string); > { > ... > } > > Then you'll be able to simply do the following to decode each > property, with fifosize being left alone if the property cannot be > found or decoded: > > dt_getprop_u32(pdev->dev.of_node, "samsung,fifosize", &fifosize); I have added the functions as you have suggested and the diff is listed below. Could you please review the diff and suggest any changes required. drivers/of/base.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/of.h | 10 ++++ 2 files changed, 139 insertions(+), 0 deletions(-) extern int of_device_is_available(const struct device_node *device); diff --git a/drivers/of/base.c b/drivers/of/base.c index 632ebae..73f0144 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -596,6 +596,135 @@ struct device_node *of_find_node_by_phandle(phandle handle) EXPORT_SYMBOL(of_find_node_by_phandle); /** + * of_read_property_u32 - Reads a indexed 32-bit property value + * @prop: property to read from. + * @offset: cell number to read. + * value: returned cell value + * + * Returns a indexed 32-bit value of a property cell, -EINVAL in case the cell + * does not exist + */ +int of_read_property_u32(struct property *prop, u32 offset, u32 *value) +{ + if (!prop || !prop->value) + return -EINVAL; + if ((offset + 1) * 4 > prop->length) + return -EINVAL; + + *value = of_read_ulong(prop->value + (offset * 4), 1); + return 0; +} +EXPORT_SYMBOL(of_read_property_u32); + +/** + * of_getprop_u32 - Find a property in a device node and read a 32-bit value + * @np: device node from which the property value is to be read. + * @propname name of the property to be searched. + * @offset: cell number to read. + * @value: returned value of the cell + * + * Search for a property in a device node and read a indexed 32-bit value of a + * property cell. Returns the 32-bit cell value, -EINVAL in case the property or + * the indexed cell does not exist. + */ +int +of_getprop_u32(struct device_node *np, char *propname, int offset, u32 *value) +{ + return of_read_property_u32(of_find_property(np, propname, NULL), + offset, value); +} +EXPORT_SYMBOL(of_getprop_u32); + +/** + * of_read_property_u64 - Reads a indexed 64-bit property value + * @prop: property to read from. + * @offset: cell number to read (each cell is 64-bits). + * @value: returned cell value + * + * Returns a indexed 64-bit value of a property cell, -EINVAL in case the cell + * does not exist + */ +int of_read_property_u64(struct property *prop, int offset, u64 *value) +{ + if (!prop || !prop->value) + return -EINVAL; + if ((offset + 1) * 8 > prop->length) + return -EINVAL; + + *value = of_read_number(prop->value + (offset * 8), 2); + return 0; +} +EXPORT_SYMBOL(of_read_property_u64); + +/** + * of_getprop_u64 - Find a property in a device node and read a 64-bit value + * @np: device node from which the property value is to be read. + * @propname name of the property to be searched. + * @offset: cell number to read (each cell is 64-bits). + * @value: returned value of the cell + * + * Search for a property in a device node and read a indexed 64-bit value of a + * property cell. Returns the 64-bit cell value, -EINVAL in case the property or + * the indexed cell does not exist. + */ +int +of_getprop_u64(struct device_node *np, char *propname, int offset, u64 *value) +{ + return of_read_property_u64(of_find_property(np, propname, NULL), + offset, value); +} +EXPORT_SYMBOL(of_getprop_u64); + +/** + * of_read_property_string - Returns a pointer to a indexed null terminated + * property value string + * @prop: property to read from. + * @offset: index of the property string to be read. + * @string: pointer to a null terminated string, valid only if the return + * value is 0. + * + * Returns a pointer to a indexed null terminated property cell string, -EINVAL + * in case the cell does not exist. + */ +int of_read_property_string(struct property *prop, int offset, char **string) +{ + char *c; + + if (!prop || !prop->value) + return -EINVAL; + + c = (char *)prop->value; + while (offset--) + while (*c++) + ; + + *string = c; + return 0; +} + +/** + * of_getprop_string - Find a property in a device node and read a null + * terminated string property + * @np: device node from which the property value is to be read. + * @propname name of the property to be searched. + * @offset: cell number to read (each cell contains a null-terminated + * string). + * @string: pointer to a null terminated string, valid only if the return + * value is 0. + * + * Search for a property in a device node and return a pointer to a indexed + * string value of a property cell. Returns a pointer to a string, -EINVAL + * in case the property or the indexed cell does not exist. + */ +int of_getprop_string(struct device_node *np, char *propname, int offset, + char **string) +{ + return of_read_property_string(of_find_property(np, propname, NULL), + offset, string); +} +EXPORT_SYMBOL(of_getprop_string); + +/** * of_parse_phandle - Resolve a phandle property to a device_node pointer * @np: Pointer to device node holding phandle property * @phandle_name: Name of property holding a phandle value diff --git a/include/linux/of.h b/include/linux/of.h index bfc0ed1..aff2786 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -195,6 +195,16 @@ extern struct device_node *of_find_node_with_property( extern struct property *of_find_property(const struct device_node *np, const char *name, int *lenp); +extern int of_read_property_u32(struct property *prop, u32 offset, u32 *value); +extern int of_getprop_u32(struct device_node *np, char *propname, int offset, + u32 *value); +extern int of_read_property_u64(struct property *prop, int offset, u64 *value); +extern int of_getprop_u64(struct device_node *np, char *propname, int offset, + u64 *value); +extern int of_read_property_string(struct property *prop, int offset, + char **string); +extern int of_getprop_string(struct device_node *np, char *propname, int offset, + char **string); extern int of_device_is_compatible(const struct device_node *device, const char *);