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

Merge tag 'gpio/shared-gpios-for-v6.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git into gpio/for-next

Immutable branch between the GPIO, ASoC and regulator trees for v6.19-rc1

Add better support for GPIOs shared by multiple consumers.

+1085 -9
+1
arch/arm64/Kconfig.platforms
··· 316 316 select GPIOLIB 317 317 select PINCTRL 318 318 select HAVE_PWRCTRL if PCI 319 + select HAVE_SHARED_GPIOS 319 320 help 320 321 This enables support for the ARMv8 based Qualcomm chipsets. 321 322
+17
drivers/gpio/Kconfig
··· 6 6 config GPIOLIB_LEGACY 7 7 def_bool y 8 8 9 + config HAVE_SHARED_GPIOS 10 + bool 11 + 9 12 menuconfig GPIOLIB 10 13 bool "GPIO Support" 11 14 help ··· 44 41 config GPIOLIB_IRQCHIP 45 42 select IRQ_DOMAIN 46 43 bool 44 + 45 + config GPIO_SHARED 46 + def_bool y 47 + depends on HAVE_SHARED_GPIOS || COMPILE_TEST 48 + select AUXILIARY_BUS 47 49 48 50 config DEBUG_GPIO 49 51 bool "Debug GPIO calls" ··· 2024 2016 help 2025 2017 This enables the GPIO simulator - a configfs-based GPIO testing 2026 2018 driver. 2019 + 2020 + config GPIO_SHARED_PROXY 2021 + tristate "Proxy driver for non-exclusive GPIOs" 2022 + default m 2023 + depends on GPIO_SHARED || COMPILE_TEST 2024 + select AUXILIARY_BUS 2025 + help 2026 + This enables the GPIO shared proxy driver - an abstraction layer 2027 + for GPIO pins that are shared by multiple devices. 2027 2028 2028 2029 endmenu 2029 2030
+2
drivers/gpio/Makefile
··· 12 12 obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o 13 13 gpiolib-acpi-y := gpiolib-acpi-core.o gpiolib-acpi-quirks.o 14 14 obj-$(CONFIG_GPIOLIB) += gpiolib-swnode.o 15 + obj-$(CONFIG_GPIO_SHARED) += gpiolib-shared.o 15 16 16 17 # Device drivers. Generally keep list sorted alphabetically 17 18 obj-$(CONFIG_GPIO_REGMAP) += gpio-regmap.o ··· 161 160 obj-$(CONFIG_GPIO_SAMA5D2_PIOBU) += gpio-sama5d2-piobu.o 162 161 obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o 163 162 obj-$(CONFIG_GPIO_SCH) += gpio-sch.o 163 + obj-$(CONFIG_GPIO_SHARED_PROXY) += gpio-shared-proxy.o 164 164 obj-$(CONFIG_GPIO_SIFIVE) += gpio-sifive.o 165 165 obj-$(CONFIG_GPIO_SIM) += gpio-sim.o 166 166 obj-$(CONFIG_GPIO_SIOX) += gpio-siox.o
+333
drivers/gpio/gpio-shared-proxy.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (C) 2025 Linaro Ltd. 4 + */ 5 + 6 + #include <linux/auxiliary_bus.h> 7 + #include <linux/cleanup.h> 8 + #include <linux/device.h> 9 + #include <linux/err.h> 10 + #include <linux/gpio/consumer.h> 11 + #include <linux/gpio/driver.h> 12 + #include <linux/mod_devicetable.h> 13 + #include <linux/module.h> 14 + #include <linux/string_choices.h> 15 + #include <linux/types.h> 16 + 17 + #include "gpiolib-shared.h" 18 + 19 + struct gpio_shared_proxy_data { 20 + struct gpio_chip gc; 21 + struct gpio_shared_desc *shared_desc; 22 + struct device *dev; 23 + bool voted_high; 24 + }; 25 + 26 + static int 27 + gpio_shared_proxy_set_unlocked(struct gpio_shared_proxy_data *proxy, 28 + int (*set_func)(struct gpio_desc *desc, int value), 29 + int value) 30 + { 31 + struct gpio_shared_desc *shared_desc = proxy->shared_desc; 32 + struct gpio_desc *desc = shared_desc->desc; 33 + int ret = 0; 34 + 35 + gpio_shared_lockdep_assert(shared_desc); 36 + 37 + if (value) { 38 + /* User wants to set value to high. */ 39 + if (proxy->voted_high) 40 + /* Already voted for high, nothing to do. */ 41 + goto out; 42 + 43 + /* Haven't voted for high yet. */ 44 + if (!shared_desc->highcnt) { 45 + /* 46 + * Current value is low, need to actually set value 47 + * to high. 48 + */ 49 + ret = set_func(desc, 1); 50 + if (ret) 51 + goto out; 52 + } 53 + 54 + shared_desc->highcnt++; 55 + proxy->voted_high = true; 56 + 57 + goto out; 58 + } 59 + 60 + /* Desired value is low. */ 61 + if (!proxy->voted_high) 62 + /* We didn't vote for high, nothing to do. */ 63 + goto out; 64 + 65 + /* We previously voted for high. */ 66 + if (shared_desc->highcnt == 1) { 67 + /* This is the last remaining vote for high, set value to low. */ 68 + ret = set_func(desc, 0); 69 + if (ret) 70 + goto out; 71 + } 72 + 73 + shared_desc->highcnt--; 74 + proxy->voted_high = false; 75 + 76 + out: 77 + if (shared_desc->highcnt) 78 + dev_dbg(proxy->dev, 79 + "Voted for value '%s', effective value is 'high', number of votes for 'high': %u\n", 80 + str_high_low(value), shared_desc->highcnt); 81 + else 82 + dev_dbg(proxy->dev, "Voted for value 'low', effective value is 'low'\n"); 83 + 84 + return ret; 85 + } 86 + 87 + static int gpio_shared_proxy_request(struct gpio_chip *gc, unsigned int offset) 88 + { 89 + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); 90 + struct gpio_shared_desc *shared_desc = proxy->shared_desc; 91 + 92 + guard(gpio_shared_desc_lock)(shared_desc); 93 + 94 + proxy->shared_desc->usecnt++; 95 + 96 + dev_dbg(proxy->dev, "Shared GPIO requested, number of users: %u\n", 97 + proxy->shared_desc->usecnt); 98 + 99 + return 0; 100 + } 101 + 102 + static void gpio_shared_proxy_free(struct gpio_chip *gc, unsigned int offset) 103 + { 104 + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); 105 + struct gpio_shared_desc *shared_desc = proxy->shared_desc; 106 + 107 + guard(gpio_shared_desc_lock)(shared_desc); 108 + 109 + proxy->shared_desc->usecnt--; 110 + 111 + dev_dbg(proxy->dev, "Shared GPIO freed, number of users: %u\n", 112 + proxy->shared_desc->usecnt); 113 + } 114 + 115 + static int gpio_shared_proxy_set_config(struct gpio_chip *gc, 116 + unsigned int offset, unsigned long cfg) 117 + { 118 + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); 119 + struct gpio_shared_desc *shared_desc = proxy->shared_desc; 120 + struct gpio_desc *desc = shared_desc->desc; 121 + int ret; 122 + 123 + guard(gpio_shared_desc_lock)(shared_desc); 124 + 125 + if (shared_desc->usecnt > 1) { 126 + if (shared_desc->cfg != cfg) { 127 + dev_dbg(proxy->dev, 128 + "Shared GPIO's configuration already set, accepting changes but users may conflict!!\n"); 129 + } else { 130 + dev_dbg(proxy->dev, "Equal config requested, nothing to do\n"); 131 + return 0; 132 + } 133 + } 134 + 135 + ret = gpiod_set_config(desc, cfg); 136 + if (ret && ret != -ENOTSUPP) 137 + return ret; 138 + 139 + shared_desc->cfg = cfg; 140 + return 0; 141 + } 142 + 143 + static int gpio_shared_proxy_direction_input(struct gpio_chip *gc, 144 + unsigned int offset) 145 + { 146 + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); 147 + struct gpio_shared_desc *shared_desc = proxy->shared_desc; 148 + struct gpio_desc *desc = shared_desc->desc; 149 + int dir; 150 + 151 + guard(gpio_shared_desc_lock)(shared_desc); 152 + 153 + if (shared_desc->usecnt == 1) { 154 + dev_dbg(proxy->dev, 155 + "Only one user of this shared GPIO, allowing to set direction to input\n"); 156 + 157 + return gpiod_direction_input(desc); 158 + } 159 + 160 + dir = gpiod_get_direction(desc); 161 + if (dir < 0) 162 + return dir; 163 + 164 + if (dir == GPIO_LINE_DIRECTION_OUT) { 165 + dev_dbg(proxy->dev, 166 + "Shared GPIO's direction already set to output, refusing to change\n"); 167 + return -EPERM; 168 + } 169 + 170 + return 0; 171 + } 172 + 173 + static int gpio_shared_proxy_direction_output(struct gpio_chip *gc, 174 + unsigned int offset, int value) 175 + { 176 + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); 177 + struct gpio_shared_desc *shared_desc = proxy->shared_desc; 178 + struct gpio_desc *desc = shared_desc->desc; 179 + int ret, dir; 180 + 181 + guard(gpio_shared_desc_lock)(shared_desc); 182 + 183 + if (shared_desc->usecnt == 1) { 184 + dev_dbg(proxy->dev, 185 + "Only one user of this shared GPIO, allowing to set direction to output with value '%s'\n", 186 + str_high_low(value)); 187 + 188 + ret = gpiod_direction_output(desc, value); 189 + if (ret) 190 + return ret; 191 + 192 + if (value) { 193 + proxy->voted_high = true; 194 + shared_desc->highcnt = 1; 195 + } else { 196 + proxy->voted_high = false; 197 + shared_desc->highcnt = 0; 198 + } 199 + 200 + return 0; 201 + } 202 + 203 + dir = gpiod_get_direction(desc); 204 + if (dir < 0) 205 + return dir; 206 + 207 + if (dir == GPIO_LINE_DIRECTION_IN) { 208 + dev_dbg(proxy->dev, 209 + "Shared GPIO's direction already set to input, refusing to change\n"); 210 + return -EPERM; 211 + } 212 + 213 + return gpio_shared_proxy_set_unlocked(proxy, gpiod_direction_output, value); 214 + } 215 + 216 + static int gpio_shared_proxy_get(struct gpio_chip *gc, unsigned int offset) 217 + { 218 + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); 219 + 220 + return gpiod_get_value(proxy->shared_desc->desc); 221 + } 222 + 223 + static int gpio_shared_proxy_get_cansleep(struct gpio_chip *gc, 224 + unsigned int offset) 225 + { 226 + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); 227 + 228 + return gpiod_get_value_cansleep(proxy->shared_desc->desc); 229 + } 230 + 231 + static int gpio_shared_proxy_do_set(struct gpio_shared_proxy_data *proxy, 232 + int (*set_func)(struct gpio_desc *desc, int value), 233 + int value) 234 + { 235 + guard(gpio_shared_desc_lock)(proxy->shared_desc); 236 + 237 + return gpio_shared_proxy_set_unlocked(proxy, set_func, value); 238 + } 239 + 240 + static int gpio_shared_proxy_set(struct gpio_chip *gc, unsigned int offset, 241 + int value) 242 + { 243 + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); 244 + 245 + return gpio_shared_proxy_do_set(proxy, gpiod_set_value, value); 246 + } 247 + 248 + static int gpio_shared_proxy_set_cansleep(struct gpio_chip *gc, 249 + unsigned int offset, int value) 250 + { 251 + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); 252 + 253 + return gpio_shared_proxy_do_set(proxy, gpiod_set_value_cansleep, value); 254 + } 255 + 256 + static int gpio_shared_proxy_get_direction(struct gpio_chip *gc, 257 + unsigned int offset) 258 + { 259 + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); 260 + 261 + return gpiod_get_direction(proxy->shared_desc->desc); 262 + } 263 + 264 + static int gpio_shared_proxy_to_irq(struct gpio_chip *gc, unsigned int offset) 265 + { 266 + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); 267 + 268 + return gpiod_to_irq(proxy->shared_desc->desc); 269 + } 270 + 271 + static int gpio_shared_proxy_probe(struct auxiliary_device *adev, 272 + const struct auxiliary_device_id *id) 273 + { 274 + struct gpio_shared_proxy_data *proxy; 275 + struct gpio_shared_desc *shared_desc; 276 + struct device *dev = &adev->dev; 277 + struct gpio_chip *gc; 278 + 279 + shared_desc = devm_gpiod_shared_get(dev); 280 + if (IS_ERR(shared_desc)) 281 + return PTR_ERR(shared_desc); 282 + 283 + proxy = devm_kzalloc(dev, sizeof(*proxy), GFP_KERNEL); 284 + if (!proxy) 285 + return -ENOMEM; 286 + 287 + proxy->shared_desc = shared_desc; 288 + proxy->dev = dev; 289 + 290 + gc = &proxy->gc; 291 + gc->base = -1; 292 + gc->ngpio = 1; 293 + gc->label = dev_name(dev); 294 + gc->parent = dev; 295 + gc->owner = THIS_MODULE; 296 + gc->can_sleep = shared_desc->can_sleep; 297 + 298 + gc->request = gpio_shared_proxy_request; 299 + gc->free = gpio_shared_proxy_free; 300 + gc->set_config = gpio_shared_proxy_set_config; 301 + gc->direction_input = gpio_shared_proxy_direction_input; 302 + gc->direction_output = gpio_shared_proxy_direction_output; 303 + if (gc->can_sleep) { 304 + gc->set = gpio_shared_proxy_set_cansleep; 305 + gc->get = gpio_shared_proxy_get_cansleep; 306 + } else { 307 + gc->set = gpio_shared_proxy_set; 308 + gc->get = gpio_shared_proxy_get; 309 + } 310 + gc->get_direction = gpio_shared_proxy_get_direction; 311 + gc->to_irq = gpio_shared_proxy_to_irq; 312 + 313 + return devm_gpiochip_add_data(dev, &proxy->gc, proxy); 314 + } 315 + 316 + static const struct auxiliary_device_id gpio_shared_proxy_id_table[] = { 317 + { .name = "gpiolib_shared.proxy" }, 318 + {}, 319 + }; 320 + MODULE_DEVICE_TABLE(auxiliary, gpio_shared_proxy_id_table); 321 + 322 + static struct auxiliary_driver gpio_shared_proxy_driver = { 323 + .driver = { 324 + .name = "gpio-shared-proxy", 325 + }, 326 + .probe = gpio_shared_proxy_probe, 327 + .id_table = gpio_shared_proxy_id_table, 328 + }; 329 + module_auxiliary_driver(gpio_shared_proxy_driver); 330 + 331 + MODULE_AUTHOR("Bartosz Golaszewski <bartosz.golaszewski@linaro.org>"); 332 + MODULE_DESCRIPTION("Shared GPIO mux driver."); 333 + MODULE_LICENSE("GPL");
+558
drivers/gpio/gpiolib-shared.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (C) 2025 Linaro Ltd. 4 + */ 5 + 6 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 7 + 8 + #include <linux/auxiliary_bus.h> 9 + #include <linux/cleanup.h> 10 + #include <linux/device.h> 11 + #include <linux/fwnode.h> 12 + #include <linux/gpio/consumer.h> 13 + #include <linux/gpio/machine.h> 14 + #include <linux/idr.h> 15 + #include <linux/kref.h> 16 + #include <linux/list.h> 17 + #include <linux/lockdep.h> 18 + #include <linux/module.h> 19 + #include <linux/mutex.h> 20 + #include <linux/of.h> 21 + #include <linux/overflow.h> 22 + #include <linux/printk.h> 23 + #include <linux/property.h> 24 + #include <linux/slab.h> 25 + #include <linux/string.h> 26 + 27 + #include "gpiolib.h" 28 + #include "gpiolib-shared.h" 29 + 30 + /* Represents a single reference to a GPIO pin. */ 31 + struct gpio_shared_ref { 32 + struct list_head list; 33 + /* Firmware node associated with this GPIO's consumer. */ 34 + struct fwnode_handle *fwnode; 35 + /* GPIO flags this consumer uses for the request. */ 36 + enum gpiod_flags flags; 37 + char *con_id; 38 + int dev_id; 39 + struct auxiliary_device adev; 40 + struct gpiod_lookup_table *lookup; 41 + }; 42 + 43 + /* Represents a single GPIO pin. */ 44 + struct gpio_shared_entry { 45 + struct list_head list; 46 + /* Firmware node associated with the GPIO controller. */ 47 + struct fwnode_handle *fwnode; 48 + /* Hardware offset of the GPIO within its chip. */ 49 + unsigned int offset; 50 + /* Index in the property value array. */ 51 + size_t index; 52 + struct gpio_shared_desc *shared_desc; 53 + struct kref ref; 54 + struct list_head refs; 55 + }; 56 + 57 + static LIST_HEAD(gpio_shared_list); 58 + static DEFINE_MUTEX(gpio_shared_lock); 59 + static DEFINE_IDA(gpio_shared_ida); 60 + 61 + static struct gpio_shared_entry * 62 + gpio_shared_find_entry(struct fwnode_handle *controller_node, 63 + unsigned int offset) 64 + { 65 + struct gpio_shared_entry *entry; 66 + 67 + list_for_each_entry(entry, &gpio_shared_list, list) { 68 + if (entry->fwnode == controller_node && entry->offset == offset) 69 + return entry; 70 + } 71 + 72 + return NULL; 73 + } 74 + 75 + #if IS_ENABLED(CONFIG_OF) 76 + static int gpio_shared_of_traverse(struct device_node *curr) 77 + { 78 + struct gpio_shared_entry *entry; 79 + size_t con_id_len, suffix_len; 80 + struct fwnode_handle *fwnode; 81 + struct of_phandle_args args; 82 + struct property *prop; 83 + unsigned int offset; 84 + const char *suffix; 85 + int ret, count, i; 86 + 87 + for_each_property_of_node(curr, prop) { 88 + /* 89 + * The standard name for a GPIO property is "foo-gpios" 90 + * or "foo-gpio". Some bindings also use "gpios" or "gpio". 91 + * There are some legacy device-trees which have a different 92 + * naming convention and for which we have rename quirks in 93 + * place in gpiolib-of.c. I don't think any of them require 94 + * support for shared GPIOs so for now let's just ignore 95 + * them. We can always just export the quirk list and 96 + * iterate over it here. 97 + */ 98 + if (!strends(prop->name, "-gpios") && 99 + !strends(prop->name, "-gpio") && 100 + strcmp(prop->name, "gpios") != 0 && 101 + strcmp(prop->name, "gpio") != 0) 102 + continue; 103 + 104 + count = of_count_phandle_with_args(curr, prop->name, 105 + "#gpio-cells"); 106 + if (count <= 0) 107 + continue; 108 + 109 + for (i = 0; i < count; i++) { 110 + struct device_node *np __free(device_node) = NULL; 111 + 112 + ret = of_parse_phandle_with_args(curr, prop->name, 113 + "#gpio-cells", i, 114 + &args); 115 + if (ret) 116 + continue; 117 + 118 + np = args.np; 119 + 120 + if (!of_property_present(np, "gpio-controller")) 121 + continue; 122 + 123 + /* 124 + * We support 1, 2 and 3 cell GPIO bindings in the 125 + * kernel currently. There's only one old MIPS dts that 126 + * has a one-cell binding but there's no associated 127 + * consumer so it may as well be an error. There don't 128 + * seem to be any 3-cell users of non-exclusive GPIOs, 129 + * so we can skip this as well. Let's occupy ourselves 130 + * with the predominant 2-cell binding with the first 131 + * cell indicating the hardware offset of the GPIO and 132 + * the second defining the GPIO flags of the request. 133 + */ 134 + if (args.args_count != 2) 135 + continue; 136 + 137 + fwnode = of_fwnode_handle(args.np); 138 + offset = args.args[0]; 139 + 140 + entry = gpio_shared_find_entry(fwnode, offset); 141 + if (!entry) { 142 + entry = kzalloc(sizeof(*entry), GFP_KERNEL); 143 + if (!entry) 144 + return -ENOMEM; 145 + 146 + entry->fwnode = fwnode_handle_get(fwnode); 147 + entry->offset = offset; 148 + entry->index = count; 149 + INIT_LIST_HEAD(&entry->refs); 150 + 151 + list_add_tail(&entry->list, &gpio_shared_list); 152 + } 153 + 154 + struct gpio_shared_ref *ref __free(kfree) = 155 + kzalloc(sizeof(*ref), GFP_KERNEL); 156 + if (!ref) 157 + return -ENOMEM; 158 + 159 + ref->fwnode = fwnode_handle_get(of_fwnode_handle(curr)); 160 + ref->flags = args.args[1]; 161 + 162 + if (strends(prop->name, "gpios")) 163 + suffix = "-gpios"; 164 + else if (strends(prop->name, "gpio")) 165 + suffix = "-gpio"; 166 + else 167 + suffix = NULL; 168 + if (!suffix) 169 + continue; 170 + 171 + /* We only set con_id if there's actually one. */ 172 + if (strcmp(prop->name, "gpios") && strcmp(prop->name, "gpio")) { 173 + ref->con_id = kstrdup(prop->name, GFP_KERNEL); 174 + if (!ref->con_id) 175 + return -ENOMEM; 176 + 177 + con_id_len = strlen(ref->con_id); 178 + suffix_len = strlen(suffix); 179 + 180 + ref->con_id[con_id_len - suffix_len] = '\0'; 181 + } 182 + 183 + ref->dev_id = ida_alloc(&gpio_shared_ida, GFP_KERNEL); 184 + if (ref->dev_id < 0) { 185 + kfree(ref->con_id); 186 + return -ENOMEM; 187 + } 188 + 189 + if (!list_empty(&entry->refs)) 190 + pr_debug("GPIO %u at %s is shared by multiple firmware nodes\n", 191 + entry->offset, fwnode_get_name(entry->fwnode)); 192 + 193 + list_add_tail(&no_free_ptr(ref)->list, &entry->refs); 194 + } 195 + } 196 + 197 + for_each_child_of_node_scoped(curr, child) { 198 + ret = gpio_shared_of_traverse(child); 199 + if (ret) 200 + return ret; 201 + } 202 + 203 + return 0; 204 + } 205 + 206 + static int gpio_shared_of_scan(void) 207 + { 208 + return gpio_shared_of_traverse(of_root); 209 + } 210 + #else 211 + static int gpio_shared_of_scan(void) 212 + { 213 + return 0; 214 + } 215 + #endif /* CONFIG_OF */ 216 + 217 + static void gpio_shared_adev_release(struct device *dev) 218 + { 219 + 220 + } 221 + 222 + static int gpio_shared_make_adev(struct gpio_device *gdev, 223 + struct gpio_shared_ref *ref) 224 + { 225 + struct auxiliary_device *adev = &ref->adev; 226 + int ret; 227 + 228 + lockdep_assert_held(&gpio_shared_lock); 229 + 230 + memset(adev, 0, sizeof(*adev)); 231 + 232 + adev->id = ref->dev_id; 233 + adev->name = "proxy"; 234 + adev->dev.parent = gdev->dev.parent; 235 + adev->dev.release = gpio_shared_adev_release; 236 + 237 + ret = auxiliary_device_init(adev); 238 + if (ret) 239 + return ret; 240 + 241 + ret = auxiliary_device_add(adev); 242 + if (ret) { 243 + auxiliary_device_uninit(adev); 244 + return ret; 245 + } 246 + 247 + pr_debug("Created an auxiliary GPIO proxy %s for GPIO device %s\n", 248 + dev_name(&adev->dev), gpio_device_get_label(gdev)); 249 + 250 + return 0; 251 + } 252 + 253 + int gpio_shared_add_proxy_lookup(struct device *consumer, unsigned long lflags) 254 + { 255 + const char *dev_id = dev_name(consumer); 256 + struct gpio_shared_entry *entry; 257 + struct gpio_shared_ref *ref; 258 + 259 + struct gpiod_lookup_table *lookup __free(kfree) = 260 + kzalloc(struct_size(lookup, table, 2), GFP_KERNEL); 261 + if (!lookup) 262 + return -ENOMEM; 263 + 264 + guard(mutex)(&gpio_shared_lock); 265 + 266 + list_for_each_entry(entry, &gpio_shared_list, list) { 267 + list_for_each_entry(ref, &entry->refs, list) { 268 + if (!device_match_fwnode(consumer, ref->fwnode)) 269 + continue; 270 + 271 + /* We've already done that on a previous request. */ 272 + if (ref->lookup) 273 + return 0; 274 + 275 + char *key __free(kfree) = 276 + kasprintf(GFP_KERNEL, 277 + KBUILD_MODNAME ".proxy.%u", 278 + ref->adev.id); 279 + if (!key) 280 + return -ENOMEM; 281 + 282 + pr_debug("Adding machine lookup entry for a shared GPIO for consumer %s, with key '%s' and con_id '%s'\n", 283 + dev_id, key, ref->con_id ?: "none"); 284 + 285 + lookup->dev_id = dev_id; 286 + lookup->table[0] = GPIO_LOOKUP(no_free_ptr(key), 0, 287 + ref->con_id, lflags); 288 + 289 + gpiod_add_lookup_table(no_free_ptr(lookup)); 290 + 291 + return 0; 292 + } 293 + } 294 + 295 + /* We warn here because this can only happen if the programmer borked. */ 296 + WARN_ON(1); 297 + return -ENOENT; 298 + } 299 + 300 + static void gpio_shared_remove_adev(struct auxiliary_device *adev) 301 + { 302 + lockdep_assert_held(&gpio_shared_lock); 303 + 304 + auxiliary_device_uninit(adev); 305 + auxiliary_device_delete(adev); 306 + } 307 + 308 + int gpio_device_setup_shared(struct gpio_device *gdev) 309 + { 310 + struct gpio_shared_entry *entry; 311 + struct gpio_shared_ref *ref; 312 + unsigned long *flags; 313 + int ret; 314 + 315 + guard(mutex)(&gpio_shared_lock); 316 + 317 + list_for_each_entry(entry, &gpio_shared_list, list) { 318 + list_for_each_entry(ref, &entry->refs, list) { 319 + if (gdev->dev.parent == &ref->adev.dev) { 320 + /* 321 + * This is a shared GPIO proxy. Mark its 322 + * descriptor as such and return here. 323 + */ 324 + __set_bit(GPIOD_FLAG_SHARED_PROXY, 325 + &gdev->descs[0].flags); 326 + return 0; 327 + } 328 + } 329 + } 330 + 331 + /* 332 + * This is not a shared GPIO proxy but it still may be the device 333 + * exposing shared pins. Find them and create the proxy devices. 334 + */ 335 + list_for_each_entry(entry, &gpio_shared_list, list) { 336 + if (!device_match_fwnode(&gdev->dev, entry->fwnode)) 337 + continue; 338 + 339 + if (list_count_nodes(&entry->refs) <= 1) 340 + continue; 341 + 342 + flags = &gdev->descs[entry->offset].flags; 343 + 344 + __set_bit(GPIOD_FLAG_SHARED, flags); 345 + /* 346 + * Shared GPIOs are not requested via the normal path. Make 347 + * them inaccessible to anyone even before we register the 348 + * chip. 349 + */ 350 + __set_bit(GPIOD_FLAG_REQUESTED, flags); 351 + 352 + pr_debug("GPIO %u owned by %s is shared by multiple consumers\n", 353 + entry->offset, gpio_device_get_label(gdev)); 354 + 355 + list_for_each_entry(ref, &entry->refs, list) { 356 + pr_debug("Setting up a shared GPIO entry for %s\n", 357 + fwnode_get_name(ref->fwnode)); 358 + 359 + ret = gpio_shared_make_adev(gdev, ref); 360 + if (ret) 361 + return ret; 362 + } 363 + } 364 + 365 + return 0; 366 + } 367 + 368 + void gpio_device_teardown_shared(struct gpio_device *gdev) 369 + { 370 + struct gpio_shared_entry *entry; 371 + struct gpio_shared_ref *ref; 372 + 373 + guard(mutex)(&gpio_shared_lock); 374 + 375 + list_for_each_entry(entry, &gpio_shared_list, list) { 376 + if (!device_match_fwnode(&gdev->dev, entry->fwnode)) 377 + continue; 378 + 379 + list_for_each_entry(ref, &entry->refs, list) { 380 + gpiod_remove_lookup_table(ref->lookup); 381 + kfree(ref->lookup->table[0].key); 382 + kfree(ref->lookup); 383 + ref->lookup = NULL; 384 + gpio_shared_remove_adev(&ref->adev); 385 + } 386 + } 387 + } 388 + 389 + static void gpio_shared_release(struct kref *kref) 390 + { 391 + struct gpio_shared_entry *entry = 392 + container_of(kref, struct gpio_shared_entry, ref); 393 + struct gpio_shared_desc *shared_desc = entry->shared_desc; 394 + 395 + guard(mutex)(&gpio_shared_lock); 396 + 397 + gpio_device_put(shared_desc->desc->gdev); 398 + if (shared_desc->can_sleep) 399 + mutex_destroy(&shared_desc->mutex); 400 + kfree(shared_desc); 401 + entry->shared_desc = NULL; 402 + } 403 + 404 + static void gpiod_shared_put(void *data) 405 + { 406 + struct gpio_shared_entry *entry = data; 407 + 408 + lockdep_assert_not_held(&gpio_shared_lock); 409 + 410 + kref_put(&entry->ref, gpio_shared_release); 411 + } 412 + 413 + static struct gpio_shared_desc * 414 + gpiod_shared_desc_create(struct gpio_shared_entry *entry) 415 + { 416 + struct gpio_shared_desc *shared_desc; 417 + struct gpio_device *gdev; 418 + 419 + shared_desc = kzalloc(sizeof(*shared_desc), GFP_KERNEL); 420 + if (!shared_desc) 421 + return ERR_PTR(-ENOMEM); 422 + 423 + gdev = gpio_device_find_by_fwnode(entry->fwnode); 424 + if (!gdev) { 425 + kfree(shared_desc); 426 + return ERR_PTR(-EPROBE_DEFER); 427 + } 428 + 429 + shared_desc->desc = &gdev->descs[entry->offset]; 430 + shared_desc->can_sleep = gpiod_cansleep(shared_desc->desc); 431 + if (shared_desc->can_sleep) 432 + mutex_init(&shared_desc->mutex); 433 + else 434 + spin_lock_init(&shared_desc->spinlock); 435 + 436 + return shared_desc; 437 + } 438 + 439 + static struct gpio_shared_entry *gpiod_shared_find(struct auxiliary_device *adev) 440 + { 441 + struct gpio_shared_desc *shared_desc; 442 + struct gpio_shared_entry *entry; 443 + struct gpio_shared_ref *ref; 444 + 445 + guard(mutex)(&gpio_shared_lock); 446 + 447 + list_for_each_entry(entry, &gpio_shared_list, list) { 448 + list_for_each_entry(ref, &entry->refs, list) { 449 + if (adev != &ref->adev) 450 + continue; 451 + 452 + if (entry->shared_desc) { 453 + kref_get(&entry->ref); 454 + return entry; 455 + } 456 + 457 + shared_desc = gpiod_shared_desc_create(entry); 458 + if (IS_ERR(shared_desc)) 459 + return ERR_CAST(shared_desc); 460 + 461 + kref_init(&entry->ref); 462 + entry->shared_desc = shared_desc; 463 + 464 + pr_debug("Device %s acquired a reference to the shared GPIO %u owned by %s\n", 465 + dev_name(&adev->dev), gpiod_hwgpio(shared_desc->desc), 466 + gpio_device_get_label(shared_desc->desc->gdev)); 467 + 468 + 469 + return entry; 470 + } 471 + } 472 + 473 + return ERR_PTR(-ENOENT); 474 + } 475 + 476 + struct gpio_shared_desc *devm_gpiod_shared_get(struct device *dev) 477 + { 478 + struct gpio_shared_entry *entry; 479 + int ret; 480 + 481 + entry = gpiod_shared_find(to_auxiliary_dev(dev)); 482 + if (IS_ERR(entry)) 483 + return ERR_CAST(entry); 484 + 485 + ret = devm_add_action_or_reset(dev, gpiod_shared_put, entry); 486 + if (ret) 487 + return ERR_PTR(ret); 488 + 489 + return entry->shared_desc; 490 + } 491 + EXPORT_SYMBOL_GPL(devm_gpiod_shared_get); 492 + 493 + static void gpio_shared_drop_ref(struct gpio_shared_ref *ref) 494 + { 495 + list_del(&ref->list); 496 + kfree(ref->con_id); 497 + ida_free(&gpio_shared_ida, ref->dev_id); 498 + fwnode_handle_put(ref->fwnode); 499 + kfree(ref); 500 + } 501 + 502 + static void gpio_shared_drop_entry(struct gpio_shared_entry *entry) 503 + { 504 + list_del(&entry->list); 505 + fwnode_handle_put(entry->fwnode); 506 + kfree(entry); 507 + } 508 + 509 + /* 510 + * This is only called if gpio_shared_init() fails so it's in fact __init and 511 + * not __exit. 512 + */ 513 + static void __init gpio_shared_teardown(void) 514 + { 515 + struct gpio_shared_entry *entry, *epos; 516 + struct gpio_shared_ref *ref, *rpos; 517 + 518 + list_for_each_entry_safe(entry, epos, &gpio_shared_list, list) { 519 + list_for_each_entry_safe(ref, rpos, &entry->refs, list) 520 + gpio_shared_drop_ref(ref); 521 + 522 + gpio_shared_drop_entry(entry); 523 + } 524 + } 525 + 526 + static void gpio_shared_free_exclusive(void) 527 + { 528 + struct gpio_shared_entry *entry, *epos; 529 + 530 + list_for_each_entry_safe(entry, epos, &gpio_shared_list, list) { 531 + if (list_count_nodes(&entry->refs) > 1) 532 + continue; 533 + 534 + gpio_shared_drop_ref(list_first_entry(&entry->refs, 535 + struct gpio_shared_ref, 536 + list)); 537 + gpio_shared_drop_entry(entry); 538 + } 539 + } 540 + 541 + static int __init gpio_shared_init(void) 542 + { 543 + int ret; 544 + 545 + /* Right now, we only support OF-based systems. */ 546 + ret = gpio_shared_of_scan(); 547 + if (ret) { 548 + gpio_shared_teardown(); 549 + pr_err("Failed to scan OF nodes for shared GPIOs: %d\n", ret); 550 + return ret; 551 + } 552 + 553 + gpio_shared_free_exclusive(); 554 + 555 + pr_debug("Finished scanning firmware nodes for shared GPIOs\n"); 556 + return 0; 557 + } 558 + postcore_initcall(gpio_shared_init);
+71
drivers/gpio/gpiolib-shared.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + #ifndef __LINUX_GPIO_SHARED_H 4 + #define __LINUX_GPIO_SHARED_H 5 + 6 + #include <linux/cleanup.h> 7 + #include <linux/lockdep.h> 8 + #include <linux/mutex.h> 9 + #include <linux/spinlock.h> 10 + 11 + struct gpio_device; 12 + struct gpio_desc; 13 + struct device; 14 + 15 + #if IS_ENABLED(CONFIG_GPIO_SHARED) 16 + 17 + int gpio_device_setup_shared(struct gpio_device *gdev); 18 + void gpio_device_teardown_shared(struct gpio_device *gdev); 19 + int gpio_shared_add_proxy_lookup(struct device *consumer, unsigned long lflags); 20 + 21 + #else 22 + 23 + static inline int gpio_device_setup_shared(struct gpio_device *gdev) 24 + { 25 + return 0; 26 + } 27 + 28 + static inline void gpio_device_teardown_shared(struct gpio_device *gdev) { } 29 + 30 + static inline int gpio_shared_add_proxy_lookup(struct device *consumer, 31 + unsigned long lflags) 32 + { 33 + return 0; 34 + } 35 + 36 + #endif /* CONFIG_GPIO_SHARED */ 37 + 38 + struct gpio_shared_desc { 39 + struct gpio_desc *desc; 40 + bool can_sleep; 41 + unsigned long cfg; 42 + unsigned int usecnt; 43 + unsigned int highcnt; 44 + union { 45 + struct mutex mutex; 46 + spinlock_t spinlock; 47 + }; 48 + }; 49 + 50 + struct gpio_shared_desc *devm_gpiod_shared_get(struct device *dev); 51 + 52 + DEFINE_LOCK_GUARD_1(gpio_shared_desc_lock, struct gpio_shared_desc, 53 + if (_T->lock->can_sleep) 54 + mutex_lock(&_T->lock->mutex); 55 + else 56 + spin_lock_irqsave(&_T->lock->spinlock, _T->flags), 57 + if (_T->lock->can_sleep) 58 + mutex_unlock(&_T->lock->mutex); 59 + else 60 + spin_unlock_irqrestore(&_T->lock->spinlock, _T->flags), 61 + unsigned long flags) 62 + 63 + static inline void gpio_shared_lockdep_assert(struct gpio_shared_desc *shared_desc) 64 + { 65 + if (shared_desc->can_sleep) 66 + lockdep_assert_held(&shared_desc->mutex); 67 + else 68 + lockdep_assert_held(&shared_desc->spinlock); 69 + } 70 + 71 + #endif /* __LINUX_GPIO_SHARED_H */
+61 -9
drivers/gpio/gpiolib.c
··· 37 37 #include "gpiolib-acpi.h" 38 38 #include "gpiolib-cdev.h" 39 39 #include "gpiolib-of.h" 40 + #include "gpiolib-shared.h" 40 41 #include "gpiolib-swnode.h" 41 42 #include "gpiolib-sysfs.h" 42 43 #include "gpiolib.h" ··· 1214 1213 if (ret) 1215 1214 goto err_remove_irqchip_mask; 1216 1215 1216 + ret = gpio_device_setup_shared(gdev); 1217 + if (ret) 1218 + goto err_remove_irqchip; 1219 + 1217 1220 /* 1218 1221 * By first adding the chardev, and then adding the device, 1219 1222 * we get a device node entry in sysfs under ··· 1229 1224 if (gpiolib_initialized) { 1230 1225 ret = gpiochip_setup_dev(gdev); 1231 1226 if (ret) 1232 - goto err_remove_irqchip; 1227 + goto err_teardown_shared; 1233 1228 } 1229 + 1234 1230 return 0; 1235 1231 1232 + err_teardown_shared: 1233 + gpio_device_teardown_shared(gdev); 1236 1234 err_remove_irqchip: 1237 1235 gpiochip_irqchip_remove(gc); 1238 1236 err_remove_irqchip_mask: ··· 1304 1296 /* Numb the device, cancelling all outstanding operations */ 1305 1297 rcu_assign_pointer(gdev->chip, NULL); 1306 1298 synchronize_srcu(&gdev->srcu); 1299 + gpio_device_teardown_shared(gdev); 1307 1300 gpiochip_irqchip_remove(gc); 1308 1301 acpi_gpiochip_remove(gc); 1309 1302 of_gpiochip_remove(gc); ··· 3998 3989 EXPORT_SYMBOL_GPL(gpiod_set_consumer_name); 3999 3990 4000 3991 /** 3992 + * gpiod_is_shared() - check if this GPIO can be shared by multiple consumers 3993 + * @desc: GPIO to inspect 3994 + * 3995 + * Returns: 3996 + * True if this GPIO can be shared by multiple consumers at once. False if it's 3997 + * a regular, exclusive GPIO. 3998 + * 3999 + * Note: 4000 + * This function returning true does not mean that this GPIO is currently being 4001 + * shared. It means the GPIO core has registered the fact that the firmware 4002 + * configuration indicates that it can be shared by multiple consumers and is 4003 + * in charge of arbitrating the access. 4004 + */ 4005 + bool gpiod_is_shared(const struct gpio_desc *desc) 4006 + { 4007 + return test_bit(GPIOD_FLAG_SHARED_PROXY, &desc->flags); 4008 + } 4009 + EXPORT_SYMBOL_GPL(gpiod_is_shared); 4010 + 4011 + /** 4001 4012 * gpiod_to_irq() - return the IRQ corresponding to a GPIO 4002 4013 * @desc: gpio whose IRQ will be returned (already requested) 4003 4014 * ··· 4688 4659 scoped_guard(srcu, &gpio_devices_srcu) { 4689 4660 desc = gpiod_fwnode_lookup(fwnode, consumer, con_id, idx, 4690 4661 &flags, &lookupflags); 4662 + if (!IS_ERR_OR_NULL(desc) && 4663 + test_bit(GPIOD_FLAG_SHARED, &desc->flags)) { 4664 + /* 4665 + * We're dealing with a GPIO shared by multiple 4666 + * consumers. This is the moment to add the machine 4667 + * lookup table for the proxy device as previously 4668 + * we only knew the consumer's fwnode. 4669 + */ 4670 + ret = gpio_shared_add_proxy_lookup(consumer, lookupflags); 4671 + if (ret) 4672 + return ERR_PTR(ret); 4673 + 4674 + /* Trigger platform lookup for shared GPIO proxy. */ 4675 + desc = ERR_PTR(-ENOENT); 4676 + /* Trigger it even for fwnode-only gpiod_get(). */ 4677 + platform_lookup_allowed = true; 4678 + } 4679 + 4691 4680 if (gpiod_not_found(desc) && platform_lookup_allowed) { 4692 4681 /* 4693 4682 * Either we are not using DT or ACPI, or their lookup 4694 - * did not return a result. In that case, use platform 4695 - * lookup as a fallback. 4683 + * did not return a result or this is a shared GPIO. In 4684 + * that case, use platform lookup as a fallback. 4696 4685 */ 4697 4686 dev_dbg(consumer, 4698 4687 "using lookup tables for GPIO lookup\n"); ··· 4733 4686 return ERR_PTR(ret); 4734 4687 4735 4688 /* 4736 - * This happens when there are several consumers for 4737 - * the same GPIO line: we just return here without 4738 - * further initialization. It is a bit of a hack. 4739 - * This is necessary to support fixed regulators. 4689 + * This happens when there are several consumers for the same 4690 + * GPIO line: we just return here without further 4691 + * initialization. It's a hack introduced long ago to support 4692 + * fixed regulators. We now have a better solution with 4693 + * automated scanning where affected platforms just need to 4694 + * select the provided Kconfig option. 4740 4695 * 4741 - * FIXME: Make this more sane and safe. 4696 + * FIXME: Remove the GPIOD_FLAGS_BIT_NONEXCLUSIVE flag after 4697 + * making sure all platforms use the new mechanism. 4742 4698 */ 4743 - dev_info(consumer, "nonexclusive access to GPIO for %s\n", name); 4699 + dev_info(consumer, 4700 + "nonexclusive access to GPIO for %s, consider updating your code to using gpio-shared-proxy\n", 4701 + name); 4744 4702 return desc; 4745 4703 } 4746 4704
+2
drivers/gpio/gpiolib.h
··· 204 204 #define GPIOD_FLAG_EDGE_FALLING 17 /* GPIO CDEV detects falling edge events */ 205 205 #define GPIOD_FLAG_EVENT_CLOCK_REALTIME 18 /* GPIO CDEV reports REALTIME timestamps in events */ 206 206 #define GPIOD_FLAG_EVENT_CLOCK_HTE 19 /* GPIO CDEV reports hardware timestamps in events */ 207 + #define GPIOD_FLAG_SHARED 20 /* GPIO is shared by multiple consumers */ 208 + #define GPIOD_FLAG_SHARED_PROXY 21 /* GPIO is a virtual proxy to a physically shared pin. */ 207 209 208 210 /* Connection label */ 209 211 struct gpio_desc_label __rcu *label;
+9
include/linux/gpio/consumer.h
··· 167 167 int gpiod_to_irq(const struct gpio_desc *desc); 168 168 int gpiod_set_consumer_name(struct gpio_desc *desc, const char *name); 169 169 170 + bool gpiod_is_shared(const struct gpio_desc *desc); 171 + 170 172 /* Convert between the old gpio_ and new gpiod_ interfaces */ 171 173 struct gpio_desc *gpio_to_desc(unsigned gpio); 172 174 int desc_to_gpio(const struct gpio_desc *desc); ··· 522 520 /* GPIO can never have been requested */ 523 521 WARN_ON(desc); 524 522 return -EINVAL; 523 + } 524 + 525 + static inline bool gpiod_is_shared(const struct gpio_desc *desc) 526 + { 527 + /* GPIO can never have been requested */ 528 + WARN_ON(desc); 529 + return false; 525 530 } 526 531 527 532 static inline struct gpio_desc *gpio_to_desc(unsigned gpio)
+18
include/linux/string.h
··· 562 562 return strncmp(str, prefix, strlen(prefix)) == 0; 563 563 } 564 564 565 + /** 566 + * strends - Check if a string ends with another string. 567 + * @str - NULL-terminated string to check against @suffix 568 + * @suffix - NULL-terminated string defining the suffix to look for in @str 569 + * 570 + * Returns: 571 + * True if @str ends with @suffix. False in all other cases. 572 + */ 573 + static inline bool strends(const char *str, const char *suffix) 574 + { 575 + unsigned int str_len = strlen(str), suffix_len = strlen(suffix); 576 + 577 + if (str_len < suffix_len) 578 + return false; 579 + 580 + return !(strcmp(str + str_len - suffix_len, suffix)); 581 + } 582 + 565 583 #endif /* _LINUX_STRING_H_ */
+13
lib/tests/string_kunit.c
··· 602 602 KUNIT_EXPECT_EQ(test, dest[7], '\0'); 603 603 } 604 604 605 + static void string_test_strends(struct kunit *test) 606 + { 607 + KUNIT_EXPECT_TRUE(test, strends("foo-bar", "bar")); 608 + KUNIT_EXPECT_TRUE(test, strends("foo-bar", "-bar")); 609 + KUNIT_EXPECT_TRUE(test, strends("foobar", "foobar")); 610 + KUNIT_EXPECT_TRUE(test, strends("foobar", "")); 611 + KUNIT_EXPECT_FALSE(test, strends("bar", "foobar")); 612 + KUNIT_EXPECT_FALSE(test, strends("", "foo")); 613 + KUNIT_EXPECT_FALSE(test, strends("foobar", "ba")); 614 + KUNIT_EXPECT_TRUE(test, strends("", "")); 615 + } 616 + 605 617 static struct kunit_case string_test_cases[] = { 606 618 KUNIT_CASE(string_test_memset16), 607 619 KUNIT_CASE(string_test_memset32), ··· 635 623 KUNIT_CASE(string_test_strlcat), 636 624 KUNIT_CASE(string_test_strtomem), 637 625 KUNIT_CASE(string_test_memtostr), 626 + KUNIT_CASE(string_test_strends), 638 627 {} 639 628 }; 640 629