linux/drivers/gpio/gpio-mockup.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   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#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  11
  12#include <linux/debugfs.h>
  13#include <linux/gpio/driver.h>
  14#include <linux/interrupt.h>
  15#include <linux/irq.h>
  16#include <linux/irq_sim.h>
  17#include <linux/irqdomain.h>
  18#include <linux/mod_devicetable.h>
  19#include <linux/module.h>
  20#include <linux/platform_device.h>
  21#include <linux/property.h>
  22#include <linux/slab.h>
  23#include <linux/string_helpers.h>
  24#include <linux/uaccess.h>
  25
  26#include "gpiolib.h"
  27
  28#define GPIO_MOCKUP_MAX_GC      10
  29/*
  30 * We're storing two values per chip: the GPIO base and the number
  31 * of GPIO lines.
  32 */
  33#define GPIO_MOCKUP_MAX_RANGES  (GPIO_MOCKUP_MAX_GC * 2)
  34/* Maximum of four properties + the sentinel. */
  35#define GPIO_MOCKUP_MAX_PROP    5
  36
  37/*
  38 * struct gpio_pin_status - structure describing a GPIO status
  39 * @dir:       Configures direction of gpio as "in" or "out"
  40 * @value:     Configures status of the gpio as 0(low) or 1(high)
  41 */
  42struct gpio_mockup_line_status {
  43        int dir;
  44        int value;
  45        int pull;
  46};
  47
  48struct gpio_mockup_chip {
  49        struct gpio_chip gc;
  50        struct gpio_mockup_line_status *lines;
  51        struct irq_domain *irq_sim_domain;
  52        struct dentry *dbg_dir;
  53        struct mutex lock;
  54};
  55
  56struct gpio_mockup_dbgfs_private {
  57        struct gpio_mockup_chip *chip;
  58        struct gpio_desc *desc;
  59        unsigned int offset;
  60};
  61
  62static int gpio_mockup_ranges[GPIO_MOCKUP_MAX_RANGES];
  63static int gpio_mockup_num_ranges;
  64module_param_array(gpio_mockup_ranges, int, &gpio_mockup_num_ranges, 0400);
  65
  66static bool gpio_mockup_named_lines;
  67module_param_named(gpio_mockup_named_lines,
  68                   gpio_mockup_named_lines, bool, 0400);
  69
  70static struct dentry *gpio_mockup_dbg_dir;
  71
  72static int gpio_mockup_range_base(unsigned int index)
  73{
  74        return gpio_mockup_ranges[index * 2];
  75}
  76
  77static int gpio_mockup_range_ngpio(unsigned int index)
  78{
  79        return gpio_mockup_ranges[index * 2 + 1];
  80}
  81
  82static int __gpio_mockup_get(struct gpio_mockup_chip *chip,
  83                             unsigned int offset)
  84{
  85        return chip->lines[offset].value;
  86}
  87
  88static int gpio_mockup_get(struct gpio_chip *gc, unsigned int offset)
  89{
  90        struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
  91        int val;
  92
  93        mutex_lock(&chip->lock);
  94        val = __gpio_mockup_get(chip, offset);
  95        mutex_unlock(&chip->lock);
  96
  97        return val;
  98}
  99
 100static int gpio_mockup_get_multiple(struct gpio_chip *gc,
 101                                    unsigned long *mask, unsigned long *bits)
 102{
 103        struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
 104        unsigned int bit, val;
 105
 106        mutex_lock(&chip->lock);
 107        for_each_set_bit(bit, mask, gc->ngpio) {
 108                val = __gpio_mockup_get(chip, bit);
 109                __assign_bit(bit, bits, val);
 110        }
 111        mutex_unlock(&chip->lock);
 112
 113        return 0;
 114}
 115
 116static void __gpio_mockup_set(struct gpio_mockup_chip *chip,
 117                              unsigned int offset, int value)
 118{
 119        chip->lines[offset].value = !!value;
 120}
 121
 122static void gpio_mockup_set(struct gpio_chip *gc,
 123                           unsigned int offset, int value)
 124{
 125        struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
 126
 127        mutex_lock(&chip->lock);
 128        __gpio_mockup_set(chip, offset, value);
 129        mutex_unlock(&chip->lock);
 130}
 131
 132static void gpio_mockup_set_multiple(struct gpio_chip *gc,
 133                                     unsigned long *mask, unsigned long *bits)
 134{
 135        struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
 136        unsigned int bit;
 137
 138        mutex_lock(&chip->lock);
 139        for_each_set_bit(bit, mask, gc->ngpio)
 140                __gpio_mockup_set(chip, bit, test_bit(bit, bits));
 141        mutex_unlock(&chip->lock);
 142}
 143
 144static int gpio_mockup_apply_pull(struct gpio_mockup_chip *chip,
 145                                  unsigned int offset, int value)
 146{
 147        int curr, irq, irq_type, ret = 0;
 148        struct gpio_desc *desc;
 149        struct gpio_chip *gc;
 150
 151        gc = &chip->gc;
 152        desc = &gc->gpiodev->descs[offset];
 153
 154        mutex_lock(&chip->lock);
 155
 156        if (test_bit(FLAG_REQUESTED, &desc->flags) &&
 157            !test_bit(FLAG_IS_OUT, &desc->flags)) {
 158                curr = __gpio_mockup_get(chip, offset);
 159                if (curr == value)
 160                        goto out;
 161
 162                irq = irq_find_mapping(chip->irq_sim_domain, offset);
 163                if (!irq)
 164                        /*
 165                         * This is fine - it just means, nobody is listening
 166                         * for interrupts on this line, otherwise
 167                         * irq_create_mapping() would have been called from
 168                         * the to_irq() callback.
 169                         */
 170                        goto set_value;
 171
 172                irq_type = irq_get_trigger_type(irq);
 173
 174                if ((value == 1 && (irq_type & IRQ_TYPE_EDGE_RISING)) ||
 175                    (value == 0 && (irq_type & IRQ_TYPE_EDGE_FALLING))) {
 176                        ret = irq_set_irqchip_state(irq, IRQCHIP_STATE_PENDING,
 177                                                    true);
 178                        if (ret)
 179                                goto out;
 180                }
 181        }
 182
 183set_value:
 184        /* Change the value unless we're actively driving the line. */
 185        if (!test_bit(FLAG_REQUESTED, &desc->flags) ||
 186            !test_bit(FLAG_IS_OUT, &desc->flags))
 187                __gpio_mockup_set(chip, offset, value);
 188
 189out:
 190        chip->lines[offset].pull = value;
 191        mutex_unlock(&chip->lock);
 192        return ret;
 193}
 194
 195static int gpio_mockup_set_config(struct gpio_chip *gc,
 196                                  unsigned int offset, unsigned long config)
 197{
 198        struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
 199
 200        switch (pinconf_to_config_param(config)) {
 201        case PIN_CONFIG_BIAS_PULL_UP:
 202                return gpio_mockup_apply_pull(chip, offset, 1);
 203        case PIN_CONFIG_BIAS_PULL_DOWN:
 204                return gpio_mockup_apply_pull(chip, offset, 0);
 205        default:
 206                break;
 207        }
 208        return -ENOTSUPP;
 209}
 210
 211static int gpio_mockup_dirout(struct gpio_chip *gc,
 212                              unsigned int offset, int value)
 213{
 214        struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
 215
 216        mutex_lock(&chip->lock);
 217        chip->lines[offset].dir = GPIO_LINE_DIRECTION_OUT;
 218        __gpio_mockup_set(chip, offset, value);
 219        mutex_unlock(&chip->lock);
 220
 221        return 0;
 222}
 223
 224static int gpio_mockup_dirin(struct gpio_chip *gc, unsigned int offset)
 225{
 226        struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
 227
 228        mutex_lock(&chip->lock);
 229        chip->lines[offset].dir = GPIO_LINE_DIRECTION_IN;
 230        mutex_unlock(&chip->lock);
 231
 232        return 0;
 233}
 234
 235static int gpio_mockup_get_direction(struct gpio_chip *gc, unsigned int offset)
 236{
 237        struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
 238        int direction;
 239
 240        mutex_lock(&chip->lock);
 241        direction = chip->lines[offset].dir;
 242        mutex_unlock(&chip->lock);
 243
 244        return direction;
 245}
 246
 247static int gpio_mockup_to_irq(struct gpio_chip *gc, unsigned int offset)
 248{
 249        struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
 250
 251        return irq_create_mapping(chip->irq_sim_domain, offset);
 252}
 253
 254static void gpio_mockup_free(struct gpio_chip *gc, unsigned int offset)
 255{
 256        struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
 257
 258        __gpio_mockup_set(chip, offset, chip->lines[offset].pull);
 259}
 260
 261static ssize_t gpio_mockup_debugfs_read(struct file *file,
 262                                        char __user *usr_buf,
 263                                        size_t size, loff_t *ppos)
 264{
 265        struct gpio_mockup_dbgfs_private *priv;
 266        struct gpio_mockup_chip *chip;
 267        struct seq_file *sfile;
 268        struct gpio_chip *gc;
 269        int val, cnt;
 270        char buf[3];
 271
 272        if (*ppos != 0)
 273                return 0;
 274
 275        sfile = file->private_data;
 276        priv = sfile->private;
 277        chip = priv->chip;
 278        gc = &chip->gc;
 279
 280        val = gpio_mockup_get(gc, priv->offset);
 281        cnt = snprintf(buf, sizeof(buf), "%d\n", val);
 282
 283        return simple_read_from_buffer(usr_buf, size, ppos, buf, cnt);
 284}
 285
 286static ssize_t gpio_mockup_debugfs_write(struct file *file,
 287                                         const char __user *usr_buf,
 288                                         size_t size, loff_t *ppos)
 289{
 290        struct gpio_mockup_dbgfs_private *priv;
 291        int rv, val;
 292        struct seq_file *sfile;
 293
 294        if (*ppos != 0)
 295                return -EINVAL;
 296
 297        rv = kstrtoint_from_user(usr_buf, size, 0, &val);
 298        if (rv)
 299                return rv;
 300        if (val != 0 && val != 1)
 301                return -EINVAL;
 302
 303        sfile = file->private_data;
 304        priv = sfile->private;
 305        rv = gpio_mockup_apply_pull(priv->chip, priv->offset, val);
 306        if (rv)
 307                return rv;
 308
 309        return size;
 310}
 311
 312static int gpio_mockup_debugfs_open(struct inode *inode, struct file *file)
 313{
 314        return single_open(file, NULL, inode->i_private);
 315}
 316
 317/*
 318 * Each mockup chip is represented by a directory named after the chip's device
 319 * name under /sys/kernel/debug/gpio-mockup/. Each line is represented by
 320 * a file using the line's offset as the name under the chip's directory.
 321 *
 322 * Reading from the line's file yields the current *value*, writing to the
 323 * line's file changes the current *pull*. Default pull for mockup lines is
 324 * down.
 325 *
 326 * Examples:
 327 * - when a line pulled down is requested in output mode and driven high, its
 328 *   value will return to 0 once it's released
 329 * - when the line is requested in output mode and driven high, writing 0 to
 330 *   the corresponding debugfs file will change the pull to down but the
 331 *   reported value will still be 1 until the line is released
 332 * - line requested in input mode always reports the same value as its pull
 333 *   configuration
 334 * - when the line is requested in input mode and monitored for events, writing
 335 *   the same value to the debugfs file will be a noop, while writing the
 336 *   opposite value will generate a dummy interrupt with an appropriate edge
 337 */
 338static const struct file_operations gpio_mockup_debugfs_ops = {
 339        .owner = THIS_MODULE,
 340        .open = gpio_mockup_debugfs_open,
 341        .read = gpio_mockup_debugfs_read,
 342        .write = gpio_mockup_debugfs_write,
 343        .llseek = no_llseek,
 344        .release = single_release,
 345};
 346
 347static void gpio_mockup_debugfs_setup(struct device *dev,
 348                                      struct gpio_mockup_chip *chip)
 349{
 350        struct gpio_mockup_dbgfs_private *priv;
 351        struct gpio_chip *gc;
 352        const char *devname;
 353        char *name;
 354        int i;
 355
 356        gc = &chip->gc;
 357        devname = dev_name(&gc->gpiodev->dev);
 358
 359        chip->dbg_dir = debugfs_create_dir(devname, gpio_mockup_dbg_dir);
 360
 361        for (i = 0; i < gc->ngpio; i++) {
 362                name = devm_kasprintf(dev, GFP_KERNEL, "%d", i);
 363                if (!name)
 364                        return;
 365
 366                priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 367                if (!priv)
 368                        return;
 369
 370                priv->chip = chip;
 371                priv->offset = i;
 372                priv->desc = &gc->gpiodev->descs[i];
 373
 374                debugfs_create_file(name, 0200, chip->dbg_dir, priv,
 375                                    &gpio_mockup_debugfs_ops);
 376        }
 377}
 378
 379static void gpio_mockup_dispose_mappings(void *data)
 380{
 381        struct gpio_mockup_chip *chip = data;
 382        struct gpio_chip *gc = &chip->gc;
 383        int i, irq;
 384
 385        for (i = 0; i < gc->ngpio; i++) {
 386                irq = irq_find_mapping(chip->irq_sim_domain, i);
 387                if (irq)
 388                        irq_dispose_mapping(irq);
 389        }
 390}
 391
 392static int gpio_mockup_probe(struct platform_device *pdev)
 393{
 394        struct gpio_mockup_chip *chip;
 395        struct gpio_chip *gc;
 396        struct device *dev;
 397        const char *name;
 398        int rv, base, i;
 399        u16 ngpio;
 400
 401        dev = &pdev->dev;
 402
 403        rv = device_property_read_u32(dev, "gpio-base", &base);
 404        if (rv)
 405                base = -1;
 406
 407        rv = device_property_read_u16(dev, "nr-gpios", &ngpio);
 408        if (rv)
 409                return rv;
 410
 411        rv = device_property_read_string(dev, "chip-label", &name);
 412        if (rv)
 413                name = dev_name(dev);
 414
 415        chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
 416        if (!chip)
 417                return -ENOMEM;
 418
 419        mutex_init(&chip->lock);
 420
 421        gc = &chip->gc;
 422        gc->base = base;
 423        gc->ngpio = ngpio;
 424        gc->label = name;
 425        gc->owner = THIS_MODULE;
 426        gc->parent = dev;
 427        gc->get = gpio_mockup_get;
 428        gc->set = gpio_mockup_set;
 429        gc->get_multiple = gpio_mockup_get_multiple;
 430        gc->set_multiple = gpio_mockup_set_multiple;
 431        gc->direction_output = gpio_mockup_dirout;
 432        gc->direction_input = gpio_mockup_dirin;
 433        gc->get_direction = gpio_mockup_get_direction;
 434        gc->set_config = gpio_mockup_set_config;
 435        gc->to_irq = gpio_mockup_to_irq;
 436        gc->free = gpio_mockup_free;
 437
 438        chip->lines = devm_kcalloc(dev, gc->ngpio,
 439                                   sizeof(*chip->lines), GFP_KERNEL);
 440        if (!chip->lines)
 441                return -ENOMEM;
 442
 443        for (i = 0; i < gc->ngpio; i++)
 444                chip->lines[i].dir = GPIO_LINE_DIRECTION_IN;
 445
 446        chip->irq_sim_domain = devm_irq_domain_create_sim(dev, NULL,
 447                                                          gc->ngpio);
 448        if (IS_ERR(chip->irq_sim_domain))
 449                return PTR_ERR(chip->irq_sim_domain);
 450
 451        rv = devm_add_action_or_reset(dev, gpio_mockup_dispose_mappings, chip);
 452        if (rv)
 453                return rv;
 454
 455        rv = devm_gpiochip_add_data(dev, &chip->gc, chip);
 456        if (rv)
 457                return rv;
 458
 459        gpio_mockup_debugfs_setup(dev, chip);
 460
 461        return 0;
 462}
 463
 464static const struct of_device_id gpio_mockup_of_match[] = {
 465        { .compatible = "gpio-mockup", },
 466        {},
 467};
 468MODULE_DEVICE_TABLE(of, gpio_mockup_of_match);
 469
 470static struct platform_driver gpio_mockup_driver = {
 471        .driver = {
 472                .name = "gpio-mockup",
 473                .of_match_table = gpio_mockup_of_match,
 474        },
 475        .probe = gpio_mockup_probe,
 476};
 477
 478static struct platform_device *gpio_mockup_pdevs[GPIO_MOCKUP_MAX_GC];
 479
 480static void gpio_mockup_unregister_pdevs(void)
 481{
 482        struct platform_device *pdev;
 483        int i;
 484
 485        for (i = 0; i < GPIO_MOCKUP_MAX_GC; i++) {
 486                pdev = gpio_mockup_pdevs[i];
 487
 488                if (pdev)
 489                        platform_device_unregister(pdev);
 490        }
 491}
 492
 493static __init char **gpio_mockup_make_line_names(const char *label,
 494                                                 unsigned int num_lines)
 495{
 496        unsigned int i;
 497        char **names;
 498
 499        names = kcalloc(num_lines + 1, sizeof(char *), GFP_KERNEL);
 500        if (!names)
 501                return NULL;
 502
 503        for (i = 0; i < num_lines; i++) {
 504                names[i] = kasprintf(GFP_KERNEL, "%s-%u", label, i);
 505                if (!names[i]) {
 506                        kfree_strarray(names, i);
 507                        return NULL;
 508                }
 509        }
 510
 511        return names;
 512}
 513
 514static int __init gpio_mockup_register_chip(int idx)
 515{
 516        struct property_entry properties[GPIO_MOCKUP_MAX_PROP];
 517        struct platform_device_info pdevinfo;
 518        struct platform_device *pdev;
 519        char **line_names = NULL;
 520        char chip_label[32];
 521        int prop = 0, base;
 522        u16 ngpio;
 523
 524        memset(properties, 0, sizeof(properties));
 525        memset(&pdevinfo, 0, sizeof(pdevinfo));
 526
 527        snprintf(chip_label, sizeof(chip_label), "gpio-mockup-%c", idx + 'A');
 528        properties[prop++] = PROPERTY_ENTRY_STRING("chip-label", chip_label);
 529
 530        base = gpio_mockup_range_base(idx);
 531        if (base >= 0)
 532                properties[prop++] = PROPERTY_ENTRY_U32("gpio-base", base);
 533
 534        ngpio = base < 0 ? gpio_mockup_range_ngpio(idx)
 535                         : gpio_mockup_range_ngpio(idx) - base;
 536        properties[prop++] = PROPERTY_ENTRY_U16("nr-gpios", ngpio);
 537
 538        if (gpio_mockup_named_lines) {
 539                line_names = gpio_mockup_make_line_names(chip_label, ngpio);
 540                if (!line_names)
 541                        return -ENOMEM;
 542
 543                properties[prop++] = PROPERTY_ENTRY_STRING_ARRAY_LEN(
 544                                        "gpio-line-names", line_names, ngpio);
 545        }
 546
 547        pdevinfo.name = "gpio-mockup";
 548        pdevinfo.id = idx;
 549        pdevinfo.properties = properties;
 550
 551        pdev = platform_device_register_full(&pdevinfo);
 552        kfree_strarray(line_names, ngpio);
 553        if (IS_ERR(pdev)) {
 554                pr_err("error registering device");
 555                return PTR_ERR(pdev);
 556        }
 557
 558        gpio_mockup_pdevs[idx] = pdev;
 559
 560        return 0;
 561}
 562
 563static int __init gpio_mockup_init(void)
 564{
 565        int i, num_chips, err;
 566
 567        if ((gpio_mockup_num_ranges % 2) ||
 568            (gpio_mockup_num_ranges > GPIO_MOCKUP_MAX_RANGES))
 569                return -EINVAL;
 570
 571        /* Each chip is described by two values. */
 572        num_chips = gpio_mockup_num_ranges / 2;
 573
 574        /*
 575         * The second value in the <base GPIO - number of GPIOS> pair must
 576         * always be greater than 0.
 577         */
 578        for (i = 0; i < num_chips; i++) {
 579                if (gpio_mockup_range_ngpio(i) < 0)
 580                        return -EINVAL;
 581        }
 582
 583        gpio_mockup_dbg_dir = debugfs_create_dir("gpio-mockup", NULL);
 584
 585        err = platform_driver_register(&gpio_mockup_driver);
 586        if (err) {
 587                pr_err("error registering platform driver\n");
 588                debugfs_remove_recursive(gpio_mockup_dbg_dir);
 589                return err;
 590        }
 591
 592        for (i = 0; i < num_chips; i++) {
 593                err = gpio_mockup_register_chip(i);
 594                if (err) {
 595                        platform_driver_unregister(&gpio_mockup_driver);
 596                        gpio_mockup_unregister_pdevs();
 597                        debugfs_remove_recursive(gpio_mockup_dbg_dir);
 598                        return err;
 599                }
 600        }
 601
 602        return 0;
 603}
 604
 605static void __exit gpio_mockup_exit(void)
 606{
 607        debugfs_remove_recursive(gpio_mockup_dbg_dir);
 608        platform_driver_unregister(&gpio_mockup_driver);
 609        gpio_mockup_unregister_pdevs();
 610}
 611
 612module_init(gpio_mockup_init);
 613module_exit(gpio_mockup_exit);
 614
 615MODULE_AUTHOR("Kamlakant Patel <kamlakant.patel@broadcom.com>");
 616MODULE_AUTHOR("Bamvor Jian Zhang <bamv2005@gmail.com>");
 617MODULE_AUTHOR("Bartosz Golaszewski <brgl@bgdev.pl>");
 618MODULE_DESCRIPTION("GPIO Testing driver");
 619MODULE_LICENSE("GPL v2");
 620