1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * GPIO Testing Device Driver 4 * 5 * Copyright (C) 2014 Kamlakant Patel <kamlakant.patel@broadcom.com> 6 * Copyright (C) 2015-2016 Bamvor Jian Zhang <bamv2005@gmail.com> 7 * Copyright (C) 2017 Bartosz Golaszewski <brgl@bgdev.pl> 8 */ 9 10 #include <linux/init.h> 11 #include <linux/module.h> 12 #include <linux/gpio/driver.h> 13 #include <linux/gpio/consumer.h> 14 #include <linux/platform_device.h> 15 #include <linux/slab.h> 16 #include <linux/interrupt.h> 17 #include <linux/irq.h> 18 #include <linux/irq_sim.h> 19 #include <linux/debugfs.h> 20 #include <linux/uaccess.h> 21 22 #include "gpiolib.h" 23 24 #define GPIO_MOCKUP_NAME "gpio-mockup" 25 #define GPIO_MOCKUP_MAX_GC 10 26 /* 27 * We're storing two values per chip: the GPIO base and the number 28 * of GPIO lines. 29 */ 30 #define GPIO_MOCKUP_MAX_RANGES (GPIO_MOCKUP_MAX_GC * 2) 31 32 #define gpio_mockup_err(...) pr_err(GPIO_MOCKUP_NAME ": " __VA_ARGS__) 33 34 enum { 35 GPIO_MOCKUP_DIR_OUT = 0, 36 GPIO_MOCKUP_DIR_IN = 1, 37 }; 38 39 /* 40 * struct gpio_pin_status - structure describing a GPIO status 41 * @dir: Configures direction of gpio as "in" or "out", 0=in, 1=out 42 * @value: Configures status of the gpio as 0(low) or 1(high) 43 */ 44 struct gpio_mockup_line_status { 45 int dir; 46 int value; 47 }; 48 49 struct gpio_mockup_chip { 50 struct gpio_chip gc; 51 struct gpio_mockup_line_status *lines; 52 struct irq_sim irqsim; 53 struct dentry *dbg_dir; 54 }; 55 56 struct gpio_mockup_dbgfs_private { 57 struct gpio_mockup_chip *chip; 58 struct gpio_desc *desc; 59 int offset; 60 }; 61 62 struct gpio_mockup_platform_data { 63 int base; 64 int ngpio; 65 int index; 66 bool named_lines; 67 }; 68 69 static int gpio_mockup_ranges[GPIO_MOCKUP_MAX_RANGES]; 70 static int gpio_mockup_num_ranges; 71 module_param_array(gpio_mockup_ranges, int, &gpio_mockup_num_ranges, 0400); 72 73 static bool gpio_mockup_named_lines; 74 module_param_named(gpio_mockup_named_lines, 75 gpio_mockup_named_lines, bool, 0400); 76 77 static struct dentry *gpio_mockup_dbg_dir; 78 79 static int gpio_mockup_range_base(unsigned int index) 80 { 81 return gpio_mockup_ranges[index * 2]; 82 } 83 84 static int gpio_mockup_range_ngpio(unsigned int index) 85 { 86 return gpio_mockup_ranges[index * 2 + 1]; 87 } 88 89 static int gpio_mockup_get(struct gpio_chip *gc, unsigned int offset) 90 { 91 struct gpio_mockup_chip *chip = gpiochip_get_data(gc); 92 93 return chip->lines[offset].value; 94 } 95 96 static void gpio_mockup_set(struct gpio_chip *gc, 97 unsigned int offset, int value) 98 { 99 struct gpio_mockup_chip *chip = gpiochip_get_data(gc); 100 101 chip->lines[offset].value = !!value; 102 } 103 104 static void gpio_mockup_set_multiple(struct gpio_chip *gc, 105 unsigned long *mask, unsigned long *bits) 106 { 107 unsigned int bit; 108 109 for_each_set_bit(bit, mask, gc->ngpio) 110 gpio_mockup_set(gc, bit, test_bit(bit, bits)); 111 112 } 113 114 static int gpio_mockup_dirout(struct gpio_chip *gc, 115 unsigned int offset, int value) 116 { 117 struct gpio_mockup_chip *chip = gpiochip_get_data(gc); 118 119 gpio_mockup_set(gc, offset, value); 120 chip->lines[offset].dir = GPIO_MOCKUP_DIR_OUT; 121 122 return 0; 123 } 124 125 static int gpio_mockup_dirin(struct gpio_chip *gc, unsigned int offset) 126 { 127 struct gpio_mockup_chip *chip = gpiochip_get_data(gc); 128 129 chip->lines[offset].dir = GPIO_MOCKUP_DIR_IN; 130 131 return 0; 132 } 133 134 static int gpio_mockup_get_direction(struct gpio_chip *gc, unsigned int offset) 135 { 136 struct gpio_mockup_chip *chip = gpiochip_get_data(gc); 137 138 return chip->lines[offset].dir; 139 } 140 141 static int gpio_mockup_to_irq(struct gpio_chip *gc, unsigned int offset) 142 { 143 struct gpio_mockup_chip *chip = gpiochip_get_data(gc); 144 145 return irq_sim_irqnum(&chip->irqsim, offset); 146 } 147 148 static ssize_t gpio_mockup_event_write(struct file *file, 149 const char __user *usr_buf, 150 size_t size, loff_t *ppos) 151 { 152 struct gpio_mockup_dbgfs_private *priv; 153 struct gpio_mockup_chip *chip; 154 struct seq_file *sfile; 155 struct gpio_desc *desc; 156 int rv, val; 157 158 rv = kstrtoint_from_user(usr_buf, size, 0, &val); 159 if (rv) 160 return rv; 161 if (val != 0 && val != 1) 162 return -EINVAL; 163 164 sfile = file->private_data; 165 priv = sfile->private; 166 desc = priv->desc; 167 chip = priv->chip; 168 169 gpiod_set_value_cansleep(desc, val); 170 irq_sim_fire(&chip->irqsim, priv->offset); 171 172 return size; 173 } 174 175 static int gpio_mockup_event_open(struct inode *inode, struct file *file) 176 { 177 return single_open(file, NULL, inode->i_private); 178 } 179 180 static const struct file_operations gpio_mockup_event_ops = { 181 .owner = THIS_MODULE, 182 .open = gpio_mockup_event_open, 183 .write = gpio_mockup_event_write, 184 .llseek = no_llseek, 185 }; 186 187 static void gpio_mockup_debugfs_setup(struct device *dev, 188 struct gpio_mockup_chip *chip) 189 { 190 struct gpio_mockup_dbgfs_private *priv; 191 struct dentry *evfile, *link; 192 struct gpio_chip *gc; 193 const char *devname; 194 char *name; 195 int i; 196 197 gc = &chip->gc; 198 devname = dev_name(&gc->gpiodev->dev); 199 200 chip->dbg_dir = debugfs_create_dir(devname, gpio_mockup_dbg_dir); 201 if (IS_ERR_OR_NULL(chip->dbg_dir)) 202 goto err; 203 204 link = debugfs_create_symlink(gc->label, gpio_mockup_dbg_dir, devname); 205 if (IS_ERR_OR_NULL(link)) 206 goto err; 207 208 for (i = 0; i < gc->ngpio; i++) { 209 name = devm_kasprintf(dev, GFP_KERNEL, "%d", i); 210 if (!name) 211 goto err; 212 213 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 214 if (!priv) 215 goto err; 216 217 priv->chip = chip; 218 priv->offset = i; 219 priv->desc = &gc->gpiodev->descs[i]; 220 221 evfile = debugfs_create_file(name, 0200, chip->dbg_dir, priv, 222 &gpio_mockup_event_ops); 223 if (IS_ERR_OR_NULL(evfile)) 224 goto err; 225 } 226 227 return; 228 229 err: 230 dev_err(dev, "error creating debugfs event files\n"); 231 } 232 233 static int gpio_mockup_name_lines(struct device *dev, 234 struct gpio_mockup_chip *chip) 235 { 236 struct gpio_chip *gc = &chip->gc; 237 char **names; 238 int i; 239 240 names = devm_kcalloc(dev, gc->ngpio, sizeof(char *), GFP_KERNEL); 241 if (!names) 242 return -ENOMEM; 243 244 for (i = 0; i < gc->ngpio; i++) { 245 names[i] = devm_kasprintf(dev, GFP_KERNEL, 246 "%s-%d", gc->label, i); 247 if (!names[i]) 248 return -ENOMEM; 249 } 250 251 gc->names = (const char *const *)names; 252 253 return 0; 254 } 255 256 static int gpio_mockup_probe(struct platform_device *pdev) 257 { 258 struct gpio_mockup_platform_data *pdata; 259 struct gpio_mockup_chip *chip; 260 struct gpio_chip *gc; 261 int rv, base, ngpio; 262 struct device *dev; 263 char *name; 264 265 dev = &pdev->dev; 266 pdata = dev_get_platdata(dev); 267 base = pdata->base; 268 ngpio = pdata->ngpio; 269 270 chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); 271 if (!chip) 272 return -ENOMEM; 273 274 name = devm_kasprintf(dev, GFP_KERNEL, "%s-%c", 275 pdev->name, pdata->index); 276 if (!name) 277 return -ENOMEM; 278 279 gc = &chip->gc; 280 gc->base = base; 281 gc->ngpio = ngpio; 282 gc->label = name; 283 gc->owner = THIS_MODULE; 284 gc->parent = dev; 285 gc->get = gpio_mockup_get; 286 gc->set = gpio_mockup_set; 287 gc->set_multiple = gpio_mockup_set_multiple; 288 gc->direction_output = gpio_mockup_dirout; 289 gc->direction_input = gpio_mockup_dirin; 290 gc->get_direction = gpio_mockup_get_direction; 291 gc->to_irq = gpio_mockup_to_irq; 292 293 chip->lines = devm_kcalloc(dev, gc->ngpio, 294 sizeof(*chip->lines), GFP_KERNEL); 295 if (!chip->lines) 296 return -ENOMEM; 297 298 if (pdata->named_lines) { 299 rv = gpio_mockup_name_lines(dev, chip); 300 if (rv) 301 return rv; 302 } 303 304 rv = devm_irq_sim_init(dev, &chip->irqsim, gc->ngpio); 305 if (rv < 0) 306 return rv; 307 308 rv = devm_gpiochip_add_data(dev, &chip->gc, chip); 309 if (rv) 310 return rv; 311 312 if (!IS_ERR_OR_NULL(gpio_mockup_dbg_dir)) 313 gpio_mockup_debugfs_setup(dev, chip); 314 315 return 0; 316 } 317 318 static struct platform_driver gpio_mockup_driver = { 319 .driver = { 320 .name = GPIO_MOCKUP_NAME, 321 }, 322 .probe = gpio_mockup_probe, 323 }; 324 325 static struct platform_device *gpio_mockup_pdevs[GPIO_MOCKUP_MAX_GC]; 326 327 static void gpio_mockup_unregister_pdevs(void) 328 { 329 struct platform_device *pdev; 330 int i; 331 332 for (i = 0; i < GPIO_MOCKUP_MAX_GC; i++) { 333 pdev = gpio_mockup_pdevs[i]; 334 335 if (pdev) 336 platform_device_unregister(pdev); 337 } 338 } 339 340 static int __init gpio_mockup_init(void) 341 { 342 int i, num_chips, err = 0, index = 'A'; 343 struct gpio_mockup_platform_data pdata; 344 struct platform_device *pdev; 345 346 if ((gpio_mockup_num_ranges < 2) || 347 (gpio_mockup_num_ranges % 2) || 348 (gpio_mockup_num_ranges > GPIO_MOCKUP_MAX_RANGES)) 349 return -EINVAL; 350 351 /* Each chip is described by two values. */ 352 num_chips = gpio_mockup_num_ranges / 2; 353 354 /* 355 * The second value in the <base GPIO - number of GPIOS> pair must 356 * always be greater than 0. 357 */ 358 for (i = 0; i < num_chips; i++) { 359 if (gpio_mockup_range_ngpio(i) < 0) 360 return -EINVAL; 361 } 362 363 gpio_mockup_dbg_dir = debugfs_create_dir("gpio-mockup-event", NULL); 364 if (IS_ERR_OR_NULL(gpio_mockup_dbg_dir)) 365 gpio_mockup_err("error creating debugfs directory\n"); 366 367 err = platform_driver_register(&gpio_mockup_driver); 368 if (err) { 369 gpio_mockup_err("error registering platform driver\n"); 370 return err; 371 } 372 373 for (i = 0; i < num_chips; i++) { 374 pdata.index = index++; 375 pdata.base = gpio_mockup_range_base(i); 376 pdata.ngpio = pdata.base < 0 377 ? gpio_mockup_range_ngpio(i) 378 : gpio_mockup_range_ngpio(i) - pdata.base; 379 pdata.named_lines = gpio_mockup_named_lines; 380 381 pdev = platform_device_register_resndata(NULL, 382 GPIO_MOCKUP_NAME, 383 i, NULL, 0, &pdata, 384 sizeof(pdata)); 385 if (IS_ERR(pdev)) { 386 gpio_mockup_err("error registering device"); 387 platform_driver_unregister(&gpio_mockup_driver); 388 gpio_mockup_unregister_pdevs(); 389 return PTR_ERR(pdev); 390 } 391 392 gpio_mockup_pdevs[i] = pdev; 393 } 394 395 return 0; 396 } 397 398 static void __exit gpio_mockup_exit(void) 399 { 400 debugfs_remove_recursive(gpio_mockup_dbg_dir); 401 platform_driver_unregister(&gpio_mockup_driver); 402 gpio_mockup_unregister_pdevs(); 403 } 404 405 module_init(gpio_mockup_init); 406 module_exit(gpio_mockup_exit); 407 408 MODULE_AUTHOR("Kamlakant Patel <kamlakant.patel@broadcom.com>"); 409 MODULE_AUTHOR("Bamvor Jian Zhang <bamv2005@gmail.com>"); 410 MODULE_AUTHOR("Bartosz Golaszewski <brgl@bgdev.pl>"); 411 MODULE_DESCRIPTION("GPIO Testing driver"); 412 MODULE_LICENSE("GPL v2"); 413