@@ -875,6 +875,16 @@ void iommu_put(struct iommu *obj)
}
EXPORT_SYMBOL_GPL(iommu_put);
+static u32 kmemleak_special_conv(u32 orig)
+{
+ u32 *iopgd = (u32 *)orig;
+
+ if (!iopgd_is_table(*iopgd))
+ return NULL;
+
+ return iopgd_page_vaddr(iopgd);
+}
+
/*
* OMAP Device MMU(IOMMU) detection
*/
@@ -948,6 +958,10 @@ static int __devinit omap_iommu_probe(struct platform_device *pdev)
BUG_ON(!IS_ALIGNED((unsigned long)obj->iopgd, IOPGD_TABLE_SIZE));
+ err = kmemleak_special_scan(p, IOPGD_TABLE_SIZE, kmemleak_special_conv);
+ if (err)
+ dev_warn(&pdev->dev, "kmemleak: failed to add special scan\n");
+
dev_info(&pdev->dev, "%s registered\n", obj->name);
return 0;
@@ -972,6 +986,7 @@ static int __devexit omap_iommu_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
iopgtable_clear_entry_all(obj);
+ kmemleak_no_special(obj->iopgd);
free_pages((unsigned long)obj->iopgd, get_order(IOPGD_TABLE_SIZE));
irq = platform_get_irq(pdev, 0);