Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

reset: Instantiate reset GPIO controller for shared reset-gpios

Devices sharing a reset GPIO could use the reset framework for
coordinated handling of that shared GPIO line. We have several cases of
such needs, at least for Devicetree-based platforms.

If Devicetree-based device requests a reset line, while "resets"
Devicetree property is missing but there is a "reset-gpios" one,
instantiate a new "reset-gpio" platform device which will handle such
reset line. This allows seamless handling of such shared reset-gpios
without need of changing Devicetree binding [1].

To avoid creating multiple "reset-gpio" platform devices, store the
Devicetree "reset-gpios" GPIO specifiers used for new devices on a
linked list. Later such Devicetree GPIO specifier (phandle to GPIO
controller, GPIO number and GPIO flags) is used to check if reset
controller for given GPIO was already registered.

If two devices have conflicting "reset-gpios" property, e.g. with
different ACTIVE_xxx flags, this would allow to spawn two separate
"reset-gpio" devices, where the second would fail probing on busy GPIO
request.

Link: https://lore.kernel.org/all/YXi5CUCEi7YmNxXM@robh.at.kernel.org/ [1]
Cc: Bartosz Golaszewski <brgl@bgdev.pl>
Cc: Chris Packham <chris.packham@alliedtelesis.co.nz>
Cc: Sean Anderson <sean.anderson@seco.com>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20240129115216.96479-5-krzysztof.kozlowski@linaro.org
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>

authored by

Krzysztof Kozlowski and committed by
Philipp Zabel
c721f189 cee544a4

