linux/drivers/base/regmap/regmap-debugfs.c
<<
>>
Prefs
   1/*
   2 * Register map access API - debugfs
   3 *
   4 * Copyright 2011 Wolfson Microelectronics plc
   5 *
   6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 */
  12
  13#include <linux/slab.h>
  14#include <linux/mutex.h>
  15#include <linux/debugfs.h>
  16#include <linux/uaccess.h>
  17#include <linux/device.h>
  18#include <linux/list.h>
  19
  20#include "internal.h"
  21
  22struct regmap_debugfs_node {
  23        struct regmap *map;
  24        const char *name;
  25        struct list_head link;
  26};
  27
  28static struct dentry *regmap_debugfs_root;
  29static LIST_HEAD(regmap_debugfs_early_list);
  30static DEFINE_MUTEX(regmap_debugfs_early_lock);
  31
  32/* Calculate the length of a fixed format  */
  33static size_t regmap_calc_reg_len(int max_val)
  34{
  35        return snprintf(NULL, 0, "%x", max_val);
  36}
  37
  38static ssize_t regmap_name_read_file(struct file *file,
  39                                     char __user *user_buf, size_t count,
  40                                     loff_t *ppos)
  41{
  42        struct regmap *map = file->private_data;
  43        int ret;
  44        char *buf;
  45
  46        buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
  47        if (!buf)
  48                return -ENOMEM;
  49
  50        ret = snprintf(buf, PAGE_SIZE, "%s\n", map->dev->driver->name);
  51        if (ret < 0) {
  52                kfree(buf);
  53                return ret;
  54        }
  55
  56        ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
  57        kfree(buf);
  58        return ret;
  59}
  60
  61static const struct file_operations regmap_name_fops = {
  62        .open = simple_open,
  63        .read = regmap_name_read_file,
  64        .llseek = default_llseek,
  65};
  66
  67static void regmap_debugfs_free_dump_cache(struct regmap *map)
  68{
  69        struct regmap_debugfs_off_cache *c;
  70
  71        while (!list_empty(&map->debugfs_off_cache)) {
  72                c = list_first_entry(&map->debugfs_off_cache,
  73                                     struct regmap_debugfs_off_cache,
  74                                     list);
  75                list_del(&c->list);
  76                kfree(c);
  77        }
  78}
  79
  80/*
  81 * Work out where the start offset maps into register numbers, bearing
  82 * in mind that we suppress hidden registers.
  83 */
  84static unsigned int regmap_debugfs_get_dump_start(struct regmap *map,
  85                                                  unsigned int base,
  86                                                  loff_t from,
  87                                                  loff_t *pos)
  88{
  89        struct regmap_debugfs_off_cache *c = NULL;
  90        loff_t p = 0;
  91        unsigned int i, ret;
  92        unsigned int fpos_offset;
  93        unsigned int reg_offset;
  94
  95        /* Suppress the cache if we're using a subrange */
  96        if (base)
  97                return base;
  98
  99        /*
 100         * If we don't have a cache build one so we don't have to do a
 101         * linear scan each time.
 102         */
 103        mutex_lock(&map->cache_lock);
 104        i = base;
 105        if (list_empty(&map->debugfs_off_cache)) {
 106                for (; i <= map->max_register; i += map->reg_stride) {
 107                        /* Skip unprinted registers, closing off cache entry */
 108                        if (!regmap_readable(map, i) ||
 109                            regmap_precious(map, i)) {
 110                                if (c) {
 111                                        c->max = p - 1;
 112                                        c->max_reg = i - map->reg_stride;
 113                                        list_add_tail(&c->list,
 114                                                      &map->debugfs_off_cache);
 115                                        c = NULL;
 116                                }
 117
 118                                continue;
 119                        }
 120
 121                        /* No cache entry?  Start a new one */
 122                        if (!c) {
 123                                c = kzalloc(sizeof(*c), GFP_KERNEL);
 124                                if (!c) {
 125                                        regmap_debugfs_free_dump_cache(map);
 126                                        mutex_unlock(&map->cache_lock);
 127                                        return base;
 128                                }
 129                                c->min = p;
 130                                c->base_reg = i;
 131                        }
 132
 133                        p += map->debugfs_tot_len;
 134                }
 135        }
 136
 137        /* Close the last entry off if we didn't scan beyond it */
 138        if (c) {
 139                c->max = p - 1;
 140                c->max_reg = i - map->reg_stride;
 141                list_add_tail(&c->list,
 142                              &map->debugfs_off_cache);
 143        }
 144
 145        /*
 146         * This should never happen; we return above if we fail to
 147         * allocate and we should never be in this code if there are
 148         * no registers at all.
 149         */
 150        WARN_ON(list_empty(&map->debugfs_off_cache));
 151        ret = base;
 152
 153        /* Find the relevant block:offset */
 154        list_for_each_entry(c, &map->debugfs_off_cache, list) {
 155                if (from >= c->min && from <= c->max) {
 156                        fpos_offset = from - c->min;
 157                        reg_offset = fpos_offset / map->debugfs_tot_len;
 158                        *pos = c->min + (reg_offset * map->debugfs_tot_len);
 159                        mutex_unlock(&map->cache_lock);
 160                        return c->base_reg + (reg_offset * map->reg_stride);
 161                }
 162
 163                *pos = c->max;
 164                ret = c->max_reg;
 165        }
 166        mutex_unlock(&map->cache_lock);
 167
 168        return ret;
 169}
 170
 171static inline void regmap_calc_tot_len(struct regmap *map,
 172                                       void *buf, size_t count)
 173{
 174        /* Calculate the length of a fixed format  */
 175        if (!map->debugfs_tot_len) {
 176                map->debugfs_reg_len = regmap_calc_reg_len(map->max_register),
 177                map->debugfs_val_len = 2 * map->format.val_bytes;
 178                map->debugfs_tot_len = map->debugfs_reg_len +
 179                        map->debugfs_val_len + 3;      /* : \n */
 180        }
 181}
 182
 183static ssize_t regmap_read_debugfs(struct regmap *map, unsigned int from,
 184                                   unsigned int to, char __user *user_buf,
 185                                   size_t count, loff_t *ppos)
 186{
 187        size_t buf_pos = 0;
 188        loff_t p = *ppos;
 189        ssize_t ret;
 190        int i;
 191        char *buf;
 192        unsigned int val, start_reg;
 193
 194        if (*ppos < 0 || !count)
 195                return -EINVAL;
 196
 197        buf = kmalloc(count, GFP_KERNEL);
 198        if (!buf)
 199                return -ENOMEM;
 200
 201        regmap_calc_tot_len(map, buf, count);
 202
 203        /* Work out which register we're starting at */
 204        start_reg = regmap_debugfs_get_dump_start(map, from, *ppos, &p);
 205
 206        for (i = start_reg; i <= to; i += map->reg_stride) {
 207                if (!regmap_readable(map, i))
 208                        continue;
 209
 210                if (regmap_precious(map, i))
 211                        continue;
 212
 213                /* If we're in the region the user is trying to read */
 214                if (p >= *ppos) {
 215                        /* ...but not beyond it */
 216                        if (buf_pos + map->debugfs_tot_len > count)
 217                                break;
 218
 219                        /* Format the register */
 220                        snprintf(buf + buf_pos, count - buf_pos, "%.*x: ",
 221                                 map->debugfs_reg_len, i - from);
 222                        buf_pos += map->debugfs_reg_len + 2;
 223
 224                        /* Format the value, write all X if we can't read */
 225                        ret = regmap_read(map, i, &val);
 226                        if (ret == 0)
 227                                snprintf(buf + buf_pos, count - buf_pos,
 228                                         "%.*x", map->debugfs_val_len, val);
 229                        else
 230                                memset(buf + buf_pos, 'X',
 231                                       map->debugfs_val_len);
 232                        buf_pos += 2 * map->format.val_bytes;
 233
 234                        buf[buf_pos++] = '\n';
 235                }
 236                p += map->debugfs_tot_len;
 237        }
 238
 239        ret = buf_pos;
 240
 241        if (copy_to_user(user_buf, buf, buf_pos)) {
 242                ret = -EFAULT;
 243                goto out;
 244        }
 245
 246        *ppos += buf_pos;
 247
 248out:
 249        kfree(buf);
 250        return ret;
 251}
 252
 253static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf,
 254                                    size_t count, loff_t *ppos)
 255{
 256        struct regmap *map = file->private_data;
 257
 258        return regmap_read_debugfs(map, 0, map->max_register, user_buf,
 259                                   count, ppos);
 260}
 261
 262#undef REGMAP_ALLOW_WRITE_DEBUGFS
 263#ifdef REGMAP_ALLOW_WRITE_DEBUGFS
 264/*
 265 * This can be dangerous especially when we have clients such as
 266 * PMICs, therefore don't provide any real compile time configuration option
 267 * for this feature, people who want to use this will need to modify
 268 * the source code directly.
 269 */
 270static ssize_t regmap_map_write_file(struct file *file,
 271                                     const char __user *user_buf,
 272                                     size_t count, loff_t *ppos)
 273{
 274        char buf[32];
 275        size_t buf_size;
 276        char *start = buf;
 277        unsigned long reg, value;
 278        struct regmap *map = file->private_data;
 279        int ret;
 280
 281        buf_size = min(count, (sizeof(buf)-1));
 282        if (copy_from_user(buf, user_buf, buf_size))
 283                return -EFAULT;
 284        buf[buf_size] = 0;
 285
 286        while (*start == ' ')
 287                start++;
 288        reg = simple_strtoul(start, &start, 16);
 289        while (*start == ' ')
 290                start++;
 291        if (kstrtoul(start, 16, &value))
 292                return -EINVAL;
 293
 294        /* Userspace has been fiddling around behind the kernel's back */
 295        add_taint(TAINT_USER, LOCKDEP_STILL_OK);
 296
 297        ret = regmap_write(map, reg, value);
 298        if (ret < 0)
 299                return ret;
 300        return buf_size;
 301}
 302#else
 303#define regmap_map_write_file NULL
 304#endif
 305
 306static const struct file_operations regmap_map_fops = {
 307        .open = simple_open,
 308        .read = regmap_map_read_file,
 309        .write = regmap_map_write_file,
 310        .llseek = default_llseek,
 311};
 312
 313static ssize_t regmap_range_read_file(struct file *file, char __user *user_buf,
 314                                      size_t count, loff_t *ppos)
 315{
 316        struct regmap_range_node *range = file->private_data;
 317        struct regmap *map = range->map;
 318
 319        return regmap_read_debugfs(map, range->range_min, range->range_max,
 320                                   user_buf, count, ppos);
 321}
 322
 323static const struct file_operations regmap_range_fops = {
 324        .open = simple_open,
 325        .read = regmap_range_read_file,
 326        .llseek = default_llseek,
 327};
 328
 329static ssize_t regmap_reg_ranges_read_file(struct file *file,
 330                                           char __user *user_buf, size_t count,
 331                                           loff_t *ppos)
 332{
 333        struct regmap *map = file->private_data;
 334        struct regmap_debugfs_off_cache *c;
 335        loff_t p = 0;
 336        size_t buf_pos = 0;
 337        char *buf;
 338        char *entry;
 339        int ret;
 340        unsigned entry_len;
 341
 342        if (*ppos < 0 || !count)
 343                return -EINVAL;
 344
 345        buf = kmalloc(count, GFP_KERNEL);
 346        if (!buf)
 347                return -ENOMEM;
 348
 349        entry = kmalloc(PAGE_SIZE, GFP_KERNEL);
 350        if (!entry) {
 351                kfree(buf);
 352                return -ENOMEM;
 353        }
 354
 355        /* While we are at it, build the register dump cache
 356         * now so the read() operation on the `registers' file
 357         * can benefit from using the cache.  We do not care
 358         * about the file position information that is contained
 359         * in the cache, just about the actual register blocks */
 360        regmap_calc_tot_len(map, buf, count);
 361        regmap_debugfs_get_dump_start(map, 0, *ppos, &p);
 362
 363        /* Reset file pointer as the fixed-format of the `registers'
 364         * file is not compatible with the `range' file */
 365        p = 0;
 366        mutex_lock(&map->cache_lock);
 367        list_for_each_entry(c, &map->debugfs_off_cache, list) {
 368                entry_len = snprintf(entry, PAGE_SIZE, "%x-%x\n",
 369                                     c->base_reg, c->max_reg);
 370                if (p >= *ppos) {
 371                        if (buf_pos + entry_len > count)
 372                                break;
 373                        memcpy(buf + buf_pos, entry, entry_len);
 374                        buf_pos += entry_len;
 375                }
 376                p += entry_len;
 377        }
 378        mutex_unlock(&map->cache_lock);
 379
 380        kfree(entry);
 381        ret = buf_pos;
 382
 383        if (copy_to_user(user_buf, buf, buf_pos)) {
 384                ret = -EFAULT;
 385                goto out_buf;
 386        }
 387
 388        *ppos += buf_pos;
 389out_buf:
 390        kfree(buf);
 391        return ret;
 392}
 393
 394static const struct file_operations regmap_reg_ranges_fops = {
 395        .open = simple_open,
 396        .read = regmap_reg_ranges_read_file,
 397        .llseek = default_llseek,
 398};
 399
 400static ssize_t regmap_access_read_file(struct file *file,
 401                                       char __user *user_buf, size_t count,
 402                                       loff_t *ppos)
 403{
 404        int reg_len, tot_len;
 405        size_t buf_pos = 0;
 406        loff_t p = 0;
 407        ssize_t ret;
 408        int i;
 409        struct regmap *map = file->private_data;
 410        char *buf;
 411
 412        if (*ppos < 0 || !count)
 413                return -EINVAL;
 414
 415        buf = kmalloc(count, GFP_KERNEL);
 416        if (!buf)
 417                return -ENOMEM;
 418
 419        /* Calculate the length of a fixed format  */
 420        reg_len = regmap_calc_reg_len(map->max_register);
 421        tot_len = reg_len + 10; /* ': R W V P\n' */
 422
 423        for (i = 0; i <= map->max_register; i += map->reg_stride) {
 424                /* Ignore registers which are neither readable nor writable */
 425                if (!regmap_readable(map, i) && !regmap_writeable(map, i))
 426                        continue;
 427
 428                /* If we're in the region the user is trying to read */
 429                if (p >= *ppos) {
 430                        /* ...but not beyond it */
 431                        if (buf_pos + tot_len + 1 >= count)
 432                                break;
 433
 434                        /* Format the register */
 435                        snprintf(buf + buf_pos, count - buf_pos,
 436                                 "%.*x: %c %c %c %c\n",
 437                                 reg_len, i,
 438                                 regmap_readable(map, i) ? 'y' : 'n',
 439                                 regmap_writeable(map, i) ? 'y' : 'n',
 440                                 regmap_volatile(map, i) ? 'y' : 'n',
 441                                 regmap_precious(map, i) ? 'y' : 'n');
 442
 443                        buf_pos += tot_len;
 444                }
 445                p += tot_len;
 446        }
 447
 448        ret = buf_pos;
 449
 450        if (copy_to_user(user_buf, buf, buf_pos)) {
 451                ret = -EFAULT;
 452                goto out;
 453        }
 454
 455        *ppos += buf_pos;
 456
 457out:
 458        kfree(buf);
 459        return ret;
 460}
 461
 462static const struct file_operations regmap_access_fops = {
 463        .open = simple_open,
 464        .read = regmap_access_read_file,
 465        .llseek = default_llseek,
 466};
 467
 468static ssize_t regmap_cache_only_write_file(struct file *file,
 469                                            const char __user *user_buf,
 470                                            size_t count, loff_t *ppos)
 471{
 472        struct regmap *map = container_of(file->private_data,
 473                                          struct regmap, cache_only);
 474        ssize_t result;
 475        bool was_enabled, require_sync = false;
 476        int err;
 477
 478        map->lock(map->lock_arg);
 479
 480        was_enabled = map->cache_only;
 481
 482        result = debugfs_write_file_bool(file, user_buf, count, ppos);
 483        if (result < 0) {
 484                map->unlock(map->lock_arg);
 485                return result;
 486        }
 487
 488        if (map->cache_only && !was_enabled) {
 489                dev_warn(map->dev, "debugfs cache_only=Y forced\n");
 490                add_taint(TAINT_USER, LOCKDEP_STILL_OK);
 491        } else if (!map->cache_only && was_enabled) {
 492                dev_warn(map->dev, "debugfs cache_only=N forced: syncing cache\n");
 493                require_sync = true;
 494        }
 495
 496        map->unlock(map->lock_arg);
 497
 498        if (require_sync) {
 499                err = regcache_sync(map);
 500                if (err)
 501                        dev_err(map->dev, "Failed to sync cache %d\n", err);
 502        }
 503
 504        return result;
 505}
 506
 507static const struct file_operations regmap_cache_only_fops = {
 508        .open = simple_open,
 509        .read = debugfs_read_file_bool,
 510        .write = regmap_cache_only_write_file,
 511};
 512
 513static ssize_t regmap_cache_bypass_write_file(struct file *file,
 514                                              const char __user *user_buf,
 515                                              size_t count, loff_t *ppos)
 516{
 517        struct regmap *map = container_of(file->private_data,
 518                                          struct regmap, cache_bypass);
 519        ssize_t result;
 520        bool was_enabled;
 521
 522        map->lock(map->lock_arg);
 523
 524        was_enabled = map->cache_bypass;
 525
 526        result = debugfs_write_file_bool(file, user_buf, count, ppos);
 527        if (result < 0)
 528                goto out;
 529
 530        if (map->cache_bypass && !was_enabled) {
 531                dev_warn(map->dev, "debugfs cache_bypass=Y forced\n");
 532                add_taint(TAINT_USER, LOCKDEP_STILL_OK);
 533        } else if (!map->cache_bypass && was_enabled) {
 534                dev_warn(map->dev, "debugfs cache_bypass=N forced\n");
 535        }
 536
 537out:
 538        map->unlock(map->lock_arg);
 539
 540        return result;
 541}
 542
 543static const struct file_operations regmap_cache_bypass_fops = {
 544        .open = simple_open,
 545        .read = debugfs_read_file_bool,
 546        .write = regmap_cache_bypass_write_file,
 547};
 548
 549void regmap_debugfs_init(struct regmap *map, const char *name)
 550{
 551        struct rb_node *next;
 552        struct regmap_range_node *range_node;
 553        const char *devname = "dummy";
 554
 555        /* If we don't have the debugfs root yet, postpone init */
 556        if (!regmap_debugfs_root) {
 557                struct regmap_debugfs_node *node;
 558                node = kzalloc(sizeof(*node), GFP_KERNEL);
 559                if (!node)
 560                        return;
 561                node->map = map;
 562                node->name = name;
 563                mutex_lock(&regmap_debugfs_early_lock);
 564                list_add(&node->link, &regmap_debugfs_early_list);
 565                mutex_unlock(&regmap_debugfs_early_lock);
 566                return;
 567        }
 568
 569        INIT_LIST_HEAD(&map->debugfs_off_cache);
 570        mutex_init(&map->cache_lock);
 571
 572        if (map->dev)
 573                devname = dev_name(map->dev);
 574
 575        if (name) {
 576                map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s",
 577                                              devname, name);
 578                name = map->debugfs_name;
 579        } else {
 580                name = devname;
 581        }
 582
 583        map->debugfs = debugfs_create_dir(name, regmap_debugfs_root);
 584        if (!map->debugfs) {
 585                dev_warn(map->dev, "Failed to create debugfs directory\n");
 586                return;
 587        }
 588
 589        debugfs_create_file("name", 0400, map->debugfs,
 590                            map, &regmap_name_fops);
 591
 592        debugfs_create_file("range", 0400, map->debugfs,
 593                            map, &regmap_reg_ranges_fops);
 594
 595        if (map->max_register || regmap_readable(map, 0)) {
 596                umode_t registers_mode;
 597
 598#if defined(REGMAP_ALLOW_WRITE_DEBUGFS)
 599                registers_mode = 0600;
 600#else
 601                registers_mode = 0400;
 602#endif
 603
 604                debugfs_create_file("registers", registers_mode, map->debugfs,
 605                                    map, &regmap_map_fops);
 606                debugfs_create_file("access", 0400, map->debugfs,
 607                                    map, &regmap_access_fops);
 608        }
 609
 610        if (map->cache_type) {
 611                debugfs_create_file("cache_only", 0600, map->debugfs,
 612                                    &map->cache_only, &regmap_cache_only_fops);
 613                debugfs_create_bool("cache_dirty", 0400, map->debugfs,
 614                                    &map->cache_dirty);
 615                debugfs_create_file("cache_bypass", 0600, map->debugfs,
 616                                    &map->cache_bypass,
 617                                    &regmap_cache_bypass_fops);
 618        }
 619
 620        next = rb_first(&map->range_tree);
 621        while (next) {
 622                range_node = rb_entry(next, struct regmap_range_node, node);
 623
 624                if (range_node->name)
 625                        debugfs_create_file(range_node->name, 0400,
 626                                            map->debugfs, range_node,
 627                                            &regmap_range_fops);
 628
 629                next = rb_next(&range_node->node);
 630        }
 631
 632        if (map->cache_ops && map->cache_ops->debugfs_init)
 633                map->cache_ops->debugfs_init(map);
 634}
 635
 636void regmap_debugfs_exit(struct regmap *map)
 637{
 638        if (map->debugfs) {
 639                debugfs_remove_recursive(map->debugfs);
 640                mutex_lock(&map->cache_lock);
 641                regmap_debugfs_free_dump_cache(map);
 642                mutex_unlock(&map->cache_lock);
 643                kfree(map->debugfs_name);
 644        } else {
 645                struct regmap_debugfs_node *node, *tmp;
 646
 647                mutex_lock(&regmap_debugfs_early_lock);
 648                list_for_each_entry_safe(node, tmp, &regmap_debugfs_early_list,
 649                                         link) {
 650                        if (node->map == map) {
 651                                list_del(&node->link);
 652                                kfree(node);
 653                        }
 654                }
 655                mutex_unlock(&regmap_debugfs_early_lock);
 656        }
 657}
 658
 659void regmap_debugfs_initcall(void)
 660{
 661        struct regmap_debugfs_node *node, *tmp;
 662
 663        regmap_debugfs_root = debugfs_create_dir("regmap", NULL);
 664        if (!regmap_debugfs_root) {
 665                pr_warn("regmap: Failed to create debugfs root\n");
 666                return;
 667        }
 668
 669        mutex_lock(&regmap_debugfs_early_lock);
 670        list_for_each_entry_safe(node, tmp, &regmap_debugfs_early_list, link) {
 671                regmap_debugfs_init(node->map, node->name);
 672                list_del(&node->link);
 673                kfree(node);
 674        }
 675        mutex_unlock(&regmap_debugfs_early_lock);
 676}
 677