aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuman Anna <s-anna@ti.com>2015-07-20 18:33:25 -0400
committerJoerg Roedel <jroedel@suse.de>2015-08-03 10:03:50 -0400
commit69c2c196328e73d3091dd0be89ab4b0c2af4b210 (patch)
treec21d4ad5f728285d59a8207a19d61df0bdc71e91
parent0cdbf727167a2fcc9ba2aaea98e2a76124ba072e (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.c111
-rw-r--r--drivers/iommu/omap-iommu.c148
-rw-r--r--drivers/iommu/omap-iommu.h28
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
46static ssize_t
47omap2_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);
67out:
68 return p - buf;
69}
70
71static 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
32static ssize_t debug_read_regs(struct file *file, char __user *userbuf, 86static 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
112static 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
135static 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
147static 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
58static ssize_t debug_read_tlb(struct file *file, char __user *userbuf, 169static 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
74struct iotlb_lock {
75 short base;
76 short vict;
77};
78
79static struct platform_driver omap_iommu_driver; 69static struct platform_driver omap_iommu_driver;
80static struct kmem_cache *iopte_cachep; 70static 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 */
215static 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
223static u32 iotlb_cr_to_virt(struct cr_regs *cr) 205static 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
262static void iotlb_lock_get(struct omap_iommu *obj, struct iotlb_lock *l) 244void 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
273static void iotlb_lock_set(struct omap_iommu *obj, struct iotlb_lock *l) 254void 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 */
299static struct cr_regs __iotlb_read_cr(struct omap_iommu *obj, int n) 280struct 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
485static ssize_t
486omap2_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);
506out:
507 return p - buf;
508}
509
510ssize_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
524static 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 **/
553static 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 **/
570size_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
16struct iotlb_entry { 21struct 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
73struct 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
194extern ssize_t
195omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len);
196extern size_t
197omap_dump_tlb_entries(struct omap_iommu *obj, char *buf, ssize_t len);
198 203
204struct cr_regs __iotlb_read_cr(struct omap_iommu *obj, int n);
205void iotlb_lock_get(struct omap_iommu *obj, struct iotlb_lock *l);
206void iotlb_lock_set(struct omap_iommu *obj, struct iotlb_lock *l);
207
208#ifdef CONFIG_OMAP_IOMMU_DEBUG
199void omap_iommu_debugfs_init(void); 209void omap_iommu_debugfs_init(void);
200void omap_iommu_debugfs_exit(void); 210void 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
235static 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 */