Release 4.10 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 | paulius zaleckas | 91 | 78.45% | 1 | 16.67% |
sascha hauer | sascha hauer | 11 | 9.48% | 2 | 33.33% |
alexander shiyan | alexander shiyan | 8 | 6.90% | 1 | 16.67% |
johannes berg | johannes berg | 4 | 3.45% | 1 | 16.67% |
peter horton | 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 wang | jason wang | 48 | 68.57% | 1 | 16.67% |
quinn jensen | quinn jensen | 10 | 14.29% | 1 | 16.67% |
lennert buytenhek | lennert buytenhek | 6 | 8.57% | 1 | 16.67% |
johannes berg | johannes berg | 2 | 2.86% | 1 | 16.67% |
sascha hauer | sascha hauer | 2 | 2.86% | 1 | 16.67% |
shawn guo | shawn guo | 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 wang | jason wang | 34 | 61.82% | 1 | 16.67% |
quinn jensen | quinn jensen | 10 | 18.18% | 1 | 16.67% |
lennert buytenhek | lennert buytenhek | 6 | 10.91% | 1 | 16.67% |
sascha hauer | sascha hauer | 2 | 3.64% | 1 | 16.67% |
shawn guo | shawn guo | 2 | 3.64% | 1 | 16.67% |
johannes berg | 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 wang | jason wang | 131 | 87.33% | 1 | 20.00% |
quinn jensen | quinn jensen | 8 | 5.33% | 1 | 20.00% |
peter horton | peter horton | 7 | 4.67% | 1 | 20.00% |
shawn guo | shawn guo | 3 | 2.00% | 1 | 20.00% |
lennert buytenhek | 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 | sascha hauer | 43 | 86.00% | 1 | 16.67% |
shawn guo | shawn guo | 3 | 6.00% | 1 | 16.67% |
alexander shiyan | alexander shiyan | 1 | 2.00% | 1 | 16.67% |
marc zyngier | marc zyngier | 1 | 2.00% | 1 | 16.67% |
quinn jensen | quinn jensen | 1 | 2.00% | 1 | 16.67% |
johannes berg | johannes berg | 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 | quinn jensen | 76 | 35.51% | 1 | 9.09% |
shawn guo | shawn guo | 75 | 35.05% | 2 | 18.18% |
sascha hauer | sascha hauer | 22 | 10.28% | 3 | 27.27% |
darius augulis | darius augulis | 18 | 8.41% | 1 | 9.09% |
paulius zaleckas | paulius zaleckas | 8 | 3.74% | 1 | 9.09% |
johannes berg | johannes berg | 7 | 3.27% | 1 | 9.09% |
alexander shiyan | alexander shiyan | 5 | 2.34% | 1 | 9.09% |
jason wang | jason wang | 3 | 1.40% | 1 | 9.09% |
| Total | 214 | 100.00% | 11 | 100.00% |
Overall Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jason wang | jason wang | 249 | 29.40% | 1 | 3.85% |
quinn jensen | quinn jensen | 111 | 13.11% | 1 | 3.85% |
sascha hauer | sascha hauer | 110 | 12.99% | 5 | 19.23% |
paulius zaleckas | paulius zaleckas | 107 | 12.63% | 1 | 3.85% |
shawn guo | shawn guo | 101 | 11.92% | 4 | 15.38% |
juergen beisert | juergen beisert | 76 | 8.97% | 1 | 3.85% |
darius augulis | darius augulis | 23 | 2.72% | 1 | 3.85% |
johannes berg | johannes berg | 15 | 1.77% | 1 | 3.85% |
alexander shiyan | alexander shiyan | 14 | 1.65% | 2 | 7.69% |
lennert buytenhek | lennert buytenhek | 13 | 1.53% | 1 | 3.85% |
peter horton | peter horton | 12 | 1.42% | 1 | 3.85% |
fabio estevam | fabio estevam | 10 | 1.18% | 3 | 11.54% |
jason liu | jason liu | 3 | 0.35% | 1 | 3.85% |
robert schwebel | robert schwebel | 1 | 0.12% | 1 | 3.85% |
marc zyngier | marc zyngier | 1 | 0.12% | 1 | 3.85% |
russell king | russell king | 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.