diff options
Diffstat (limited to 'drivers/iommu')
-rw-r--r-- | drivers/iommu/amd_iommu_init.c | 2 | ||||
-rw-r--r-- | drivers/iommu/intel-iommu.c | 61 | ||||
-rw-r--r-- | drivers/iommu/omap-iommu-debug.c | 59 | ||||
-rw-r--r-- | drivers/iommu/omap-iommu.c | 3 |
4 files changed, 84 insertions, 41 deletions
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index bdea288dc185..a35e98ad9725 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c | |||
@@ -275,7 +275,7 @@ static void iommu_set_exclusion_range(struct amd_iommu *iommu) | |||
275 | } | 275 | } |
276 | 276 | ||
277 | /* Programs the physical address of the device table into the IOMMU hardware */ | 277 | /* Programs the physical address of the device table into the IOMMU hardware */ |
278 | static void __init iommu_set_device_table(struct amd_iommu *iommu) | 278 | static void iommu_set_device_table(struct amd_iommu *iommu) |
279 | { | 279 | { |
280 | u64 entry; | 280 | u64 entry; |
281 | 281 | ||
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index c9c6053198d4..132f93b05154 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -48,8 +48,6 @@ | |||
48 | #define ROOT_SIZE VTD_PAGE_SIZE | 48 | #define ROOT_SIZE VTD_PAGE_SIZE |
49 | #define CONTEXT_SIZE VTD_PAGE_SIZE | 49 | #define CONTEXT_SIZE VTD_PAGE_SIZE |
50 | 50 | ||
51 | #define IS_BRIDGE_HOST_DEVICE(pdev) \ | ||
52 | ((pdev->class >> 8) == PCI_CLASS_BRIDGE_HOST) | ||
53 | #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) | 51 | #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) |
54 | #define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA) | 52 | #define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA) |
55 | #define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e) | 53 | #define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e) |
@@ -356,10 +354,18 @@ static int hw_pass_through = 1; | |||
356 | /* si_domain contains mulitple devices */ | 354 | /* si_domain contains mulitple devices */ |
357 | #define DOMAIN_FLAG_STATIC_IDENTITY (1 << 2) | 355 | #define DOMAIN_FLAG_STATIC_IDENTITY (1 << 2) |
358 | 356 | ||
357 | /* define the limit of IOMMUs supported in each domain */ | ||
358 | #ifdef CONFIG_X86 | ||
359 | # define IOMMU_UNITS_SUPPORTED MAX_IO_APICS | ||
360 | #else | ||
361 | # define IOMMU_UNITS_SUPPORTED 64 | ||
362 | #endif | ||
363 | |||
359 | struct dmar_domain { | 364 | struct dmar_domain { |
360 | int id; /* domain id */ | 365 | int id; /* domain id */ |
361 | int nid; /* node id */ | 366 | int nid; /* node id */ |
362 | unsigned long iommu_bmp; /* bitmap of iommus this domain uses*/ | 367 | DECLARE_BITMAP(iommu_bmp, IOMMU_UNITS_SUPPORTED); |
368 | /* bitmap of iommus this domain uses*/ | ||
363 | 369 | ||
364 | struct list_head devices; /* all devices' list */ | 370 | struct list_head devices; /* all devices' list */ |
365 | struct iova_domain iovad; /* iova's that belong to this domain */ | 371 | struct iova_domain iovad; /* iova's that belong to this domain */ |
@@ -571,7 +577,7 @@ static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain) | |||
571 | BUG_ON(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE); | 577 | BUG_ON(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE); |
572 | BUG_ON(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY); | 578 | BUG_ON(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY); |
573 | 579 | ||
574 | iommu_id = find_first_bit(&domain->iommu_bmp, g_num_of_iommus); | 580 | iommu_id = find_first_bit(domain->iommu_bmp, g_num_of_iommus); |
575 | if (iommu_id < 0 || iommu_id >= g_num_of_iommus) | 581 | if (iommu_id < 0 || iommu_id >= g_num_of_iommus) |
576 | return NULL; | 582 | return NULL; |
577 | 583 | ||
@@ -584,7 +590,7 @@ static void domain_update_iommu_coherency(struct dmar_domain *domain) | |||
584 | 590 | ||
585 | domain->iommu_coherency = 1; | 591 | domain->iommu_coherency = 1; |
586 | 592 | ||
587 | for_each_set_bit(i, &domain->iommu_bmp, g_num_of_iommus) { | 593 | for_each_set_bit(i, domain->iommu_bmp, g_num_of_iommus) { |
588 | if (!ecap_coherent(g_iommus[i]->ecap)) { | 594 | if (!ecap_coherent(g_iommus[i]->ecap)) { |
589 | domain->iommu_coherency = 0; | 595 | domain->iommu_coherency = 0; |
590 | break; | 596 | break; |
@@ -598,7 +604,7 @@ static void domain_update_iommu_snooping(struct dmar_domain *domain) | |||
598 | 604 | ||
599 | domain->iommu_snooping = 1; | 605 | domain->iommu_snooping = 1; |
600 | 606 | ||
601 | for_each_set_bit(i, &domain->iommu_bmp, g_num_of_iommus) { | 607 | for_each_set_bit(i, domain->iommu_bmp, g_num_of_iommus) { |
602 | if (!ecap_sc_support(g_iommus[i]->ecap)) { | 608 | if (!ecap_sc_support(g_iommus[i]->ecap)) { |
603 | domain->iommu_snooping = 0; | 609 | domain->iommu_snooping = 0; |
604 | break; | 610 | break; |
@@ -1241,7 +1247,7 @@ static int iommu_init_domains(struct intel_iommu *iommu) | |||
1241 | unsigned long nlongs; | 1247 | unsigned long nlongs; |
1242 | 1248 | ||
1243 | ndomains = cap_ndoms(iommu->cap); | 1249 | ndomains = cap_ndoms(iommu->cap); |
1244 | pr_debug("IOMMU %d: Number of Domains supportd <%ld>\n", iommu->seq_id, | 1250 | pr_debug("IOMMU %d: Number of Domains supported <%ld>\n", iommu->seq_id, |
1245 | ndomains); | 1251 | ndomains); |
1246 | nlongs = BITS_TO_LONGS(ndomains); | 1252 | nlongs = BITS_TO_LONGS(ndomains); |
1247 | 1253 | ||
@@ -1334,7 +1340,7 @@ static struct dmar_domain *alloc_domain(void) | |||
1334 | return NULL; | 1340 | return NULL; |
1335 | 1341 | ||
1336 | domain->nid = -1; | 1342 | domain->nid = -1; |
1337 | memset(&domain->iommu_bmp, 0, sizeof(unsigned long)); | 1343 | memset(domain->iommu_bmp, 0, sizeof(domain->iommu_bmp)); |
1338 | domain->flags = 0; | 1344 | domain->flags = 0; |
1339 | 1345 | ||
1340 | return domain; | 1346 | return domain; |
@@ -1360,7 +1366,7 @@ static int iommu_attach_domain(struct dmar_domain *domain, | |||
1360 | 1366 | ||
1361 | domain->id = num; | 1367 | domain->id = num; |
1362 | set_bit(num, iommu->domain_ids); | 1368 | set_bit(num, iommu->domain_ids); |
1363 | set_bit(iommu->seq_id, &domain->iommu_bmp); | 1369 | set_bit(iommu->seq_id, domain->iommu_bmp); |
1364 | iommu->domains[num] = domain; | 1370 | iommu->domains[num] = domain; |
1365 | spin_unlock_irqrestore(&iommu->lock, flags); | 1371 | spin_unlock_irqrestore(&iommu->lock, flags); |
1366 | 1372 | ||
@@ -1385,7 +1391,7 @@ static void iommu_detach_domain(struct dmar_domain *domain, | |||
1385 | 1391 | ||
1386 | if (found) { | 1392 | if (found) { |
1387 | clear_bit(num, iommu->domain_ids); | 1393 | clear_bit(num, iommu->domain_ids); |
1388 | clear_bit(iommu->seq_id, &domain->iommu_bmp); | 1394 | clear_bit(iommu->seq_id, domain->iommu_bmp); |
1389 | iommu->domains[num] = NULL; | 1395 | iommu->domains[num] = NULL; |
1390 | } | 1396 | } |
1391 | spin_unlock_irqrestore(&iommu->lock, flags); | 1397 | spin_unlock_irqrestore(&iommu->lock, flags); |
@@ -1527,7 +1533,7 @@ static void domain_exit(struct dmar_domain *domain) | |||
1527 | dma_pte_free_pagetable(domain, 0, DOMAIN_MAX_PFN(domain->gaw)); | 1533 | dma_pte_free_pagetable(domain, 0, DOMAIN_MAX_PFN(domain->gaw)); |
1528 | 1534 | ||
1529 | for_each_active_iommu(iommu, drhd) | 1535 | for_each_active_iommu(iommu, drhd) |
1530 | if (test_bit(iommu->seq_id, &domain->iommu_bmp)) | 1536 | if (test_bit(iommu->seq_id, domain->iommu_bmp)) |
1531 | iommu_detach_domain(domain, iommu); | 1537 | iommu_detach_domain(domain, iommu); |
1532 | 1538 | ||
1533 | free_domain_mem(domain); | 1539 | free_domain_mem(domain); |
@@ -1653,7 +1659,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain, int segment, | |||
1653 | spin_unlock_irqrestore(&iommu->lock, flags); | 1659 | spin_unlock_irqrestore(&iommu->lock, flags); |
1654 | 1660 | ||
1655 | spin_lock_irqsave(&domain->iommu_lock, flags); | 1661 | spin_lock_irqsave(&domain->iommu_lock, flags); |
1656 | if (!test_and_set_bit(iommu->seq_id, &domain->iommu_bmp)) { | 1662 | if (!test_and_set_bit(iommu->seq_id, domain->iommu_bmp)) { |
1657 | domain->iommu_count++; | 1663 | domain->iommu_count++; |
1658 | if (domain->iommu_count == 1) | 1664 | if (domain->iommu_count == 1) |
1659 | domain->nid = iommu->node; | 1665 | domain->nid = iommu->node; |
@@ -2369,18 +2375,18 @@ static int __init iommu_prepare_static_identity_mapping(int hw) | |||
2369 | return -EFAULT; | 2375 | return -EFAULT; |
2370 | 2376 | ||
2371 | for_each_pci_dev(pdev) { | 2377 | for_each_pci_dev(pdev) { |
2372 | /* Skip Host/PCI Bridge devices */ | ||
2373 | if (IS_BRIDGE_HOST_DEVICE(pdev)) | ||
2374 | continue; | ||
2375 | if (iommu_should_identity_map(pdev, 1)) { | 2378 | if (iommu_should_identity_map(pdev, 1)) { |
2376 | printk(KERN_INFO "IOMMU: %s identity mapping for device %s\n", | ||
2377 | hw ? "hardware" : "software", pci_name(pdev)); | ||
2378 | |||
2379 | ret = domain_add_dev_info(si_domain, pdev, | 2379 | ret = domain_add_dev_info(si_domain, pdev, |
2380 | hw ? CONTEXT_TT_PASS_THROUGH : | 2380 | hw ? CONTEXT_TT_PASS_THROUGH : |
2381 | CONTEXT_TT_MULTI_LEVEL); | 2381 | CONTEXT_TT_MULTI_LEVEL); |
2382 | if (ret) | 2382 | if (ret) { |
2383 | /* device not associated with an iommu */ | ||
2384 | if (ret == -ENODEV) | ||
2385 | continue; | ||
2383 | return ret; | 2386 | return ret; |
2387 | } | ||
2388 | pr_info("IOMMU: %s identity mapping for device %s\n", | ||
2389 | hw ? "hardware" : "software", pci_name(pdev)); | ||
2384 | } | 2390 | } |
2385 | } | 2391 | } |
2386 | 2392 | ||
@@ -2402,12 +2408,17 @@ static int __init init_dmars(void) | |||
2402 | * endfor | 2408 | * endfor |
2403 | */ | 2409 | */ |
2404 | for_each_drhd_unit(drhd) { | 2410 | for_each_drhd_unit(drhd) { |
2405 | g_num_of_iommus++; | ||
2406 | /* | 2411 | /* |
2407 | * lock not needed as this is only incremented in the single | 2412 | * lock not needed as this is only incremented in the single |
2408 | * threaded kernel __init code path all other access are read | 2413 | * threaded kernel __init code path all other access are read |
2409 | * only | 2414 | * only |
2410 | */ | 2415 | */ |
2416 | if (g_num_of_iommus < IOMMU_UNITS_SUPPORTED) { | ||
2417 | g_num_of_iommus++; | ||
2418 | continue; | ||
2419 | } | ||
2420 | printk_once(KERN_ERR "intel-iommu: exceeded %d IOMMUs\n", | ||
2421 | IOMMU_UNITS_SUPPORTED); | ||
2411 | } | 2422 | } |
2412 | 2423 | ||
2413 | g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *), | 2424 | g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *), |
@@ -3748,7 +3759,7 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain, | |||
3748 | if (found == 0) { | 3759 | if (found == 0) { |
3749 | unsigned long tmp_flags; | 3760 | unsigned long tmp_flags; |
3750 | spin_lock_irqsave(&domain->iommu_lock, tmp_flags); | 3761 | spin_lock_irqsave(&domain->iommu_lock, tmp_flags); |
3751 | clear_bit(iommu->seq_id, &domain->iommu_bmp); | 3762 | clear_bit(iommu->seq_id, domain->iommu_bmp); |
3752 | domain->iommu_count--; | 3763 | domain->iommu_count--; |
3753 | domain_update_iommu_cap(domain); | 3764 | domain_update_iommu_cap(domain); |
3754 | spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags); | 3765 | spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags); |
@@ -3790,7 +3801,7 @@ static void vm_domain_remove_all_dev_info(struct dmar_domain *domain) | |||
3790 | */ | 3801 | */ |
3791 | spin_lock_irqsave(&domain->iommu_lock, flags2); | 3802 | spin_lock_irqsave(&domain->iommu_lock, flags2); |
3792 | if (test_and_clear_bit(iommu->seq_id, | 3803 | if (test_and_clear_bit(iommu->seq_id, |
3793 | &domain->iommu_bmp)) { | 3804 | domain->iommu_bmp)) { |
3794 | domain->iommu_count--; | 3805 | domain->iommu_count--; |
3795 | domain_update_iommu_cap(domain); | 3806 | domain_update_iommu_cap(domain); |
3796 | } | 3807 | } |
@@ -3815,7 +3826,7 @@ static struct dmar_domain *iommu_alloc_vm_domain(void) | |||
3815 | 3826 | ||
3816 | domain->id = vm_domid++; | 3827 | domain->id = vm_domid++; |
3817 | domain->nid = -1; | 3828 | domain->nid = -1; |
3818 | memset(&domain->iommu_bmp, 0, sizeof(unsigned long)); | 3829 | memset(domain->iommu_bmp, 0, sizeof(domain->iommu_bmp)); |
3819 | domain->flags = DOMAIN_FLAG_VIRTUAL_MACHINE; | 3830 | domain->flags = DOMAIN_FLAG_VIRTUAL_MACHINE; |
3820 | 3831 | ||
3821 | return domain; | 3832 | return domain; |
diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c index 288da5c1499d..103dbd92e256 100644 --- a/drivers/iommu/omap-iommu-debug.c +++ b/drivers/iommu/omap-iommu-debug.c | |||
@@ -44,7 +44,8 @@ static ssize_t debug_read_ver(struct file *file, char __user *userbuf, | |||
44 | static ssize_t debug_read_regs(struct file *file, char __user *userbuf, | 44 | static ssize_t debug_read_regs(struct file *file, char __user *userbuf, |
45 | size_t count, loff_t *ppos) | 45 | size_t count, loff_t *ppos) |
46 | { | 46 | { |
47 | struct omap_iommu *obj = file->private_data; | 47 | struct device *dev = file->private_data; |
48 | struct omap_iommu *obj = dev_to_omap_iommu(dev); | ||
48 | char *p, *buf; | 49 | char *p, *buf; |
49 | ssize_t bytes; | 50 | ssize_t bytes; |
50 | 51 | ||
@@ -67,7 +68,8 @@ static ssize_t debug_read_regs(struct file *file, char __user *userbuf, | |||
67 | static ssize_t debug_read_tlb(struct file *file, char __user *userbuf, | 68 | static ssize_t debug_read_tlb(struct file *file, char __user *userbuf, |
68 | size_t count, loff_t *ppos) | 69 | size_t count, loff_t *ppos) |
69 | { | 70 | { |
70 | struct omap_iommu *obj = file->private_data; | 71 | struct device *dev = file->private_data; |
72 | struct omap_iommu *obj = dev_to_omap_iommu(dev); | ||
71 | char *p, *buf; | 73 | char *p, *buf; |
72 | ssize_t bytes, rest; | 74 | ssize_t bytes, rest; |
73 | 75 | ||
@@ -97,7 +99,8 @@ static ssize_t debug_write_pagetable(struct file *file, | |||
97 | struct iotlb_entry e; | 99 | struct iotlb_entry e; |
98 | struct cr_regs cr; | 100 | struct cr_regs cr; |
99 | int err; | 101 | int err; |
100 | struct omap_iommu *obj = file->private_data; | 102 | struct device *dev = file->private_data; |
103 | struct omap_iommu *obj = dev_to_omap_iommu(dev); | ||
101 | char buf[MAXCOLUMN], *p = buf; | 104 | char buf[MAXCOLUMN], *p = buf; |
102 | 105 | ||
103 | count = min(count, sizeof(buf)); | 106 | count = min(count, sizeof(buf)); |
@@ -184,7 +187,8 @@ out: | |||
184 | static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf, | 187 | static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf, |
185 | size_t count, loff_t *ppos) | 188 | size_t count, loff_t *ppos) |
186 | { | 189 | { |
187 | struct omap_iommu *obj = file->private_data; | 190 | struct device *dev = file->private_data; |
191 | struct omap_iommu *obj = dev_to_omap_iommu(dev); | ||
188 | char *p, *buf; | 192 | char *p, *buf; |
189 | size_t bytes; | 193 | size_t bytes; |
190 | 194 | ||
@@ -212,7 +216,8 @@ static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf, | |||
212 | static ssize_t debug_read_mmap(struct file *file, char __user *userbuf, | 216 | static ssize_t debug_read_mmap(struct file *file, char __user *userbuf, |
213 | size_t count, loff_t *ppos) | 217 | size_t count, loff_t *ppos) |
214 | { | 218 | { |
215 | struct omap_iommu *obj = file->private_data; | 219 | struct device *dev = file->private_data; |
220 | struct omap_iommu *obj = dev_to_omap_iommu(dev); | ||
216 | char *p, *buf; | 221 | char *p, *buf; |
217 | struct iovm_struct *tmp; | 222 | struct iovm_struct *tmp; |
218 | int uninitialized_var(i); | 223 | int uninitialized_var(i); |
@@ -254,7 +259,7 @@ static ssize_t debug_read_mmap(struct file *file, char __user *userbuf, | |||
254 | static ssize_t debug_read_mem(struct file *file, char __user *userbuf, | 259 | static ssize_t debug_read_mem(struct file *file, char __user *userbuf, |
255 | size_t count, loff_t *ppos) | 260 | size_t count, loff_t *ppos) |
256 | { | 261 | { |
257 | struct omap_iommu *obj = file->private_data; | 262 | struct device *dev = file->private_data; |
258 | char *p, *buf; | 263 | char *p, *buf; |
259 | struct iovm_struct *area; | 264 | struct iovm_struct *area; |
260 | ssize_t bytes; | 265 | ssize_t bytes; |
@@ -268,8 +273,8 @@ static ssize_t debug_read_mem(struct file *file, char __user *userbuf, | |||
268 | 273 | ||
269 | mutex_lock(&iommu_debug_lock); | 274 | mutex_lock(&iommu_debug_lock); |
270 | 275 | ||
271 | area = omap_find_iovm_area(obj, (u32)ppos); | 276 | area = omap_find_iovm_area(dev, (u32)ppos); |
272 | if (IS_ERR(area)) { | 277 | if (!area) { |
273 | bytes = -EINVAL; | 278 | bytes = -EINVAL; |
274 | goto err_out; | 279 | goto err_out; |
275 | } | 280 | } |
@@ -287,7 +292,7 @@ err_out: | |||
287 | static ssize_t debug_write_mem(struct file *file, const char __user *userbuf, | 292 | static ssize_t debug_write_mem(struct file *file, const char __user *userbuf, |
288 | size_t count, loff_t *ppos) | 293 | size_t count, loff_t *ppos) |
289 | { | 294 | { |
290 | struct omap_iommu *obj = file->private_data; | 295 | struct device *dev = file->private_data; |
291 | struct iovm_struct *area; | 296 | struct iovm_struct *area; |
292 | char *p, *buf; | 297 | char *p, *buf; |
293 | 298 | ||
@@ -305,8 +310,8 @@ static ssize_t debug_write_mem(struct file *file, const char __user *userbuf, | |||
305 | goto err_out; | 310 | goto err_out; |
306 | } | 311 | } |
307 | 312 | ||
308 | area = omap_find_iovm_area(obj, (u32)ppos); | 313 | area = omap_find_iovm_area(dev, (u32)ppos); |
309 | if (IS_ERR(area)) { | 314 | if (!area) { |
310 | count = -EINVAL; | 315 | count = -EINVAL; |
311 | goto err_out; | 316 | goto err_out; |
312 | } | 317 | } |
@@ -350,7 +355,7 @@ DEBUG_FOPS(mem); | |||
350 | { \ | 355 | { \ |
351 | struct dentry *dent; \ | 356 | struct dentry *dent; \ |
352 | dent = debugfs_create_file(#attr, mode, parent, \ | 357 | dent = debugfs_create_file(#attr, mode, parent, \ |
353 | obj, &debug_##attr##_fops); \ | 358 | dev, &debug_##attr##_fops); \ |
354 | if (!dent) \ | 359 | if (!dent) \ |
355 | return -ENOMEM; \ | 360 | return -ENOMEM; \ |
356 | } | 361 | } |
@@ -362,20 +367,29 @@ static int iommu_debug_register(struct device *dev, void *data) | |||
362 | { | 367 | { |
363 | struct platform_device *pdev = to_platform_device(dev); | 368 | struct platform_device *pdev = to_platform_device(dev); |
364 | struct omap_iommu *obj = platform_get_drvdata(pdev); | 369 | struct omap_iommu *obj = platform_get_drvdata(pdev); |
370 | struct omap_iommu_arch_data *arch_data; | ||
365 | struct dentry *d, *parent; | 371 | struct dentry *d, *parent; |
366 | 372 | ||
367 | if (!obj || !obj->dev) | 373 | if (!obj || !obj->dev) |
368 | return -EINVAL; | 374 | return -EINVAL; |
369 | 375 | ||
376 | arch_data = kzalloc(sizeof(*arch_data), GFP_KERNEL); | ||
377 | if (!arch_data) | ||
378 | return -ENOMEM; | ||
379 | |||
380 | arch_data->iommu_dev = obj; | ||
381 | |||
382 | dev->archdata.iommu = arch_data; | ||
383 | |||
370 | d = debugfs_create_dir(obj->name, iommu_debug_root); | 384 | d = debugfs_create_dir(obj->name, iommu_debug_root); |
371 | if (!d) | 385 | if (!d) |
372 | return -ENOMEM; | 386 | goto nomem; |
373 | parent = d; | 387 | parent = d; |
374 | 388 | ||
375 | d = debugfs_create_u8("nr_tlb_entries", 400, parent, | 389 | d = debugfs_create_u8("nr_tlb_entries", 400, parent, |
376 | (u8 *)&obj->nr_tlb_entries); | 390 | (u8 *)&obj->nr_tlb_entries); |
377 | if (!d) | 391 | if (!d) |
378 | return -ENOMEM; | 392 | goto nomem; |
379 | 393 | ||
380 | DEBUG_ADD_FILE_RO(ver); | 394 | DEBUG_ADD_FILE_RO(ver); |
381 | DEBUG_ADD_FILE_RO(regs); | 395 | DEBUG_ADD_FILE_RO(regs); |
@@ -385,6 +399,22 @@ static int iommu_debug_register(struct device *dev, void *data) | |||
385 | DEBUG_ADD_FILE(mem); | 399 | DEBUG_ADD_FILE(mem); |
386 | 400 | ||
387 | return 0; | 401 | return 0; |
402 | |||
403 | nomem: | ||
404 | kfree(arch_data); | ||
405 | return -ENOMEM; | ||
406 | } | ||
407 | |||
408 | static int iommu_debug_unregister(struct device *dev, void *data) | ||
409 | { | ||
410 | if (!dev->archdata.iommu) | ||
411 | return 0; | ||
412 | |||
413 | kfree(dev->archdata.iommu); | ||
414 | |||
415 | dev->archdata.iommu = NULL; | ||
416 | |||
417 | return 0; | ||
388 | } | 418 | } |
389 | 419 | ||
390 | static int __init iommu_debug_init(void) | 420 | static int __init iommu_debug_init(void) |
@@ -411,6 +441,7 @@ module_init(iommu_debug_init) | |||
411 | static void __exit iommu_debugfs_exit(void) | 441 | static void __exit iommu_debugfs_exit(void) |
412 | { | 442 | { |
413 | debugfs_remove_recursive(iommu_debug_root); | 443 | debugfs_remove_recursive(iommu_debug_root); |
444 | omap_foreach_iommu_device(NULL, iommu_debug_unregister); | ||
414 | } | 445 | } |
415 | module_exit(iommu_debugfs_exit) | 446 | module_exit(iommu_debugfs_exit) |
416 | 447 | ||
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index d8edd979d01b..6899dcd02dfa 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c | |||
@@ -1223,7 +1223,8 @@ static int __init omap_iommu_init(void) | |||
1223 | 1223 | ||
1224 | return platform_driver_register(&omap_iommu_driver); | 1224 | return platform_driver_register(&omap_iommu_driver); |
1225 | } | 1225 | } |
1226 | module_init(omap_iommu_init); | 1226 | /* must be ready before omap3isp is probed */ |
1227 | subsys_initcall(omap_iommu_init); | ||
1227 | 1228 | ||
1228 | static void __exit omap_iommu_exit(void) | 1229 | static void __exit omap_iommu_exit(void) |
1229 | { | 1230 | { |