sh: Add support for R7780RP and R7780MP boards.
[firefly-linux-kernel-4.4.55.git] / arch / sh / boards / renesas / r7780rp / irq.c
1 /*
2  * linux/arch/sh/boards/renesas/r7780rp/irq.c
3  *
4  * Copyright (C) 2000  Kazumoto Kojima
5  *
6  * Renesas Solutions Highlander R7780RP-1 Support.
7  *
8  * Modified for R7780RP-1 by
9  * Atom Create Engineering Co., Ltd. 2002.
10  */
11
12 #include <linux/config.h>
13 #include <linux/init.h>
14 #include <linux/irq.h>
15 #include <asm/io.h>
16 #include <asm/irq.h>
17 #include <asm/r7780rp/r7780rp.h>
18
19 #ifdef CONFIG_SH_R7780MP
20 static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0};
21 #else
22 static int mask_pos[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 5, 6, 4, 0, 1, 2, 0};
23 #endif
24
25 static void enable_r7780rp_irq(unsigned int irq);
26 static void disable_r7780rp_irq(unsigned int irq);
27
28 /* shutdown is same as "disable" */
29 #define shutdown_r7780rp_irq disable_r7780rp_irq
30
31 static void ack_r7780rp_irq(unsigned int irq);
32 static void end_r7780rp_irq(unsigned int irq);
33
34 static unsigned int startup_r7780rp_irq(unsigned int irq)
35 {
36         enable_r7780rp_irq(irq);
37         return 0; /* never anything pending */
38 }
39
40 static void disable_r7780rp_irq(unsigned int irq)
41 {
42         unsigned long flags;
43         unsigned short val;
44         unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]);
45
46         /* Set the priority in IPR to 0 */
47         local_irq_save(flags);
48         val = ctrl_inw(IRLCNTR1);
49         val &= mask;
50         ctrl_outw(val, IRLCNTR1);
51         local_irq_restore(flags);
52 }
53
54 static void enable_r7780rp_irq(unsigned int irq)
55 {
56         unsigned long flags;
57         unsigned short val;
58         unsigned short value = (0x0001 << mask_pos[irq]);
59
60         /* Set priority in IPR back to original value */
61         local_irq_save(flags);
62         val = ctrl_inw(IRLCNTR1);
63         val |= value;
64         ctrl_outw(val, IRLCNTR1);
65         local_irq_restore(flags);
66 }
67
68 static void ack_r7780rp_irq(unsigned int irq)
69 {
70         disable_r7780rp_irq(irq);
71 }
72
73 static void end_r7780rp_irq(unsigned int irq)
74 {
75         if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
76                 enable_r7780rp_irq(irq);
77 }
78
79 static struct hw_interrupt_type r7780rp_irq_type = {
80         .typename = "R7780RP-IRQ",
81         .startup = startup_r7780rp_irq,
82         .shutdown = shutdown_r7780rp_irq,
83         .enable = enable_r7780rp_irq,
84         .disable = disable_r7780rp_irq,
85         .ack = ack_r7780rp_irq,
86         .end = end_r7780rp_irq,
87 };
88
89 static void make_r7780rp_irq(unsigned int irq)
90 {
91         disable_irq_nosync(irq);
92         irq_desc[irq].handler = &r7780rp_irq_type;
93         disable_r7780rp_irq(irq);
94 }
95
96 /*
97  * Initialize IRQ setting
98  */
99 void __init init_r7780rp_IRQ(void)
100 {
101         int i;
102
103         /* IRL0=PCI Slot #A
104          * IRL1=PCI Slot #B
105          * IRL2=PCI Slot #C
106          * IRL3=PCI Slot #D
107          * IRL4=CF Card
108          * IRL5=CF Card Insert
109          * IRL6=M66596
110          * IRL7=SD Card
111          * IRL8=Touch Panel
112          * IRL9=SCI
113          * IRL10=Serial
114          * IRL11=Extention #A
115          * IRL11=Extention #B
116          * IRL12=Debug LAN
117          * IRL13=Push Switch
118          * IRL14=ZiggBee IO
119          */
120
121         for (i=0; i<15; i++)
122                 make_r7780rp_irq(i);
123 }