diff options
author | Cho KyongHo <pullip.cho@samsung.com> | 2014-05-12 02:14:56 -0400 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2014-05-13 13:12:55 -0400 |
commit | 1fab7fa7230fa0422ca81cea7d1bfbf3f9b0d3f9 (patch) | |
tree | 3f98e9a9edfb3751fc55d20782c6600e9b8232ff /drivers/iommu | |
parent | 7060587052e0370ea1b7a41c84d5ad364be16f51 (diff) |
iommu/exynos: Remove custom fault handler
This commit removes custom fault handler. The device drivers that
need to register fault handler can register
with iommu_set_fault_handler().
CC: Grant Grundler <grundler@chromium.org>
Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
Signed-off-by: Shaik Ameer Basha <shaik.ameer@samsung.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu')
-rw-r--r-- | drivers/iommu/exynos-iommu.c | 80 |
1 files changed, 24 insertions, 56 deletions
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 5af5c5c16f49..c1be65fd0af5 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c | |||
@@ -125,16 +125,6 @@ enum exynos_sysmmu_inttype { | |||
125 | SYSMMU_FAULTS_NUM | 125 | SYSMMU_FAULTS_NUM |
126 | }; | 126 | }; |
127 | 127 | ||
128 | /* | ||
129 | * @itype: type of fault. | ||
130 | * @pgtable_base: the physical address of page table base. This is 0 if @itype | ||
131 | * is SYSMMU_BUSERROR. | ||
132 | * @fault_addr: the device (virtual) address that the System MMU tried to | ||
133 | * translated. This is 0 if @itype is SYSMMU_BUSERROR. | ||
134 | */ | ||
135 | typedef int (*sysmmu_fault_handler_t)(enum exynos_sysmmu_inttype itype, | ||
136 | phys_addr_t pgtable_base, unsigned long fault_addr); | ||
137 | |||
138 | static unsigned short fault_reg_offset[SYSMMU_FAULTS_NUM] = { | 128 | static unsigned short fault_reg_offset[SYSMMU_FAULTS_NUM] = { |
139 | REG_PAGE_FAULT_ADDR, | 129 | REG_PAGE_FAULT_ADDR, |
140 | REG_AR_FAULT_ADDR, | 130 | REG_AR_FAULT_ADDR, |
@@ -176,7 +166,6 @@ struct sysmmu_drvdata { | |||
176 | int activations; | 166 | int activations; |
177 | rwlock_t lock; | 167 | rwlock_t lock; |
178 | struct iommu_domain *domain; | 168 | struct iommu_domain *domain; |
179 | sysmmu_fault_handler_t fault_handler; | ||
180 | phys_addr_t pgtable; | 169 | phys_addr_t pgtable; |
181 | }; | 170 | }; |
182 | 171 | ||
@@ -245,34 +234,17 @@ static void __sysmmu_set_ptbase(void __iomem *sfrbase, | |||
245 | __sysmmu_tlb_invalidate(sfrbase); | 234 | __sysmmu_tlb_invalidate(sfrbase); |
246 | } | 235 | } |
247 | 236 | ||
248 | static void __set_fault_handler(struct sysmmu_drvdata *data, | 237 | static void show_fault_information(const char *name, |
249 | sysmmu_fault_handler_t handler) | 238 | enum exynos_sysmmu_inttype itype, |
250 | { | 239 | phys_addr_t pgtable_base, unsigned long fault_addr) |
251 | unsigned long flags; | ||
252 | |||
253 | write_lock_irqsave(&data->lock, flags); | ||
254 | data->fault_handler = handler; | ||
255 | write_unlock_irqrestore(&data->lock, flags); | ||
256 | } | ||
257 | |||
258 | void exynos_sysmmu_set_fault_handler(struct device *dev, | ||
259 | sysmmu_fault_handler_t handler) | ||
260 | { | ||
261 | struct sysmmu_drvdata *data = dev_get_drvdata(dev->archdata.iommu); | ||
262 | |||
263 | __set_fault_handler(data, handler); | ||
264 | } | ||
265 | |||
266 | static int default_fault_handler(enum exynos_sysmmu_inttype itype, | ||
267 | phys_addr_t pgtable_base, unsigned long fault_addr) | ||
268 | { | 240 | { |
269 | unsigned long *ent; | 241 | unsigned long *ent; |
270 | 242 | ||
271 | if ((itype >= SYSMMU_FAULTS_NUM) || (itype < SYSMMU_PAGEFAULT)) | 243 | if ((itype >= SYSMMU_FAULTS_NUM) || (itype < SYSMMU_PAGEFAULT)) |
272 | itype = SYSMMU_FAULT_UNKNOWN; | 244 | itype = SYSMMU_FAULT_UNKNOWN; |
273 | 245 | ||
274 | pr_err("%s occurred at 0x%lx(Page table base: %pa)\n", | 246 | pr_err("%s occurred at %#lx by %s(Page table base: %pa)\n", |
275 | sysmmu_fault_name[itype], fault_addr, &pgtable_base); | 247 | sysmmu_fault_name[itype], fault_addr, name, &pgtable_base); |
276 | 248 | ||
277 | ent = section_entry(phys_to_virt(pgtable_base), fault_addr); | 249 | ent = section_entry(phys_to_virt(pgtable_base), fault_addr); |
278 | pr_err("\tLv1 entry: 0x%lx\n", *ent); | 250 | pr_err("\tLv1 entry: 0x%lx\n", *ent); |
@@ -281,12 +253,6 @@ static int default_fault_handler(enum exynos_sysmmu_inttype itype, | |||
281 | ent = page_entry(ent, fault_addr); | 253 | ent = page_entry(ent, fault_addr); |
282 | pr_err("\t Lv2 entry: 0x%lx\n", *ent); | 254 | pr_err("\t Lv2 entry: 0x%lx\n", *ent); |
283 | } | 255 | } |
284 | |||
285 | pr_err("Generating Kernel OOPS... because it is unrecoverable.\n"); | ||
286 | |||
287 | BUG(); | ||
288 | |||
289 | return 0; | ||
290 | } | 256 | } |
291 | 257 | ||
292 | static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id) | 258 | static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id) |
@@ -310,24 +276,28 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id) | |||
310 | else | 276 | else |
311 | addr = __raw_readl(data->sfrbase + fault_reg_offset[itype]); | 277 | addr = __raw_readl(data->sfrbase + fault_reg_offset[itype]); |
312 | 278 | ||
313 | if (data->domain) | 279 | if (itype == SYSMMU_FAULT_UNKNOWN) { |
314 | ret = report_iommu_fault(data->domain, data->dev, addr, itype); | 280 | pr_err("%s: Fault is not occurred by System MMU '%s'!\n", |
315 | 281 | __func__, dev_name(data->sysmmu)); | |
316 | if ((ret == -ENOSYS) && data->fault_handler) { | 282 | pr_err("%s: Please check if IRQ is correctly configured.\n", |
317 | unsigned long base = data->pgtable; | 283 | __func__); |
318 | if (itype != SYSMMU_FAULT_UNKNOWN) | 284 | BUG(); |
319 | base = __raw_readl(data->sfrbase + REG_PT_BASE_ADDR); | 285 | } else { |
320 | ret = data->fault_handler(itype, base, addr); | 286 | unsigned long base = |
287 | __raw_readl(data->sfrbase + REG_PT_BASE_ADDR); | ||
288 | show_fault_information(dev_name(data->sysmmu), | ||
289 | itype, base, addr); | ||
290 | if (data->domain) | ||
291 | ret = report_iommu_fault(data->domain, | ||
292 | data->dev, addr, itype); | ||
321 | } | 293 | } |
322 | 294 | ||
323 | if (!ret && (itype != SYSMMU_FAULT_UNKNOWN)) | 295 | /* fault is not recovered by fault handler */ |
324 | __raw_writel(1 << itype, data->sfrbase + REG_INT_CLEAR); | 296 | BUG_ON(ret != 0); |
325 | else | ||
326 | dev_dbg(data->sysmmu, "%s is not handled.\n", | ||
327 | sysmmu_fault_name[itype]); | ||
328 | 297 | ||
329 | if (itype != SYSMMU_FAULT_UNKNOWN) | 298 | __raw_writel(1 << itype, data->sfrbase + REG_INT_CLEAR); |
330 | sysmmu_unblock(data->sfrbase); | 299 | |
300 | sysmmu_unblock(data->sfrbase); | ||
331 | 301 | ||
332 | if (!IS_ERR(data->clk_master)) | 302 | if (!IS_ERR(data->clk_master)) |
333 | clk_disable(data->clk_master); | 303 | clk_disable(data->clk_master); |
@@ -576,8 +546,6 @@ static int exynos_sysmmu_probe(struct platform_device *pdev) | |||
576 | rwlock_init(&data->lock); | 546 | rwlock_init(&data->lock); |
577 | INIT_LIST_HEAD(&data->node); | 547 | INIT_LIST_HEAD(&data->node); |
578 | 548 | ||
579 | __set_fault_handler(data, &default_fault_handler); | ||
580 | |||
581 | platform_set_drvdata(pdev, data); | 549 | platform_set_drvdata(pdev, data); |
582 | 550 | ||
583 | pm_runtime_enable(dev); | 551 | pm_runtime_enable(dev); |