Received: by 2002:a05:6a10:9afc:0:0:0:0 with SMTP id t28csp2192423pxm; Fri, 4 Mar 2022 11:04:53 -0800 (PST) X-Google-Smtp-Source: ABdhPJwodLglDjxmXUHM6Vhrdd75bH/9HvoIAtQB1ADZjtfUZPCEvf1HNzrXPz9WavNGNmiY39Yw X-Received: by 2002:a05:6a00:1516:b0:4be:3d3a:c6d0 with SMTP id q22-20020a056a00151600b004be3d3ac6d0mr44696745pfu.4.1646420693218; Fri, 04 Mar 2022 11:04:53 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1646420693; cv=none; d=google.com; s=arc-20160816; b=xVjDCR6rWJa8BMaOKEYXsFw/hbLpo+hw3+ff7qwxfFQo9EdsAh51E/oIPs7IWpwGHA mLIpgOMWiCJIo5Z//9TmetPw+6WEqIqVwQss9CE0af3cCROViAOYE4awlL3+1wKobiCe 5UvesYz1/r7qqTX6UQVYvorashcQ70eoFff3jgiRItqUMfgDZIx1mB60Fb1mDefD5dyF RY0iw1GGnrZgn5iV42OSsYNlEkDPAkOCZrUOvp71UAdG7/u0qih+FWKZ7KS0fPwF8R2M 4bpwq8KES1OBgxRA1LCXTdP2AaOqpQWKXeu6QdE9C5TVA4wmhQaNyCdypR7KoYvTsh+W cwYA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=uRy0J0DSybhFBbV7vdTYC3G26F9Tm8KBStgUhNFj2TM=; b=I6O+XMkNHlieFnDSeeslxoLTlmvoV3ulojDEjQmidG8wI/cOyyn4j89dQ7LAY0PIX9 Mja1BsVKcpdwsbksb61JtpWfV6WeJZmz+BHcmBYIxh/1E1644LMIuAyOCs76x0QdVQHs iCFrKHu7KKta7WoykkcNrEMfsy+YHy8968vGJ/Gp1nMzoH2v3Qt1pavsUPXApqNMAw/0 +Wx04zzkYda7Z0ZxYDCEn0URxFDQVA2kJkw7EqnGyl5r08eUhAmk0TAg4+MCVT6XxxxR +czYLgJGk46kaBSb2FfOiOa5KsceO8eIfMQy1CM2F4VU44uSXDxQJVlqaNk9mGsSryoL qmSw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=g8C3hNPd; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [2620:137:e000::1:18]) by mx.google.com with ESMTPS id fw23-20020a17090b129700b001bd14e01f80si310714pjb.110.2022.03.04.11.04.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Mar 2022 11:04:53 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) client-ip=2620:137:e000::1:18; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=g8C3hNPd; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 08DCC1E0147; Fri, 4 Mar 2022 11:02:18 -0800 (PST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235421AbiCDReF (ORCPT + 99 others); Fri, 4 Mar 2022 12:34:05 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46082 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241222AbiCDRds (ORCPT ); Fri, 4 Mar 2022 12:33:48 -0500 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9E4AB1BEB5; Fri, 4 Mar 2022 09:32:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1646415166; x=1677951166; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=WxH94sQT9bd80kpGay6iFp+GMfyabjLVSaP0PrDfODE=; b=g8C3hNPdqoeimuZXNIcuXKdAQNhEcAdtZp7+zd87JL4ORoJU5t3SaxNQ JW04lnbhSJMUyAnejCPjGNvSrUT5WPUvZTOIE9Prn6TZPaDAxDqLxdVMp qLOfL7TFIRl8pZPyzn8bcNdqcTY6GMavdn96jqSGED34DtAB0e2lHcSYd rotV6B6O1t/6ss95WOOIkygnkXrt31R/NsjJibMUNm2jDIhFBdywg4YY3 8V16ZNqG49FxDo1TDigxczgHAmKRBJC1RuDm7A1aMoshGyVPndGp49ESM X8p9hLqI07fJFdwbGFLzzfs9ZL/VU05V8kFhZ93WSKPjris1XyKGdKIf8 Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10276"; a="241445927" X-IronPort-AV: E=Sophos;i="5.90,155,1643702400"; d="scan'208";a="241445927" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Mar 2022 09:32:43 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.90,155,1643702400"; d="scan'208";a="552298153" Received: from black.fi.intel.com ([10.237.72.28]) by orsmga008.jf.intel.com with ESMTP; 04 Mar 2022 09:32:40 -0800 Received: by black.fi.intel.com (Postfix, from userid 1003) id 80034A7; Fri, 4 Mar 2022 19:32:58 +0200 (EET) From: Andy Shevchenko To: Andy Shevchenko , "Rafael J. Wysocki" , linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Daniel Scally , Heikki Krogerus , Sakari Ailus , Greg Kroah-Hartman , "Rafael J. Wysocki" , Len Brown , =?UTF-8?q?Nuno=20S=C3=A1?= Subject: [PATCH v2 1/1] device property: Allow error pointer to be passed to fwnode APIs Date: Fri, 4 Mar 2022 19:32:56 +0200 Message-Id: <20220304173256.39059-1-andriy.shevchenko@linux.intel.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.2 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Some of the fwnode APIs might return an error pointer instead of NULL or valid fwnode handle. The result of such API call may be considered optional and hence the test for it is usually done in a form of fwnode = fwnode_find_reference(...); if (IS_ERR_OR_NULL(fwnode)) ...error handling... Nevertheless the resulting fwnode may have bumped reference count and hence caller of the above API is obliged to call fwnode_handle_put(). Since fwnode may be not valid either as NULL or error pointer the check has to be performed there. This approach uglifies the code and adds a point of making a mistake, i.e. forgetting about error point case. To prevent this allow error pointer to be passed to the fwnode APIs. Fixes: 83b34afb6b79 ("device property: Introduce fwnode_find_reference()") Reported-by: Nuno Sá Signed-off-by: Andy Shevchenko --- v2: adjusted the entire fwnode API (Sakari) Nuno, can you test this with the ltc2983 series, including the IS_ERR_OR_NULL() fix to it? drivers/base/property.c | 45 +++++++++++++++++++++++++---------------- include/linux/fwnode.h | 10 ++++----- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/drivers/base/property.c b/drivers/base/property.c index c0e94cce9c29..1922818470b0 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -45,14 +46,16 @@ EXPORT_SYMBOL_GPL(device_property_present); bool fwnode_property_present(const struct fwnode_handle *fwnode, const char *propname) { - bool ret; + if (IS_ERR_OR_NULL(fwnode)) + return false; - ret = fwnode_call_bool_op(fwnode, property_present, propname); - if (ret == false && !IS_ERR_OR_NULL(fwnode) && - !IS_ERR_OR_NULL(fwnode->secondary)) - ret = fwnode_call_bool_op(fwnode->secondary, property_present, - propname); - return ret; + if (fwnode_call_bool_op(fwnode, property_present, propname)) + return true; + + if (IS_ERR_OR_NULL(fwnode->secondary)) + return false; + + return fwnode_call_bool_op(fwnode->secondary, property_present, propname); } EXPORT_SYMBOL_GPL(fwnode_property_present); @@ -232,10 +235,12 @@ static int fwnode_property_read_int_array(const struct fwnode_handle *fwnode, { int ret; + if (IS_ERR_OR_NULL(fwnode)) + return -EINVAL; + ret = fwnode_call_int_op(fwnode, property_read_int_array, propname, elem_size, val, nval); - if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) && - !IS_ERR_OR_NULL(fwnode->secondary)) + if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode->secondary)) ret = fwnode_call_int_op( fwnode->secondary, property_read_int_array, propname, elem_size, val, nval); @@ -371,10 +376,12 @@ int fwnode_property_read_string_array(const struct fwnode_handle *fwnode, { int ret; + if (IS_ERR_OR_NULL(fwnode)) + return -EINVAL; + ret = fwnode_call_int_op(fwnode, property_read_string_array, propname, val, nval); - if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) && - !IS_ERR_OR_NULL(fwnode->secondary)) + if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode->secondary)) ret = fwnode_call_int_op(fwnode->secondary, property_read_string_array, propname, val, nval); @@ -480,11 +487,12 @@ int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode, { int ret; + if (IS_ERR_OR_NULL(fwnode)) + return -ENOENT; + ret = fwnode_call_int_op(fwnode, get_reference_args, prop, nargs_prop, nargs, index, args); - - if (ret < 0 && !IS_ERR_OR_NULL(fwnode) && - !IS_ERR_OR_NULL(fwnode->secondary)) + if (ret < 0 && !IS_ERR_OR_NULL(fwnode->secondary)) ret = fwnode_call_int_op(fwnode->secondary, get_reference_args, prop, nargs_prop, nargs, index, args); @@ -798,6 +806,9 @@ EXPORT_SYMBOL_GPL(fwnode_handle_put); */ bool fwnode_device_is_available(const struct fwnode_handle *fwnode) { + if (IS_ERR_OR_NULL(fwnode)) + return false; + if (!fwnode_has_op(fwnode, device_is_available)) return true; @@ -988,11 +999,11 @@ fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode, parent = fwnode_graph_get_port_parent(prev); else parent = fwnode; + if (IS_ERR_OR_NULL(parent)) + return NULL; ep = fwnode_call_ptr_op(parent, graph_get_next_endpoint, prev); - - if (IS_ERR_OR_NULL(ep) && - !IS_ERR_OR_NULL(parent) && !IS_ERR_OR_NULL(parent->secondary)) + if (!ep && !IS_ERR_OR_NULL(parent->secondary)) ep = fwnode_graph_get_next_endpoint(parent->secondary, NULL); return ep; diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h index 3a532ba66f6c..7defac04f9a3 100644 --- a/include/linux/fwnode.h +++ b/include/linux/fwnode.h @@ -148,12 +148,12 @@ struct fwnode_operations { int (*add_links)(struct fwnode_handle *fwnode); }; -#define fwnode_has_op(fwnode, op) \ - ((fwnode) && (fwnode)->ops && (fwnode)->ops->op) +#define fwnode_has_op(fwnode, op) \ + (!IS_ERR_OR_NULL(fwnode) && (fwnode)->ops && (fwnode)->ops->op) + #define fwnode_call_int_op(fwnode, op, ...) \ - (fwnode ? (fwnode_has_op(fwnode, op) ? \ - (fwnode)->ops->op(fwnode, ## __VA_ARGS__) : -ENXIO) : \ - -EINVAL) + (fwnode_has_op(fwnode, op) ? \ + (fwnode)->ops->op(fwnode, ## __VA_ARGS__) : (IS_ERR_OR_NULL(fwnode) ? -EINVAL : -ENXIO)) #define fwnode_call_bool_op(fwnode, op, ...) \ (fwnode_has_op(fwnode, op) ? \ -- 2.34.1