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