+215 -13
+211 -13
drivers/reset/core.c
··· 5 5 * Copyright 2013 Philipp Zabel, Pengutronix 6 6 */ 7 7 #include <linux/atomic.h> 8 + #include <linux/cleanup.h> 8 9 #include <linux/device.h> 9 10 #include <linux/err.h> 10 11 #include <linux/export.h> 11 12 #include <linux/kernel.h> 12 13 #include <linux/kref.h> 14 + #include <linux/gpio/driver.h> 15 + #include <linux/gpio/machine.h> 16 + #include <linux/idr.h> 13 17 #include <linux/module.h> 14 18 #include <linux/of.h> 15 19 #include <linux/acpi.h> 20 + #include <linux/platform_device.h> 16 21 #include <linux/reset.h> 17 22 #include <linux/reset-controller.h> 18 23 #include <linux/slab.h> ··· 27 22 28 23 static DEFINE_MUTEX(reset_lookup_mutex); 29 24 static LIST_HEAD(reset_lookup_list); 25 + 26 + /* Protects reset_gpio_lookup_list */ 27 + static DEFINE_MUTEX(reset_gpio_lookup_mutex); 28 + static LIST_HEAD(reset_gpio_lookup_list); 29 + static DEFINE_IDA(reset_gpio_ida); 30 30 31 31 /** 32 32 * struct reset_control - a reset control ··· 73 63 struct reset_control *rstc[] __counted_by(num_rstcs); 74 64 }; 75 65 66 + /** 67 + * struct reset_gpio_lookup - lookup key for ad-hoc created reset-gpio devices 68 + * @of_args: phandle to the reset controller with all the args like GPIO number 69 + * @list: list entry for the reset_gpio_lookup_list 70 + */ 71 + struct reset_gpio_lookup { 72 + struct of_phandle_args of_args; 73 + struct list_head list; 74 + }; 75 + 76 76 static const char *rcdev_name(struct reset_controller_dev *rcdev) 77 77 { 78 78 if (rcdev->dev) ··· 90 70 91 71 if (rcdev->of_node) 92 72 return rcdev->of_node->full_name; 73 + 74 + if (rcdev->of_args) 75 + return rcdev->of_args->np->full_name; 93 76 94 77 return NULL; 95 78 } ··· 122 99 */ 123 100 int reset_controller_register(struct reset_controller_dev *rcdev) 124 101 { 102 + if (rcdev->of_node && rcdev->of_args) 103 + return -EINVAL; 104 + 125 105 if (!rcdev->of_xlate) { 126 106 rcdev->of_reset_n_cells = 1; 127 107 rcdev->of_xlate = of_reset_simple_xlate; ··· 839 813 kref_put(&rstc->refcnt, __reset_control_release); 840 814 } 841 815 816 + static int __reset_add_reset_gpio_lookup(int id, struct device_node *np, 817 + unsigned int gpio, 818 + unsigned int of_flags) 819 + { 820 + const struct fwnode_handle *fwnode = of_fwnode_handle(np); 821 + unsigned int lookup_flags; 822 + const char *label_tmp; 823 + 824 + /* 825 + * Later we map GPIO flags between OF and Linux, however not all 826 + * constants from include/dt-bindings/gpio/gpio.h and 827 + * include/linux/gpio/machine.h match each other. 828 + */ 829 + if (of_flags > GPIO_ACTIVE_LOW) { 830 + pr_err("reset-gpio code does not support GPIO flags %u for GPIO %u\n", 831 + of_flags, gpio); 832 + return -EINVAL; 833 + } 834 + 835 + struct gpio_device *gdev __free(gpio_device_put) = gpio_device_find_by_fwnode(fwnode); 836 + if (!gdev) 837 + return -EPROBE_DEFER; 838 + 839 + label_tmp = gpio_device_get_label(gdev); 840 + if (!label_tmp) 841 + return -EINVAL; 842 + 843 + char *label __free(kfree) = kstrdup(label_tmp, GFP_KERNEL); 844 + if (!label) 845 + return -ENOMEM; 846 + 847 + /* Size: one lookup entry plus sentinel */ 848 + struct gpiod_lookup_table *lookup __free(kfree) = kzalloc(struct_size(lookup, table, 2), 849 + GFP_KERNEL); 850 + if (!lookup) 851 + return -ENOMEM; 852 + 853 + lookup->dev_id = kasprintf(GFP_KERNEL, "reset-gpio.%d", id); 854 + if (!lookup->dev_id) 855 + return -ENOMEM; 856 + 857 + lookup_flags = GPIO_PERSISTENT; 858 + lookup_flags |= of_flags & GPIO_ACTIVE_LOW; 859 + lookup->table[0] = GPIO_LOOKUP(no_free_ptr(label), gpio, "reset", 860 + lookup_flags); 861 + 862 + /* Not freed on success, because it is persisent subsystem data. */ 863 + gpiod_add_lookup_table(no_free_ptr(lookup)); 864 + 865 + return 0; 866 + } 867 + 868 + /* 869 + * @args: phandle to the GPIO provider with all the args like GPIO number 870 + */ 871 + static int __reset_add_reset_gpio_device(const struct of_phandle_args *args) 872 + { 873 + struct reset_gpio_lookup *rgpio_dev; 874 + struct platform_device *pdev; 875 + int id, ret; 876 + 877 + /* 878 + * Currently only #gpio-cells=2 is supported with the meaning of: 879 + * args[0]: GPIO number 880 + * args[1]: GPIO flags 881 + * TODO: Handle other cases. 882 + */ 883 + if (args->args_count != 2) 884 + return -ENOENT; 885 + 886 + /* 887 + * Registering reset-gpio device might cause immediate 888 + * bind, resulting in its probe() registering new reset controller thus 889 + * taking reset_list_mutex lock via reset_controller_register(). 890 + */ 891 + lockdep_assert_not_held(&reset_list_mutex); 892 + 893 + mutex_lock(&reset_gpio_lookup_mutex); 894 + 895 + list_for_each_entry(rgpio_dev, &reset_gpio_lookup_list, list) { 896 + if (args->np == rgpio_dev->of_args.np) { 897 + if (of_phandle_args_equal(args, &rgpio_dev->of_args)) 898 + goto out; /* Already on the list, done */ 899 + } 900 + } 901 + 902 + id = ida_alloc(&reset_gpio_ida, GFP_KERNEL); 903 + if (id < 0) { 904 + ret = id; 905 + goto err_unlock; 906 + } 907 + 908 + /* Not freed on success, because it is persisent subsystem data. */ 909 + rgpio_dev = kzalloc(sizeof(*rgpio_dev), GFP_KERNEL); 910 + if (!rgpio_dev) { 911 + ret = -ENOMEM; 912 + goto err_ida_free; 913 + } 914 + 915 + ret = __reset_add_reset_gpio_lookup(id, args->np, args->args[0], 916 + args->args[1]); 917 + if (ret < 0) 918 + goto err_kfree; 919 + 920 + rgpio_dev->of_args = *args; 921 + /* 922 + * We keep the device_node reference, but of_args.np is put at the end 923 + * of __of_reset_control_get(), so get it one more time. 924 + * Hold reference as long as rgpio_dev memory is valid. 925 + */ 926 + of_node_get(rgpio_dev->of_args.np); 927 + pdev = platform_device_register_data(NULL, "reset-gpio", id, 928 + &rgpio_dev->of_args, 929 + sizeof(rgpio_dev->of_args)); 930 + ret = PTR_ERR_OR_ZERO(pdev); 931 + if (ret) 932 + goto err_put; 933 + 934 + list_add(&rgpio_dev->list, &reset_gpio_lookup_list); 935 + 936 + out: 937 + mutex_unlock(&reset_gpio_lookup_mutex); 938 + 939 + return 0; 940 + 941 + err_put: 942 + of_node_put(rgpio_dev->of_args.np); 943 + err_kfree: 944 + kfree(rgpio_dev); 945 + err_ida_free: 946 + ida_free(&reset_gpio_ida, id); 947 + err_unlock: 948 + mutex_unlock(&reset_gpio_lookup_mutex); 949 + 950 + return ret; 951 + } 952 + 953 + static struct reset_controller_dev *__reset_find_rcdev(const struct of_phandle_args *args, 954 + bool gpio_fallback) 955 + { 956 + struct reset_controller_dev *rcdev; 957 + 958 + lockdep_assert_held(&reset_list_mutex); 959 + 960 + list_for_each_entry(rcdev, &reset_controller_list, list) { 961 + if (gpio_fallback) { 962 + if (rcdev->of_args && of_phandle_args_equal(args, 963 + rcdev->of_args)) 964 + return rcdev; 965 + } else { 966 + if (args->np == rcdev->of_node) 967 + return rcdev; 968 + } 969 + } 970 + 971 + return NULL; 972 + } 973 + 842 974 struct reset_control * 843 975 __of_reset_control_get(struct device_node *node, const char *id, int index, 844 976 bool shared, bool optional, bool acquired) 845 977 { 978 + bool gpio_fallback = false; 846 979 struct reset_control *rstc; 847 - struct reset_controller_dev *r, *rcdev; 980 + struct reset_controller_dev *rcdev; 848 981 struct of_phandle_args args; 849 982 int rstc_id; 850 983 int ret; ··· 1024 839 index, &args); 1025 840 if (ret == -EINVAL) 1026 841 return ERR_PTR(ret); 1027 - if (ret) 1028 - return optional ? NULL : ERR_PTR(ret); 842 + if (ret) { 843 + if (!IS_ENABLED(CONFIG_RESET_GPIO)) 844 + return optional ? NULL : ERR_PTR(ret); 1029 845 1030 - mutex_lock(&reset_list_mutex); 1031 - rcdev = NULL; 1032 - list_for_each_entry(r, &reset_controller_list, list) { 1033 - if (args.np == r->of_node) { 1034 - rcdev = r; 1035 - break; 846 + /* 847 + * There can be only one reset-gpio for regular devices, so 848 + * don't bother with the "reset-gpios" phandle index. 849 + */ 850 + ret = of_parse_phandle_with_args(node, "reset-gpios", "#gpio-cells", 851 + 0, &args); 852 + if (ret) 853 + return optional ? NULL : ERR_PTR(ret); 854 + 855 + gpio_fallback = true; 856 + 857 + ret = __reset_add_reset_gpio_device(&args); 858 + if (ret) { 859 + rstc = ERR_PTR(ret); 860 + goto out_put; 1036 861 } 1037 862 } 1038 863 864 + mutex_lock(&reset_list_mutex); 865 + rcdev = __reset_find_rcdev(&args, gpio_fallback); 1039 866 if (!rcdev) { 1040 867 rstc = ERR_PTR(-EPROBE_DEFER); 1041 - goto out; 868 + goto out_unlock; 1042 869 } 1043 870 1044 871 if (WARN_ON(args.args_count != rcdev->of_reset_n_cells)) { 1045 872 rstc = ERR_PTR(-EINVAL); 1046 - goto out; 873 + goto out_unlock; 1047 874 } 1048 875 1049 876 rstc_id = rcdev->of_xlate(rcdev, &args); 1050 877 if (rstc_id < 0) { 1051 878 rstc = ERR_PTR(rstc_id); 1052 - goto out; 879 + goto out_unlock; 1053 880 } 1054 881 1055 882 /* reset_list_mutex also protects the rcdev's reset_control list */ 1056 883 rstc = __reset_control_get_internal(rcdev, rstc_id, shared, acquired); 1057 884 1058 - out: 885 + out_unlock: 1059 886 mutex_unlock(&reset_list_mutex); 887 + out_put: 1060 888 of_node_put(args.np); 1061 889 1062 890 return rstc;
+4
include/linux/reset-controller.h
··· 60 60 * @reset_control_head: head of internal list of requested reset controls 61 61 * @dev: corresponding driver model device struct 62 62 * @of_node: corresponding device tree node as phandle target 63 + * @of_args: for reset-gpios controllers: corresponding phandle args with 64 + * of_node and GPIO number complementing of_node; either this or 65 + * of_node should be present 63 66 * @of_reset_n_cells: number of cells in reset line specifiers 64 67 * @of_xlate: translation function to translate from specifier as found in the 65 68 * device tree to id as given to the reset control ops, defaults ··· 76 73 struct list_head reset_control_head; 77 74 struct device *dev; 78 75 struct device_node *of_node; 76 + const struct of_phandle_args *of_args; 79 77 int of_reset_n_cells; 80 78 int (*of_xlate)(struct reset_controller_dev *rcdev, 81 79 const struct of_phandle_args *reset_spec);