}
EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table);
#endif
+
+#ifdef CONFIG_DEBUG_FS
+#include <linux/debugfs.h>
+
+static int opp_summary_show(struct seq_file *s, void *data)
+{
+ struct list_head *lists = (struct list_head *)s->private;
+ struct opp_table *opp_table;
+ struct dev_pm_opp *opp;
+
+ mutex_lock(&opp_table_lock);
+
+ seq_puts(s, " device rate(Hz) target(uV) min(uV) max(uV)\n");
+ seq_puts(s, "-------------------------------------------------------------------\n");
+
+ list_for_each_entry_rcu(opp_table, lists, node) {
+ seq_printf(s, " %s\n", opp_table->dentry_name);
+ list_for_each_entry(opp, &opp_table->opp_list, node) {
+ seq_printf(s, "%31lu %12lu %11lu %11lu\n",
+ opp->rate,
+ opp->u_volt,
+ opp->u_volt_min,
+ opp->u_volt_max);
+ }
+ }
+
+ mutex_unlock(&opp_table_lock);
+
+ return 0;
+}
+
+static int opp_summary_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, opp_summary_show, inode->i_private);
+}
+
+static const struct file_operations opp_summary_fops = {
+ .open = opp_summary_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init opp_debug_init(void)
+{
+ struct dentry *parent, *d;
+
+ parent = debugfs_lookup("opp", NULL);
+ if (!parent)
+ return -ENOMEM;
+
+ d = debugfs_create_file("opp_summary", 0444, parent, &opp_tables,
+ &opp_summary_fops);
+ if (!d)
+ return -ENOMEM;
+
+ return 0;
+}
+late_initcall(opp_debug_init);
+#endif