Release 4.11 arch/arm/mach-imx/avic.c
/*
* Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright 2008 Juergen Beisert, kernel@pengutronix.de
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include <linux/module.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/io.h>
#include <linux/of.h>
#include <asm/mach/irq.h>
#include <asm/exception.h>
#include "common.h"
#include "hardware.h"
#include "irq-common.h"
#define AVIC_INTCNTL 0x00
/* int control reg */
#define AVIC_NIMASK 0x04
/* int mask reg */
#define AVIC_INTENNUM 0x08
/* int enable number reg */
#define AVIC_INTDISNUM 0x0C
/* int disable number reg */
#define AVIC_INTENABLEH 0x10
/* int enable reg high */
#define AVIC_INTENABLEL 0x14
/* int enable reg low */
#define AVIC_INTTYPEH 0x18
/* int type reg high */
#define AVIC_INTTYPEL 0x1C
/* int type reg low */
#define AVIC_NIPRIORITY(x) (0x20 + 4 * (7 - (x)))
/* int priority */
#define AVIC_NIVECSR 0x40
/* norm int vector/status */
#define AVIC_FIVECSR 0x44
/* fast int vector/status */
#define AVIC_INTSRCH 0x48
/* int source reg high */
#define AVIC_INTSRCL 0x4C
/* int source reg low */
#define AVIC_INTFRCH 0x50
/* int force reg high */
#define AVIC_INTFRCL 0x54
/* int force reg low */
#define AVIC_NIPNDH 0x58
/* norm int pending high */
#define AVIC_NIPNDL 0x5C
/* norm int pending low */
#define AVIC_FIPNDH 0x60
/* fast int pending high */
#define AVIC_FIPNDL 0x64
/* fast int pending low */
#define AVIC_NUM_IRQS 64
static void __iomem *avic_base;
static struct irq_domain *domain;
#ifdef CONFIG_FIQ
static int avic_set_irq_fiq(unsigned int hwirq, unsigned int type)
{
unsigned int irqt;
if (hwirq >= AVIC_NUM_IRQS)
return -EINVAL;
if (hwirq < AVIC_NUM_IRQS / 2) {
irqt = imx_readl(avic_base + AVIC_INTTYPEL) & ~(1 << hwirq);
imx_writel(irqt | (!!type << hwirq), avic_base + AVIC_INTTYPEL);
} else {
hwirq -= AVIC_NUM_IRQS / 2;
irqt = imx_readl(avic_base + AVIC_INTTYPEH) & ~(1 << hwirq);
imx_writel(irqt | (!!type << hwirq), avic_base + AVIC_INTTYPEH);
}
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Paulius Zaleckas | 91 | 78.45% | 1 | 16.67% |
Sascha Hauer | 11 | 9.48% | 2 | 33.33% |
Alexander Shiyan | 8 | 6.90% | 1 | 16.67% |
Johannes Berg | 4 | 3.45% | 1 | 16.67% |
Peter Horton | 2 | 1.72% | 1 | 16.67% |
Total | 116 | 100.00% | 6 | 100.00% |
#endif /* CONFIG_FIQ */
static struct mxc_extra_irq avic_extra_irq = {
#ifdef CONFIG_FIQ
.set_irq_fiq = avic_set_irq_fiq,
#endif
};
#ifdef CONFIG_PM
static u32 avic_saved_mask_reg[2];
static void avic_irq_suspend(struct irq_data *d)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct irq_chip_type *ct = gc->chip_types;
int idx = d->hwirq >> 5;
avic_saved_mask_reg[idx] = imx_readl(avic_base + ct->regs.mask);
imx_writel(gc->wake_active, avic_base + ct->regs.mask);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jason (Hui) Wang | 48 | 68.57% | 1 | 16.67% |
Quinn Jensen | 10 | 14.29% | 1 | 16.67% |
Lennert Buytenhek | 6 | 8.57% | 1 | 16.67% |
Sascha Hauer | 2 | 2.86% | 1 | 16.67% |
Shawn Guo | 2 | 2.86% | 1 | 16.67% |
Johannes Berg | 2 | 2.86% | 1 | 16.67% |
Total | 70 | 100.00% | 6 | 100.00% |
static void avic_irq_resume(struct irq_data *d)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct irq_chip_type *ct = gc->chip_types;
int idx = d->hwirq >> 5;
imx_writel(avic_saved_mask_reg[idx], avic_base + ct->regs.mask);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jason (Hui) Wang | 34 | 61.82% | 1 | 16.67% |
Quinn Jensen | 10 | 18.18% | 1 | 16.67% |
Lennert Buytenhek | 6 | 10.91% | 1 | 16.67% |
Sascha Hauer | 2 | 3.64% | 1 | 16.67% |
Shawn Guo | 2 | 3.64% | 1 | 16.67% |
Johannes Berg | 1 | 1.82% | 1 | 16.67% |
Total | 55 | 100.00% | 6 | 100.00% |
#else
#define avic_irq_suspend NULL
#define avic_irq_resume NULL
#endif
static __init void avic_init_gc(int idx, unsigned int irq_start)
{
struct irq_chip_generic *gc;
struct irq_chip_type *ct;
gc = irq_alloc_generic_chip("mxc-avic", 1, irq_start, avic_base,
handle_level_irq);
gc->private = &avic_extra_irq;
gc->wake_enabled = IRQ_MSK(32);
ct = gc->chip_types;
ct->chip.irq_mask = irq_gc_mask_clr_bit;
ct->chip.irq_unmask = irq_gc_mask_set_bit;
ct->chip.irq_ack = irq_gc_mask_clr_bit;
ct->chip.irq_set_wake = irq_gc_set_wake;
ct->chip.irq_suspend = avic_irq_suspend;
ct->chip.irq_resume = avic_irq_resume;
ct->regs.mask = !idx ? AVIC_INTENABLEL : AVIC_INTENABLEH;
ct->regs.ack = ct->regs.mask;
irq_setup_generic_chip(gc, IRQ_MSK(32), 0, IRQ_NOREQUEST, 0);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jason (Hui) Wang | 131 | 87.33% | 1 | 20.00% |
Quinn Jensen | 8 | 5.33% | 1 | 20.00% |
Peter Horton | 7 | 4.67% | 1 | 20.00% |
Shawn Guo | 3 | 2.00% | 1 | 20.00% |
Lennert Buytenhek | 1 | 0.67% | 1 | 20.00% |
Total | 150 | 100.00% | 5 | 100.00% |
static void __exception_irq_entry avic_handle_irq(struct pt_regs *regs)
{
u32 nivector;
do {
nivector = imx_readl(avic_base + AVIC_NIVECSR) >> 16;
if (nivector == 0xffff)
break;
handle_domain_irq(domain, nivector, regs);
} while (1);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Sascha Hauer | 43 | 86.00% | 1 | 16.67% |
Shawn Guo | 3 | 6.00% | 1 | 16.67% |
Quinn Jensen | 1 | 2.00% | 1 | 16.67% |
Johannes Berg | 1 | 2.00% | 1 | 16.67% |
Alexander Shiyan | 1 | 2.00% | 1 | 16.67% |
Marc Zyngier | 1 | 2.00% | 1 | 16.67% |
Total | 50 | 100.00% | 6 | 100.00% |
/*
* This function initializes the AVIC hardware and disables all the
* interrupts. It registers the interrupt enable and disable functions
* to the kernel for each interrupt source.
*/
void __init mxc_init_irq(void __iomem *irqbase)
{
struct device_node *np;
int irq_base;
int i;
avic_base = irqbase;
/* put the AVIC into the reset value with
* all interrupts disabled
*/
imx_writel(0, avic_base + AVIC_INTCNTL);
imx_writel(0x1f, avic_base + AVIC_NIMASK);
/* disable all interrupts */
imx_writel(0, avic_base + AVIC_INTENABLEH);
imx_writel(0, avic_base + AVIC_INTENABLEL);
/* all IRQ no FIQ */
imx_writel(0, avic_base + AVIC_INTTYPEH);
imx_writel(0, avic_base + AVIC_INTTYPEL);
irq_base = irq_alloc_descs(-1, 0, AVIC_NUM_IRQS, numa_node_id());
WARN_ON(irq_base < 0);
np = of_find_compatible_node(NULL, NULL, "fsl,avic");
domain = irq_domain_add_legacy(np, AVIC_NUM_IRQS, irq_base, 0,
&irq_domain_simple_ops, NULL);
WARN_ON(!domain);
for (i = 0; i < AVIC_NUM_IRQS / 32; i++, irq_base += 32)
avic_init_gc(i, irq_base);
/* Set default priority value (0) for all IRQ's */
for (i = 0; i < 8; i++)
imx_writel(0, avic_base + AVIC_NIPRIORITY(i));
set_handle_irq(avic_handle_irq);
#ifdef CONFIG_FIQ
/* Initialize FIQ */
init_FIQ(FIQ_START);
#endif
printk(KERN_INFO "MXC IRQ initialized\n");
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Quinn Jensen | 76 | 35.51% | 1 | 9.09% |
Shawn Guo | 75 | 35.05% | 2 | 18.18% |
Sascha Hauer | 22 | 10.28% | 3 | 27.27% |
Darius Augulis | 18 | 8.41% | 1 | 9.09% |
Paulius Zaleckas | 8 | 3.74% | 1 | 9.09% |
Johannes Berg | 7 | 3.27% | 1 | 9.09% |
Alexander Shiyan | 5 | 2.34% | 1 | 9.09% |
Jason (Hui) Wang | 3 | 1.40% | 1 | 9.09% |
Total | 214 | 100.00% | 11 | 100.00% |
Overall Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jason (Hui) Wang | 249 | 29.40% | 1 | 3.85% |
Quinn Jensen | 111 | 13.11% | 1 | 3.85% |
Sascha Hauer | 110 | 12.99% | 5 | 19.23% |
Paulius Zaleckas | 107 | 12.63% | 1 | 3.85% |
Shawn Guo | 101 | 11.92% | 4 | 15.38% |
Juergen Beisert | 76 | 8.97% | 1 | 3.85% |
Darius Augulis | 23 | 2.72% | 1 | 3.85% |
Johannes Berg | 15 | 1.77% | 1 | 3.85% |
Alexander Shiyan | 14 | 1.65% | 2 | 7.69% |
Lennert Buytenhek | 13 | 1.53% | 1 | 3.85% |
Peter Horton | 12 | 1.42% | 1 | 3.85% |
Fabio Estevam | 10 | 1.18% | 3 | 11.54% |
Jason Liu | 3 | 0.35% | 1 | 3.85% |
Marc Zyngier | 1 | 0.12% | 1 | 3.85% |
Russell King | 1 | 0.12% | 1 | 3.85% |
Robert Schwebel | 1 | 0.12% | 1 | 3.85% |
Total | 847 | 100.00% | 26 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.