Message ID | 20240815071651.3645949-2-ye.zhang@rock-chips.com |
---|---|
State | New |
Headers | show |
Series | gpio: rockchip: Update the GPIO driver | expand |
On Thu, Aug 15, 2024 at 9:17 AM Ye Zhang <ye.zhang@rock-chips.com> wrote: > > 1. support ACPI > 2. support 'clock-names' from dt nodes > 3. driver works without pinctrl device This is not how commit messages are written. Please take a look at examples in kernel git history. Also: the three bullet points here sound like they should be separate commits. Bart
Hi Ye, kernel test robot noticed the following build warnings: https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Ye-Zhang/gpio-rockchip-support-acpi/20240815-154340 base: https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git for-next patch link: https://lore.kernel.org/r/20240815071651.3645949-2-ye.zhang%40rock-chips.com patch subject: [PATCH v1 1/5] gpio: rockchip: support acpi config: arc-randconfig-r073-20240824 (https://download.01.org/0day-ci/archive/20240824/202408241538.j3g0NqRa-lkp@intel.com/config) compiler: arc-elf-gcc (GCC) 13.2.0 If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Reported-by: Dan Carpenter <dan.carpenter@linaro.org> | Closes: https://lore.kernel.org/r/202408241538.j3g0NqRa-lkp@intel.com/ smatch warnings: drivers/gpio/gpio-rockchip.c:797 rockchip_gpio_probe() warn: can 'cfg' even be NULL? vim +/cfg +797 drivers/gpio/gpio-rockchip.c 936ee2675eee1f Jianqun Xu 2021-08-16 699 static int rockchip_gpio_probe(struct platform_device *pdev) 936ee2675eee1f Jianqun Xu 2021-08-16 700 { 936ee2675eee1f Jianqun Xu 2021-08-16 701 struct device *dev = &pdev->dev; 936ee2675eee1f Jianqun Xu 2021-08-16 702 struct pinctrl_dev *pctldev = NULL; 936ee2675eee1f Jianqun Xu 2021-08-16 703 struct rockchip_pin_bank *bank = NULL; 371a1b26dd7c7c Ye Zhang 2024-08-15 704 int bank_id = 0; 371a1b26dd7c7c Ye Zhang 2024-08-15 705 int ret; 936ee2675eee1f Jianqun Xu 2021-08-16 706 371a1b26dd7c7c Ye Zhang 2024-08-15 707 bank_id = rockchip_gpio_acpi_get_bank_id(dev); 371a1b26dd7c7c Ye Zhang 2024-08-15 708 if (bank_id < 0) { 371a1b26dd7c7c Ye Zhang 2024-08-15 709 bank_id = rockchip_gpio_of_get_bank_id(dev); 371a1b26dd7c7c Ye Zhang 2024-08-15 710 if (bank_id < 0) 371a1b26dd7c7c Ye Zhang 2024-08-15 711 return bank_id; 371a1b26dd7c7c Ye Zhang 2024-08-15 712 } 371a1b26dd7c7c Ye Zhang 2024-08-15 713 371a1b26dd7c7c Ye Zhang 2024-08-15 714 if (!ACPI_COMPANION(dev)) { 371a1b26dd7c7c Ye Zhang 2024-08-15 715 struct device_node *pctlnp = of_get_parent(dev->of_node); 936ee2675eee1f Jianqun Xu 2021-08-16 716 936ee2675eee1f Jianqun Xu 2021-08-16 717 pctldev = of_pinctrl_get(pctlnp); 371a1b26dd7c7c Ye Zhang 2024-08-15 718 of_node_put(pctlnp); 936ee2675eee1f Jianqun Xu 2021-08-16 719 if (!pctldev) 936ee2675eee1f Jianqun Xu 2021-08-16 720 return -EPROBE_DEFER; 936ee2675eee1f Jianqun Xu 2021-08-16 721 371a1b26dd7c7c Ye Zhang 2024-08-15 722 bank = rockchip_gpio_find_bank(pctldev, bank_id); 371a1b26dd7c7c Ye Zhang 2024-08-15 723 if (!bank) 371a1b26dd7c7c Ye Zhang 2024-08-15 724 return -ENODEV; 371a1b26dd7c7c Ye Zhang 2024-08-15 725 } 936ee2675eee1f Jianqun Xu 2021-08-16 726 371a1b26dd7c7c Ye Zhang 2024-08-15 727 if (!bank) { 371a1b26dd7c7c Ye Zhang 2024-08-15 728 bank = devm_kzalloc(dev, sizeof(*bank), GFP_KERNEL); 936ee2675eee1f Jianqun Xu 2021-08-16 729 if (!bank) 371a1b26dd7c7c Ye Zhang 2024-08-15 730 return -ENOMEM; 371a1b26dd7c7c Ye Zhang 2024-08-15 731 } 936ee2675eee1f Jianqun Xu 2021-08-16 732 371a1b26dd7c7c Ye Zhang 2024-08-15 733 bank->bank_num = bank_id; 936ee2675eee1f Jianqun Xu 2021-08-16 734 bank->dev = dev; 371a1b26dd7c7c Ye Zhang 2024-08-15 735 371a1b26dd7c7c Ye Zhang 2024-08-15 736 bank->reg_base = devm_platform_ioremap_resource(pdev, 0); 371a1b26dd7c7c Ye Zhang 2024-08-15 737 if (IS_ERR(bank->reg_base)) 371a1b26dd7c7c Ye Zhang 2024-08-15 738 return PTR_ERR(bank->reg_base); 371a1b26dd7c7c Ye Zhang 2024-08-15 739 371a1b26dd7c7c Ye Zhang 2024-08-15 740 bank->irq = platform_get_irq(pdev, 0); 371a1b26dd7c7c Ye Zhang 2024-08-15 741 if (bank->irq < 0) 371a1b26dd7c7c Ye Zhang 2024-08-15 742 return bank->irq; 936ee2675eee1f Jianqun Xu 2021-08-16 743 936ee2675eee1f Jianqun Xu 2021-08-16 744 raw_spin_lock_init(&bank->slock); 936ee2675eee1f Jianqun Xu 2021-08-16 745 371a1b26dd7c7c Ye Zhang 2024-08-15 746 if (!ACPI_COMPANION(dev)) { 371a1b26dd7c7c Ye Zhang 2024-08-15 747 bank->clk = devm_clk_get(dev, "bus"); 371a1b26dd7c7c Ye Zhang 2024-08-15 748 if (IS_ERR(bank->clk)) { 371a1b26dd7c7c Ye Zhang 2024-08-15 749 bank->clk = of_clk_get(dev->of_node, 0); 371a1b26dd7c7c Ye Zhang 2024-08-15 750 if (IS_ERR(bank->clk)) { 371a1b26dd7c7c Ye Zhang 2024-08-15 751 dev_err(dev, "fail to get apb clock\n"); 371a1b26dd7c7c Ye Zhang 2024-08-15 752 return PTR_ERR(bank->clk); 371a1b26dd7c7c Ye Zhang 2024-08-15 753 } 371a1b26dd7c7c Ye Zhang 2024-08-15 754 } 371a1b26dd7c7c Ye Zhang 2024-08-15 755 371a1b26dd7c7c Ye Zhang 2024-08-15 756 bank->db_clk = devm_clk_get(dev, "db"); 371a1b26dd7c7c Ye Zhang 2024-08-15 757 if (IS_ERR(bank->db_clk)) { 371a1b26dd7c7c Ye Zhang 2024-08-15 758 bank->db_clk = of_clk_get(dev->of_node, 1); 371a1b26dd7c7c Ye Zhang 2024-08-15 759 if (IS_ERR(bank->db_clk)) 371a1b26dd7c7c Ye Zhang 2024-08-15 760 bank->db_clk = NULL; 371a1b26dd7c7c Ye Zhang 2024-08-15 761 } 371a1b26dd7c7c Ye Zhang 2024-08-15 762 } 371a1b26dd7c7c Ye Zhang 2024-08-15 763 371a1b26dd7c7c Ye Zhang 2024-08-15 764 clk_prepare_enable(bank->clk); 371a1b26dd7c7c Ye Zhang 2024-08-15 765 clk_prepare_enable(bank->db_clk); 371a1b26dd7c7c Ye Zhang 2024-08-15 766 371a1b26dd7c7c Ye Zhang 2024-08-15 767 rockchip_gpio_get_ver(bank); 936ee2675eee1f Jianqun Xu 2021-08-16 768 59dd178e1d7cb6 Heiko Stuebner 2021-09-14 769 /* 59dd178e1d7cb6 Heiko Stuebner 2021-09-14 770 * Prevent clashes with a deferred output setting 59dd178e1d7cb6 Heiko Stuebner 2021-09-14 771 * being added right at this moment. 59dd178e1d7cb6 Heiko Stuebner 2021-09-14 772 */ 59dd178e1d7cb6 Heiko Stuebner 2021-09-14 773 mutex_lock(&bank->deferred_lock); 59dd178e1d7cb6 Heiko Stuebner 2021-09-14 774 936ee2675eee1f Jianqun Xu 2021-08-16 775 ret = rockchip_gpiolib_register(bank); 936ee2675eee1f Jianqun Xu 2021-08-16 776 if (ret) { 371a1b26dd7c7c Ye Zhang 2024-08-15 777 dev_err(bank->dev, "Failed to register gpio %d\n", ret); 371a1b26dd7c7c Ye Zhang 2024-08-15 778 goto err_unlock; 371a1b26dd7c7c Ye Zhang 2024-08-15 779 } 371a1b26dd7c7c Ye Zhang 2024-08-15 780 371a1b26dd7c7c Ye Zhang 2024-08-15 781 if (!device_property_read_bool(bank->dev, "gpio-ranges") && pctldev) { 371a1b26dd7c7c Ye Zhang 2024-08-15 782 struct gpio_chip *gc = &bank->gpio_chip; 371a1b26dd7c7c Ye Zhang 2024-08-15 783 371a1b26dd7c7c Ye Zhang 2024-08-15 784 ret = gpiochip_add_pin_range(gc, dev_name(pctldev->dev), 0, 371a1b26dd7c7c Ye Zhang 2024-08-15 785 gc->base, gc->ngpio); 371a1b26dd7c7c Ye Zhang 2024-08-15 786 if (ret) { 371a1b26dd7c7c Ye Zhang 2024-08-15 787 dev_err(bank->dev, "Failed to add pin range\n"); 371a1b26dd7c7c Ye Zhang 2024-08-15 788 goto err_unlock; 371a1b26dd7c7c Ye Zhang 2024-08-15 789 } 936ee2675eee1f Jianqun Xu 2021-08-16 790 } 936ee2675eee1f Jianqun Xu 2021-08-16 791 8ce5ef64546850 Caleb Connolly 2022-03-28 792 while (!list_empty(&bank->deferred_pins)) { 371a1b26dd7c7c Ye Zhang 2024-08-15 793 struct rockchip_pin_deferred *cfg; 371a1b26dd7c7c Ye Zhang 2024-08-15 794 8ce5ef64546850 Caleb Connolly 2022-03-28 795 cfg = list_first_entry(&bank->deferred_pins, 8ce5ef64546850 Caleb Connolly 2022-03-28 796 struct rockchip_pin_deferred, head); 371a1b26dd7c7c Ye Zhang 2024-08-15 @797 if (!cfg) 371a1b26dd7c7c Ye Zhang 2024-08-15 798 break; The patch adds a NULL check here, but list_first_entry() can never return NULL. 371a1b26dd7c7c Ye Zhang 2024-08-15 799 59dd178e1d7cb6 Heiko Stuebner 2021-09-14 800 list_del(&cfg->head); 59dd178e1d7cb6 Heiko Stuebner 2021-09-14 801 8ce5ef64546850 Caleb Connolly 2022-03-28 802 switch (cfg->param) { 8ce5ef64546850 Caleb Connolly 2022-03-28 803 case PIN_CONFIG_OUTPUT: 59dd178e1d7cb6 Heiko Stuebner 2021-09-14 804 ret = rockchip_gpio_direction_output(&bank->gpio_chip, cfg->pin, cfg->arg); 59dd178e1d7cb6 Heiko Stuebner 2021-09-14 805 if (ret) 8ce5ef64546850 Caleb Connolly 2022-03-28 806 dev_warn(dev, "setting output pin %u to %u failed\n", cfg->pin, 8ce5ef64546850 Caleb Connolly 2022-03-28 807 cfg->arg); 8ce5ef64546850 Caleb Connolly 2022-03-28 808 break; 7ff11357810fd1 Caleb Connolly 2022-03-28 809 case PIN_CONFIG_INPUT_ENABLE: 7ff11357810fd1 Caleb Connolly 2022-03-28 810 ret = rockchip_gpio_direction_input(&bank->gpio_chip, cfg->pin); 7ff11357810fd1 Caleb Connolly 2022-03-28 811 if (ret) 7ff11357810fd1 Caleb Connolly 2022-03-28 812 dev_warn(dev, "setting input pin %u failed\n", cfg->pin); 7ff11357810fd1 Caleb Connolly 2022-03-28 813 break; 8ce5ef64546850 Caleb Connolly 2022-03-28 814 default: 8ce5ef64546850 Caleb Connolly 2022-03-28 815 dev_warn(dev, "unknown deferred config param %d\n", cfg->param); 8ce5ef64546850 Caleb Connolly 2022-03-28 816 break; 8ce5ef64546850 Caleb Connolly 2022-03-28 817 } 59dd178e1d7cb6 Heiko Stuebner 2021-09-14 818 kfree(cfg); 59dd178e1d7cb6 Heiko Stuebner 2021-09-14 819 } 59dd178e1d7cb6 Heiko Stuebner 2021-09-14 820 59dd178e1d7cb6 Heiko Stuebner 2021-09-14 821 mutex_unlock(&bank->deferred_lock); 59dd178e1d7cb6 Heiko Stuebner 2021-09-14 822 936ee2675eee1f Jianqun Xu 2021-08-16 823 platform_set_drvdata(pdev, bank); 371a1b26dd7c7c Ye Zhang 2024-08-15 824 dev_info(dev, "probed %pfw\n", dev_fwnode(dev)); 936ee2675eee1f Jianqun Xu 2021-08-16 825 936ee2675eee1f Jianqun Xu 2021-08-16 826 return 0; 371a1b26dd7c7c Ye Zhang 2024-08-15 827 err_unlock: 371a1b26dd7c7c Ye Zhang 2024-08-15 828 mutex_unlock(&bank->deferred_lock); 371a1b26dd7c7c Ye Zhang 2024-08-15 829 clk_disable_unprepare(bank->clk); 371a1b26dd7c7c Ye Zhang 2024-08-15 830 clk_disable_unprepare(bank->db_clk); 371a1b26dd7c7c Ye Zhang 2024-08-15 831 371a1b26dd7c7c Ye Zhang 2024-08-15 832 return ret; 936ee2675eee1f Jianqun Xu 2021-08-16 833 }
diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c index 0bd339813110..251961a876a9 100644 --- a/drivers/gpio/gpio-rockchip.c +++ b/drivers/gpio/gpio-rockchip.c @@ -6,6 +6,7 @@ * Copyright (c) 2021 Rockchip Electronics Co. Ltd. */ +#include <linux/acpi.h> #include <linux/bitops.h> #include <linux/clk.h> #include <linux/device.h> @@ -17,10 +18,12 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/of_device.h> #include <linux/of_irq.h> #include <linux/pinctrl/consumer.h> #include <linux/pinctrl/pinconf-generic.h> #include <linux/platform_device.h> +#include <linux/property.h> #include <linux/regmap.h> #include "../pinctrl/core.h" @@ -30,6 +33,8 @@ #define GPIO_TYPE_V2 (0x01000C2B) /* GPIO Version ID 0x01000C2B */ #define GPIO_TYPE_V2_1 (0x0101157C) /* GPIO Version ID 0x0101157C */ +#define GPIO_MAX_PINS (32) + static const struct rockchip_gpio_regs gpio_regs_v1 = { .port_dr = 0x00, .port_ddr = 0x04, @@ -157,7 +162,6 @@ static int rockchip_gpio_set_direction(struct gpio_chip *chip, unsigned long flags; u32 data = input ? 0 : 1; - if (input) pinctrl_gpio_direction_input(chip, offset); else @@ -514,7 +518,7 @@ 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, + bank->domain = irq_domain_create_linear(dev_fwnode(bank->dev), 32, &irq_generic_chip_ops, NULL); if (!bank->domain) { dev_warn(bank->dev, "could not init irq domain for bank %s\n", @@ -585,6 +589,16 @@ static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank) gc->label = bank->name; gc->parent = bank->dev; + if (!gc->base) + gc->base = GPIO_MAX_PINS * bank->bank_num; + if (!gc->ngpio) + gc->ngpio = GPIO_MAX_PINS; + if (!gc->label) { + gc->label = kasprintf(GFP_KERNEL, "gpio%d", bank->bank_num); + if (!gc->label) + return -ENOMEM; + } + ret = gpiochip_add_data(gc, bank); if (ret) { dev_err(bank->dev, "failed to add gpiochip %s, %d\n", @@ -592,36 +606,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); - of_node_put(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); @@ -636,47 +620,18 @@ static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank) return ret; } -static int rockchip_get_bank_data(struct rockchip_pin_bank *bank) +static void rockchip_gpio_get_ver(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; - - bank->clk = of_clk_get(bank->of_node, 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); + int id = readl(bank->reg_base + gpio_regs_v2.version_id); /* If not gpio v2, that is default to v1. */ if (id == GPIO_TYPE_V2 || 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; } - - return 0; } static struct rockchip_pin_bank * @@ -698,40 +653,118 @@ rockchip_gpio_find_bank(struct pinctrl_dev *pctldev, int id) return found ? bank : NULL; } +static int rockchip_gpio_of_get_bank_id(struct device *dev) +{ + static int gpio; + int bank_id = -1; + + if (IS_ENABLED(CONFIG_OF) && dev->of_node) { + bank_id = of_alias_get_id(dev->of_node, "gpio"); + if (bank_id < 0) + bank_id = gpio++; + } + + return bank_id; +} + +#ifdef CONFIG_ACPI +static int rockchip_gpio_acpi_get_bank_id(struct device *dev) +{ + struct acpi_device *adev; + unsigned long bank_id = -1; + const char *uid; + int ret; + + adev = ACPI_COMPANION(dev); + if (!adev) + return -ENXIO; + + uid = acpi_device_uid(adev); + if (!uid || !(*uid)) { + dev_err(dev, "Cannot retrieve UID\n"); + return -ENODEV; + } + + ret = kstrtoul(uid, 0, &bank_id); + + return !ret ? bank_id : -ERANGE; +} +#else +static int rockchip_gpio_acpi_get_bank_id(struct device *dev) +{ + return -ENOENT; +} +#endif /* CONFIG_ACPI */ + 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; + int bank_id = 0; + int ret; - if (!np || !pctlnp) - return -ENODEV; + bank_id = rockchip_gpio_acpi_get_bank_id(dev); + if (bank_id < 0) { + bank_id = rockchip_gpio_of_get_bank_id(dev); + if (bank_id < 0) + return bank_id; + } + + if (!ACPI_COMPANION(dev)) { + struct device_node *pctlnp = of_get_parent(dev->of_node); - pctldev = of_pinctrl_get(pctlnp); - if (!pctldev) - return -EPROBE_DEFER; + pctldev = of_pinctrl_get(pctlnp); + of_node_put(pctlnp); + if (!pctldev) + return -EPROBE_DEFER; - id = of_alias_get_id(np, "gpio"); - if (id < 0) - id = gpio++; + bank = rockchip_gpio_find_bank(pctldev, bank_id); + if (!bank) + return -ENODEV; + } - bank = rockchip_gpio_find_bank(pctldev, id); - if (!bank) - return -EINVAL; + if (!bank) { + bank = devm_kzalloc(dev, sizeof(*bank), GFP_KERNEL); + if (!bank) + return -ENOMEM; + } + bank->bank_num = bank_id; bank->dev = dev; - bank->of_node = np; + + bank->reg_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(bank->reg_base)) + return PTR_ERR(bank->reg_base); + + bank->irq = platform_get_irq(pdev, 0); + if (bank->irq < 0) + return bank->irq; raw_spin_lock_init(&bank->slock); - ret = rockchip_get_bank_data(bank); - if (ret) - return ret; + if (!ACPI_COMPANION(dev)) { + bank->clk = devm_clk_get(dev, "bus"); + if (IS_ERR(bank->clk)) { + bank->clk = of_clk_get(dev->of_node, 0); + if (IS_ERR(bank->clk)) { + dev_err(dev, "fail to get apb clock\n"); + return PTR_ERR(bank->clk); + } + } + + bank->db_clk = devm_clk_get(dev, "db"); + if (IS_ERR(bank->db_clk)) { + bank->db_clk = of_clk_get(dev->of_node, 1); + if (IS_ERR(bank->db_clk)) + bank->db_clk = NULL; + } + } + + clk_prepare_enable(bank->clk); + clk_prepare_enable(bank->db_clk); + + rockchip_gpio_get_ver(bank); /* * Prevent clashes with a deferred output setting @@ -741,14 +774,29 @@ static int rockchip_gpio_probe(struct platform_device *pdev) ret = rockchip_gpiolib_register(bank); if (ret) { - clk_disable_unprepare(bank->clk); - mutex_unlock(&bank->deferred_lock); - return ret; + dev_err(bank->dev, "Failed to register gpio %d\n", ret); + goto err_unlock; + } + + if (!device_property_read_bool(bank->dev, "gpio-ranges") && pctldev) { + struct gpio_chip *gc = &bank->gpio_chip; + + 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 err_unlock; + } } while (!list_empty(&bank->deferred_pins)) { + struct rockchip_pin_deferred *cfg; + cfg = list_first_entry(&bank->deferred_pins, struct rockchip_pin_deferred, head); + if (!cfg) + break; + list_del(&cfg->head); switch (cfg->param) { @@ -773,9 +821,15 @@ static int rockchip_gpio_probe(struct platform_device *pdev) 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_unlock: + mutex_unlock(&bank->deferred_lock); + clk_disable_unprepare(bank->clk); + clk_disable_unprepare(bank->db_clk); + + return ret; } static void rockchip_gpio_remove(struct platform_device *pdev) @@ -783,6 +837,7 @@ static void rockchip_gpio_remove(struct platform_device *pdev) struct rockchip_pin_bank *bank = platform_get_drvdata(pdev); clk_disable_unprepare(bank->clk); + clk_disable_unprepare(bank->db_clk); gpiochip_remove(&bank->gpio_chip); }
1. support ACPI 2. support 'clock-names' from dt nodes 3. driver works without pinctrl device Signed-off-by: Ye Zhang <ye.zhang@rock-chips.com> --- drivers/gpio/gpio-rockchip.c | 229 ++++++++++++++++++++++------------- 1 file changed, 142 insertions(+), 87 deletions(-)