From patchwork Tue Nov 24 10:22:54 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Shevchenko X-Patchwork-Id: 7689361 Return-Path: X-Original-To: patchwork-linux-acpi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 69E759F4F5 for ; Tue, 24 Nov 2015 10:24:34 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 5961D20826 for ; Tue, 24 Nov 2015 10:24:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3136820820 for ; Tue, 24 Nov 2015 10:24:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754322AbbKXKYG (ORCPT ); Tue, 24 Nov 2015 05:24:06 -0500 Received: from mga01.intel.com ([192.55.52.88]:49627 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753975AbbKXKYB (ORCPT ); Tue, 24 Nov 2015 05:24:01 -0500 Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga101.fm.intel.com with ESMTP; 24 Nov 2015 02:23:38 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,338,1444719600"; d="scan'208";a="858273551" Received: from black.fi.intel.com ([10.237.72.93]) by orsmga002.jf.intel.com with ESMTP; 24 Nov 2015 02:23:35 -0800 Received: by black.fi.intel.com (Postfix, from userid 1003) id DCDF417B; Tue, 24 Nov 2015 12:23:00 +0200 (EET) From: Andy Shevchenko To: "Rafael J. Wysocki" , Greg Kroah-Hartman , Jarkko Nikula , linux-i2c@vger.kernel.org, linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, Lee Jones , Mika Westerberg , Kevin Fenzi , Arnd Bergmann , Wolfram Sang Cc: Andy Shevchenko Subject: [PATCH v1 08/13] device property: Fallback to secondary fwnode if primary misses the property Date: Tue, 24 Nov 2015 12:22:54 +0200 Message-Id: <1448360579-79260-9-git-send-email-andriy.shevchenko@linux.intel.com> X-Mailer: git-send-email 2.6.2 In-Reply-To: <1448360579-79260-1-git-send-email-andriy.shevchenko@linux.intel.com> References: <1448360579-79260-1-git-send-email-andriy.shevchenko@linux.intel.com> Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The struct fwnode has notion of secondary fwnode. This is supposed to used as fallback if the primary firmware interface (DT, ACPI) does not have the property in question. However, the current implementation never checks the secondary node which prevents one to add default "built-in" properties to devices. This patch adds fallback to the secondary fwnode if the primary fwnode returns that the property does not exists. Signed-off-by: Mika Westerberg Signed-off-by: Andy Shevchenko --- drivers/base/property.c | 109 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 78 insertions(+), 31 deletions(-) diff --git a/drivers/base/property.c b/drivers/base/property.c index c8e9722..1768e61 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -212,12 +212,8 @@ bool device_property_present(struct device *dev, const char *propname) } EXPORT_SYMBOL_GPL(device_property_present); -/** - * fwnode_property_present - check if a property of a firmware node is present - * @fwnode: Firmware node whose property to check - * @propname: Name of the property - */ -bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname) +static bool __fwnode_property_present(struct fwnode_handle *fwnode, + const char *propname) { if (is_of_node(fwnode)) return of_property_read_bool(to_of_node(fwnode), propname); @@ -227,6 +223,21 @@ bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname) return !!pset_prop_get(to_pset_node(fwnode), propname); return false; } + +/** + * fwnode_property_present - check if a property of a firmware node is present + * @fwnode: Firmware node whose property to check + * @propname: Name of the property + */ +bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname) +{ + bool ret; + + ret = __fwnode_property_present(fwnode, propname); + if (ret == false && fwnode->secondary) + ret = __fwnode_property_present(fwnode->secondary, propname); + return ret; +} EXPORT_SYMBOL_GPL(fwnode_property_present); /** @@ -406,7 +417,7 @@ EXPORT_SYMBOL_GPL(device_property_match_string); (val) ? pset_prop_read_##type##_array((node), (propname), (val), (nval)) \ : pset_prop_count_elems_of_size((node), (propname), sizeof(type)) -#define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \ +#define FWNODE_PROP_READ(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \ ({ \ int _ret_; \ if (is_of_node(_fwnode_)) \ @@ -423,6 +434,17 @@ EXPORT_SYMBOL_GPL(device_property_match_string); _ret_; \ }) +#define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \ +({ \ + int _ret_; \ + _ret_ = FWNODE_PROP_READ(_fwnode_, _propname_, _type_, _proptype_, \ + _val_, _nval_); \ + if (_ret_ == -EINVAL && _fwnode_->secondary) \ + _ret_ = FWNODE_PROP_READ(_fwnode_->secondary, _propname_, _type_, \ + _proptype_, _val_, _nval_); \ + _ret_; \ +}) + /** * fwnode_property_read_u8_array - return a u8 array property of firmware node * @fwnode: Firmware node to get the property of @@ -527,6 +549,41 @@ int fwnode_property_read_u64_array(struct fwnode_handle *fwnode, } EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array); +static int __fwnode_property_read_string_array(struct fwnode_handle *fwnode, + const char *propname, + const char **val, size_t nval) +{ + if (is_of_node(fwnode)) + return val ? + of_property_read_string_array(to_of_node(fwnode), + propname, val, nval) : + of_property_count_strings(to_of_node(fwnode), propname); + else if (is_acpi_node(fwnode)) + return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING, + val, nval); + else if (is_pset_node(fwnode)) + return val ? + pset_prop_read_string_array(to_pset_node(fwnode), + propname, val, nval) : + pset_prop_count_elems_of_size(to_pset_node(fwnode), + propname, + sizeof(const char *)); + return -ENXIO; +} + +static int __fwnode_property_read_string(struct fwnode_handle *fwnode, + const char *propname, const char **val) +{ + if (is_of_node(fwnode)) + return of_property_read_string(to_of_node(fwnode), propname, val); + else if (is_acpi_node(fwnode)) + return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING, + val, 1); + else if (is_pset_node(fwnode)) + return pset_prop_read_string(to_pset_node(fwnode), propname, val); + return -ENXIO; +} + /** * fwnode_property_read_string_array - return string array property of a node * @fwnode: Firmware node to get the property of @@ -549,22 +606,13 @@ int fwnode_property_read_string_array(struct fwnode_handle *fwnode, const char *propname, const char **val, size_t nval) { - if (is_of_node(fwnode)) - return val ? - of_property_read_string_array(to_of_node(fwnode), - propname, val, nval) : - of_property_count_strings(to_of_node(fwnode), propname); - else if (is_acpi_node(fwnode)) - return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING, - val, nval); - else if (is_pset_node(fwnode)) - return val ? - pset_prop_read_string_array(to_pset_node(fwnode), - propname, val, nval) : - pset_prop_count_elems_of_size(to_pset_node(fwnode), - propname, - sizeof(const char *)); - return -ENXIO; + int ret; + + ret = __fwnode_property_read_string_array(fwnode, propname, val, nval); + if (ret == -EINVAL && fwnode->secondary) + ret = __fwnode_property_read_string_array(fwnode->secondary, + propname, val, nval); + return ret; } EXPORT_SYMBOL_GPL(fwnode_property_read_string_array); @@ -586,14 +634,13 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_string_array); int fwnode_property_read_string(struct fwnode_handle *fwnode, const char *propname, const char **val) { - if (is_of_node(fwnode)) - return of_property_read_string(to_of_node(fwnode), propname, val); - else if (is_acpi_node(fwnode)) - return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING, - val, 1); - else if (is_pset_node(fwnode)) - return pset_prop_read_string(to_pset_node(fwnode), propname, val); - return -ENXIO; + int ret; + + ret = __fwnode_property_read_string(fwnode, propname, val); + if (ret == -EINVAL && fwnode->secondary) + ret = __fwnode_property_read_string(fwnode->secondary, + propname, val); + return ret; } EXPORT_SYMBOL_GPL(fwnode_property_read_string);