aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/omap-iommu-debug.c
diff options
context:
space:
mode:
authorSuman Anna <s-anna@ti.com>2014-10-22 18:22:35 -0400
committerJoerg Roedel <jroedel@suse.de>2014-10-23 08:33:48 -0400
commit9c83e9f384f5d1513e42935af43c13a601aad842 (patch)
treed622c905507aaddf267b15ee3a3c118e13f93cf6 /drivers/iommu/omap-iommu-debug.c
parentc5cf5c5377fbd0a1ff2a09ad1f0c7e261aabc567 (diff)
iommu/omap: Switch pagetable debugfs entry to use seq_file
The debugfs entry 'pagetable' that shows the page table entry (PTE) data currently outputs only data that can be fit into a page. Switch the entry to use the seq_file interface so that it can show all the valid page table entries. The patch also corrected the output for L2 entries, and prints the proper L2 PTE instead of the previous L1 page descriptor pointer. Signed-off-by: Suman Anna <s-anna@ti.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/omap-iommu-debug.c')
-rw-r--r--drivers/iommu/omap-iommu-debug.c81
1 files changed, 28 insertions, 53 deletions
diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c
index 41b09a1d78ea..f3d20a2039d2 100644
--- a/drivers/iommu/omap-iommu-debug.c
+++ b/drivers/iommu/omap-iommu-debug.c
@@ -85,95 +85,70 @@ static ssize_t debug_read_tlb(struct file *file, char __user *userbuf,
85 return bytes; 85 return bytes;
86} 86}
87 87
88#define dump_ioptable_entry_one(lv, da, val) \ 88static void dump_ioptable(struct seq_file *s)
89 ({ \
90 int __err = 0; \
91 ssize_t bytes; \
92 const int maxcol = 22; \
93 const char *str = "%d: %08x %08x\n"; \
94 bytes = snprintf(p, maxcol, str, lv, da, val); \
95 p += bytes; \
96 len -= bytes; \
97 if (len < maxcol) \
98 __err = -ENOMEM; \
99 __err; \
100 })
101
102static ssize_t dump_ioptable(struct omap_iommu *obj, char *buf, ssize_t len)
103{ 89{
104 int i; 90 int i, j;
105 u32 *iopgd; 91 u32 da;
106 char *p = buf; 92 u32 *iopgd, *iopte;
93 struct omap_iommu *obj = s->private;
107 94
108 spin_lock(&obj->page_table_lock); 95 spin_lock(&obj->page_table_lock);
109 96
110 iopgd = iopgd_offset(obj, 0); 97 iopgd = iopgd_offset(obj, 0);
111 for (i = 0; i < PTRS_PER_IOPGD; i++, iopgd++) { 98 for (i = 0; i < PTRS_PER_IOPGD; i++, iopgd++) {
112 int j, err;
113 u32 *iopte;
114 u32 da;
115
116 if (!*iopgd) 99 if (!*iopgd)
117 continue; 100 continue;
118 101
119 if (!(*iopgd & IOPGD_TABLE)) { 102 if (!(*iopgd & IOPGD_TABLE)) {
120 da = i << IOPGD_SHIFT; 103 da = i << IOPGD_SHIFT;
121 104 seq_printf(s, "1: 0x%08x 0x%08x\n", da, *iopgd);
122 err = dump_ioptable_entry_one(1, da, *iopgd);
123 if (err)
124 goto out;
125 continue; 105 continue;
126 } 106 }
127 107
128 iopte = iopte_offset(iopgd, 0); 108 iopte = iopte_offset(iopgd, 0);
129
130 for (j = 0; j < PTRS_PER_IOPTE; j++, iopte++) { 109 for (j = 0; j < PTRS_PER_IOPTE; j++, iopte++) {
131 if (!*iopte) 110 if (!*iopte)
132 continue; 111 continue;
133 112
134 da = (i << IOPGD_SHIFT) + (j << IOPTE_SHIFT); 113 da = (i << IOPGD_SHIFT) + (j << IOPTE_SHIFT);
135 err = dump_ioptable_entry_one(2, da, *iopgd); 114 seq_printf(s, "2: 0x%08x 0x%08x\n", da, *iopte);
136 if (err)
137 goto out;
138 } 115 }
139 } 116 }
140out:
141 spin_unlock(&obj->page_table_lock);
142 117
143 return p - buf; 118 spin_unlock(&obj->page_table_lock);
144} 119}
145 120
146static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf, 121static int debug_read_pagetable(struct seq_file *s, void *data)
147 size_t count, loff_t *ppos)
148{ 122{
149 struct omap_iommu *obj = file->private_data; 123 struct omap_iommu *obj = s->private;
150 char *p, *buf;
151 size_t bytes;
152 124
153 if (is_omap_iommu_detached(obj)) 125 if (is_omap_iommu_detached(obj))
154 return -EPERM; 126 return -EPERM;
155 127
156 buf = (char *)__get_free_page(GFP_KERNEL);
157 if (!buf)
158 return -ENOMEM;
159 p = buf;
160
161 p += sprintf(p, "L: %8s %8s\n", "da:", "pa:");
162 p += sprintf(p, "-----------------------------------------\n");
163
164 mutex_lock(&iommu_debug_lock); 128 mutex_lock(&iommu_debug_lock);
165 129
166 bytes = PAGE_SIZE - (p - buf); 130 seq_printf(s, "L: %8s %8s\n", "da:", "pte:");
167 p += dump_ioptable(obj, p, bytes); 131 seq_puts(s, "--------------------------\n");
168 132 dump_ioptable(s);
169 bytes = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
170 133
171 mutex_unlock(&iommu_debug_lock); 134 mutex_unlock(&iommu_debug_lock);
172 free_page((unsigned long)buf);
173 135
174 return bytes; 136 return 0;
175} 137}
176 138
139#define DEBUG_SEQ_FOPS_RO(name) \
140 static int debug_open_##name(struct inode *inode, struct file *file) \
141 { \
142 return single_open(file, debug_read_##name, inode->i_private); \
143 } \
144 \
145 static const struct file_operations debug_##name##_fops = { \
146 .open = debug_open_##name, \
147 .read = seq_read, \
148 .llseek = seq_lseek, \
149 .release = single_release, \
150 }
151
177#define DEBUG_FOPS_RO(name) \ 152#define DEBUG_FOPS_RO(name) \
178 static const struct file_operations debug_##name##_fops = { \ 153 static const struct file_operations debug_##name##_fops = { \
179 .open = simple_open, \ 154 .open = simple_open, \
@@ -183,7 +158,7 @@ static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf,
183 158
184DEBUG_FOPS_RO(regs); 159DEBUG_FOPS_RO(regs);
185DEBUG_FOPS_RO(tlb); 160DEBUG_FOPS_RO(tlb);
186DEBUG_FOPS_RO(pagetable); 161DEBUG_SEQ_FOPS_RO(pagetable);
187 162
188#define __DEBUG_ADD_FILE(attr, mode) \ 163#define __DEBUG_ADD_FILE(attr, mode) \
189 { \ 164 { \