Merge branch 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[cascardo/linux.git] / arch / mips / alchemy / devboards / pb1200 / irqmap.c
1 /*
2  * BRIEF MODULE DESCRIPTION
3  *      Au1xxx irq map table
4  *
5  *  This program is free software; you can redistribute  it and/or modify it
6  *  under  the terms of  the GNU General  Public License as published by the
7  *  Free Software Foundation;  either version 2 of the  License, or (at your
8  *  option) any later version.
9  *
10  *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
11  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
12  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
13  *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
14  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
15  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
16  *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
17  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
18  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
19  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20  *
21  *  You should have received a copy of the  GNU General Public License along
22  *  with this program; if not, write  to the Free Software Foundation, Inc.,
23  *  675 Mass Ave, Cambridge, MA 02139, USA.
24  */
25
26 #include <linux/init.h>
27 #include <linux/interrupt.h>
28
29 #include <asm/mach-au1x00/au1000.h>
30
31 #ifdef CONFIG_MIPS_PB1200
32 #include <asm/mach-pb1x00/pb1200.h>
33 #endif
34
35 #ifdef CONFIG_MIPS_DB1200
36 #include <asm/mach-db1x00/db1200.h>
37 #define PB1200_INT_BEGIN DB1200_INT_BEGIN
38 #define PB1200_INT_END DB1200_INT_END
39 #endif
40
41 struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
42         /* This is external interrupt cascade */
43         { AU1000_GPIO_7, IRQF_TRIGGER_LOW, 0 },
44 };
45
46
47 /*
48  * Support for External interrupts on the Pb1200 Development platform.
49  */
50
51 static void pb1200_cascade_handler(unsigned int irq, struct irq_desc *d)
52 {
53         unsigned short bisr = bcsr->int_status;
54
55         for ( ; bisr; bisr &= bisr - 1)
56                 generic_handle_irq(PB1200_INT_BEGIN + __ffs(bisr));
57 }
58
59 /* NOTE: both the enable and mask bits must be cleared, otherwise the
60  * CPLD generates tons of spurious interrupts (at least on the DB1200).
61  */
62 static void pb1200_mask_irq(unsigned int irq_nr)
63 {
64         bcsr->intclr_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
65         bcsr->intclr = 1 << (irq_nr - PB1200_INT_BEGIN);
66         au_sync();
67 }
68
69 static void pb1200_maskack_irq(unsigned int irq_nr)
70 {
71         bcsr->intclr_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
72         bcsr->intclr = 1 << (irq_nr - PB1200_INT_BEGIN);
73         bcsr->int_status = 1 << (irq_nr - PB1200_INT_BEGIN);    /* ack */
74         au_sync();
75 }
76
77 static void pb1200_unmask_irq(unsigned int irq_nr)
78 {
79         bcsr->intset = 1 << (irq_nr - PB1200_INT_BEGIN);
80         bcsr->intset_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
81         au_sync();
82 }
83
84 static struct irq_chip pb1200_cpld_irq_type = {
85 #ifdef CONFIG_MIPS_PB1200
86         .name = "Pb1200 Ext",
87 #endif
88 #ifdef CONFIG_MIPS_DB1200
89         .name = "Db1200 Ext",
90 #endif
91         .mask           = pb1200_mask_irq,
92         .mask_ack       = pb1200_maskack_irq,
93         .unmask         = pb1200_unmask_irq,
94 };
95
96 void __init board_init_irq(void)
97 {
98         unsigned int irq;
99
100         au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
101
102 #ifdef CONFIG_MIPS_PB1200
103         /* We have a problem with CPLD rev 3. */
104         if (((bcsr->whoami & BCSR_WHOAMI_CPLD) >> 4) <= 3) {
105                 printk(KERN_ERR "WARNING!!!\n");
106                 printk(KERN_ERR "WARNING!!!\n");
107                 printk(KERN_ERR "WARNING!!!\n");
108                 printk(KERN_ERR "WARNING!!!\n");
109                 printk(KERN_ERR "WARNING!!!\n");
110                 printk(KERN_ERR "WARNING!!!\n");
111                 printk(KERN_ERR "Pb1200 must be at CPLD rev 4. Please have Pb1200\n");
112                 printk(KERN_ERR "updated to latest revision. This software will\n");
113                 printk(KERN_ERR "not work on anything less than CPLD rev 4.\n");
114                 printk(KERN_ERR "WARNING!!!\n");
115                 printk(KERN_ERR "WARNING!!!\n");
116                 printk(KERN_ERR "WARNING!!!\n");
117                 printk(KERN_ERR "WARNING!!!\n");
118                 printk(KERN_ERR "WARNING!!!\n");
119                 printk(KERN_ERR "WARNING!!!\n");
120                 panic("Game over.  Your score is 0.");
121         }
122 #endif
123         /* mask & disable & ack all */
124         bcsr->intclr_mask = 0xffff;
125         bcsr->intclr = 0xffff;
126         bcsr->int_status = 0xffff;
127         au_sync();
128
129         for (irq = PB1200_INT_BEGIN; irq <= PB1200_INT_END; irq++)
130                 set_irq_chip_and_handler_name(irq, &pb1200_cpld_irq_type,
131                                          handle_level_irq, "level");
132
133         set_irq_chained_handler(AU1000_GPIO_7, pb1200_cascade_handler);
134 }