public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v8 09/12] iommu/exynos: remove custom fault handler
@ 2013-07-26 11:29 Cho KyongHo
  2013-07-26 17:22 ` Grant Grundler
  0 siblings, 1 reply; 2+ messages in thread
From: Cho KyongHo @ 2013-07-26 11:29 UTC (permalink / raw)
  To: 'Linux ARM Kernel', 'Linux IOMMU',
	'Linux Kernel', 'Linux Samsung SOC'
  Cc: 'Hyunwoong Kim', 'Joerg Roedel',
	'Kukjin Kim', 'Prathyush', 'Rahul Sharma',
	'Subash Patel', 'Keyyoung Park',
	'Grant Grundler', 'Antonios Motakis', kvmarm,
	'Sachin Kamat'

This commit removes custom fault handler. The device drivers that
need to register fault handler can register
with iommu_set_fault_handler().

Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
---
 drivers/iommu/exynos-iommu.c |   71 ++++++++++--------------------------------
 1 files changed, 17 insertions(+), 54 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 87f6bb7..f9853fe 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -131,16 +131,6 @@ enum exynos_sysmmu_inttype {
 	SYSMMU_FAULTS_NUM
 };
 
-/*
- * @itype: type of fault.
- * @pgtable_base: the physical address of page table base. This is 0 if @itype
- *                is SYSMMU_BUSERROR.
- * @fault_addr: the device (virtual) address that the System MMU tried to
- *             translated. This is 0 if @itype is SYSMMU_BUSERROR.
- */
-typedef int (*sysmmu_fault_handler_t)(enum exynos_sysmmu_inttype itype,
-			unsigned long pgtable_base, unsigned long fault_addr);
-
 static unsigned short fault_reg_offset[SYSMMU_FAULTS_NUM] = {
 	REG_PAGE_FAULT_ADDR,
 	REG_AR_FAULT_ADDR,
@@ -181,7 +171,6 @@ struct sysmmu_drvdata {
 	int activations;
 	rwlock_t lock;
 	struct iommu_domain *domain;
-	sysmmu_fault_handler_t fault_handler;
 	unsigned long pgtable;
 	void __iomem *sfrbases[0];
 };
@@ -313,34 +302,17 @@ finish:
 	read_unlock_irqrestore(&data->lock, flags);
 }
 
-static void __set_fault_handler(struct sysmmu_drvdata *data,
-					sysmmu_fault_handler_t handler)
-{
-	unsigned long flags;
-
-	write_lock_irqsave(&data->lock, flags);
-	data->fault_handler = handler;
-	write_unlock_irqrestore(&data->lock, flags);
-}
-
-void exynos_sysmmu_set_fault_handler(struct device *dev,
-					sysmmu_fault_handler_t handler)
-{
-	struct sysmmu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
-
-	__set_fault_handler(data, handler);
-}
-
-static int default_fault_handler(enum exynos_sysmmu_inttype itype,
-		     unsigned long pgtable_base, unsigned long fault_addr)
+static void show_fault_information(const char *name,
+		enum exynos_sysmmu_inttype itype,
+		unsigned long pgtable_base, unsigned long fault_addr)
 {
 	unsigned long *ent;
 
 	if ((itype >= SYSMMU_FAULTS_NUM) || (itype < SYSMMU_PAGEFAULT))
 		itype = SYSMMU_FAULT_UNKNOWN;
 
-	pr_err("%s occurred at 0x%lx(Page table base: 0x%lx)\n",
-			sysmmu_fault_name[itype], fault_addr, pgtable_base);
+	pr_err("%s occurred at 0x%lx by %s(Page table base: 0x%lx)\n",
+		sysmmu_fault_name[itype], fault_addr, name, pgtable_base);
 
 	ent = section_entry(__va(pgtable_base), fault_addr);
 	pr_err("\tLv1 entry: 0x%lx\n", *ent);
@@ -353,16 +325,12 @@ static int default_fault_handler(enum exynos_sysmmu_inttype itype,
 	pr_err("Generating Kernel OOPS... because it is unrecoverable.\n");
 
 	BUG();
-
-	return 0;
 }
 
 static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
 {
 	/* SYSMMU is in blocked when interrupt occurred. */
 	struct sysmmu_drvdata *data = dev_id;
-	struct resource *irqres;
-	struct platform_device *pdev;
 	enum exynos_sysmmu_inttype itype;
 	unsigned long addr = -1;
 
@@ -372,14 +340,15 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
 
 	WARN_ON(!is_sysmmu_active(data));
 
-	pdev = to_platform_device(data->sysmmu);
-	for (i = 0; i < (pdev->num_resources / 2); i++) {
-		irqres = platform_get_resource(pdev, IORESOURCE_IRQ, i);
+	for (i = 0; i < data->nsfrs; i++) {
+		struct resource *irqres;
+		irqres = platform_get_resource(to_platform_device(data->sysmmu),
+						IORESOURCE_IRQ, i);
 		if (irqres && ((int)irqres->start == irq))
 			break;
 	}
 
-	if (i == pdev->num_resources) {
+	if (i == data->nsfrs) {
 		itype = SYSMMU_FAULT_UNKNOWN;
 	} else {
 		itype = (enum exynos_sysmmu_inttype)
@@ -395,19 +364,15 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
 		ret = report_iommu_fault(data->domain, data->dev,
 				addr, itype);
 
-	if ((ret == -ENOSYS) && data->fault_handler) {
-		unsigned long base = data->pgtable;
-		if (itype != SYSMMU_FAULT_UNKNOWN)
-			base = __raw_readl(
-					data->sfrbases[i] + REG_PT_BASE_ADDR);
-		ret = data->fault_handler(itype, base, addr);
-	}
-
 	if (!ret && (itype != SYSMMU_FAULT_UNKNOWN))
 		__raw_writel(1 << itype, data->sfrbases[i] + REG_INT_CLEAR);
-	else
-		dev_dbg(data->sysmmu, "%s is not handled.\n",
-				sysmmu_fault_name[itype]);
+	else {
+		unsigned long ba = data->pgtable;
+		if (itype != SYSMMU_FAULT_UNKNOWN)
+			ba = __raw_readl(data->sfrbases[i] + REG_PT_BASE_ADDR);
+		show_fault_information(dev_name(data->sysmmu),
+					itype, ba, addr);
+	}
 
 	if (itype != SYSMMU_FAULT_UNKNOWN)
 		sysmmu_unblock(data->sfrbases[i]);
@@ -644,8 +609,6 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
 
 	pm_runtime_enable(dev);
 
-	__set_fault_handler(data, &default_fault_handler);
-
 	data->sysmmu = dev;
 	data->clk = devm_clk_get(dev, "sysmmu");
 	if (IS_ERR(data->clk)) {
-- 
1.7.2.5



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH v8 09/12] iommu/exynos: remove custom fault handler
  2013-07-26 11:29 [PATCH v8 09/12] iommu/exynos: remove custom fault handler Cho KyongHo
@ 2013-07-26 17:22 ` Grant Grundler
  0 siblings, 0 replies; 2+ messages in thread
