aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Shiyan <shc_work@mail.ru>2016-06-19 02:55:53 -0400
committerShawn Guo <shawnguo@kernel.org>2016-06-21 03:57:05 -0400
commitd1e1c31ccd5a807a707c94386d5fa36d18600892 (patch)
treea60a9b3188157d495b235df3e356b52625c9b33f
parent4dbc39e98b57a7f67c739b04f12d9829fe659bfa (diff)
ARM: i.MX: Fix FIQ interrupt handling for TZIC
IRQ number should be translated from VIRQ to HWIRQ for TZIC. As a solution for this issue, move existing translation code from AVIC to common place. Signed-off-by: Alexander Shiyan <shc_work@mail.ru> Signed-off-by: Shawn Guo <shawnguo@kernel.org>
-rw-r--r--arch/arm/mach-imx/avic.c19
-rw-r--r--arch/arm/mach-imx/irq-common.c6
-rw-r--r--arch/arm/mach-imx/tzic.c6
3 files changed, 15 insertions, 16 deletions
diff --git a/arch/arm/mach-imx/avic.c b/arch/arm/mach-imx/avic.c
index 7fa176e792bd..1afccae0420c 100644
--- a/arch/arm/mach-imx/avic.c
+++ b/arch/arm/mach-imx/avic.c
@@ -55,23 +55,20 @@ static void __iomem *avic_base;
55static struct irq_domain *domain; 55static struct irq_domain *domain;
56 56
57#ifdef CONFIG_FIQ 57#ifdef CONFIG_FIQ
58static int avic_set_irq_fiq(unsigned int irq, unsigned int type) 58static int avic_set_irq_fiq(unsigned int hwirq, unsigned int type)
59{ 59{
60 struct irq_data *d = irq_get_irq_data(irq);
61 unsigned int irqt; 60 unsigned int irqt;
62 61
63 irq = d->hwirq; 62 if (hwirq >= AVIC_NUM_IRQS)
64
65 if (irq >= AVIC_NUM_IRQS)
66 return -EINVAL; 63 return -EINVAL;
67 64
68 if (irq < AVIC_NUM_IRQS / 2) { 65 if (hwirq < AVIC_NUM_IRQS / 2) {
69 irqt = imx_readl(avic_base + AVIC_INTTYPEL) & ~(1 << irq); 66 irqt = imx_readl(avic_base + AVIC_INTTYPEL) & ~(1 << hwirq);
70 imx_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEL); 67 imx_writel(irqt | (!!type << hwirq), avic_base + AVIC_INTTYPEL);
71 } else { 68 } else {
72 irq -= AVIC_NUM_IRQS / 2; 69 hwirq -= AVIC_NUM_IRQS / 2;
73 irqt = imx_readl(avic_base + AVIC_INTTYPEH) & ~(1 << irq); 70 irqt = imx_readl(avic_base + AVIC_INTTYPEH) & ~(1 << hwirq);
74 imx_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEH); 71 imx_writel(irqt | (!!type << hwirq), avic_base + AVIC_INTTYPEH);
75 } 72 }
76 73
77 return 0; 74 return 0;
diff --git a/arch/arm/mach-imx/irq-common.c b/arch/arm/mach-imx/irq-common.c
index 0a920d184867..210d36eba8f2 100644
--- a/arch/arm/mach-imx/irq-common.c
+++ b/arch/arm/mach-imx/irq-common.c
@@ -33,8 +33,10 @@ int mxc_set_irq_fiq(unsigned int irq, unsigned int type)
33 gc = irq_get_chip_data(irq); 33 gc = irq_get_chip_data(irq);
34 if (gc && gc->private) { 34 if (gc && gc->private) {
35 exirq = gc->private; 35 exirq = gc->private;
36 if (exirq->set_irq_fiq) 36 if (exirq->set_irq_fiq) {
37 ret = exirq->set_irq_fiq(irq, type); 37 struct irq_data *d = irq_get_irq_data(irq);
38 ret = exirq->set_irq_fiq(irqd_to_hwirq(d), type);
39 }
38 } 40 }
39 41
40 return ret; 42 return ret;
diff --git a/arch/arm/mach-imx/tzic.c b/arch/arm/mach-imx/tzic.c
index ae23d50f7861..4399abd0f11f 100644
--- a/arch/arm/mach-imx/tzic.c
+++ b/arch/arm/mach-imx/tzic.c
@@ -56,14 +56,14 @@ static struct irq_domain *domain;
56#define TZIC_NUM_IRQS 128 56#define TZIC_NUM_IRQS 128
57 57
58#ifdef CONFIG_FIQ 58#ifdef CONFIG_FIQ
59static int tzic_set_irq_fiq(unsigned int irq, unsigned int type) 59static int tzic_set_irq_fiq(unsigned int hwirq, unsigned int type)
60{ 60{
61 unsigned int index, mask, value; 61 unsigned int index, mask, value;
62 62
63 index = irq >> 5; 63 index = hwirq >> 5;
64 if (unlikely(index >= 4)) 64 if (unlikely(index >= 4))
65 return -EINVAL; 65 return -EINVAL;
66 mask = 1U << (irq & 0x1F); 66 mask = 1U << (hwirq & 0x1F);
67 67
68 value = imx_readl(tzic_base + TZIC_INTSEC0(index)) | mask; 68 value = imx_readl(tzic_base + TZIC_INTSEC0(index)) | mask;
69 if (type) 69 if (type)