diff options
Diffstat (limited to 'fs/debugfs/file.c')
-rw-r--r-- | fs/debugfs/file.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index 90f76575c056..ea62afa4fd57 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c | |||
@@ -15,9 +15,11 @@ | |||
15 | 15 | ||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
18 | #include <linux/seq_file.h> | ||
18 | #include <linux/pagemap.h> | 19 | #include <linux/pagemap.h> |
19 | #include <linux/namei.h> | 20 | #include <linux/namei.h> |
20 | #include <linux/debugfs.h> | 21 | #include <linux/debugfs.h> |
22 | #include <linux/io.h> | ||
21 | 23 | ||
22 | static ssize_t default_read_file(struct file *file, char __user *buf, | 24 | static ssize_t default_read_file(struct file *file, char __user *buf, |
23 | size_t count, loff_t *ppos) | 25 | size_t count, loff_t *ppos) |
@@ -525,3 +527,96 @@ struct dentry *debugfs_create_blob(const char *name, mode_t mode, | |||
525 | return debugfs_create_file(name, mode, parent, blob, &fops_blob); | 527 | return debugfs_create_file(name, mode, parent, blob, &fops_blob); |
526 | } | 528 | } |
527 | EXPORT_SYMBOL_GPL(debugfs_create_blob); | 529 | EXPORT_SYMBOL_GPL(debugfs_create_blob); |
530 | |||
531 | #ifdef CONFIG_HAS_IOMEM | ||
532 | |||
533 | /* | ||
534 | * The regset32 stuff is used to print 32-bit registers using the | ||
535 | * seq_file utilities. We offer printing a register set in an already-opened | ||
536 | * sequential file or create a debugfs file that only prints a regset32. | ||
537 | */ | ||
538 | |||
539 | /** | ||
540 | * debugfs_print_regs32 - use seq_print to describe a set of registers | ||
541 | * @s: the seq_file structure being used to generate output | ||
542 | * @regs: an array if struct debugfs_reg32 structures | ||
543 | * @mregs: the length of the above array | ||
544 | * @base: the base address to be used in reading the registers | ||
545 | * @prefix: a string to be prefixed to every output line | ||
546 | * | ||
547 | * This function outputs a text block describing the current values of | ||
548 | * some 32-bit hardware registers. It is meant to be used within debugfs | ||
549 | * files based on seq_file that need to show registers, intermixed with other | ||
550 | * information. The prefix argument may be used to specify a leading string, | ||
551 | * because some peripherals have several blocks of identical registers, | ||
552 | * for example configuration of dma channels | ||
553 | */ | ||
554 | int debugfs_print_regs32(struct seq_file *s, const struct debugfs_reg32 *regs, | ||
555 | int nregs, void __iomem *base, char *prefix) | ||
556 | { | ||
557 | int i, ret = 0; | ||
558 | |||
559 | for (i = 0; i < nregs; i++, regs++) { | ||
560 | if (prefix) | ||
561 | ret += seq_printf(s, "%s", prefix); | ||
562 | ret += seq_printf(s, "%s = 0x%08x\n", regs->name, | ||
563 | readl(base + regs->offset)); | ||
564 | } | ||
565 | return ret; | ||
566 | } | ||
567 | EXPORT_SYMBOL_GPL(debugfs_print_regs32); | ||
568 | |||
569 | static int debugfs_show_regset32(struct seq_file *s, void *data) | ||
570 | { | ||
571 | struct debugfs_regset32 *regset = s->private; | ||
572 | |||
573 | debugfs_print_regs32(s, regset->regs, regset->nregs, regset->base, ""); | ||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | static int debugfs_open_regset32(struct inode *inode, struct file *file) | ||
578 | { | ||
579 | return single_open(file, debugfs_show_regset32, inode->i_private); | ||
580 | } | ||
581 | |||
582 | static const struct file_operations fops_regset32 = { | ||
583 | .open = debugfs_open_regset32, | ||
584 | .read = seq_read, | ||
585 | .llseek = seq_lseek, | ||
586 | .release = single_release, | ||
587 | }; | ||
588 | |||
589 | /** | ||
590 | * debugfs_create_regset32 - create a debugfs file that returns register values | ||
591 | * @name: a pointer to a string containing the name of the file to create. | ||
592 | * @mode: the permission that the file should have | ||
593 | * @parent: a pointer to the parent dentry for this file. This should be a | ||
594 | * directory dentry if set. If this parameter is %NULL, then the | ||
595 | * file will be created in the root of the debugfs filesystem. | ||
596 | * @regset: a pointer to a struct debugfs_regset32, which contains a pointer | ||
597 | * to an array of register definitions, the array size and the base | ||
598 | * address where the register bank is to be found. | ||
599 | * | ||
600 | * This function creates a file in debugfs with the given name that reports | ||
601 | * the names and values of a set of 32-bit registers. If the @mode variable | ||
602 | * is so set it can be read from. Writing is not supported. | ||
603 | * | ||
604 | * This function will return a pointer to a dentry if it succeeds. This | ||
605 | * pointer must be passed to the debugfs_remove() function when the file is | ||
606 | * to be removed (no automatic cleanup happens if your module is unloaded, | ||
607 | * you are responsible here.) If an error occurs, %NULL will be returned. | ||
608 | * | ||
609 | * If debugfs is not enabled in the kernel, the value -%ENODEV will be | ||
610 | * returned. It is not wise to check for this value, but rather, check for | ||
611 | * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling | ||
612 | * code. | ||
613 | */ | ||
614 | struct dentry *debugfs_create_regset32(const char *name, mode_t mode, | ||
615 | struct dentry *parent, | ||
616 | struct debugfs_regset32 *regset) | ||
617 | { | ||
618 | return debugfs_create_file(name, mode, parent, regset, &fops_regset32); | ||
619 | } | ||
620 | EXPORT_SYMBOL_GPL(debugfs_create_regset32); | ||
621 | |||
622 | #endif /* CONFIG_HAS_IOMEM */ | ||