From: Grant Grundler @ 2013-07-26 17:22 UTC (permalink / raw)
  To: Cho KyongHo
  Cc: Linux ARM Kernel, Linux IOMMU, Linux Kernel, Linux Samsung SOC,
	Hyunwoong Kim, Joerg Roedel, Kukjin Kim, Prathyush, Rahul Sharma,
	Subash Patel, Keyyoung Park, Grant Grundler, Antonios Motakis,
	kvmarm, Sachin Kamat

On Fri, Jul 26, 2013 at 4:29 AM, Cho KyongHo <pullip.cho@samsung.com> wrote:
> This commit removes custom fault handler. The device drivers that
> need to register fault handler can register
> with iommu_set_fault_handler().
>
> Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>


Reviewed-by: Grant Grundler <grundler@chromium.org>

cheers
grant

> ---
>  drivers/iommu/exynos-iommu.c |   71 ++++++++++--------------------------------
>  1 files changed, 17 insertions(+), 54 deletions(-)
>
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index 87f6bb7..f9853fe 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -131,16 +131,6 @@ enum exynos_sysmmu_inttype {
>         SYSMMU_FAULTS_NUM
>  };
>
> -/*
> - * @itype: type of fault.
> - * @pgtable_base: the physical address of page table base. This is 0 if @itype
> - *                is SYSMMU_BUSERROR.
> - * @fault_addr: the device (virtual) address that the System MMU tried to
> - *             translated. This is 0 if @itype is SYSMMU_BUSERROR.
> - */
> -typedef int (*sysmmu_fault_handler_t)(enum exynos_sysmmu_inttype itype,
> -                       unsigned long pgtable_base, unsigned long fault_addr);
> -
>  static unsigned short fault_reg_offset[SYSMMU_FAULTS_NUM] = {
>         REG_PAGE_FAULT_ADDR,
>         REG_AR_FAULT_ADDR,
> @@ -181,7 +171,6 @@ struct sysmmu_drvdata {
>         int activations;
>         rwlock_t lock;
>         struct iommu_domain *domain;
> -       sysmmu_fault_handler_t fault_handler;
>         unsigned long pgtable;
>         void __iomem *sfrbases[0];
>  };
> @@ -313,34 +302,17 @@ finish:
>         read_unlock_irqrestore(&data->lock, flags);
>  }
>
> -static void __set_fault_handler(struct sysmmu_drvdata *data,
> -                                       sysmmu_fault_handler_t handler)
> -{
> -       unsigned long flags;
> -
> -       write_lock_irqsave(&data->lock, flags);
> -       data->fault_handler = handler;
> -       write_unlock_irqrestore(&data->lock, flags);
> -}
> -
> -void exynos_sysmmu_set_fault_handler(struct device *dev,
> -                                       sysmmu_fault_handler_t handler)
> -{
> -       struct sysmmu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
> -
> -       __set_fault_handler(data, handler);
> -}
> -
> -static int default_fault_handler(enum exynos_sysmmu_inttype itype,
> -                    unsigned long pgtable_base, unsigned long fault_addr)
> +static void show_fault_information(const char *name,
> +               enum exynos_sysmmu_inttype itype,
> +               unsigned long pgtable_base, unsigned long fault_addr)
>  {
>         unsigned long *ent;
>
>         if ((itype >= SYSMMU_FAULTS_NUM) || (itype < SYSMMU_PAGEFAULT))
>                 itype = SYSMMU_FAULT_UNKNOWN;
>
> -       pr_err("%s occurred at 0x%lx(Page table base: 0x%lx)\n",
> -                       sysmmu_fault_name[itype], fault_addr, pgtable_base);
> +       pr_err("%s occurred at 0x%lx by %s(Page table base: 0x%lx)\n",
> +               sysmmu_fault_name[itype], fault_addr, name, pgtable_base);
>
>         ent = section_entry(__va(pgtable_base), fault_addr);
>         pr_err("\tLv1 entry: 0x%lx\n", *ent);
> @@ -353,16 +325,12 @@ static int default_fault_handler(enum exynos_sysmmu_inttype itype,
>         pr_err("Generating Kernel OOPS... because it is unrecoverable.\n");
>
>         BUG();
> -
> -       return 0;
>  }
>
>  static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
>  {
>         /* SYSMMU is in blocked when interrupt occurred. */
>         struct sysmmu_drvdata *data = dev_id;
> -       struct resource *irqres;
> -       struct platform_device *pdev;
>         enum exynos_sysmmu_inttype itype;
>         unsigned long addr = -1;
>
> @@ -372,14 +340,15 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
>
>         WARN_ON(!is_sysmmu_active(data));
>
> -       pdev = to_platform_device(data->sysmmu);
> -       for (i = 0; i < (pdev->num_resources / 2); i++) {
> -               irqres = platform_get_resource(pdev, IORESOURCE_IRQ, i);
> +       for (i = 0; i < data->nsfrs; i++) {
> +               struct resource *irqres;
> +               irqres = platform_get_resource(to_platform_device(data->sysmmu),
> +                                               IORESOURCE_IRQ, i);
>                 if (irqres && ((int)irqres->start == irq))
>                         break;
>         }
>
> -       if (i == pdev->num_resources) {
> +       if (i == data->nsfrs) {
>                 itype = SYSMMU_FAULT_UNKNOWN;
>         } else {
>                 itype = (enum exynos_sysmmu_inttype)
> @@ -395,19 +364,15 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
>                 ret = report_iommu_fault(data->domain, data->dev,
>                                 addr, itype);
>
> -       if ((ret == -ENOSYS) && data->fault_handler) {
> -               unsigned long base = data->pgtable;
> -               if (itype != SYSMMU_FAULT_UNKNOWN)
> -                       base = __raw_readl(
> -                                       data->sfrbases[i] + REG_PT_BASE_ADDR);
> -               ret = data->fault_handler(itype, base, addr);
> -       }
> -
>         if (!ret && (itype != SYSMMU_FAULT_UNKNOWN))
>                 __raw_writel(1 << itype, data->sfrbases[i] + REG_INT_CLEAR);
> -       else
> -               dev_dbg(data->sysmmu, "%s is not handled.\n",
> -                               sysmmu_fault_name[itype]);
> +       else {
> +               unsigned long ba = data->pgtable;
> +               if (itype != SYSMMU_FAULT_UNKNOWN)
> +                       ba = __raw_readl(data->sfrbases[i] + REG_PT_BASE_ADDR);
> +               show_fault_information(dev_name(data->sysmmu),
> +                                       itype, ba, addr);
> +       }
>
>         if (itype != SYSMMU_FAULT_UNKNOWN)
>                 sysmmu_unblock(data->sfrbases[i]);
> @@ -644,8 +609,6 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
>
>         pm_runtime_enable(dev);
>
> -       __set_fault_handler(data, &default_fault_handler);
> -
>         data->sysmmu = dev;
>         data->clk = devm_clk_get(dev, "sysmmu");
>         if (IS_ERR(data->clk)) {
> --
> 1.7.2.5
>
>

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2013-07-26 17:22 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-26 11:29 [PATCH v8 09/12] iommu/exynos: remove custom fault handler Cho KyongHo
2013-07-26 17:22 ` Grant Grundler

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox