blob: d36c9374aed1dffc9daf9980a5a8439f3da2dd00 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * linux/arch/sh/boards/renesas/rts7751r2d/irq.c
3 *
4 * Copyright (C) 2000 Kazumoto Kojima
5 *
6 * Renesas Technology Sales RTS7751R2D Support.
7 *
8 * Modified for RTS7751R2D 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/rts7751r2d/rts7751r2d.h>
18
19#if defined(CONFIG_RTS7751R2D_REV11)
20static int mask_pos[] = {11, 9, 8, 12, 10, 6, 5, 4, 7, 14, 13, 0, 0, 0, 0};
21#else
22static int mask_pos[] = {6, 11, 9, 8, 12, 10, 5, 4, 7, 14, 13, 0, 0, 0, 0};
23#endif
24
25extern int voyagergx_irq_demux(int irq);
26extern void setup_voyagergx_irq(void);
27
28static void enable_rts7751r2d_irq(unsigned int irq);
29static void disable_rts7751r2d_irq(unsigned int irq);
30
31/* shutdown is same as "disable" */
32#define shutdown_rts7751r2d_irq disable_rts7751r2d_irq
33
34static void ack_rts7751r2d_irq(unsigned int irq);
35static void end_rts7751r2d_irq(unsigned int irq);
36
37static unsigned int startup_rts7751r2d_irq(unsigned int irq)
38{
39 enable_rts7751r2d_irq(irq);
40 return 0; /* never anything pending */
41}
42
43static void disable_rts7751r2d_irq(unsigned int irq)
44{
45 unsigned long flags;
46 unsigned short val;
47 unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]);
48
49 /* Set the priority in IPR to 0 */
50 local_irq_save(flags);
51 val = ctrl_inw(IRLCNTR1);
52 val &= mask;
53 ctrl_outw(val, IRLCNTR1);
54 local_irq_restore(flags);
55}
56
57static void enable_rts7751r2d_irq(unsigned int irq)
58{
59 unsigned long flags;
60 unsigned short val;
61 unsigned short value = (0x0001 << mask_pos[irq]);
62
63 /* Set priority in IPR back to original value */
64 local_irq_save(flags);
65 val = ctrl_inw(IRLCNTR1);
66 val |= value;
67 ctrl_outw(val, IRLCNTR1);
68 local_irq_restore(flags);
69}
70
71int rts7751r2d_irq_demux(int irq)
72{
73 int demux_irq;
74
75 demux_irq = voyagergx_irq_demux(irq);
76 return demux_irq;
77}
78
79static void ack_rts7751r2d_irq(unsigned int irq)
80{
81 disable_rts7751r2d_irq(irq);
82}
83
84static void end_rts7751r2d_irq(unsigned int irq)
85{
86 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
87 enable_rts7751r2d_irq(irq);
88}
89
90static struct hw_interrupt_type rts7751r2d_irq_type = {
Thomas Gleixner08d0fd02005-09-10 00:26:42 -070091 .typename = "RTS7751R2D IRQ",
92 .startup = startup_rts7751r2d_irq,
93 .shutdown = shutdown_rts7751r2d_irq,
94 .enable = enable_rts7751r2d_irq,
95 .disable = disable_rts7751r2d_irq,
96 .ack = ack_rts7751r2d_irq,
97 .end = end_rts7751r2d_irq,
Linus Torvalds1da177e2005-04-16 15:20:36 -070098};
99
100static void make_rts7751r2d_irq(unsigned int irq)
101{
102 disable_irq_nosync(irq);
103 irq_desc[irq].handler = &rts7751r2d_irq_type;
104 disable_rts7751r2d_irq(irq);
105}
106
107/*
108 * Initialize IRQ setting
109 */
110void __init init_rts7751r2d_IRQ(void)
111{
112 int i;
113
114 /* IRL0=KEY Input
115 * IRL1=Ethernet
116 * IRL2=CF Card
117 * IRL3=CF Card Insert
118 * IRL4=PCMCIA
119 * IRL5=VOYAGER
120 * IRL6=RTC Alarm
121 * IRL7=RTC Timer
122 * IRL8=SD Card
123 * IRL9=PCI Slot #1
124 * IRL10=PCI Slot #2
125 * IRL11=Extention #0
126 * IRL12=Extention #1
127 * IRL13=Extention #2
128 * IRL14=Extention #3
129 */
130
131 for (i=0; i<15; i++)
132 make_rts7751r2d_irq(i);
133
134 setup_voyagergx_irq();
135}