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/lockdep.h> 13 #include <linux/module.h> 14 #include <linux/mutex.h> 15 #include <linux/string_choices.h> 16 #include <linux/types.h> 17 18 #include "gpiolib-shared.h" 19 20 struct gpio_shared_proxy_data { 21 struct gpio_chip gc; 22 struct gpio_shared_desc *shared_desc; 23 struct device *dev; 24 bool voted_change; 25 }; 26 27 static int 28 gpio_shared_proxy_set_unlocked(struct gpio_shared_proxy_data *proxy, int value) 29 { 30 struct gpio_shared_desc *shared_desc = proxy->shared_desc; 31 struct gpio_desc *desc = shared_desc->desc; 32 int ret = 0; 33 34 lockdep_assert_held(&shared_desc->mutex); 35 36 if (value != shared_desc->def_val) { 37 /* User wants to vote for a value change. */ 38 if (proxy->voted_change) 39 /* Already voted for a change, nothing to do. */ 40 goto out; 41 42 /* Haven't voted for a value change yet. */ 43 if (!shared_desc->votecnt) { 44 /* 45 * Current value is default, need to actually set value 46 * to the opposite. 47 */ 48 ret = gpiod_set_value_cansleep(desc, value); 49 if (ret) 50 goto out; 51 } 52 53 shared_desc->votecnt++; 54 proxy->voted_change = true; 55 56 goto out; 57 } 58 59 /* Desired value is the default. */ 60 if (!proxy->voted_change) 61 /* We didn't vote for change previously, nothing to do. */ 62 goto out; 63 64 /* We previously voted for change. */ 65 if (shared_desc->votecnt == 1) { 66 /* This is the last remaining vote for change, set value to default. */ 67 ret = gpiod_set_value_cansleep(desc, shared_desc->def_val); 68 if (ret) 69 goto out; 70 } 71 72 shared_desc->votecnt--; 73 proxy->voted_change = false; 74 75 out: 76 if (shared_desc->votecnt) 77 dev_dbg(proxy->dev, 78 "Voted for value '%s', effective value is '%s', number of votes: %u\n", 79 str_high_low(value), str_high_low(!shared_desc->def_val), 80 shared_desc->votecnt); 81 else 82 dev_dbg(proxy->dev, "Voted for value '%s', effective value is '%s'\n", 83 str_high_low(value), str_high_low(shared_desc->def_val)); 84 85 return ret; 86 } 87 88 static int gpio_shared_proxy_request(struct gpio_chip *gc, unsigned int offset) 89 { 90 struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); 91 struct gpio_shared_desc *shared_desc = proxy->shared_desc; 92 93 guard(mutex)(&shared_desc->mutex); 94 95 proxy->shared_desc->usecnt++; 96 97 dev_dbg(proxy->dev, "Shared GPIO requested, number of users: %u\n", 98 proxy->shared_desc->usecnt); 99 100 return 0; 101 } 102 103 static void gpio_shared_proxy_free(struct gpio_chip *gc, unsigned int offset) 104 { 105 struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); 106 struct gpio_shared_desc *shared_desc = proxy->shared_desc; 107 int ret; 108 109 guard(mutex)(&shared_desc->mutex); 110 111 if (proxy->voted_change) { 112 ret = gpio_shared_proxy_set_unlocked(proxy, shared_desc->def_val); 113 if (ret) 114 dev_err(proxy->dev, 115 "Failed to unset the shared GPIO value on release: %d\n", ret); 116 } 117 118 proxy->shared_desc->usecnt--; 119 120 dev_dbg(proxy->dev, "Shared GPIO freed, number of users: %u\n", 121 proxy->shared_desc->usecnt); 122 } 123 124 static int gpio_shared_proxy_set_config(struct gpio_chip *gc, 125 unsigned int offset, unsigned long cfg) 126 { 127 struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); 128 struct gpio_shared_desc *shared_desc = proxy->shared_desc; 129 struct gpio_desc *desc = shared_desc->desc; 130 int ret; 131 132 guard(mutex)(&shared_desc->mutex); 133 134 if (shared_desc->usecnt > 1) { 135 if (shared_desc->cfg != cfg) { 136 dev_dbg(proxy->dev, 137 "Shared GPIO's configuration already set, accepting changes but users may conflict!!\n"); 138 } else { 139 dev_dbg(proxy->dev, "Equal config requested, nothing to do\n"); 140 return 0; 141 } 142 } 143 144 ret = gpiod_set_config(desc, cfg); 145 if (ret && ret != -ENOTSUPP) 146 return ret; 147 148 shared_desc->cfg = cfg; 149 return 0; 150 } 151 152 static int gpio_shared_proxy_direction_input(struct gpio_chip *gc, 153 unsigned int offset) 154 { 155 struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); 156 struct gpio_shared_desc *shared_desc = proxy->shared_desc; 157 struct gpio_desc *desc = shared_desc->desc; 158 int dir; 159 160 guard(mutex)(&shared_desc->mutex); 161 162 if (shared_desc->usecnt == 1) { 163 dev_dbg(proxy->dev, 164 "Only one user of this shared GPIO, allowing to set direction to input\n"); 165 166 return gpiod_direction_input(desc); 167 } 168 169 dir = gpiod_get_direction(desc); 170 if (dir < 0) 171 return dir; 172 173 if (dir == GPIO_LINE_DIRECTION_OUT) { 174 dev_dbg(proxy->dev, 175 "Shared GPIO's direction already set to output, refusing to change\n"); 176 return -EPERM; 177 } 178 179 return 0; 180 } 181 182 static int gpio_shared_proxy_direction_output(struct gpio_chip *gc, 183 unsigned int offset, int value) 184 { 185 struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); 186 struct gpio_shared_desc *shared_desc = proxy->shared_desc; 187 struct gpio_desc *desc = shared_desc->desc; 188 int ret, dir; 189 190 guard(mutex)(&shared_desc->mutex); 191 192 if (shared_desc->usecnt == 1) { 193 dev_dbg(proxy->dev, 194 "Only one user of this shared GPIO, allowing to set direction to output with value '%s'\n", 195 str_high_low(value)); 196 197 ret = gpiod_direction_output(desc, value); 198 if (ret) 199 return ret; 200 201 shared_desc->def_val = value; 202 shared_desc->votecnt = 0; 203 proxy->voted_change = false; 204 205 return 0; 206 } 207 208 dir = gpiod_get_direction(desc); 209 if (dir < 0) 210 return dir; 211 212 if (dir == GPIO_LINE_DIRECTION_IN) { 213 dev_dbg(proxy->dev, 214 "Shared GPIO's direction already set to input, refusing to change\n"); 215 return -EPERM; 216 } 217 218 return gpio_shared_proxy_set_unlocked(proxy, value); 219 } 220 221 static int gpio_shared_proxy_get_cansleep(struct gpio_chip *gc, 222 unsigned int offset) 223 { 224 struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); 225 226 return gpiod_get_value_cansleep(proxy->shared_desc->desc); 227 } 228 229 static int gpio_shared_proxy_set_cansleep(struct gpio_chip *gc, 230 unsigned int offset, int value) 231 { 232 struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); 233 234 guard(mutex)(&proxy->shared_desc->mutex); 235 236 return gpio_shared_proxy_set_unlocked(proxy, value); 237 } 238 239 static int gpio_shared_proxy_get_direction(struct gpio_chip *gc, 240 unsigned int offset) 241 { 242 struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); 243 244 return gpiod_get_direction(proxy->shared_desc->desc); 245 } 246 247 static int gpio_shared_proxy_to_irq(struct gpio_chip *gc, unsigned int offset) 248 { 249 struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); 250 251 return gpiod_to_irq(proxy->shared_desc->desc); 252 } 253 254 static int gpio_shared_proxy_probe(struct auxiliary_device *adev, 255 const struct auxiliary_device_id *id) 256 { 257 struct gpio_shared_proxy_data *proxy; 258 struct gpio_shared_desc *shared_desc; 259 struct device *dev = &adev->dev; 260 struct gpio_chip *gc; 261 262 shared_desc = devm_gpiod_shared_get(dev); 263 if (IS_ERR(shared_desc)) 264 return PTR_ERR(shared_desc); 265 266 proxy = devm_kzalloc(dev, sizeof(*proxy), GFP_KERNEL); 267 if (!proxy) 268 return -ENOMEM; 269 270 proxy->shared_desc = shared_desc; 271 proxy->dev = dev; 272 273 gc = &proxy->gc; 274 gc->base = -1; 275 gc->ngpio = 1; 276 gc->label = dev_name(dev); 277 gc->parent = dev; 278 gc->owner = THIS_MODULE; 279 /* 280 * Under the descriptor mutex the proxy may call 281 * gpiod_set_config()/gpiod_direction_*(), which can reach pinctrl 282 * paths that take a mutex (e.g. gpiod_set_config() -> 283 * gpiochip_generic_config() -> pinctrl_gpio_set_config()), independent 284 * of the underlying chip's can_sleep. So the descriptor lock must be a 285 * mutex and the proxy gpiochip is therefore always sleeping; drive the 286 * underlying GPIO through the cansleep value accessors, which are valid 287 * for both sleeping and non-sleeping chips. 288 */ 289 gc->can_sleep = true; 290 291 gc->request = gpio_shared_proxy_request; 292 gc->free = gpio_shared_proxy_free; 293 gc->set_config = gpio_shared_proxy_set_config; 294 gc->direction_input = gpio_shared_proxy_direction_input; 295 gc->direction_output = gpio_shared_proxy_direction_output; 296 gc->set = gpio_shared_proxy_set_cansleep; 297 gc->get = gpio_shared_proxy_get_cansleep; 298 gc->get_direction = gpio_shared_proxy_get_direction; 299 gc->to_irq = gpio_shared_proxy_to_irq; 300 301 return devm_gpiochip_add_data(dev, &proxy->gc, proxy); 302 } 303 304 static const struct auxiliary_device_id gpio_shared_proxy_id_table[] = { 305 { .name = "gpiolib_shared.proxy" }, 306 {}, 307 }; 308 MODULE_DEVICE_TABLE(auxiliary, gpio_shared_proxy_id_table); 309 310 static struct auxiliary_driver gpio_shared_proxy_driver = { 311 .driver = { 312 .name = "gpio-shared-proxy", 313 .suppress_bind_attrs = true, 314 }, 315 .probe = gpio_shared_proxy_probe, 316 .id_table = gpio_shared_proxy_id_table, 317 }; 318 module_auxiliary_driver(gpio_shared_proxy_driver); 319 320 MODULE_AUTHOR("Bartosz Golaszewski <bartosz.golaszewski@linaro.org>"); 321 MODULE_DESCRIPTION("Shared GPIO mux driver."); 322 MODULE_LICENSE("GPL"); 323