From patchwork Thu Jul 21 05:05:23 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 72525 Delivered-To: patch@linaro.org Received: by 10.140.29.52 with SMTP id a49csp239272qga; Wed, 20 Jul 2016 22:04:40 -0700 (PDT) X-Received: by 10.98.0.83 with SMTP id 80mr70670119pfa.0.1469077480524; Wed, 20 Jul 2016 22:04:40 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k69si7431263pfa.207.2016.07.20.22.04.34; Wed, 20 Jul 2016 22:04:40 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@nifty.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751314AbcGUFEc (ORCPT + 29 others); Thu, 21 Jul 2016 01:04:32 -0400 Received: from conuserg-11.nifty.com ([210.131.2.78]:20723 "EHLO conuserg-11.nifty.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750800AbcGUFE3 (ORCPT ); Thu, 21 Jul 2016 01:04:29 -0400 Received: from beagle.diag.org (p14092-ipngnfx01kyoto.kyoto.ocn.ne.jp [153.142.97.92]) (authenticated) by conuserg-11.nifty.com with ESMTP id u6L53hil006074; Thu, 21 Jul 2016 14:03:43 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conuserg-11.nifty.com u6L53hil006074 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1469077424; bh=awPX9iKH7kmtgGRu+JYeYYAyGM2ltNHs1wnLf6bFc/o=; h=From:To:Cc:Subject:Date:From; b=YmQa763DPN+9tLVdbbQ6XJNrtyuW0us5pDbGSK+n2hJ2cBsJw+4Z1WZhpzD2XwAqz 0p479aZFp/k5otIHz8Ee3xBCoSNIFjH7juCxv9cJWHicGDZVKQ2KtC4bH2b1Lv19ZM UQNftOkN3fBcmW9wt65xsJpGyCnAl9ZrxoN8rOC6FQ+VmV89iL4vPqTT3iClpp/FDP 8hvNcVdnh8D6rtYl3e7H7H+jGL3LtRC1VUOmCK1Khimv3HfdUodhNxfDIB/gncQZZn YEhdVnj89d4zGE6GKFpMZpj9ySdFNRiNiNbSXErBcvSDzNNVjZ81AYr3LRKf6dV+Bi lF7UkDy98NxlA== X-Nifty-SrcIP: [153.142.97.92] From: Masahiro Yamada To: linux-kernel@vger.kernel.org Cc: Hans de Goede , Philipp Zabel , Lee Jones , Masahiro Yamada Subject: [PATCH] reset: generate reset_control_get variants with macro expansion Date: Thu, 21 Jul 2016 14:05:23 +0900 Message-Id: <1469077523-23163-1-git-send-email-yamada.masahiro@socionext.com> X-Mailer: git-send-email 1.9.1 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The recent update in the reset subsystem requires all reset consumers to be explicit about the requested reset lines; _explicit or _shared. This effectively doubled the number of reset_control_get variants. Also, we already had _optional variants. We see some pattern in the reset_control_get APIs. There are 6 base functions in terms of function prototype: reset_control_get reset_control_get_by_index of_reset_control_get of_reset_control_get_by_index devm_reset_control_get devm_reset_control_get_by_index Each of them has 4 variants with the following suffixes: _exclusive _shared _optional_exclusive _optional_shared The exhaustive set of functions (6 * 4) can be generated with macro expansion. It will mitigate the pain of maintaining proliferating APIs. I merged similar comment blocks into two, for functions in core.c because copy-paste work for similar comment blocks is error-prone. Signed-off-by: Masahiro Yamada --- drivers/reset/core.c | 36 ++++++ include/linux/reset.h | 306 +++++++++----------------------------------------- 2 files changed, 86 insertions(+), 256 deletions(-) -- 1.9.1 diff --git a/drivers/reset/core.c b/drivers/reset/core.c index e21251d..dd536c3 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -257,6 +257,30 @@ static void __reset_control_put(struct reset_control *rstc) kfree(rstc); } +/** + * __of_reset_control_get - Lookup and obtain a reference to a reset controller. + * @node: device to be reset by the controller + * @id: optional reset line name + * @index: index of the reset line (valid iif @id is NULL) + * @shared: shareability of reset control + * + * Returns a struct reset_control or IS_ERR() condition containing errno. + * The target reset line can be specified by either @id or @index. + * + * Set the @shared flag for use with reset-controls which are shared between + * multiple hardware blocks. When a reset-control is shared, the behavior of + * reset_control_assert / deassert is changed; the reset-core will keep track + * of a deassert_count and only (re-)assert the reset after reset_control_assert + * has been called as many times as reset_control_deassert was called. Calling + * reset_control_assert without first calling reset_control_deassert is not + * allowed on a shared reset control. Calling reset_control_reset is also not + * allowed on a shared reset control. Also see the remark about shared reset + * controls in the reset_control_assert docs. + * + * If the @shared flag is not set, this function gets an exclusive reference to + * a reset controller; if this function is called more then once for the same + * reset_control it will return -EBUSY. + */ struct reset_control *__of_reset_control_get(struct device_node *node, const char *id, int index, int shared) { @@ -337,6 +361,18 @@ static void devm_reset_control_release(struct device *dev, void *res) reset_control_put(*(struct reset_control **)res); } +/** + * __devm_reset_control_get - resource managed __of_reset_control_get() + * @dev: device to be reset by the controller + * @id: optional reset line name + * @index: index of the reset line (valid iif @id is NULL) + * @shared: shareability of reset control + * + * Managed __of_reset_control_get(). For reset controllers returned from this + * function, reset_control_put() is called automatically on driver detach. + * + * See __of_reset_control_get() for more information. + */ struct reset_control *__devm_reset_control_get(struct device *dev, const char *id, int index, int shared) { diff --git a/include/linux/reset.h b/include/linux/reset.h index cb7db61..5894f0f 100644 --- a/include/linux/reset.h +++ b/include/linux/reset.h @@ -83,262 +83,56 @@ static inline struct reset_control *__devm_reset_control_get( #endif /* CONFIG_RESET_CONTROLLER */ -/** - * reset_control_get_exclusive - Lookup and obtain an exclusive reference - * to a reset controller. - * @dev: device to be reset by the controller - * @id: reset line name - * - * Returns a struct reset_control or IS_ERR() condition containing errno. - * If this function is called more then once for the same reset_control it will - * return -EBUSY. - * - * See reset_control_get_shared for details on shared references to - * reset-controls. - * - * Use of id names is optional. - */ -static inline struct reset_control * -__must_check reset_control_get_exclusive(struct device *dev, const char *id) -{ -#ifndef CONFIG_RESET_CONTROLLER - WARN_ON(1); -#endif - return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, 0); -} - -/** - * reset_control_get_shared - Lookup and obtain a shared reference to a - * reset controller. - * @dev: device to be reset by the controller - * @id: reset line name - * - * Returns a struct reset_control or IS_ERR() condition containing errno. - * This function is intended for use with reset-controls which are shared - * between hardware-blocks. - * - * When a reset-control is shared, the behavior of reset_control_assert / - * deassert is changed, the reset-core will keep track of a deassert_count - * and only (re-)assert the reset after reset_control_assert has been called - * as many times as reset_control_deassert was called. Also see the remark - * about shared reset-controls in the reset_control_assert docs. - * - * Calling reset_control_assert without first calling reset_control_deassert - * is not allowed on a shared reset control. Calling reset_control_reset is - * also not allowed on a shared reset control. - * - * Use of id names is optional. - */ -static inline struct reset_control *reset_control_get_shared( - struct device *dev, const char *id) -{ -#ifndef CONFIG_RESET_CONTROLLER - WARN_ON(1); -#endif - return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, 1); -} - -static inline struct reset_control *reset_control_get_optional_exclusive( - struct device *dev, const char *id) -{ - return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, 0); -} - -static inline struct reset_control *reset_control_get_optional_shared( - struct device *dev, const char *id) -{ - return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, 1); -} - -/** - * of_reset_control_get_exclusive - Lookup and obtain an exclusive reference - * to a reset controller. - * @node: device to be reset by the controller - * @id: reset line name - * - * Returns a struct reset_control or IS_ERR() condition containing errno. - * - * Use of id names is optional. - */ -static inline struct reset_control *of_reset_control_get_exclusive( - struct device_node *node, const char *id) -{ -#ifndef CONFIG_RESET_CONTROLLER - WARN_ON(1); -#endif - return __of_reset_control_get(node, id, 0, 0); -} - -/** - * of_reset_control_get_shared - Lookup and obtain an shared reference - * to a reset controller. - * @node: device to be reset by the controller - * @id: reset line name - * - * When a reset-control is shared, the behavior of reset_control_assert / - * deassert is changed, the reset-core will keep track of a deassert_count - * and only (re-)assert the reset after reset_control_assert has been called - * as many times as reset_control_deassert was called. Also see the remark - * about shared reset-controls in the reset_control_assert docs. - * - * Calling reset_control_assert without first calling reset_control_deassert - * is not allowed on a shared reset control. Calling reset_control_reset is - * also not allowed on a shared reset control. - * Returns a struct reset_control or IS_ERR() condition containing errno. - * - * Use of id names is optional. - */ -static inline struct reset_control *of_reset_control_get_shared( - struct device_node *node, const char *id) -{ -#ifndef CONFIG_RESET_CONTROLLER - WARN_ON(1); -#endif - return __of_reset_control_get(node, id, 0, 1); -} - -/** - * of_reset_control_get_exclusive_by_index - Lookup and obtain an exclusive - * reference to a reset controller - * by index. - * @node: device to be reset by the controller - * @index: index of the reset controller - * - * This is to be used to perform a list of resets for a device or power domain - * in whatever order. Returns a struct reset_control or IS_ERR() condition - * containing errno. - */ -static inline struct reset_control *of_reset_control_get_exclusive_by_index( - struct device_node *node, int index) -{ -#ifndef CONFIG_RESET_CONTROLLER - WARN_ON(1); -#endif - return __of_reset_control_get(node, NULL, index, 0); -} - -/** - * of_reset_control_get_shared_by_index - Lookup and obtain an shared - * reference to a reset controller - * by index. - * @node: device to be reset by the controller - * @index: index of the reset controller - * - * When a reset-control is shared, the behavior of reset_control_assert / - * deassert is changed, the reset-core will keep track of a deassert_count - * and only (re-)assert the reset after reset_control_assert has been called - * as many times as reset_control_deassert was called. Also see the remark - * about shared reset-controls in the reset_control_assert docs. - * - * Calling reset_control_assert without first calling reset_control_deassert - * is not allowed on a shared reset control. Calling reset_control_reset is - * also not allowed on a shared reset control. - * Returns a struct reset_control or IS_ERR() condition containing errno. - * - * This is to be used to perform a list of resets for a device or power domain - * in whatever order. Returns a struct reset_control or IS_ERR() condition - * containing errno. - */ -static inline struct reset_control *of_reset_control_get_shared_by_index( - struct device_node *node, int index) -{ -#ifndef CONFIG_RESET_CONTROLLER - WARN_ON(1); -#endif - return __of_reset_control_get(node, NULL, index, 1); -} - -/** - * devm_reset_control_get_exclusive - resource managed - * reset_control_get_exclusive() - * @dev: device to be reset by the controller - * @id: reset line name - * - * Managed reset_control_get_exclusive(). For reset controllers returned - * from this function, reset_control_put() is called automatically on driver - * detach. - * - * See reset_control_get_exclusive() for more information. - */ -static inline struct reset_control * -__must_check devm_reset_control_get_exclusive(struct device *dev, - const char *id) -{ -#ifndef CONFIG_RESET_CONTROLLER - WARN_ON(1); -#endif - return __devm_reset_control_get(dev, id, 0, 0); -} - -/** - * devm_reset_control_get_shared - resource managed reset_control_get_shared() - * @dev: device to be reset by the controller - * @id: reset line name - * - * Managed reset_control_get_shared(). For reset controllers returned from - * this function, reset_control_put() is called automatically on driver detach. - * See reset_control_get_shared() for more information. - */ -static inline struct reset_control *devm_reset_control_get_shared( - struct device *dev, const char *id) -{ -#ifndef CONFIG_RESET_CONTROLLER - WARN_ON(1); -#endif - return __devm_reset_control_get(dev, id, 0, 1); -} - -static inline struct reset_control *devm_reset_control_get_optional_exclusive( - struct device *dev, const char *id) -{ - return __devm_reset_control_get(dev, id, 0, 0); -} - -static inline struct reset_control *devm_reset_control_get_optional_shared( - struct device *dev, const char *id) -{ - return __devm_reset_control_get(dev, id, 0, 1); -} - -/** - * devm_reset_control_get_exclusive_by_index - resource managed - * reset_control_get_exclusive() - * @dev: device to be reset by the controller - * @index: index of the reset controller - * - * Managed reset_control_get_exclusive(). For reset controllers returned from - * this function, reset_control_put() is called automatically on driver - * detach. - * - * See reset_control_get_exclusive() for more information. - */ -static inline struct reset_control * -devm_reset_control_get_exclusive_by_index(struct device *dev, int index) -{ -#ifndef CONFIG_RESET_CONTROLLER - WARN_ON(1); -#endif - return __devm_reset_control_get(dev, NULL, index, 0); -} - -/** - * devm_reset_control_get_shared_by_index - resource managed - * reset_control_get_shared - * @dev: device to be reset by the controller - * @index: index of the reset controller - * - * Managed reset_control_get_shared(). For reset controllers returned from - * this function, reset_control_put() is called automatically on driver detach. - * See reset_control_get_shared() for more information. - */ -static inline struct reset_control * -devm_reset_control_get_shared_by_index(struct device *dev, int index) -{ -#ifndef CONFIG_RESET_CONTROLLER - WARN_ON(1); -#endif - return __devm_reset_control_get(dev, NULL, index, 1); -} +#define GENERATE_RESET_CONTROL_GET_FUNCS(optional, shared, suffix) \ +static inline struct reset_control * __must_check \ +reset_control_get_ ## suffix(struct device *dev, const char *id) \ +{ \ + WARN_ON(!IS_ENABLED(CONFIG_RESET_CONTROLLER) && !optional); \ + return __of_reset_control_get(dev ? dev->of_node : NULL, \ + id, 0, shared); \ +} \ + \ +static inline struct reset_control * __must_check \ +reset_control_get_ ## suffix ## _by_index(struct device *dev, int index)\ +{ \ + WARN_ON(!IS_ENABLED(CONFIG_RESET_CONTROLLER) && !optional); \ + return __of_reset_control_get(dev ? dev->of_node : NULL, \ + NULL, index, shared); \ +} \ + \ +static inline struct reset_control * __must_check \ +of_reset_control_get_ ## suffix(struct device_node *node, const char *id)\ +{ \ + WARN_ON(!IS_ENABLED(CONFIG_RESET_CONTROLLER) && !optional); \ + return __of_reset_control_get(node, id, 0, shared); \ +} \ + \ +static inline struct reset_control * __must_check \ +of_reset_control_get_ ## suffix ## _by_index(struct device_node *node, \ + int index) \ +{ \ + WARN_ON(!IS_ENABLED(CONFIG_RESET_CONTROLLER) && !optional); \ + return __of_reset_control_get(node, NULL, index, shared); \ +} \ + \ +static inline struct reset_control * __must_check \ +devm_reset_control_get_ ## suffix(struct device *dev, const char *id) \ +{ \ + WARN_ON(!IS_ENABLED(CONFIG_RESET_CONTROLLER) && !optional); \ + return __devm_reset_control_get(dev, id, 0, shared); \ +} \ + \ +static inline struct reset_control * __must_check \ +devm_reset_control_get_ ## suffix ## _by_index(struct device *dev, int index)\ +{ \ + WARN_ON(!IS_ENABLED(CONFIG_RESET_CONTROLLER) && !optional); \ + return __devm_reset_control_get(dev, 0, index, shared); \ +} + +GENERATE_RESET_CONTROL_GET_FUNCS(0, 0, exclusive) +GENERATE_RESET_CONTROL_GET_FUNCS(0, 1, shared) +GENERATE_RESET_CONTROL_GET_FUNCS(1, 0, optional_exclusive) +GENERATE_RESET_CONTROL_GET_FUNCS(1, 1, optional_shared) /* * TEMPORARY calls to use during transition: