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
23
24void enable_adm8668_irq(unsigned int irq);
25void disable_adm8668_irq(unsigned int irq);
26void adm8668_irq_cascade(void);
27
28void plat_irq_dispatch(void)
29{
30    unsigned int pending;
31
32    pending = read_c0_cause() & read_c0_status() & ST0_IM;
33
34    /* timer interrupt, that we renumbered */
35    if (pending & STATUSF_IP7)
36        do_IRQ(MIPS_CPU_IRQ_BASE + 7);
37    if (pending & STATUSF_IP2)
38        adm8668_irq_cascade();
39}
40
41/*
42 * System irq dispatch
43 */
44void adm8668_irq_cascade()
45{
46    int i;
47    unsigned long intsrc;
48
49    intsrc = ADM8668_INTC_REG(IRQ_STATUS_REG) & IRQ_MASK;
50    for (i = 0; intsrc; intsrc >>= 1, i++)
51        if (intsrc & 0x1)
52            do_IRQ(i);
53}
54
55/*
56 * irq enable
57 */
58static __inline void _irq_enable(int irql)
59{
60    ADM8668_INTC_REG(IRQ_ENABLE_REG) = (1 << irql);
61}
62
63
64/*
65 * irq disable
66 */
67static __inline void _irq_disable(int irql)
68{
69    ADM8668_INTC_REG(IRQ_DISABLE_REG) = (1 << irql);
70}
71
72
73/*
74 * enable 8668 irq
75 */
76void enable_adm8668_irq(unsigned int irq)
77{
78    if ((irq < 0) || (irq > NR_IRQS))
79        return;
80
81    _irq_enable(irq);
82}
83
84
85/*
86 * disable 8668 irq
87 */
88void disable_adm8668_irq(unsigned int irq)
89{
90    if ((irq < 0) || (irq > NR_IRQS))
91        return;
92
93    _irq_disable(irq);
94}
95
96static inline void ack_adm8668_irq(unsigned int irq_nr)
97{
98    ADM8668_INTC_REG(IRQ_DISABLE_REG) = (1 << irq_nr);
99}
100
101/*
102 * system irq type
103 */
104
105static struct irq_chip adm8668_irq_type = {
106    .name = "adm8668",
107    .ack = ack_adm8668_irq,
108    .mask = disable_adm8668_irq,
109    .unmask = enable_adm8668_irq
110};
111
112/*
113 * irq init
114 */
115void __init init_adm8668_irqs(void)
116{
117    int i;
118
119    for (i = 0; i <= INT_LVL_MAX; i++)
120        set_irq_chip_and_handler(i, &adm8668_irq_type,
121            handle_level_irq);
122
123    /* hw0 is where our interrupts are uh.. interrupted at. */
124    set_c0_status(IE_IRQ0);
125}
126
127/*
128 * system init
129 */
130void __init arch_init_irq(void)
131{
132    mips_cpu_irq_init();
133    init_adm8668_irqs();
134}
135

Archive Download this file



interactive