linux/drivers/mfd/ab5500-debugfs.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2011 ST-Ericsson
   3 * License terms: GNU General Public License (GPL) version 2
   4 * Debugfs support for the AB5500 MFD driver
   5 */
   6
   7#include <linux/module.h>
   8#include <linux/debugfs.h>
   9#include <linux/seq_file.h>
  10#include <linux/mfd/abx500.h>
  11#include <linux/mfd/abx500/ab5500.h>
  12#include <linux/uaccess.h>
  13
  14#include "ab5500-core.h"
  15#include "ab5500-debugfs.h"
  16
  17static struct ab5500_i2c_ranges ab5500_reg_ranges[AB5500_NUM_BANKS] = {
  18        [AB5500_BANK_LED] = {
  19                .bankid = AB5500_BANK_LED,
  20                .nranges = 1,
  21                .range = (struct ab5500_reg_range[]) {
  22                        {
  23                                .first = 0x00,
  24                                .last = 0x0C,
  25                                .perm = AB5500_PERM_RW,
  26                        },
  27                },
  28        },
  29        [AB5500_BANK_ADC] = {
  30                .bankid = AB5500_BANK_ADC,
  31                .nranges = 6,
  32                .range = (struct ab5500_reg_range[]) {
  33                        {
  34                                .first = 0x1F,
  35                                .last = 0x22,
  36                                .perm = AB5500_PERM_RO,
  37                        },
  38                        {
  39                                .first = 0x23,
  40                                .last = 0x24,
  41                                .perm = AB5500_PERM_RW,
  42                        },
  43                        {
  44                                .first = 0x26,
  45                                .last = 0x2D,
  46                                .perm = AB5500_PERM_RO,
  47                        },
  48                        {
  49                                .first = 0x2F,
  50                                .last = 0x34,
  51                                .perm = AB5500_PERM_RW,
  52                        },
  53                        {
  54                                .first = 0x37,
  55                                .last = 0x57,
  56                                .perm = AB5500_PERM_RW,
  57                        },
  58                        {
  59                                .first = 0x58,
  60                                .last = 0x58,
  61                                .perm = AB5500_PERM_RO,
  62                        },
  63                },
  64        },
  65        [AB5500_BANK_RTC] = {
  66                .bankid = AB5500_BANK_RTC,
  67                .nranges = 2,
  68                .range = (struct ab5500_reg_range[]) {
  69                        {
  70                                .first = 0x00,
  71                                .last = 0x04,
  72                                .perm = AB5500_PERM_RW,
  73                        },
  74                        {
  75                                .first = 0x06,
  76                                .last = 0x0C,
  77                                .perm = AB5500_PERM_RW,
  78                        },
  79                },
  80        },
  81        [AB5500_BANK_STARTUP] = {
  82                .bankid = AB5500_BANK_STARTUP,
  83                .nranges = 12,
  84                .range = (struct ab5500_reg_range[]) {
  85                        {
  86                                .first = 0x00,
  87                                .last = 0x01,
  88                                .perm = AB5500_PERM_RW,
  89                        },
  90                        {
  91                                .first = 0x1F,
  92                                .last = 0x1F,
  93                                .perm = AB5500_PERM_RW,
  94                        },
  95                        {
  96                                .first = 0x2E,
  97                                .last = 0x2E,
  98                                .perm = AB5500_PERM_RO,
  99                        },
 100                        {
 101                                .first = 0x2F,
 102                                .last = 0x30,
 103                                .perm = AB5500_PERM_RW,
 104                        },
 105                        {
 106                                .first = 0x50,
 107                                .last = 0x51,
 108                                .perm = AB5500_PERM_RW,
 109                        },
 110                        {
 111                                .first = 0x60,
 112                                .last = 0x61,
 113                                .perm = AB5500_PERM_RW,
 114                        },
 115                        {
 116                                .first = 0x66,
 117                                .last = 0x8A,
 118                                .perm = AB5500_PERM_RW,
 119                        },
 120                        {
 121                                .first = 0x8C,
 122                                .last = 0x96,
 123                                .perm = AB5500_PERM_RW,
 124                        },
 125                        {
 126                                .first = 0xAA,
 127                                .last = 0xB4,
 128                                .perm = AB5500_PERM_RW,
 129                        },
 130                        {
 131                                .first = 0xB7,
 132                                .last = 0xBF,
 133                                .perm = AB5500_PERM_RW,
 134                        },
 135                        {
 136                                .first = 0xC1,
 137                                .last = 0xCA,
 138                                .perm = AB5500_PERM_RW,
 139                        },
 140                        {
 141                                .first = 0xD3,
 142                                .last = 0xE0,
 143                                .perm = AB5500_PERM_RW,
 144                        },
 145                },
 146        },
 147        [AB5500_BANK_DBI_ECI] = {
 148                .bankid = AB5500_BANK_DBI_ECI,
 149                .nranges = 3,
 150                .range = (struct ab5500_reg_range[]) {
 151                        {
 152                                .first = 0x00,
 153                                .last = 0x07,
 154                                .perm = AB5500_PERM_RW,
 155                        },
 156                        {
 157                                .first = 0x10,
 158                                .last = 0x10,
 159                                .perm = AB5500_PERM_RW,
 160                        },
 161                        {
 162                                .first = 0x13,
 163                                .last = 0x13,
 164                                .perm = AB5500_PERM_RW,
 165                        },
 166                },
 167        },
 168        [AB5500_BANK_CHG] = {
 169                .bankid = AB5500_BANK_CHG,
 170                .nranges = 2,
 171                .range = (struct ab5500_reg_range[]) {
 172                        {
 173                                .first = 0x11,
 174                                .last = 0x11,
 175                                .perm = AB5500_PERM_RO,
 176                        },
 177                        {
 178                                .first = 0x12,
 179                                .last = 0x1B,
 180                                .perm = AB5500_PERM_RW,
 181                        },
 182                },
 183        },
 184        [AB5500_BANK_FG_BATTCOM_ACC] = {
 185                .bankid = AB5500_BANK_FG_BATTCOM_ACC,
 186                .nranges = 2,
 187                .range = (struct ab5500_reg_range[]) {
 188                        {
 189                                .first = 0x00,
 190                                .last = 0x0B,
 191                                .perm = AB5500_PERM_RO,
 192                        },
 193                        {
 194                                .first = 0x0C,
 195                                .last = 0x10,
 196                                .perm = AB5500_PERM_RW,
 197                        },
 198                },
 199        },
 200        [AB5500_BANK_USB] = {
 201                .bankid = AB5500_BANK_USB,
 202                .nranges = 12,
 203                .range = (struct ab5500_reg_range[]) {
 204                        {
 205                                .first = 0x01,
 206                                .last = 0x01,
 207                                .perm = AB5500_PERM_RW,
 208                        },
 209                        {
 210                                .first = 0x80,
 211                                .last = 0x83,
 212                                .perm = AB5500_PERM_RW,
 213                        },
 214                        {
 215                                .first = 0x87,
 216                                .last = 0x8A,
 217                                .perm = AB5500_PERM_RW,
 218                        },
 219                        {
 220                                .first = 0x8B,
 221                                .last = 0x8B,
 222                                .perm = AB5500_PERM_RO,
 223                        },
 224                        {
 225                                .first = 0x91,
 226                                .last = 0x92,
 227                                .perm = AB5500_PERM_RO,
 228                        },
 229                        {
 230                                .first = 0x93,
 231                                .last = 0x93,
 232                                .perm = AB5500_PERM_RW,
 233                        },
 234                        {
 235                                .first = 0x94,
 236                                .last = 0x94,
 237                                .perm = AB5500_PERM_RO,
 238                        },
 239                        {
 240                                .first = 0xA8,
 241                                .last = 0xB0,
 242                                .perm = AB5500_PERM_RO,
 243                        },
 244                        {
 245                                .first = 0xB2,
 246                                .last = 0xB2,
 247                                .perm = AB5500_PERM_RO,
 248                        },
 249                        {
 250                                .first = 0xB4,
 251                                .last = 0xBC,
 252                                .perm = AB5500_PERM_RO,
 253                        },
 254                        {
 255                                .first = 0xBF,
 256                                .last = 0xBF,
 257                                .perm = AB5500_PERM_RO,
 258                        },
 259                        {
 260                                .first = 0xC1,
 261                                .last = 0xC5,
 262                                .perm = AB5500_PERM_RO,
 263                        },
 264                },
 265        },
 266        [AB5500_BANK_IT] = {
 267                .bankid = AB5500_BANK_IT,
 268                .nranges = 4,
 269                .range = (struct ab5500_reg_range[]) {
 270                        {
 271                                .first = 0x00,
 272                                .last = 0x02,
 273                                .perm = AB5500_PERM_RO,
 274                        },
 275                        {
 276                                .first = 0x20,
 277                                .last = 0x36,
 278                                .perm = AB5500_PERM_RO,
 279                        },
 280                        {
 281                                .first = 0x40,
 282                                .last = 0x56,
 283                                .perm = AB5500_PERM_RO,
 284                        },
 285                        {
 286                                .first = 0x60,
 287                                .last = 0x76,
 288                                .perm = AB5500_PERM_RO,
 289                        },
 290                },
 291        },
 292        [AB5500_BANK_VDDDIG_IO_I2C_CLK_TST] = {
 293                .bankid = AB5500_BANK_VDDDIG_IO_I2C_CLK_TST,
 294                .nranges = 7,
 295                .range = (struct ab5500_reg_range[]) {
 296                        {
 297                                .first = 0x02,
 298                                .last = 0x02,
 299                                .perm = AB5500_PERM_RW,
 300                        },
 301                        {
 302                                .first = 0x12,
 303                                .last = 0x12,
 304                                .perm = AB5500_PERM_RW,
 305                        },
 306                        {
 307                                .first = 0x30,
 308                                .last = 0x34,
 309                                .perm = AB5500_PERM_RW,
 310                        },
 311                        {
 312                                .first = 0x40,
 313                                .last = 0x44,
 314                                .perm = AB5500_PERM_RW,
 315                        },
 316                        {
 317                                .first = 0x50,
 318                                .last = 0x54,
 319                                .perm = AB5500_PERM_RW,
 320                        },
 321                        {
 322                                .first = 0x60,
 323                                .last = 0x64,
 324                                .perm = AB5500_PERM_RW,
 325                        },
 326                        {
 327                                .first = 0x70,
 328                                .last = 0x74,
 329                                .perm = AB5500_PERM_RW,
 330                        },
 331                },
 332        },
 333        [AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP] = {
 334                .bankid = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP,
 335                .nranges = 13,
 336                .range = (struct ab5500_reg_range[]) {
 337                        {
 338                                .first = 0x01,
 339                                .last = 0x01,
 340                                .perm = AB5500_PERM_RW,
 341                        },
 342                        {
 343                                .first = 0x02,
 344                                .last = 0x02,
 345                                .perm = AB5500_PERM_RO,
 346                        },
 347                        {
 348                                .first = 0x0D,
 349                                .last = 0x0F,
 350                                .perm = AB5500_PERM_RW,
 351                        },
 352                        {
 353                                .first = 0x1C,
 354                                .last = 0x1C,
 355                                .perm = AB5500_PERM_RW,
 356                        },
 357                        {
 358                                .first = 0x1E,
 359                                .last = 0x1E,
 360                                .perm = AB5500_PERM_RW,
 361                        },
 362                        {
 363                                .first = 0x20,
 364                                .last = 0x21,
 365                                .perm = AB5500_PERM_RW,
 366                        },
 367                        {
 368                                .first = 0x25,
 369                                .last = 0x25,
 370                                .perm = AB5500_PERM_RW,
 371                        },
 372                        {
 373                                .first = 0x28,
 374                                .last = 0x2A,
 375                                .perm = AB5500_PERM_RW,
 376                        },
 377                        {
 378                                .first = 0x30,
 379                                .last = 0x33,
 380                                .perm = AB5500_PERM_RW,
 381                        },
 382                        {
 383                                .first = 0x40,
 384                                .last = 0x43,
 385                                .perm = AB5500_PERM_RW,
 386                        },
 387                        {
 388                                .first = 0x50,
 389                                .last = 0x53,
 390                                .perm = AB5500_PERM_RW,
 391                        },
 392                        {
 393                                .first = 0x60,
 394                                .last = 0x63,
 395                                .perm = AB5500_PERM_RW,
 396                        },
 397                        {
 398                                .first = 0x70,
 399                                .last = 0x73,
 400                                .perm = AB5500_PERM_RW,
 401                        },
 402                },
 403        },
 404        [AB5500_BANK_VIBRA] = {
 405                .bankid = AB5500_BANK_VIBRA,
 406                .nranges = 2,
 407                .range = (struct ab5500_reg_range[]) {
 408                        {
 409                                .first = 0x10,
 410                                .last = 0x13,
 411                                .perm = AB5500_PERM_RW,
 412                        },
 413                        {
 414                                .first = 0xFE,
 415                                .last = 0xFE,
 416                                .perm = AB5500_PERM_RW,
 417                        },
 418                },
 419        },
 420        [AB5500_BANK_AUDIO_HEADSETUSB] = {
 421                .bankid = AB5500_BANK_AUDIO_HEADSETUSB,
 422                .nranges = 2,
 423                .range = (struct ab5500_reg_range[]) {
 424                        {
 425                                .first = 0x00,
 426                                .last = 0x48,
 427                                .perm = AB5500_PERM_RW,
 428                        },
 429                        {
 430                                .first = 0xEB,
 431                                .last = 0xFB,
 432                                .perm = AB5500_PERM_RW,
 433                        },
 434                },
 435        },
 436        [AB5500_BANK_SIM_USBSIM] = {
 437                .bankid = AB5500_BANK_SIM_USBSIM,
 438                .nranges = 1,
 439                .range = (struct ab5500_reg_range[]) {
 440                        {
 441                                .first = 0x13,
 442                                .last = 0x19,
 443                                .perm = AB5500_PERM_RW,
 444                        },
 445                },
 446        },
 447        [AB5500_BANK_VDENC] = {
 448                .bankid = AB5500_BANK_VDENC,
 449                .nranges = 12,
 450                .range = (struct ab5500_reg_range[]) {
 451                        {
 452                                .first = 0x00,
 453                                .last = 0x08,
 454                                .perm = AB5500_PERM_RW,
 455                        },
 456                        {
 457                                .first = 0x09,
 458                                .last = 0x09,
 459                                .perm = AB5500_PERM_RO,
 460                        },
 461                        {
 462                                .first = 0x0A,
 463                                .last = 0x12,
 464                                .perm = AB5500_PERM_RW,
 465                        },
 466                        {
 467                                .first = 0x15,
 468                                .last = 0x19,
 469                                .perm = AB5500_PERM_RW,
 470                        },
 471                        {
 472                                .first = 0x1B,
 473                                .last = 0x21,
 474                                .perm = AB5500_PERM_RW,
 475                        },
 476                        {
 477                                .first = 0x27,
 478                                .last = 0x2C,
 479                                .perm = AB5500_PERM_RW,
 480                        },
 481                        {
 482                                .first = 0x41,
 483                                .last = 0x41,
 484                                .perm = AB5500_PERM_RW,
 485                        },
 486                        {
 487                                .first = 0x45,
 488                                .last = 0x5B,
 489                                .perm = AB5500_PERM_RW,
 490                        },
 491                        {
 492                                .first = 0x5D,
 493                                .last = 0x5D,
 494                                .perm = AB5500_PERM_RW,
 495                        },
 496                        {
 497                                .first = 0x69,
 498                                .last = 0x69,
 499                                .perm = AB5500_PERM_RW,
 500                        },
 501                        {
 502                                .first = 0x6C,
 503                                .last = 0x6D,
 504                                .perm = AB5500_PERM_RW,
 505                        },
 506                        {
 507                                .first = 0x80,
 508                                .last = 0x81,
 509                                .perm = AB5500_PERM_RW,
 510                        },
 511                },
 512        },
 513};
 514
 515static int ab5500_registers_print(struct seq_file *s, void *p)
 516{
 517        struct ab5500 *ab = s->private;
 518        unsigned int i;
 519        u8 bank = (u8)ab->debug_bank;
 520
 521        seq_printf(s, "ab5500 register values:\n");
 522        for (bank = 0; bank < AB5500_NUM_BANKS; bank++) {
 523                seq_printf(s, " bank %u, %s (0x%x):\n", bank,
 524                                bankinfo[bank].name,
 525                                bankinfo[bank].slave_addr);
 526                for (i = 0; i < ab5500_reg_ranges[bank].nranges; i++) {
 527                        u8 reg;
 528                        int err;
 529
 530                        for (reg = ab5500_reg_ranges[bank].range[i].first;
 531                                reg <= ab5500_reg_ranges[bank].range[i].last;
 532                                reg++) {
 533                                u8 value;
 534
 535                                err = ab5500_get_register_interruptible_raw(ab,
 536                                                                bank, reg,
 537                                                                &value);
 538                                if (err < 0) {
 539                                        dev_err(ab->dev, "get_reg failed %d"
 540                                                "bank 0x%x reg 0x%x\n",
 541                                                err, bank, reg);
 542                                        return err;
 543                                }
 544
 545                                err = seq_printf(s, "[%d/0x%02X]: 0x%02X\n",
 546                                                bank, reg, value);
 547                                if (err < 0) {
 548                                        dev_err(ab->dev,
 549                                                "seq_printf overflow\n");
 550                                        /*
 551                                         * Error is not returned here since
 552                                         * the output is wanted in any case
 553                                         */
 554                                        return 0;
 555                                }
 556                        }
 557                }
 558        }
 559        return 0;
 560}
 561
 562static int ab5500_registers_open(struct inode *inode, struct file *file)
 563{
 564        return single_open(file, ab5500_registers_print, inode->i_private);
 565}
 566
 567static const struct file_operations ab5500_registers_fops = {
 568        .open = ab5500_registers_open,
 569        .read = seq_read,
 570        .llseek = seq_lseek,
 571        .release = single_release,
 572        .owner = THIS_MODULE,
 573};
 574
 575static int ab5500_bank_print(struct seq_file *s, void *p)
 576{
 577        struct ab5500 *ab = s->private;
 578
 579        seq_printf(s, "%d\n", ab->debug_bank);
 580        return 0;
 581}
 582
 583static int ab5500_bank_open(struct inode *inode, struct file *file)
 584{
 585        return single_open(file, ab5500_bank_print, inode->i_private);
 586}
 587
 588static ssize_t ab5500_bank_write(struct file *file,
 589        const char __user *user_buf,
 590        size_t count, loff_t *ppos)
 591{
 592        struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private;
 593        char buf[32];
 594        int buf_size;
 595        unsigned long user_bank;
 596        int err;
 597
 598        /* Get userspace string and assure termination */
 599        buf_size = min(count, (sizeof(buf) - 1));
 600        if (copy_from_user(buf, user_buf, buf_size))
 601                return -EFAULT;
 602        buf[buf_size] = 0;
 603
 604        err = strict_strtoul(buf, 0, &user_bank);
 605        if (err)
 606                return -EINVAL;
 607
 608        if (user_bank >= AB5500_NUM_BANKS) {
 609                dev_err(ab->dev,
 610                        "debugfs error input > number of banks\n");
 611                return -EINVAL;
 612        }
 613
 614        ab->debug_bank = user_bank;
 615
 616        return buf_size;
 617}
 618
 619static int ab5500_address_print(struct seq_file *s, void *p)
 620{
 621        struct ab5500 *ab = s->private;
 622
 623        seq_printf(s, "0x%02X\n", ab->debug_address);
 624        return 0;
 625}
 626
 627static int ab5500_address_open(struct inode *inode, struct file *file)
 628{
 629        return single_open(file, ab5500_address_print, inode->i_private);
 630}
 631
 632static ssize_t ab5500_address_write(struct file *file,
 633        const char __user *user_buf,
 634        size_t count, loff_t *ppos)
 635{
 636        struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private;
 637        char buf[32];
 638        int buf_size;
 639        unsigned long user_address;
 640        int err;
 641
 642        /* Get userspace string and assure termination */
 643        buf_size = min(count, (sizeof(buf) - 1));
 644        if (copy_from_user(buf, user_buf, buf_size))
 645                return -EFAULT;
 646        buf[buf_size] = 0;
 647
 648        err = strict_strtoul(buf, 0, &user_address);
 649        if (err)
 650                return -EINVAL;
 651        if (user_address > 0xff) {
 652                dev_err(ab->dev,
 653                        "debugfs error input > 0xff\n");
 654                return -EINVAL;
 655        }
 656        ab->debug_address = user_address;
 657        return buf_size;
 658}
 659
 660static int ab5500_val_print(struct seq_file *s, void *p)
 661{
 662        struct ab5500 *ab = s->private;
 663        int err;
 664        u8 regvalue;
 665
 666        err = ab5500_get_register_interruptible_raw(ab, (u8)ab->debug_bank,
 667                (u8)ab->debug_address, &regvalue);
 668        if (err) {
 669                dev_err(ab->dev, "get_reg failed %d, bank 0x%x"
 670                        ", reg 0x%x\n", err, ab->debug_bank,
 671                        ab->debug_address);
 672                return -EINVAL;
 673        }
 674        seq_printf(s, "0x%02X\n", regvalue);
 675
 676        return 0;
 677}
 678
 679static int ab5500_val_open(struct inode *inode, struct file *file)
 680{
 681        return single_open(file, ab5500_val_print, inode->i_private);
 682}
 683
 684static ssize_t ab5500_val_write(struct file *file,
 685        const char __user *user_buf,
 686        size_t count, loff_t *ppos)
 687{
 688        struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private;
 689        char buf[32];
 690        int buf_size;
 691        unsigned long user_val;
 692        int err;
 693        u8 regvalue;
 694
 695        /* Get userspace string and assure termination */
 696        buf_size = min(count, (sizeof(buf)-1));
 697        if (copy_from_user(buf, user_buf, buf_size))
 698                return -EFAULT;
 699        buf[buf_size] = 0;
 700
 701        err = strict_strtoul(buf, 0, &user_val);
 702        if (err)
 703                return -EINVAL;
 704        if (user_val > 0xff) {
 705                dev_err(ab->dev,
 706                        "debugfs error input > 0xff\n");
 707                return -EINVAL;
 708        }
 709        err = ab5500_mask_and_set_register_interruptible_raw(
 710                ab, (u8)ab->debug_bank,
 711                (u8)ab->debug_address, 0xFF, (u8)user_val);
 712        if (err)
 713                return -EINVAL;
 714
 715        ab5500_get_register_interruptible_raw(ab, (u8)ab->debug_bank,
 716                (u8)ab->debug_address, &regvalue);
 717        if (err)
 718                return -EINVAL;
 719
 720        return buf_size;
 721}
 722
 723static const struct file_operations ab5500_bank_fops = {
 724        .open = ab5500_bank_open,
 725        .write = ab5500_bank_write,
 726        .read = seq_read,
 727        .llseek = seq_lseek,
 728        .release = single_release,
 729        .owner = THIS_MODULE,
 730};
 731
 732static const struct file_operations ab5500_address_fops = {
 733        .open = ab5500_address_open,
 734        .write = ab5500_address_write,
 735        .read = seq_read,
 736        .llseek = seq_lseek,
 737        .release = single_release,
 738        .owner = THIS_MODULE,
 739};
 740
 741static const struct file_operations ab5500_val_fops = {
 742        .open = ab5500_val_open,
 743        .write = ab5500_val_write,
 744        .read = seq_read,
 745        .llseek = seq_lseek,
 746        .release = single_release,
 747        .owner = THIS_MODULE,
 748};
 749
 750static struct dentry *ab5500_dir;
 751static struct dentry *ab5500_reg_file;
 752static struct dentry *ab5500_bank_file;
 753static struct dentry *ab5500_address_file;
 754static struct dentry *ab5500_val_file;
 755
 756void __init ab5500_setup_debugfs(struct ab5500 *ab)
 757{
 758        ab->debug_bank = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP;
 759        ab->debug_address = AB5500_CHIP_ID;
 760
 761        ab5500_dir = debugfs_create_dir("ab5500", NULL);
 762        if (!ab5500_dir)
 763                goto exit_no_debugfs;
 764
 765        ab5500_reg_file = debugfs_create_file("all-bank-registers",
 766                S_IRUGO, ab5500_dir, ab, &ab5500_registers_fops);
 767        if (!ab5500_reg_file)
 768                goto exit_destroy_dir;
 769
 770        ab5500_bank_file = debugfs_create_file("register-bank",
 771                (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_bank_fops);
 772        if (!ab5500_bank_file)
 773                goto exit_destroy_reg;
 774
 775        ab5500_address_file = debugfs_create_file("register-address",
 776                (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_address_fops);
 777        if (!ab5500_address_file)
 778                goto exit_destroy_bank;
 779
 780        ab5500_val_file = debugfs_create_file("register-value",
 781                (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_val_fops);
 782        if (!ab5500_val_file)
 783                goto exit_destroy_address;
 784
 785        return;
 786
 787exit_destroy_address:
 788        debugfs_remove(ab5500_address_file);
 789exit_destroy_bank:
 790        debugfs_remove(ab5500_bank_file);
 791exit_destroy_reg:
 792        debugfs_remove(ab5500_reg_file);
 793exit_destroy_dir:
 794        debugfs_remove(ab5500_dir);
 795exit_no_debugfs:
 796        dev_err(ab->dev, "failed to create debugfs entries.\n");
 797        return;
 798}
 799
 800void __exit ab5500_remove_debugfs(void)
 801{
 802        debugfs_remove(ab5500_val_file);
 803        debugfs_remove(ab5500_address_file);
 804        debugfs_remove(ab5500_bank_file);
 805        debugfs_remove(ab5500_reg_file);
 806        debugfs_remove(ab5500_dir);
 807}
 808
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.