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