Root/target/linux/adm8668/files/arch/mips/adm8668/irq.c

1/*
2 * Copyright (C) 2010 Scott Nicholas <neutronscott@scottn.us>
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 */
8
9#include <linux/init.h>
10#include <linux/kernel_stat.h>
11#include <linux/signal.h>
12#include <linux/sched.h>
13#include <linux/interrupt.h>
14#include <linux/slab.h>
15#include <linux/random.h>
16#include <linux/pm.h>
17#include <linux/irq.h>
18#include <asm/mipsregs.h>
19#include <asm/irq_cpu.h>
20#include <asm/irq.h>
21#include <adm8668.h>
22
23static void adm8668_irq_cascade(void)
24{
25    int i;
26    unsigned long intsrc;
27
28    intsrc = ADM8668_INTC_REG(IRQ_STATUS_REG) & IRQ_MASK;
29    for (i = 0; intsrc; intsrc >>= 1, i++)
30        if (intsrc & 0x1)
31            do_IRQ(i);
32}
33
34/*
35 * System irq dispatch
36 */
37void plat_irq_dispatch(void)
38{
39    unsigned int pending;
40
41    pending = read_c0_cause() & read_c0_status() & ST0_IM;
42
43    /* timer interrupt, that we renumbered */
44    if (pending & STATUSF_IP7)
45        do_IRQ(MIPS_CPU_IRQ_BASE + 7);
46    if (pending & STATUSF_IP2)
47        adm8668_irq_cascade();
48}
49
50/*
51 * enable 8668 irq
52 */
53static void enable_adm8668_irq(struct irq_data *d)
54{
55    int irq = d->irq;
56
57    if ((irq < 0) || (irq > NR_IRQS))
58        return;
59
60    ADM8668_INTC_REG(IRQ_ENABLE_REG) = (1 << irq);
61}
62
63
64/*
65 * disable 8668 irq
66 */
67static void disable_adm8668_irq(struct irq_data *d)
68{
69    int irq = d->irq;
70
71    if ((irq < 0) || (irq > NR_IRQS))
72        return;
73
74    ADM8668_INTC_REG(IRQ_DISABLE_REG) = (1 << irq);
75}
76
77static void ack_adm8668_irq(struct irq_data *d)
78{
79    int irq = d->irq;
80
81    ADM8668_INTC_REG(IRQ_DISABLE_REG) = (1 << irq);
82}
83
84/*
85 * system irq type
86 */
87
88static struct irq_chip adm8668_irq_type = {
89    .name = "adm8668",
90    .irq_ack = ack_adm8668_irq,
91    .irq_mask = disable_adm8668_irq,
92    .irq_unmask = enable_adm8668_irq
93};
94
95/*
96 * irq init
97 */
98static void __init init_adm8668_irqs(void)
99{
100    int i;
101
102    for (i = 0; i <= INT_LVL_MAX; i++)
103        irq_set_chip_and_handler(i, &adm8668_irq_type,
104            handle_level_irq);
105
106    /* hw0 is where our interrupts are uh.. interrupted at. */
107    set_c0_status(IE_IRQ0);
108}
109
110/*
111 * system init
112 */
113void __init arch_init_irq(void)
114{
115    mips_cpu_irq_init();
116    init_adm8668_irqs();
117}
118

Archive Download this file



interactive