aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu
diff options
context:
space:
mode:
authorCho KyongHo <pullip.cho@samsung.com>2014-05-12 02:14:56 -0400
committerJoerg Roedel <jroedel@suse.de>2014-05-13 13:12:55 -0400
commit1fab7fa7230fa0422ca81cea7d1bfbf3f9b0d3f9 (patch)
tree3f98e9a9edfb3751fc55d20782c6600e9b8232ff /drivers/iommu
parent7060587052e0370ea1b7a41c84d5ad364be16f51 (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.c80
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 */
135typedef int (*sysmmu_fault_handler_t)(enum exynos_sysmmu_inttype itype,
136 phys_addr_t pgtable_base, unsigned long fault_addr);
137
138static unsigned short fault_reg_offset[SYSMMU_FAULTS_NUM] = { 128static 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
248static void __set_fault_handler(struct sysmmu_drvdata *data, 237static 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
258void 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
266static 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
292static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id) 258static 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);