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>
This commit is contained in:
parent
4dbc39e98b
commit
d1e1c31ccd
|
@ -55,23 +55,20 @@ static void __iomem *avic_base;
|
||||||
static struct irq_domain *domain;
|
static struct irq_domain *domain;
|
||||||
|
|
||||||
#ifdef CONFIG_FIQ
|
#ifdef CONFIG_FIQ
|
||||||
static int avic_set_irq_fiq(unsigned int irq, unsigned int type)
|
static int avic_set_irq_fiq(unsigned int hwirq, unsigned int type)
|
||||||
{
|
{
|
||||||
struct irq_data *d = irq_get_irq_data(irq);
|
|
||||||
unsigned int irqt;
|
unsigned int irqt;
|
||||||
|
|
||||||
irq = d->hwirq;
|
if (hwirq >= AVIC_NUM_IRQS)
|
||||||
|
|
||||||
if (irq >= AVIC_NUM_IRQS)
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (irq < AVIC_NUM_IRQS / 2) {
|
if (hwirq < AVIC_NUM_IRQS / 2) {
|
||||||
irqt = imx_readl(avic_base + AVIC_INTTYPEL) & ~(1 << irq);
|
irqt = imx_readl(avic_base + AVIC_INTTYPEL) & ~(1 << hwirq);
|
||||||
imx_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEL);
|
imx_writel(irqt | (!!type << hwirq), avic_base + AVIC_INTTYPEL);
|
||||||
} else {
|
} else {
|
||||||
irq -= AVIC_NUM_IRQS / 2;
|
hwirq -= AVIC_NUM_IRQS / 2;
|
||||||
irqt = imx_readl(avic_base + AVIC_INTTYPEH) & ~(1 << irq);
|
irqt = imx_readl(avic_base + AVIC_INTTYPEH) & ~(1 << hwirq);
|
||||||
imx_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEH);
|
imx_writel(irqt | (!!type << hwirq), avic_base + AVIC_INTTYPEH);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -33,8 +33,10 @@ int mxc_set_irq_fiq(unsigned int irq, unsigned int type)
|
||||||
gc = irq_get_chip_data(irq);
|
gc = irq_get_chip_data(irq);
|
||||||
if (gc && gc->private) {
|
if (gc && gc->private) {
|
||||||
exirq = gc->private;
|
exirq = gc->private;
|
||||||
if (exirq->set_irq_fiq)
|
if (exirq->set_irq_fiq) {
|
||||||
ret = exirq->set_irq_fiq(irq, type);
|
struct irq_data *d = irq_get_irq_data(irq);
|
||||||
|
ret = exirq->set_irq_fiq(irqd_to_hwirq(d), type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -56,14 +56,14 @@ static struct irq_domain *domain;
|
||||||
#define TZIC_NUM_IRQS 128
|
#define TZIC_NUM_IRQS 128
|
||||||
|
|
||||||
#ifdef CONFIG_FIQ
|
#ifdef CONFIG_FIQ
|
||||||
static int tzic_set_irq_fiq(unsigned int irq, unsigned int type)
|
static int tzic_set_irq_fiq(unsigned int hwirq, unsigned int type)
|
||||||
{
|
{
|
||||||
unsigned int index, mask, value;
|
unsigned int index, mask, value;
|
||||||
|
|
||||||
index = irq >> 5;
|
index = hwirq >> 5;
|
||||||
if (unlikely(index >= 4))
|
if (unlikely(index >= 4))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
mask = 1U << (irq & 0x1F);
|
mask = 1U << (hwirq & 0x1F);
|
||||||
|
|
||||||
value = imx_readl(tzic_base + TZIC_INTSEC0(index)) | mask;
|
value = imx_readl(tzic_base + TZIC_INTSEC0(index)) | mask;
|
||||||
if (type)
|
if (type)
|
||||||
|
|
Loading…
Reference in New Issue