aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuman Anna <s-anna@ti.com>2014-10-22 18:22:30 -0400
committerJoerg Roedel <jroedel@suse.de>2014-10-23 08:33:16 -0400
commit61c753526dc3ef91a0601e0bf2bdeeb6c415e747 (patch)
treea6adb75a11acb5ab5f75edf62ed32c63ed764f02
parent3ca5db072c770c950a816c46ef2330d9e0ced8a7 (diff)
iommu/omap: Integrate omap-iommu-debug into omap-iommu
The debugfs support for OMAP IOMMU is currently implemented as a module, warranting certain OMAP-specific IOMMU API to be exported. The OMAP IOMMU, when enabled, can only be built-in into the kernel, so integrate the OMAP IOMMU debug module into the OMAP IOMMU driver. This helps in eliminating the need to export most of the current OMAP IOMMU API. The following are the main changes: - The debugfs directory and entry creation logic is reversed, the calls are invoked by the OMAP IOMMU driver now. - The current iffy circular logic of adding IOMMU archdata to the IOMMU devices itself to get a pointer to the omap_iommu object in the debugfs support code is replaced by directly using the omap_iommu structure while creating the debugfs entries. - The debugfs root directory is renamed from the generic name "iommu" to a specific name "omap_iommu". - Unneeded headers have also been cleaned up while at this. - There will no longer be a omap-iommu-debug.ko module after this patch. - The OMAP_IOMMU_DEBUG Kconfig option is converted to boolean only, the OMAP IOMMU debugfs support is built alongside the OMAP IOMMU driver only when this option is enabled. 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>
-rw-r--r--drivers/iommu/Kconfig12
-rw-r--r--drivers/iommu/omap-iommu-debug.c100
-rw-r--r--drivers/iommu/omap-iommu.c11
-rw-r--r--drivers/iommu/omap-iommu.h15
4 files changed, 58 insertions, 80 deletions
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index dd5112265cc9..1d54996b6a70 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -144,13 +144,13 @@ config OMAP_IOMMU
144 select IOMMU_API 144 select IOMMU_API
145 145
146config OMAP_IOMMU_DEBUG 146config OMAP_IOMMU_DEBUG
147 tristate "Export OMAP IOMMU internals in DebugFS" 147 bool "Export OMAP IOMMU internals in DebugFS"
148 depends on OMAP_IOMMU && DEBUG_FS 148 depends on OMAP_IOMMU && DEBUG_FS
149 help 149 ---help---
150 Select this to see extensive information about 150 Select this to see extensive information about
151 the internal state of OMAP IOMMU in debugfs. 151 the internal state of OMAP IOMMU in debugfs.
152 152
153 Say N unless you know you need this. 153 Say N unless you know you need this.
154 154
155config TEGRA_IOMMU_GART 155config TEGRA_IOMMU_GART
156 bool "Tegra GART IOMMU Support" 156 bool "Tegra GART IOMMU Support"
diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c
index 28de657e38c0..4813d3a71a00 100644
--- a/drivers/iommu/omap-iommu-debug.c
+++ b/drivers/iommu/omap-iommu-debug.c
@@ -10,15 +10,11 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#include <linux/module.h>
14#include <linux/err.h> 13#include <linux/err.h>
15#include <linux/clk.h>
16#include <linux/io.h> 14#include <linux/io.h>
17#include <linux/slab.h> 15#include <linux/slab.h>
18#include <linux/uaccess.h> 16#include <linux/uaccess.h>
19#include <linux/platform_device.h>
20#include <linux/debugfs.h> 17#include <linux/debugfs.h>
21#include <linux/omap-iommu.h>
22#include <linux/platform_data/iommu-omap.h> 18#include <linux/platform_data/iommu-omap.h>
23 19
24#include "omap-iopgtable.h" 20#include "omap-iopgtable.h"
@@ -31,8 +27,7 @@ static struct dentry *iommu_debug_root;
31static ssize_t debug_read_regs(struct file *file, char __user *userbuf, 27static ssize_t debug_read_regs(struct file *file, char __user *userbuf,
32 size_t count, loff_t *ppos) 28 size_t count, loff_t *ppos)
33{ 29{
34 struct device *dev = file->private_data; 30 struct omap_iommu *obj = file->private_data;
35 struct omap_iommu *obj = dev_to_omap_iommu(dev);
36 char *p, *buf; 31 char *p, *buf;
37 ssize_t bytes; 32 ssize_t bytes;
38 33
@@ -55,8 +50,7 @@ static ssize_t debug_read_regs(struct file *file, char __user *userbuf,
55static ssize_t debug_read_tlb(struct file *file, char __user *userbuf, 50static ssize_t debug_read_tlb(struct file *file, char __user *userbuf,
56 size_t count, loff_t *ppos) 51 size_t count, loff_t *ppos)
57{ 52{
58 struct device *dev = file->private_data; 53 struct omap_iommu *obj = file->private_data;
59 struct omap_iommu *obj = dev_to_omap_iommu(dev);
60 char *p, *buf; 54 char *p, *buf;
61 ssize_t bytes, rest; 55 ssize_t bytes, rest;
62 56
@@ -141,8 +135,7 @@ out:
141static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf, 135static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf,
142 size_t count, loff_t *ppos) 136 size_t count, loff_t *ppos)
143{ 137{
144 struct device *dev = file->private_data; 138 struct omap_iommu *obj = file->private_data;
145 struct omap_iommu *obj = dev_to_omap_iommu(dev);
146 char *p, *buf; 139 char *p, *buf;
147 size_t bytes; 140 size_t bytes;
148 141
@@ -181,93 +174,56 @@ DEBUG_FOPS_RO(pagetable);
181#define __DEBUG_ADD_FILE(attr, mode) \ 174#define __DEBUG_ADD_FILE(attr, mode) \
182 { \ 175 { \
183 struct dentry *dent; \ 176 struct dentry *dent; \
184 dent = debugfs_create_file(#attr, mode, parent, \ 177 dent = debugfs_create_file(#attr, mode, obj->debug_dir, \
185 dev, &debug_##attr##_fops); \ 178 obj, &debug_##attr##_fops); \
186 if (!dent) \ 179 if (!dent) \
187 return -ENOMEM; \ 180 goto err; \
188 } 181 }
189 182
190#define DEBUG_ADD_FILE_RO(name) __DEBUG_ADD_FILE(name, 0400) 183#define DEBUG_ADD_FILE_RO(name) __DEBUG_ADD_FILE(name, 0400)
191 184
192static int iommu_debug_register(struct device *dev, void *data) 185void omap_iommu_debugfs_add(struct omap_iommu *obj)
193{ 186{
194 struct platform_device *pdev = to_platform_device(dev); 187 struct dentry *d;
195 struct omap_iommu *obj = platform_get_drvdata(pdev);
196 struct omap_iommu_arch_data *arch_data;
197 struct dentry *d, *parent;
198
199 if (!obj || !obj->dev)
200 return -EINVAL;
201
202 arch_data = kzalloc(sizeof(*arch_data), GFP_KERNEL);
203 if (!arch_data)
204 return -ENOMEM;
205
206 arch_data->iommu_dev = obj;
207 188
208 dev->archdata.iommu = arch_data; 189 if (!iommu_debug_root)
190 return;
209 191
210 d = debugfs_create_dir(obj->name, iommu_debug_root); 192 obj->debug_dir = debugfs_create_dir(obj->name, iommu_debug_root);
211 if (!d) 193 if (!obj->debug_dir)
212 goto nomem; 194 return;
213 parent = d;
214 195
215 d = debugfs_create_u8("nr_tlb_entries", 0400, parent, 196 d = debugfs_create_u8("nr_tlb_entries", 0400, obj->debug_dir,
216 (u8 *)&obj->nr_tlb_entries); 197 (u8 *)&obj->nr_tlb_entries);
217 if (!d) 198 if (!d)
218 goto nomem; 199 return;
219 200
220 DEBUG_ADD_FILE_RO(regs); 201 DEBUG_ADD_FILE_RO(regs);
221 DEBUG_ADD_FILE_RO(tlb); 202 DEBUG_ADD_FILE_RO(tlb);
222 DEBUG_ADD_FILE_RO(pagetable); 203 DEBUG_ADD_FILE_RO(pagetable);
223 204
224 return 0; 205 return;
225 206
226nomem: 207err:
227 kfree(arch_data); 208 debugfs_remove_recursive(obj->debug_dir);
228 return -ENOMEM;
229} 209}
230 210
231static int iommu_debug_unregister(struct device *dev, void *data) 211void omap_iommu_debugfs_remove(struct omap_iommu *obj)
232{ 212{
233 if (!dev->archdata.iommu) 213 if (!obj->debug_dir)
234 return 0; 214 return;
235
236 kfree(dev->archdata.iommu);
237
238 dev->archdata.iommu = NULL;
239 215
240 return 0; 216 debugfs_remove_recursive(obj->debug_dir);
241} 217}
242 218
243static int __init iommu_debug_init(void) 219void __init omap_iommu_debugfs_init(void)
244{ 220{
245 struct dentry *d; 221 iommu_debug_root = debugfs_create_dir("omap_iommu", NULL);
246 int err; 222 if (!iommu_debug_root)
247 223 pr_err("can't create debugfs dir\n");
248 d = debugfs_create_dir("iommu", NULL);
249 if (!d)
250 return -ENOMEM;
251 iommu_debug_root = d;
252
253 err = omap_foreach_iommu_device(d, iommu_debug_register);
254 if (err)
255 goto err_out;
256 return 0;
257
258err_out:
259 debugfs_remove_recursive(iommu_debug_root);
260 return err;
261} 224}
262module_init(iommu_debug_init)
263 225
264static void __exit iommu_debugfs_exit(void) 226void __exit omap_iommu_debugfs_exit(void)
265{ 227{
266 debugfs_remove_recursive(iommu_debug_root); 228 debugfs_remove(iommu_debug_root);
267 omap_foreach_iommu_device(NULL, iommu_debug_unregister);
268} 229}
269module_exit(iommu_debugfs_exit)
270
271MODULE_DESCRIPTION("omap iommu: debugfs interface");
272MODULE_AUTHOR("Hiroshi DOYU <Hiroshi.DOYU@nokia.com>");
273MODULE_LICENSE("GPL v2");
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index 91262fa2a351..b92b6fc33690 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -472,7 +472,7 @@ static void flush_iotlb_all(struct omap_iommu *obj)
472 pm_runtime_put_sync(obj->dev); 472 pm_runtime_put_sync(obj->dev);
473} 473}
474 474
475#if defined(CONFIG_OMAP_IOMMU_DEBUG) || defined(CONFIG_OMAP_IOMMU_DEBUG_MODULE) 475#ifdef CONFIG_OMAP_IOMMU_DEBUG
476 476
477#define pr_reg(name) \ 477#define pr_reg(name) \
478 do { \ 478 do { \
@@ -602,7 +602,7 @@ int omap_foreach_iommu_device(void *data, int (*fn)(struct device *, void *))
602} 602}
603EXPORT_SYMBOL_GPL(omap_foreach_iommu_device); 603EXPORT_SYMBOL_GPL(omap_foreach_iommu_device);
604 604
605#endif /* CONFIG_OMAP_IOMMU_DEBUG_MODULE */ 605#endif /* CONFIG_OMAP_IOMMU_DEBUG */
606 606
607/* 607/*
608 * H/W pagetable operations 608 * H/W pagetable operations
@@ -1077,6 +1077,8 @@ static int omap_iommu_probe(struct platform_device *pdev)
1077 pm_runtime_irq_safe(obj->dev); 1077 pm_runtime_irq_safe(obj->dev);
1078 pm_runtime_enable(obj->dev); 1078 pm_runtime_enable(obj->dev);
1079 1079
1080 omap_iommu_debugfs_add(obj);
1081
1080 dev_info(&pdev->dev, "%s registered\n", obj->name); 1082 dev_info(&pdev->dev, "%s registered\n", obj->name);
1081 return 0; 1083 return 0;
1082} 1084}
@@ -1086,6 +1088,7 @@ static int omap_iommu_remove(struct platform_device *pdev)
1086 struct omap_iommu *obj = platform_get_drvdata(pdev); 1088 struct omap_iommu *obj = platform_get_drvdata(pdev);
1087 1089
1088 iopgtable_clear_entry_all(obj); 1090 iopgtable_clear_entry_all(obj);
1091 omap_iommu_debugfs_remove(obj);
1089 1092
1090 pm_runtime_disable(obj->dev); 1093 pm_runtime_disable(obj->dev);
1091 1094
@@ -1403,6 +1406,8 @@ static int __init omap_iommu_init(void)
1403 1406
1404 bus_set_iommu(&platform_bus_type, &omap_iommu_ops); 1407 bus_set_iommu(&platform_bus_type, &omap_iommu_ops);
1405 1408
1409 omap_iommu_debugfs_init();
1410
1406 return platform_driver_register(&omap_iommu_driver); 1411 return platform_driver_register(&omap_iommu_driver);
1407} 1412}
1408/* must be ready before omap3isp is probed */ 1413/* must be ready before omap3isp is probed */
@@ -1413,6 +1418,8 @@ static void __exit omap_iommu_exit(void)
1413 kmem_cache_destroy(iopte_cachep); 1418 kmem_cache_destroy(iopte_cachep);
1414 1419
1415 platform_driver_unregister(&omap_iommu_driver); 1420 platform_driver_unregister(&omap_iommu_driver);
1421
1422 omap_iommu_debugfs_exit();
1416} 1423}
1417module_exit(omap_iommu_exit); 1424module_exit(omap_iommu_exit);
1418 1425
diff --git a/drivers/iommu/omap-iommu.h b/drivers/iommu/omap-iommu.h
index 0516e0ed77d7..478377924e8f 100644
--- a/drivers/iommu/omap-iommu.h
+++ b/drivers/iommu/omap-iommu.h
@@ -30,6 +30,7 @@ struct omap_iommu {
30 void __iomem *regbase; 30 void __iomem *regbase;
31 struct device *dev; 31 struct device *dev;
32 struct iommu_domain *domain; 32 struct iommu_domain *domain;
33 struct dentry *debug_dir;
33 34
34 spinlock_t iommu_lock; /* global for this whole object */ 35 spinlock_t iommu_lock; /* global for this whole object */
35 36
@@ -197,11 +198,25 @@ omap_iopgtable_store_entry(struct omap_iommu *obj, struct iotlb_entry *e);
197extern int omap_foreach_iommu_device(void *data, 198extern int omap_foreach_iommu_device(void *data,
198 int (*fn)(struct device *, void *)); 199 int (*fn)(struct device *, void *));
199 200
201#ifdef CONFIG_OMAP_IOMMU_DEBUG
200extern ssize_t 202extern ssize_t
201omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len); 203omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len);
202extern size_t 204extern size_t
203omap_dump_tlb_entries(struct omap_iommu *obj, char *buf, ssize_t len); 205omap_dump_tlb_entries(struct omap_iommu *obj, char *buf, ssize_t len);
204 206
207void omap_iommu_debugfs_init(void);
208void omap_iommu_debugfs_exit(void);
209
210void omap_iommu_debugfs_add(struct omap_iommu *obj);
211void omap_iommu_debugfs_remove(struct omap_iommu *obj);
212#else
213static inline void omap_iommu_debugfs_init(void) { }
214static inline void omap_iommu_debugfs_exit(void) { }
215
216static inline void omap_iommu_debugfs_add(struct omap_iommu *obj) { }
217static inline void omap_iommu_debugfs_remove(struct omap_iommu *obj) { }
218#endif
219
205/* 220/*
206 * register accessors 221 * register accessors
207 */ 222 */