diff options
author | Suman Anna <s-anna@ti.com> | 2015-07-20 18:33:25 -0400 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2015-08-03 10:03:50 -0400 |
commit | 69c2c196328e73d3091dd0be89ab4b0c2af4b210 (patch) | |
tree | c21d4ad5f728285d59a8207a19d61df0bdc71e91 | |
parent | 0cdbf727167a2fcc9ba2aaea98e2a76124ba072e (diff) |
iommu/omap: Move debugfs functions to omap-iommu-debug.c
The main OMAP IOMMU driver file has some helper functions used
by the OMAP IOMMU debugfs functionality, and there is already a
dedicated source file omap-iommu-debug.c dealing with these debugfs
routines. Move all these functions to the omap-iommu-debug.c file,
so that all the debugfs related routines are in one place.
The move required exposing some new functions and moving some
definitions to the internal omap-iommu.h header file.
Signed-off-by: Suman Anna <s-anna@ti.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
-rw-r--r-- | drivers/iommu/omap-iommu-debug.c | 111 | ||||
-rw-r--r-- | drivers/iommu/omap-iommu.c | 148 | ||||
-rw-r--r-- | drivers/iommu/omap-iommu.h | 28 |
3 files changed, 137 insertions, 150 deletions
diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c index f3d20a2039d2..b4b96db37e6a 100644 --- a/drivers/iommu/omap-iommu-debug.c +++ b/drivers/iommu/omap-iommu-debug.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/uaccess.h> | 16 | #include <linux/uaccess.h> |
17 | #include <linux/pm_runtime.h> | ||
17 | #include <linux/debugfs.h> | 18 | #include <linux/debugfs.h> |
18 | #include <linux/platform_data/iommu-omap.h> | 19 | #include <linux/platform_data/iommu-omap.h> |
19 | 20 | ||
@@ -29,6 +30,59 @@ static inline bool is_omap_iommu_detached(struct omap_iommu *obj) | |||
29 | return !obj->domain; | 30 | return !obj->domain; |
30 | } | 31 | } |
31 | 32 | ||
33 | #define pr_reg(name) \ | ||
34 | do { \ | ||
35 | ssize_t bytes; \ | ||
36 | const char *str = "%20s: %08x\n"; \ | ||
37 | const int maxcol = 32; \ | ||
38 | bytes = snprintf(p, maxcol, str, __stringify(name), \ | ||
39 | iommu_read_reg(obj, MMU_##name)); \ | ||
40 | p += bytes; \ | ||
41 | len -= bytes; \ | ||
42 | if (len < maxcol) \ | ||
43 | goto out; \ | ||
44 | } while (0) | ||
45 | |||
46 | static ssize_t | ||
47 | omap2_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len) | ||
48 | { | ||
49 | char *p = buf; | ||
50 | |||
51 | pr_reg(REVISION); | ||
52 | pr_reg(IRQSTATUS); | ||
53 | pr_reg(IRQENABLE); | ||
54 | pr_reg(WALKING_ST); | ||
55 | pr_reg(CNTL); | ||
56 | pr_reg(FAULT_AD); | ||
57 | pr_reg(TTB); | ||
58 | pr_reg(LOCK); | ||
59 | pr_reg(LD_TLB); | ||
60 | pr_reg(CAM); | ||
61 | pr_reg(RAM); | ||
62 | pr_reg(GFLUSH); | ||
63 | pr_reg(FLUSH_ENTRY); | ||
64 | pr_reg(READ_CAM); | ||
65 | pr_reg(READ_RAM); | ||
66 | pr_reg(EMU_FAULT_AD); | ||
67 | out: | ||
68 | return p - buf; | ||
69 | } | ||
70 | |||
71 | static ssize_t omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, | ||
72 | ssize_t bytes) | ||
73 | { | ||
74 | if (!obj || !buf) | ||
75 | return -EINVAL; | ||
76 | |||
77 | pm_runtime_get_sync(obj->dev); | ||
78 | |||
79 | bytes = omap2_iommu_dump_ctx(obj, buf, bytes); | ||
80 | |||
81 | pm_runtime_put_sync(obj->dev); | ||
82 | |||
83 | return bytes; | ||
84 | } | ||
85 | |||
32 | static ssize_t debug_read_regs(struct file *file, char __user *userbuf, | 86 | static ssize_t debug_read_regs(struct file *file, char __user *userbuf, |
33 | size_t count, loff_t *ppos) | 87 | size_t count, loff_t *ppos) |
34 | { | 88 | { |
@@ -55,6 +109,63 @@ static ssize_t debug_read_regs(struct file *file, char __user *userbuf, | |||
55 | return bytes; | 109 | return bytes; |
56 | } | 110 | } |
57 | 111 | ||
112 | static int | ||
113 | __dump_tlb_entries(struct omap_iommu *obj, struct cr_regs *crs, int num) | ||
114 | { | ||
115 | int i; | ||
116 | struct iotlb_lock saved; | ||
117 | struct cr_regs tmp; | ||
118 | struct cr_regs *p = crs; | ||
119 | |||
120 | pm_runtime_get_sync(obj->dev); | ||
121 | iotlb_lock_get(obj, &saved); | ||
122 | |||
123 | for_each_iotlb_cr(obj, num, i, tmp) { | ||
124 | if (!iotlb_cr_valid(&tmp)) | ||
125 | continue; | ||
126 | *p++ = tmp; | ||
127 | } | ||
128 | |||
129 | iotlb_lock_set(obj, &saved); | ||
130 | pm_runtime_put_sync(obj->dev); | ||
131 | |||
132 | return p - crs; | ||
133 | } | ||
134 | |||
135 | static ssize_t iotlb_dump_cr(struct omap_iommu *obj, struct cr_regs *cr, | ||
136 | char *buf) | ||
137 | { | ||
138 | char *p = buf; | ||
139 | |||
140 | /* FIXME: Need more detail analysis of cam/ram */ | ||
141 | p += sprintf(p, "%08x %08x %01x\n", cr->cam, cr->ram, | ||
142 | (cr->cam & MMU_CAM_P) ? 1 : 0); | ||
143 | |||
144 | return p - buf; | ||
145 | } | ||
146 | |||
147 | static size_t omap_dump_tlb_entries(struct omap_iommu *obj, char *buf, | ||
148 | ssize_t bytes) | ||
149 | { | ||
150 | int i, num; | ||
151 | struct cr_regs *cr; | ||
152 | char *p = buf; | ||
153 | |||
154 | num = bytes / sizeof(*cr); | ||
155 | num = min(obj->nr_tlb_entries, num); | ||
156 | |||
157 | cr = kcalloc(num, sizeof(*cr), GFP_KERNEL); | ||
158 | if (!cr) | ||
159 | return 0; | ||
160 | |||
161 | num = __dump_tlb_entries(obj, cr, num); | ||
162 | for (i = 0; i < num; i++) | ||
163 | p += iotlb_dump_cr(obj, cr + i, p); | ||
164 | kfree(cr); | ||
165 | |||
166 | return p - buf; | ||
167 | } | ||
168 | |||
58 | static ssize_t debug_read_tlb(struct file *file, char __user *userbuf, | 169 | static ssize_t debug_read_tlb(struct file *file, char __user *userbuf, |
59 | size_t count, loff_t *ppos) | 170 | size_t count, loff_t *ppos) |
60 | { | 171 | { |
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index eeecfc4073af..0fc00f31c39d 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c | |||
@@ -37,11 +37,6 @@ | |||
37 | #define to_iommu(dev) \ | 37 | #define to_iommu(dev) \ |
38 | ((struct omap_iommu *)platform_get_drvdata(to_platform_device(dev))) | 38 | ((struct omap_iommu *)platform_get_drvdata(to_platform_device(dev))) |
39 | 39 | ||
40 | #define for_each_iotlb_cr(obj, n, __i, cr) \ | ||
41 | for (__i = 0; \ | ||
42 | (__i < (n)) && (cr = __iotlb_read_cr((obj), __i), true); \ | ||
43 | __i++) | ||
44 | |||
45 | /* bitmap of the page sizes currently supported */ | 40 | /* bitmap of the page sizes currently supported */ |
46 | #define OMAP_IOMMU_PGSIZES (SZ_4K | SZ_64K | SZ_1M | SZ_16M) | 41 | #define OMAP_IOMMU_PGSIZES (SZ_4K | SZ_64K | SZ_1M | SZ_16M) |
47 | 42 | ||
@@ -71,11 +66,6 @@ struct omap_iommu_domain { | |||
71 | #define MMU_LOCK_VICT(x) \ | 66 | #define MMU_LOCK_VICT(x) \ |
72 | ((x & MMU_LOCK_VICT_MASK) >> MMU_LOCK_VICT_SHIFT) | 67 | ((x & MMU_LOCK_VICT_MASK) >> MMU_LOCK_VICT_SHIFT) |
73 | 68 | ||
74 | struct iotlb_lock { | ||
75 | short base; | ||
76 | short vict; | ||
77 | }; | ||
78 | |||
79 | static struct platform_driver omap_iommu_driver; | 69 | static struct platform_driver omap_iommu_driver; |
80 | static struct kmem_cache *iopte_cachep; | 70 | static struct kmem_cache *iopte_cachep; |
81 | 71 | ||
@@ -212,14 +202,6 @@ static void iommu_disable(struct omap_iommu *obj) | |||
212 | /* | 202 | /* |
213 | * TLB operations | 203 | * TLB operations |
214 | */ | 204 | */ |
215 | static inline int iotlb_cr_valid(struct cr_regs *cr) | ||
216 | { | ||
217 | if (!cr) | ||
218 | return -EINVAL; | ||
219 | |||
220 | return cr->cam & MMU_CAM_V; | ||
221 | } | ||
222 | |||
223 | static u32 iotlb_cr_to_virt(struct cr_regs *cr) | 205 | static u32 iotlb_cr_to_virt(struct cr_regs *cr) |
224 | { | 206 | { |
225 | u32 page_size = cr->cam & MMU_CAM_PGSZ_MASK; | 207 | u32 page_size = cr->cam & MMU_CAM_PGSZ_MASK; |
@@ -259,7 +241,7 @@ static u32 iommu_report_fault(struct omap_iommu *obj, u32 *da) | |||
259 | return status; | 241 | return status; |
260 | } | 242 | } |
261 | 243 | ||
262 | static void iotlb_lock_get(struct omap_iommu *obj, struct iotlb_lock *l) | 244 | void iotlb_lock_get(struct omap_iommu *obj, struct iotlb_lock *l) |
263 | { | 245 | { |
264 | u32 val; | 246 | u32 val; |
265 | 247 | ||
@@ -267,10 +249,9 @@ static void iotlb_lock_get(struct omap_iommu *obj, struct iotlb_lock *l) | |||
267 | 249 | ||
268 | l->base = MMU_LOCK_BASE(val); | 250 | l->base = MMU_LOCK_BASE(val); |
269 | l->vict = MMU_LOCK_VICT(val); | 251 | l->vict = MMU_LOCK_VICT(val); |
270 | |||
271 | } | 252 | } |
272 | 253 | ||
273 | static void iotlb_lock_set(struct omap_iommu *obj, struct iotlb_lock *l) | 254 | void iotlb_lock_set(struct omap_iommu *obj, struct iotlb_lock *l) |
274 | { | 255 | { |
275 | u32 val; | 256 | u32 val; |
276 | 257 | ||
@@ -296,7 +277,7 @@ static void iotlb_load_cr(struct omap_iommu *obj, struct cr_regs *cr) | |||
296 | } | 277 | } |
297 | 278 | ||
298 | /* only used in iotlb iteration for-loop */ | 279 | /* only used in iotlb iteration for-loop */ |
299 | static struct cr_regs __iotlb_read_cr(struct omap_iommu *obj, int n) | 280 | struct cr_regs __iotlb_read_cr(struct omap_iommu *obj, int n) |
300 | { | 281 | { |
301 | struct cr_regs cr; | 282 | struct cr_regs cr; |
302 | struct iotlb_lock l; | 283 | struct iotlb_lock l; |
@@ -467,129 +448,6 @@ static void flush_iotlb_all(struct omap_iommu *obj) | |||
467 | pm_runtime_put_sync(obj->dev); | 448 | pm_runtime_put_sync(obj->dev); |
468 | } | 449 | } |
469 | 450 | ||
470 | #ifdef CONFIG_OMAP_IOMMU_DEBUG | ||
471 | |||
472 | #define pr_reg(name) \ | ||
473 | do { \ | ||
474 | ssize_t bytes; \ | ||
475 | const char *str = "%20s: %08x\n"; \ | ||
476 | const int maxcol = 32; \ | ||
477 | bytes = snprintf(p, maxcol, str, __stringify(name), \ | ||
478 | iommu_read_reg(obj, MMU_##name)); \ | ||
479 | p += bytes; \ | ||
480 | len -= bytes; \ | ||
481 | if (len < maxcol) \ | ||
482 | goto out; \ | ||
483 | } while (0) | ||
484 | |||
485 | static ssize_t | ||
486 | omap2_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len) | ||
487 | { | ||
488 | char *p = buf; | ||
489 | |||
490 | pr_reg(REVISION); | ||
491 | pr_reg(IRQSTATUS); | ||
492 | pr_reg(IRQENABLE); | ||
493 | pr_reg(WALKING_ST); | ||
494 | pr_reg(CNTL); | ||
495 | pr_reg(FAULT_AD); | ||
496 | pr_reg(TTB); | ||
497 | pr_reg(LOCK); | ||
498 | pr_reg(LD_TLB); | ||
499 | pr_reg(CAM); | ||
500 | pr_reg(RAM); | ||
501 | pr_reg(GFLUSH); | ||
502 | pr_reg(FLUSH_ENTRY); | ||
503 | pr_reg(READ_CAM); | ||
504 | pr_reg(READ_RAM); | ||
505 | pr_reg(EMU_FAULT_AD); | ||
506 | out: | ||
507 | return p - buf; | ||
508 | } | ||
509 | |||
510 | ssize_t omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t bytes) | ||
511 | { | ||
512 | if (!obj || !buf) | ||
513 | return -EINVAL; | ||
514 | |||
515 | pm_runtime_get_sync(obj->dev); | ||
516 | |||
517 | bytes = omap2_iommu_dump_ctx(obj, buf, bytes); | ||
518 | |||
519 | pm_runtime_put_sync(obj->dev); | ||
520 | |||
521 | return bytes; | ||
522 | } | ||
523 | |||
524 | static int | ||
525 | __dump_tlb_entries(struct omap_iommu *obj, struct cr_regs *crs, int num) | ||
526 | { | ||
527 | int i; | ||
528 | struct iotlb_lock saved; | ||
529 | struct cr_regs tmp; | ||
530 | struct cr_regs *p = crs; | ||
531 | |||
532 | pm_runtime_get_sync(obj->dev); | ||
533 | iotlb_lock_get(obj, &saved); | ||
534 | |||
535 | for_each_iotlb_cr(obj, num, i, tmp) { | ||
536 | if (!iotlb_cr_valid(&tmp)) | ||
537 | continue; | ||
538 | *p++ = tmp; | ||
539 | } | ||
540 | |||
541 | iotlb_lock_set(obj, &saved); | ||
542 | pm_runtime_put_sync(obj->dev); | ||
543 | |||
544 | return p - crs; | ||
545 | } | ||
546 | |||
547 | /** | ||
548 | * iotlb_dump_cr - Dump an iommu tlb entry into buf | ||
549 | * @obj: target iommu | ||
550 | * @cr: contents of cam and ram register | ||
551 | * @buf: output buffer | ||
552 | **/ | ||
553 | static ssize_t iotlb_dump_cr(struct omap_iommu *obj, struct cr_regs *cr, | ||
554 | char *buf) | ||
555 | { | ||
556 | char *p = buf; | ||
557 | |||
558 | /* FIXME: Need more detail analysis of cam/ram */ | ||
559 | p += sprintf(p, "%08x %08x %01x\n", cr->cam, cr->ram, | ||
560 | (cr->cam & MMU_CAM_P) ? 1 : 0); | ||
561 | |||
562 | return p - buf; | ||
563 | } | ||
564 | |||
565 | /** | ||
566 | * omap_dump_tlb_entries - dump cr arrays to given buffer | ||
567 | * @obj: target iommu | ||
568 | * @buf: output buffer | ||
569 | **/ | ||
570 | size_t omap_dump_tlb_entries(struct omap_iommu *obj, char *buf, ssize_t bytes) | ||
571 | { | ||
572 | int i, num; | ||
573 | struct cr_regs *cr; | ||
574 | char *p = buf; | ||
575 | |||
576 | num = bytes / sizeof(*cr); | ||
577 | num = min(obj->nr_tlb_entries, num); | ||
578 | |||
579 | cr = kcalloc(num, sizeof(*cr), GFP_KERNEL); | ||
580 | if (!cr) | ||
581 | return 0; | ||
582 | |||
583 | num = __dump_tlb_entries(obj, cr, num); | ||
584 | for (i = 0; i < num; i++) | ||
585 | p += iotlb_dump_cr(obj, cr + i, p); | ||
586 | kfree(cr); | ||
587 | |||
588 | return p - buf; | ||
589 | } | ||
590 | |||
591 | #endif /* CONFIG_OMAP_IOMMU_DEBUG */ | ||
592 | |||
593 | /* | 451 | /* |
594 | * H/W pagetable operations | 452 | * H/W pagetable operations |
595 | */ | 453 | */ |
diff --git a/drivers/iommu/omap-iommu.h b/drivers/iommu/omap-iommu.h index d736630df3c8..b6cc90b2ba41 100644 --- a/drivers/iommu/omap-iommu.h +++ b/drivers/iommu/omap-iommu.h | |||
@@ -13,6 +13,11 @@ | |||
13 | #ifndef _OMAP_IOMMU_H | 13 | #ifndef _OMAP_IOMMU_H |
14 | #define _OMAP_IOMMU_H | 14 | #define _OMAP_IOMMU_H |
15 | 15 | ||
16 | #define for_each_iotlb_cr(obj, n, __i, cr) \ | ||
17 | for (__i = 0; \ | ||
18 | (__i < (n)) && (cr = __iotlb_read_cr((obj), __i), true); \ | ||
19 | __i++) | ||
20 | |||
16 | struct iotlb_entry { | 21 | struct iotlb_entry { |
17 | u32 da; | 22 | u32 da; |
18 | u32 pa; | 23 | u32 pa; |
@@ -65,6 +70,11 @@ struct cr_regs { | |||
65 | }; | 70 | }; |
66 | }; | 71 | }; |
67 | 72 | ||
73 | struct iotlb_lock { | ||
74 | short base; | ||
75 | short vict; | ||
76 | }; | ||
77 | |||
68 | /** | 78 | /** |
69 | * dev_to_omap_iommu() - retrieves an omap iommu object from a user device | 79 | * dev_to_omap_iommu() - retrieves an omap iommu object from a user device |
70 | * @dev: iommu client device | 80 | * @dev: iommu client device |
@@ -190,12 +200,12 @@ static inline struct omap_iommu *dev_to_omap_iommu(struct device *dev) | |||
190 | /* | 200 | /* |
191 | * global functions | 201 | * global functions |
192 | */ | 202 | */ |
193 | #ifdef CONFIG_OMAP_IOMMU_DEBUG | ||
194 | extern ssize_t | ||
195 | omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len); | ||
196 | extern size_t | ||
197 | omap_dump_tlb_entries(struct omap_iommu *obj, char *buf, ssize_t len); | ||
198 | 203 | ||
204 | struct cr_regs __iotlb_read_cr(struct omap_iommu *obj, int n); | ||
205 | void iotlb_lock_get(struct omap_iommu *obj, struct iotlb_lock *l); | ||
206 | void iotlb_lock_set(struct omap_iommu *obj, struct iotlb_lock *l); | ||
207 | |||
208 | #ifdef CONFIG_OMAP_IOMMU_DEBUG | ||
199 | void omap_iommu_debugfs_init(void); | 209 | void omap_iommu_debugfs_init(void); |
200 | void omap_iommu_debugfs_exit(void); | 210 | void omap_iommu_debugfs_exit(void); |
201 | 211 | ||
@@ -222,4 +232,12 @@ static inline void iommu_write_reg(struct omap_iommu *obj, u32 val, size_t offs) | |||
222 | __raw_writel(val, obj->regbase + offs); | 232 | __raw_writel(val, obj->regbase + offs); |
223 | } | 233 | } |
224 | 234 | ||
235 | static inline int iotlb_cr_valid(struct cr_regs *cr) | ||
236 | { | ||
237 | if (!cr) | ||
238 | return -EINVAL; | ||
239 | |||
240 | return cr->cam & MMU_CAM_V; | ||
241 | } | ||
242 | |||
225 | #endif /* _OMAP_IOMMU_H */ | 243 | #endif /* _OMAP_IOMMU_H */ |