From patchwork Tue Sep 20 02:01:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jianqun Xu X-Patchwork-Id: 608456 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 50E17C6FA82 for ; Tue, 20 Sep 2022 02:01:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230060AbiITCBp (ORCPT ); Mon, 19 Sep 2022 22:01:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56946 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230089AbiITCBo (ORCPT ); Mon, 19 Sep 2022 22:01:44 -0400 Received: from mail-m11879.qiye.163.com (mail-m11879.qiye.163.com [115.236.118.79]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 65E2F57210 for ; Mon, 19 Sep 2022 19:01:42 -0700 (PDT) Received: from localhost.localdomain (unknown [58.22.7.114]) by mail-m11879.qiye.163.com (Hmail) with ESMTPA id 4BC276805D2; Tue, 20 Sep 2022 10:01:40 +0800 (CST) From: Jianqun Xu To: jbx6244@gmail.com, heiko@sntech.de, linus.walleij@linaro.org, andriy.shevchenko@linux.intel.com Cc: brgl@bgdev.pl, linux-gpio@vger.kernel.org, linux-rockchip@lists.infradead.org, Hans de Goede Subject: [PATCH v8 1/3] ACPI: utils: Add acpi_dev_uid_to_integer() helper to get _UID as integer Date: Tue, 20 Sep 2022 10:01:36 +0800 Message-Id: <20220920020138.861083-2-jay.xu@rock-chips.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220920020138.861083-1-jay.xu@rock-chips.com> References: <20220920020138.861083-1-jay.xu@rock-chips.com> MIME-Version: 1.0 X-HM-Spam-Status: e1kfGhgUHx5ZQUpXWQgPGg8OCBgUHx5ZQUlOS1dZFg8aDwILHllBWSg2Ly tZV1koWUFJSktLSjdXWS1ZQUlXWQ8JGhUIEh9ZQVlDHksaVhkYHksaSUNCTEtMHlUTARMWGhIXJB QOD1lXWRgSC1lBWU5DVUlJVUxVSkpPWVdZFhoPEhUdFFlBWU9LSFVKSktISkxVSktLVUtZBg++ X-HM-Sender-Digest: e1kMHhlZQR0aFwgeV1kSHx4VD1lBWUc6Nzo6DQw*Tz0eCB5RKykfTUo# Eh1PFBJVSlVKTU1ITUhCSEtLQkpIVTMWGhIXVREaAlUDDjsJFBgQVhgTEgsIVRgUFkVZV1kSC1lB WU5DVUlJVUxVSkpPWVdZCAFZQUhDS0k3Bg++ X-HM-Tid: 0a8358a129942eb5kusn4bc276805d2 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Andy Shevchenko Some users interpret _UID only as integer and for them it's easier to have an integer representation of _UID. Add respective helper for that. Signed-off-by: Andy Shevchenko Reviewed-by: Hans de Goede --- v8: - none drivers/acpi/utils.c | 24 ++++++++++++++++++++++++ include/acpi/acpi_bus.h | 1 + include/linux/acpi.h | 5 +++++ 3 files changed, 30 insertions(+) diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 5a7b8065e77f..febf9b8da3a0 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -793,6 +793,30 @@ bool acpi_dev_hid_uid_match(struct acpi_device *adev, } EXPORT_SYMBOL(acpi_dev_hid_uid_match); +/** + * acpi_dev_uid_to_integer - treat ACPI device _UID as integer + * @adev: ACPI device to get _UID from + * @integer: output buffer for integer + * + * Considers _UID as integer and converts it to @integer. + * + * Returns 0 on success, or negative error code otherwise. + */ +int acpi_dev_uid_to_integer(struct acpi_device *adev, u64 *integer) +{ + const char *uid; + + if (!adev) + return -ENODEV; + + uid = acpi_device_uid(adev); + if (!uid) + return -ENODATA; + + return kstrtou64(uid, 0, integer); +} +EXPORT_SYMBOL(acpi_dev_uid_to_integer); + /** * acpi_dev_found - Detect presence of a given ACPI device in the namespace. * @hid: Hardware ID of the device. diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index e7d27373ff71..bd0db916f330 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -733,6 +733,7 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev) } bool acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2); +int acpi_dev_uid_to_integer(struct acpi_device *adev, u64 *integer); void acpi_dev_clear_dependencies(struct acpi_device *supplier); bool acpi_dev_ready_for_enumeration(const struct acpi_device *device); diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 6f64b2f3dc54..9434db02cb60 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -798,6 +798,11 @@ acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *u return false; } +static inline int acpi_dev_uid_to_integer(struct acpi_device *adev, u64 *integer) +{ + return -ENODEV; +} + static inline struct acpi_device * acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv) { From patchwork Tue Sep 20 02:01:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jianqun Xu X-Patchwork-Id: 607819 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 24C65C6FA91 for ; Tue, 20 Sep 2022 02:01:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230085AbiITCBq (ORCPT ); Mon, 19 Sep 2022 22:01:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57020 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230089AbiITCBp (ORCPT ); Mon, 19 Sep 2022 22:01:45 -0400 Received: from mail-m11879.qiye.163.com (mail-m11879.qiye.163.com [115.236.118.79]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0F6EE53D3F for ; Mon, 19 Sep 2022 19:01:43 -0700 (PDT) Received: from localhost.localdomain (unknown [58.22.7.114]) by mail-m11879.qiye.163.com (Hmail) with ESMTPA id 05A9B6806D8; Tue, 20 Sep 2022 10:01:40 +0800 (CST) From: Jianqun Xu To: jbx6244@gmail.com, heiko@sntech.de, linus.walleij@linaro.org, andriy.shevchenko@linux.intel.com Cc: brgl@bgdev.pl, linux-gpio@vger.kernel.org, linux-rockchip@lists.infradead.org, Jianqun Xu Subject: [PATCH v8 2/3] gpio: rockchip: support acpi Date: Tue, 20 Sep 2022 10:01:37 +0800 Message-Id: <20220920020138.861083-3-jay.xu@rock-chips.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220920020138.861083-1-jay.xu@rock-chips.com> References: <20220920020138.861083-1-jay.xu@rock-chips.com> MIME-Version: 1.0 X-HM-Spam-Status: e1kfGhgUHx5ZQUpXWQgPGg8OCBgUHx5ZQUlOS1dZFg8aDwILHllBWSg2Ly tZV1koWUFJSktLSjdXWS1ZQUlXWQ8JGhUIEh9ZQVlDT0tDVkJITUNPQkNMHRlKTFUTARMWGhIXJB QOD1lXWRgSC1lBWU5DVUlJVUxVSkpPWVdZFhoPEhUdFFlBWU9LSFVKSktISkxVSktLVUtZBg++ X-HM-Sender-Digest: e1kMHhlZQR0aFwgeV1kSHx4VD1lBWUc6NVE6Czo4Qj0jEB4TKykMTU4t MTcwCQFVSlVKTU1ITUhCSEtKQ0hOVTMWGhIXVREaAlUDDjsJFBgQVhgTEgsIVRgUFkVZV1kSC1lB WU5DVUlJVUxVSkpPWVdZCAFZQUpOT0xPNwY+ X-HM-Tid: 0a8358a12c9e2eb5kusn05a9b6806d8 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org The GPIO driver for Rockchip GPIO controller is seperated from rockchip pinctrl driver, at the first version, it keeps things original to make the patch easy to be reviewed, such as the GPIO driver must work with the pinctrl dt node to be its parent node. This patch wants to fix the driver to support ACPI since GPIO controller should work well during ACPI is enabled. Changes including: - only get clocks when is_of_node since ACPI case not need. - get io resource and irq by platform common apis. - use fwnode instead of of_node from device structure. - drop pinctrl related codes, pinctrl self should to find the gpiochip. Signed-off-by: Jianqun Xu --- v8: - move gpio_chip as the first member of bank structure - fix typper 'trriger' to 'trigger' - add pull and drive-strength set for rockchip_gpio_set_config - fix clock error path drivers/gpio/gpio-rockchip.c | 326 +++++++++++++++++++---------------- 1 file changed, 182 insertions(+), 144 deletions(-) diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c index ebb50c25a461..967d6dc8aa65 100644 --- a/drivers/gpio/gpio-rockchip.c +++ b/drivers/gpio/gpio-rockchip.c @@ -6,9 +6,9 @@ * Copyright (c) 2021 Rockchip Electronics Co. Ltd. */ +#include #include #include -#include #include #include #include @@ -16,19 +16,90 @@ #include #include #include -#include -#include -#include -#include +#include +#include #include -#include "../pinctrl/core.h" -#include "../pinctrl/pinctrl-rockchip.h" - #define GPIO_TYPE_V1 (0) /* GPIO Version ID reserved */ #define GPIO_TYPE_V2 (0x01000C2B) /* GPIO Version ID 0x01000C2B */ #define GPIO_TYPE_V2_1 (0x0101157C) /* GPIO Version ID 0x0101157C */ +#define GPIO_MAX_PINS (32) + +/** + * struct rockchip_gpio_regs + * @port_dr: data register + * @port_ddr: data direction register + * @int_en: interrupt enable + * @int_mask: interrupt mask + * @int_type: interrupt trigger type, such as high, low, edge trigger type. + * @int_polarity: interrupt polarity enable register + * @int_bothedge: interrupt bothedge enable register + * @int_status: interrupt status register + * @int_rawstatus: int_status = int_rawstatus & int_mask + * @debounce: enable debounce for interrupt signal + * @dbclk_div_en: enable divider for debounce clock + * @dbclk_div_con: setting for divider of debounce clock + * @port_eoi: end of interrupt of the port + * @ext_port: port data from external + * @version_id: controller version register + */ +struct rockchip_gpio_regs { + u32 port_dr; + u32 port_ddr; + u32 int_en; + u32 int_mask; + u32 int_type; + u32 int_polarity; + u32 int_bothedge; + u32 int_status; + u32 int_rawstatus; + u32 debounce; + u32 dbclk_div_en; + u32 dbclk_div_con; + u32 port_eoi; + u32 ext_port; + u32 version_id; +}; + +/** + * struct rockchip_pin_bank + * @dev: the pinctrl device bind to the bank + * @reg_base: register base of the gpio bank + * @clk: clock of the gpio bank + * @db_clk: clock of the gpio debounce + * @irq: interrupt of the gpio bank + * @saved_masks: Saved content of GPIO_INTEN at suspend time. + * @pin_base: first pin number + * @nr_pins: number of pins in this bank + * @name: name of the bank + * @bank_num: number of the bank, to account for holes + * @domain: irqdomain of the gpio bank + * @gpio_chip: gpiolib chip + * @grange: gpio range + * @slock: spinlock for the gpio bank + * @toggle_edge_mode: bit mask to toggle (falling/rising) edge mode + */ +struct rockchip_pin_bank { + struct gpio_chip gpio_chip; + struct device *dev; + void __iomem *reg_base; + struct clk *clk; + struct clk *db_clk; + int irq; + u32 saved_masks; + u32 pin_base; + u8 nr_pins; + char *name; + u8 bank_num; + struct device_node *of_node; + struct irq_domain *domain; + raw_spinlock_t slock; + const struct rockchip_gpio_regs *gpio_regs; + u32 gpio_type; + u32 toggle_edge_mode; +}; + static const struct rockchip_gpio_regs gpio_regs_v1 = { .port_dr = 0x00, .port_ddr = 0x04, @@ -200,6 +271,9 @@ static int rockchip_gpio_set_debounce(struct gpio_chip *gc, if (bank->gpio_type == GPIO_TYPE_V2 && !IS_ERR(bank->db_clk)) { div_debounce_support = true; freq = clk_get_rate(bank->db_clk); + if (!freq) + return -EINVAL; + max_debounce = (GENMASK(23, 0) + 1) * 2 * 1000000 / freq; if (debounce > max_debounce) return -EINVAL; @@ -286,6 +360,11 @@ static int rockchip_gpio_set_config(struct gpio_chip *gc, unsigned int offset, * of gpiod_set_debounce won't change its behaviour. */ return -ENOTSUPP; + case PIN_CONFIG_BIAS_DISABLE: + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_DRIVE_STRENGTH: + return pinctrl_gpio_set_config(offset, config); default: return -ENOTSUPP; } @@ -507,21 +586,20 @@ static int rockchip_interrupts_register(struct rockchip_pin_bank *bank) struct irq_chip_generic *gc; int ret; - bank->domain = irq_domain_add_linear(bank->of_node, 32, - &irq_generic_chip_ops, NULL); + bank->domain = irq_domain_create_linear(dev_fwnode(bank->dev), + GPIO_MAX_PINS, + &irq_generic_chip_ops, NULL); if (!bank->domain) { - dev_warn(bank->dev, "could not init irq domain for bank %s\n", - bank->name); + dev_warn(bank->dev, "could not init irq domain\n"); return -EINVAL; } - ret = irq_alloc_domain_generic_chips(bank->domain, 32, 1, + ret = irq_alloc_domain_generic_chips(bank->domain, GPIO_MAX_PINS, 1, "rockchip_gpio_irq", handle_level_irq, clr, 0, 0); if (ret) { - dev_err(bank->dev, "could not alloc generic chips for bank %s\n", - bank->name); + dev_err(bank->dev, "could not alloc generic chips\n"); irq_domain_remove(bank->domain); return -EINVAL; } @@ -575,8 +653,13 @@ static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank) gc = &bank->gpio_chip; gc->base = bank->pin_base; gc->ngpio = bank->nr_pins; - gc->label = bank->name; gc->parent = bank->dev; + gc->label = devm_kasprintf(bank->dev, GFP_KERNEL, "gpio%d", bank->bank_num); + if (!gc->label) + return -ENOMEM; +#ifdef CONFIG_OF_GPIO + gc->of_node = of_node_get(bank->dev->of_node); +#endif ret = gpiochip_add_data(gc, bank); if (ret) { @@ -585,35 +668,6 @@ static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank) return ret; } - /* - * For DeviceTree-supported systems, the gpio core checks the - * pinctrl's device node for the "gpio-ranges" property. - * If it is present, it takes care of adding the pin ranges - * for the driver. In this case the driver can skip ahead. - * - * In order to remain compatible with older, existing DeviceTree - * files which don't set the "gpio-ranges" property or systems that - * utilize ACPI the driver has to call gpiochip_add_pin_range(). - */ - if (!of_property_read_bool(bank->of_node, "gpio-ranges")) { - struct device_node *pctlnp = of_get_parent(bank->of_node); - struct pinctrl_dev *pctldev = NULL; - - if (!pctlnp) - return -ENODATA; - - pctldev = of_pinctrl_get(pctlnp); - if (!pctldev) - return -ENODEV; - - ret = gpiochip_add_pin_range(gc, dev_name(pctldev->dev), 0, - gc->base, gc->ngpio); - if (ret) { - dev_err(bank->dev, "Failed to add pin range\n"); - goto fail; - } - } - ret = rockchip_interrupts_register(bank); if (ret) { dev_err(bank->dev, "failed to register interrupt, %d\n", ret); @@ -628,153 +682,137 @@ static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank) return ret; } -static int rockchip_get_bank_data(struct rockchip_pin_bank *bank) +static int rockchip_gpio_set_regs(struct rockchip_pin_bank *bank) { - struct resource res; - int id = 0; - - if (of_address_to_resource(bank->of_node, 0, &res)) { - dev_err(bank->dev, "cannot find IO resource for bank\n"); - return -ENOENT; - } - - bank->reg_base = devm_ioremap_resource(bank->dev, &res); - if (IS_ERR(bank->reg_base)) - return PTR_ERR(bank->reg_base); - - bank->irq = irq_of_parse_and_map(bank->of_node, 0); - if (!bank->irq) - return -EINVAL; + struct device *dev = bank->dev; + struct fwnode_handle *fwnode = dev_fwnode(dev); + int version_id; + int ret; - bank->clk = of_clk_get(bank->of_node, 0); - if (IS_ERR(bank->clk)) - return PTR_ERR(bank->clk); + if (is_of_node(fwnode)) { + bank->clk = of_clk_get(to_of_node(fwnode), 0); + if (IS_ERR(bank->clk)) + return PTR_ERR(bank->clk); - clk_prepare_enable(bank->clk); - id = readl(bank->reg_base + gpio_regs_v2.version_id); + ret = clk_prepare_enable(bank->clk); + if (ret < 0) + goto put_clk; + } - /* If not gpio v2, that is default to v1. */ - if (id == GPIO_TYPE_V2 || id == GPIO_TYPE_V2_1) { + version_id = readl(bank->reg_base + gpio_regs_v2.version_id); + if (version_id == GPIO_TYPE_V2 || version_id == GPIO_TYPE_V2_1) { bank->gpio_regs = &gpio_regs_v2; bank->gpio_type = GPIO_TYPE_V2; - bank->db_clk = of_clk_get(bank->of_node, 1); - if (IS_ERR(bank->db_clk)) { - dev_err(bank->dev, "cannot find debounce clk\n"); - clk_disable_unprepare(bank->clk); - return -EINVAL; - } } else { bank->gpio_regs = &gpio_regs_v1; bank->gpio_type = GPIO_TYPE_V1; } + if (bank->gpio_type == GPIO_TYPE_V2 && is_of_node(fwnode)) { + bank->db_clk = of_clk_get(to_of_node(fwnode), 1); + if (IS_ERR(bank->db_clk)) { + ret = PTR_ERR(bank->db_clk); + goto unprepare_clk; + } + + ret = clk_prepare_enable(bank->db_clk); + if (ret < 0) { + clk_put(bank->db_clk); + goto unprepare_clk; + } + } + return 0; +unprepare_clk: + clk_disable_unprepare(bank->clk); +put_clk: + clk_put(bank->clk); + + return ret; } -static struct rockchip_pin_bank * -rockchip_gpio_find_bank(struct pinctrl_dev *pctldev, int id) +static int rockchip_gpio_get_bank_id(struct device *dev) { - struct rockchip_pinctrl *info; - struct rockchip_pin_bank *bank; - int i, found = 0; + struct fwnode_handle *fwnode = dev_fwnode(dev); + int bank_id = -EINVAL; + u64 uid; + int ret; + static int gpio; - info = pinctrl_dev_get_drvdata(pctldev); - bank = info->ctrl->pin_banks; - for (i = 0; i < info->ctrl->nr_banks; i++, bank++) { - if (bank->bank_num == id) { - found = 1; - break; - } + if (is_acpi_node(fwnode)) { + ret = acpi_dev_uid_to_integer(ACPI_COMPANION(dev), &uid); + if (ret < 0) + return ret; + + bank_id = uid; + } else { + bank_id = of_alias_get_id(to_of_node(fwnode), "gpio"); + if (bank_id < 0) + bank_id = gpio++; } - return found ? bank : NULL; + return bank_id; } static int rockchip_gpio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - struct device_node *pctlnp = of_get_parent(np); - struct pinctrl_dev *pctldev = NULL; - struct rockchip_pin_bank *bank = NULL; - struct rockchip_pin_deferred *cfg; - static int gpio; - int id, ret; + struct rockchip_pin_bank *bank; + int ret; - if (!np || !pctlnp) - return -ENODEV; + bank = devm_kzalloc(dev, sizeof(*bank), GFP_KERNEL); + if (!bank) + return -ENOMEM; - pctldev = of_pinctrl_get(pctlnp); - if (!pctldev) - return -EPROBE_DEFER; + bank->reg_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(bank->reg_base)) + return PTR_ERR(bank->reg_base); - id = of_alias_get_id(np, "gpio"); - if (id < 0) - id = gpio++; + bank->irq = platform_get_irq(pdev, 0); + if (bank->irq < 0) + return bank->irq; - bank = rockchip_gpio_find_bank(pctldev, id); - if (!bank) - return -EINVAL; + bank->bank_num = rockchip_gpio_get_bank_id(dev); + if (bank->bank_num < 0) + return bank->bank_num; bank->dev = dev; - bank->of_node = np; + bank->pin_base = GPIO_MAX_PINS * bank->bank_num; + bank->nr_pins = GPIO_MAX_PINS; - raw_spin_lock_init(&bank->slock); - - ret = rockchip_get_bank_data(bank); + ret = rockchip_gpio_set_regs(bank); if (ret) return ret; - /* - * Prevent clashes with a deferred output setting - * being added right at this moment. - */ - mutex_lock(&bank->deferred_lock); + raw_spin_lock_init(&bank->slock); ret = rockchip_gpiolib_register(bank); if (ret) { - clk_disable_unprepare(bank->clk); - mutex_unlock(&bank->deferred_lock); - return ret; - } - - while (!list_empty(&bank->deferred_pins)) { - cfg = list_first_entry(&bank->deferred_pins, - struct rockchip_pin_deferred, head); - list_del(&cfg->head); - - switch (cfg->param) { - case PIN_CONFIG_OUTPUT: - ret = rockchip_gpio_direction_output(&bank->gpio_chip, cfg->pin, cfg->arg); - if (ret) - dev_warn(dev, "setting output pin %u to %u failed\n", cfg->pin, - cfg->arg); - break; - case PIN_CONFIG_INPUT_ENABLE: - ret = rockchip_gpio_direction_input(&bank->gpio_chip, cfg->pin); - if (ret) - dev_warn(dev, "setting input pin %u failed\n", cfg->pin); - break; - default: - dev_warn(dev, "unknown deferred config param %d\n", cfg->param); - break; - } - kfree(cfg); + dev_err(bank->dev, "Failed to register gpio %d\n", ret); + goto err; } - mutex_unlock(&bank->deferred_lock); - platform_set_drvdata(pdev, bank); - dev_info(dev, "probed %pOF\n", np); + dev_info(dev, "probed %pfw\n", dev_fwnode(dev)); return 0; +err: + clk_put(bank->clk); + clk_put(bank->db_clk); + clk_disable_unprepare(bank->clk); + clk_disable_unprepare(bank->db_clk); + + return ret; } static int rockchip_gpio_remove(struct platform_device *pdev) { struct rockchip_pin_bank *bank = platform_get_drvdata(pdev); + clk_put(bank->clk); + clk_put(bank->db_clk); clk_disable_unprepare(bank->clk); + clk_disable_unprepare(bank->db_clk); gpiochip_remove(&bank->gpio_chip); return 0; From patchwork Tue Sep 20 02:01:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jianqun Xu X-Patchwork-Id: 608455 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A0C82C6FA8B for ; Tue, 20 Sep 2022 02:01:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230083AbiITCBq (ORCPT ); Mon, 19 Sep 2022 22:01:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57010 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230088AbiITCBp (ORCPT ); Mon, 19 Sep 2022 22:01:45 -0400 Received: from mail-m11879.qiye.163.com (mail-m11879.qiye.163.com [115.236.118.79]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 88A4156BB9 for ; Mon, 19 Sep 2022 19:01:44 -0700 (PDT) Received: from localhost.localdomain (unknown [58.22.7.114]) by mail-m11879.qiye.163.com (Hmail) with ESMTPA id E7AA268025A; Tue, 20 Sep 2022 10:01:41 +0800 (CST) From: Jianqun Xu To: jbx6244@gmail.com, heiko@sntech.de, linus.walleij@linaro.org, andriy.shevchenko@linux.intel.com Cc: brgl@bgdev.pl, linux-gpio@vger.kernel.org, linux-rockchip@lists.infradead.org, Jianqun Xu Subject: [PATCH v8 3/3] gpiolib: make gpiochip_find_by_name to be common function Date: Tue, 20 Sep 2022 10:01:38 +0800 Message-Id: <20220920020138.861083-4-jay.xu@rock-chips.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220920020138.861083-1-jay.xu@rock-chips.com> References: <20220920020138.861083-1-jay.xu@rock-chips.com> MIME-Version: 1.0 X-HM-Spam-Status: e1kfGhgUHx5ZQUpXWQgPGg8OCBgUHx5ZQUlOS1dZFg8aDwILHllBWSg2Ly tZV1koWUFJSktLSjdXWS1ZQUlXWQ8JGhUIEh9ZQVlCGR9MVkpIHxgZH0pKGU1KTFUTARMWGhIXJB QOD1lXWRgSC1lBWU5DVUlJVUxVSkpPWVdZFhoPEhUdFFlBWU9LSFVKSktISkxVSktLVUtZBg++ X-HM-Sender-Digest: e1kMHhlZQR0aFwgeV1kSHx4VD1lBWUc6Mxg6Ihw5DT0aPh4MQi8TTUhI CzMaC0JVSlVKTU1ITUhCSEtJTUJLVTMWGhIXVREaAlUDDjsJFBgQVhgTEgsIVRgUFkVZV1kSC1lB WU5DVUlJVUxVSkpPWVdZCAFZQUhNTE43Bg++ X-HM-Tid: 0a8358a130772eb5kusne7aa268025a Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Move find_chip_by_name from gpiolib to the gpio/driver.h, also rename to gpiochip_find_by_name, make it to be a common function. Signed-off-by: Jianqun Xu --- v8: - new to this serial patches, used by pinctrl. drivers/gpio/gpiolib.c | 16 ++-------------- include/linux/gpio/driver.h | 12 ++++++++++++ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index cc9c0a12259e..c06334772c47 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -935,18 +935,6 @@ struct gpio_chip *gpiochip_find(void *data, } EXPORT_SYMBOL_GPL(gpiochip_find); -static int gpiochip_match_name(struct gpio_chip *gc, void *data) -{ - const char *name = data; - - return !strcmp(gc->label, name); -} - -static struct gpio_chip *find_chip_by_name(const char *name) -{ - return gpiochip_find((void *)name, gpiochip_match_name); -} - #ifdef CONFIG_GPIOLIB_IRQCHIP /* @@ -3660,7 +3648,7 @@ void gpiod_add_hogs(struct gpiod_hog *hogs) * The chip may have been registered earlier, so check if it * exists and, if so, try to hog the line now. */ - gc = find_chip_by_name(hog->chip_label); + gc = gpiochip_find_by_name(hog->chip_label); if (gc) gpiochip_machine_hog(gc, hog); } @@ -3745,7 +3733,7 @@ static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id, return ERR_PTR(-EPROBE_DEFER); } - gc = find_chip_by_name(p->key); + gc = gpiochip_find_by_name(p->key); if (!gc) { /* diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 6aeea1071b1b..4ed26a7d98ff 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -618,6 +618,18 @@ extern int devm_gpiochip_add_data_with_key(struct device *dev, struct gpio_chip extern struct gpio_chip *gpiochip_find(void *data, int (*match)(struct gpio_chip *gc, void *data)); +static int gpiochip_match_name(struct gpio_chip *gc, void *data) +{ + const char *name = data; + + return !strcmp(gc->label, name); +} + +static inline struct gpio_chip *gpiochip_find_by_name(const char *name) +{ + return gpiochip_find((void *)name, gpiochip_match_name); +} + bool gpiochip_line_is_irq(struct gpio_chip *gc, unsigned int offset); int gpiochip_reqres_irq(struct gpio_chip *gc, unsigned int offset); void gpiochip_relres_irq(struct gpio_chip *gc, unsigned int offset);