aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sh/boards/renesas/rts7751r2d/irq.c6
-rw-r--r--arch/sh/boards/renesas/rts7751r2d/setup.c5
-rw-r--r--arch/sh/cchips/voyagergx/irq.c188
-rw-r--r--include/asm-sh/voyagergx.h39
4 files changed, 95 insertions, 143 deletions
diff --git a/arch/sh/boards/renesas/rts7751r2d/irq.c b/arch/sh/boards/renesas/rts7751r2d/irq.c
index 0bae9041aceb..b97c25de3a41 100644
--- a/arch/sh/boards/renesas/rts7751r2d/irq.c
+++ b/arch/sh/boards/renesas/rts7751r2d/irq.c
@@ -13,6 +13,7 @@
13#include <linux/irq.h> 13#include <linux/irq.h>
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <asm/voyagergx.h>
16#include <asm/rts7751r2d.h> 17#include <asm/rts7751r2d.h>
17 18
18#if defined(CONFIG_RTS7751R2D_REV11) 19#if defined(CONFIG_RTS7751R2D_REV11)
@@ -21,9 +22,6 @@ static int mask_pos[] = {11, 9, 8, 12, 10, 6, 5, 4, 7, 14, 13, 0, 0, 0, 0};
21static int mask_pos[] = {6, 11, 9, 8, 12, 10, 5, 4, 7, 14, 13, 0, 0, 0, 0}; 22static int mask_pos[] = {6, 11, 9, 8, 12, 10, 5, 4, 7, 14, 13, 0, 0, 0, 0};
22#endif 23#endif
23 24
24extern int voyagergx_irq_demux(int irq);
25extern void setup_voyagergx_irq(void);
26
27static void enable_rts7751r2d_irq(unsigned int irq) 25static void enable_rts7751r2d_irq(unsigned int irq)
28{ 26{
29 /* Set priority in IPR back to original value */ 27 /* Set priority in IPR back to original value */
@@ -39,7 +37,7 @@ static void disable_rts7751r2d_irq(unsigned int irq)
39 37
40int rts7751r2d_irq_demux(int irq) 38int rts7751r2d_irq_demux(int irq)
41{ 39{
42 return voyagergx_irq_demux(irq); 40 return irq;
43} 41}
44 42
45static struct irq_chip rts7751r2d_irq_chip __read_mostly = { 43static struct irq_chip rts7751r2d_irq_chip __read_mostly = {
diff --git a/arch/sh/boards/renesas/rts7751r2d/setup.c b/arch/sh/boards/renesas/rts7751r2d/setup.c
index 6f7029d33241..4d1bbd30e52b 100644
--- a/arch/sh/boards/renesas/rts7751r2d/setup.c
+++ b/arch/sh/boards/renesas/rts7751r2d/setup.c
@@ -82,7 +82,7 @@ static struct plat_serial8250_port uart_platform_data[] = {
82 .membase = (void __iomem *)VOYAGER_UART_BASE, 82 .membase = (void __iomem *)VOYAGER_UART_BASE,
83 .mapbase = VOYAGER_UART_BASE, 83 .mapbase = VOYAGER_UART_BASE,
84 .iotype = UPIO_MEM, 84 .iotype = UPIO_MEM,
85 .irq = VOYAGER_UART0_IRQ, 85 .irq = IRQ_SM501_U0,
86 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, 86 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
87 .regshift = 2, 87 .regshift = 2,
88 .uartclk = (9600 * 16), 88 .uartclk = (9600 * 16),
@@ -125,7 +125,7 @@ static struct resource sm501_resources[] = {
125 .flags = IORESOURCE_MEM, 125 .flags = IORESOURCE_MEM,
126 }, 126 },
127 [2] = { 127 [2] = {
128 .start = 32, 128 .start = IRQ_SM501_CV,
129 .flags = IORESOURCE_IRQ, 129 .flags = IORESOURCE_IRQ,
130 }, 130 },
131}; 131};
@@ -187,7 +187,6 @@ static void __init rts7751r2d_setup(char **cmdline_p)
187static struct sh_machine_vector mv_rts7751r2d __initmv = { 187static struct sh_machine_vector mv_rts7751r2d __initmv = {
188 .mv_name = "RTS7751R2D", 188 .mv_name = "RTS7751R2D",
189 .mv_setup = rts7751r2d_setup, 189 .mv_setup = rts7751r2d_setup,
190 .mv_nr_irqs = 72,
191 190
192 .mv_init_irq = init_rts7751r2d_IRQ, 191 .mv_init_irq = init_rts7751r2d_IRQ,
193 .mv_irq_demux = rts7751r2d_irq_demux, 192 .mv_irq_demux = rts7751r2d_irq_demux,
diff --git a/arch/sh/cchips/voyagergx/irq.c b/arch/sh/cchips/voyagergx/irq.c
index d70e5c8461b5..0ca405a46a5b 100644
--- a/arch/sh/cchips/voyagergx/irq.c
+++ b/arch/sh/cchips/voyagergx/irq.c
@@ -23,149 +23,79 @@
23#include <asm/voyagergx.h> 23#include <asm/voyagergx.h>
24#include <asm/rts7751r2d.h> 24#include <asm/rts7751r2d.h>
25 25
26static void disable_voyagergx_irq(unsigned int irq) 26enum {
27{ 27 UNUSED = 0,
28 unsigned long val; 28
29 unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); 29 /* voyager specific interrupt sources */
30 30 UP, G54, G53, G52, G51, G50, G49, G48,
31 pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask); 31 I2C, PW, DMA, PCI, I2S, AC, US,
32 val = readl((void __iomem *)VOYAGER_INT_MASK); 32 U1, U0, CV, MC, S1, S0,
33 val &= ~mask; 33 UH, TWOD, ZD, PV, CI,
34 writel(val, (void __iomem *)VOYAGER_INT_MASK);
35}
36
37static void enable_voyagergx_irq(unsigned int irq)
38{
39 unsigned long val;
40 unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE);
41
42 pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask);
43 val = readl((void __iomem *)VOYAGER_INT_MASK);
44 val |= mask;
45 writel(val, (void __iomem *)VOYAGER_INT_MASK);
46}
47
48static void mask_and_ack_voyagergx(unsigned int irq)
49{
50 disable_voyagergx_irq(irq);
51}
52
53static void end_voyagergx_irq(unsigned int irq)
54{
55 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
56 enable_voyagergx_irq(irq);
57}
58
59static unsigned int startup_voyagergx_irq(unsigned int irq)
60{
61 enable_voyagergx_irq(irq);
62 return 0;
63}
64
65static void shutdown_voyagergx_irq(unsigned int irq)
66{
67 disable_voyagergx_irq(irq);
68}
69
70static struct hw_interrupt_type voyagergx_irq_type = {
71 .typename = "VOYAGERGX-IRQ",
72 .startup = startup_voyagergx_irq,
73 .shutdown = shutdown_voyagergx_irq,
74 .enable = enable_voyagergx_irq,
75 .disable = disable_voyagergx_irq,
76 .ack = mask_and_ack_voyagergx,
77 .end = end_voyagergx_irq,
78}; 34};
79 35
80static irqreturn_t voyagergx_interrupt(int irq, void *dev_id) 36static struct intc_vect vectors[] = {
81{ 37 INTC_IRQ(UP, IRQ_SM501_UP), INTC_IRQ(G54, IRQ_SM501_G54),
82 printk(KERN_INFO 38 INTC_IRQ(G53, IRQ_SM501_G53), INTC_IRQ(G52, IRQ_SM501_G52),
83 "VoyagerGX: spurious interrupt, status: 0x%x\n", 39 INTC_IRQ(G51, IRQ_SM501_G51), INTC_IRQ(G50, IRQ_SM501_G50),
84 (unsigned int)readl((void __iomem *)INT_STATUS)); 40 INTC_IRQ(G49, IRQ_SM501_G49), INTC_IRQ(G48, IRQ_SM501_G48),
85 return IRQ_HANDLED; 41 INTC_IRQ(I2C, IRQ_SM501_I2C), INTC_IRQ(PW, IRQ_SM501_PW),
86} 42 INTC_IRQ(DMA, IRQ_SM501_DMA), INTC_IRQ(PCI, IRQ_SM501_PCI),
87 43 INTC_IRQ(I2S, IRQ_SM501_I2S), INTC_IRQ(AC, IRQ_SM501_AC),
88static struct { 44 INTC_IRQ(US, IRQ_SM501_US), INTC_IRQ(U1, IRQ_SM501_U1),
89 int (*func)(int, void *); 45 INTC_IRQ(U0, IRQ_SM501_U0), INTC_IRQ(CV, IRQ_SM501_CV),
90 void *dev; 46 INTC_IRQ(MC, IRQ_SM501_MC), INTC_IRQ(S1, IRQ_SM501_S1),
91} voyagergx_demux[VOYAGER_IRQ_NUM]; 47 INTC_IRQ(S0, IRQ_SM501_S0), INTC_IRQ(UH, IRQ_SM501_UH),
48 INTC_IRQ(TWOD, IRQ_SM501_2D), INTC_IRQ(ZD, IRQ_SM501_ZD),
49 INTC_IRQ(PV, IRQ_SM501_PV), INTC_IRQ(CI, IRQ_SM501_CI),
50};
92 51
93void voyagergx_register_irq_demux(int irq, 52static struct intc_mask_reg mask_registers[] = {
94 int (*demux)(int irq, void *dev), void *dev) 53 { VOYAGER_INT_MASK, 1, 32, /* "Interrupt Mask", MMIO_base + 0x30 */
95{ 54 { UP, G54, G53, G52, G51, G50, G49, G48,
96 voyagergx_demux[irq - VOYAGER_IRQ_BASE].func = demux; 55 I2C, PW, 0, DMA, PCI, I2S, AC, US,
97 voyagergx_demux[irq - VOYAGER_IRQ_BASE].dev = dev; 56 0, 0, U1, U0, CV, MC, S1, S0,
98} 57 0, UH, 0, 0, TWOD, ZD, PV, CI } },
58};
99 59
100void voyagergx_unregister_irq_demux(int irq) 60static DECLARE_INTC_DESC(intc_desc, "voyagergx", vectors,
101{ 61 NULL, NULL, mask_registers, NULL, NULL);
102 voyagergx_demux[irq - VOYAGER_IRQ_BASE].func = 0; 62
103} 63static unsigned int voyagergx_stat2irq[32] = {
64 IRQ_SM501_CI, IRQ_SM501_PV, IRQ_SM501_ZD, IRQ_SM501_2D,
65 0, 0, IRQ_SM501_UH, 0,
66 IRQ_SM501_S0, IRQ_SM501_S1, IRQ_SM501_MC, IRQ_SM501_CV,
67 IRQ_SM501_U0, IRQ_SM501_U1, 0, 0,
68 IRQ_SM501_US, IRQ_SM501_AC, IRQ_SM501_I2S, IRQ_SM501_PCI,
69 IRQ_SM501_DMA, 0, IRQ_SM501_PW, IRQ_SM501_I2C,
70 IRQ_SM501_G48, IRQ_SM501_G49, IRQ_SM501_G50, IRQ_SM501_G51,
71 IRQ_SM501_G52, IRQ_SM501_G53, IRQ_SM501_G54, IRQ_SM501_UP
72};
104 73
105int voyagergx_irq_demux(int irq) 74static void voyagergx_irq_demux(unsigned int irq, struct irq_desc *desc)
106{ 75{
107 76 unsigned long intv = ctrl_inl(INT_STATUS);
108 if (irq == IRQ_VOYAGER ) { 77 struct irq_desc *ext_desc;
109 unsigned long i = 0, bit __attribute__ ((unused)); 78 unsigned int ext_irq;
110 unsigned long val = readl((void __iomem *)INT_STATUS); 79 unsigned int k = 0;
111 80
112 if (val & (1 << 1)) 81 while (intv) {
113 i = 1; 82 ext_irq = voyagergx_stat2irq[k];
114 else if (val & (1 << 2)) 83 if (ext_irq && (intv & 1)) {
115 i = 2; 84 ext_desc = irq_desc + ext_irq;
116 else if (val & (1 << 6)) 85 handle_level_irq(ext_irq, ext_desc);
117 i = 6;
118 else if (val & (1 << 10))
119 i = 10;
120 else if (val & (1 << 11))
121 i = 11;
122 else if (val & (1 << 12))
123 i = 12;
124 else if (val & (1 << 17))
125 i = 17;
126 else
127 printk("Unexpected IRQ irq = %d status = 0x%08lx\n", irq, val);
128 pr_debug("voyagergx_irq_demux %ld \n", i);
129 if (i < VOYAGER_IRQ_NUM) {
130 irq = VOYAGER_IRQ_BASE + i;
131 if (voyagergx_demux[i].func != 0)
132 irq = voyagergx_demux[i].func(irq,
133 voyagergx_demux[i].dev);
134 } 86 }
87 intv >>= 1;
88 k++;
135 } 89 }
136 return irq;
137} 90}
138 91
139static struct irqaction irq0 = {
140 .name = "voyagergx",
141 .handler = voyagergx_interrupt,
142 .flags = IRQF_DISABLED,
143 .mask = CPU_MASK_NONE,
144};
145
146void __init setup_voyagergx_irq(void) 92void __init setup_voyagergx_irq(void)
147{ 93{
148 int i, flag; 94 printk(KERN_INFO "VoyagerGX on irq %d (mapped into %d to %d)\n",
149
150 printk(KERN_INFO "VoyagerGX configured at 0x%x on irq %d(mapped into %d to %d)\n",
151 VOYAGER_BASE,
152 IRQ_VOYAGER, 95 IRQ_VOYAGER,
153 VOYAGER_IRQ_BASE, 96 VOYAGER_IRQ_BASE,
154 VOYAGER_IRQ_BASE + VOYAGER_IRQ_NUM - 1); 97 VOYAGER_IRQ_BASE + VOYAGER_IRQ_NUM - 1);
155 98
156 for (i=0; i<VOYAGER_IRQ_NUM; i++) { 99 register_intc_controller(&intc_desc);
157 flag = 0; 100 set_irq_chained_handler(IRQ_VOYAGER, voyagergx_irq_demux);
158 switch (VOYAGER_IRQ_BASE + i) {
159 case VOYAGER_USBH_IRQ:
160 case VOYAGER_8051_IRQ:
161 case VOYAGER_UART0_IRQ:
162 case VOYAGER_UART1_IRQ:
163 case VOYAGER_AC97_IRQ:
164 flag = 1;
165 }
166 if (flag == 1)
167 irq_desc[VOYAGER_IRQ_BASE + i].chip = &voyagergx_irq_type;
168 }
169
170 setup_irq(IRQ_VOYAGER, &irq0);
171} 101}
diff --git a/include/asm-sh/voyagergx.h b/include/asm-sh/voyagergx.h
index 64c936b22715..d825596562df 100644
--- a/include/asm-sh/voyagergx.h
+++ b/include/asm-sh/voyagergx.h
@@ -27,13 +27,35 @@
27#define VOYAGER_UART_BASE (0x30000 + VOYAGER_BASE) 27#define VOYAGER_UART_BASE (0x30000 + VOYAGER_BASE)
28#define VOYAGER_AC97_BASE (0xa0000 + VOYAGER_BASE) 28#define VOYAGER_AC97_BASE (0xa0000 + VOYAGER_BASE)
29 29
30#define VOYAGER_IRQ_NUM 32 30#define VOYAGER_IRQ_NUM 26
31#define VOYAGER_IRQ_BASE 50 31#define VOYAGER_IRQ_BASE 200
32#define VOYAGER_USBH_IRQ VOYAGER_IRQ_BASE + 6 32
33#define VOYAGER_8051_IRQ VOYAGER_IRQ_BASE + 10 33#define IRQ_SM501_UP (VOYAGER_IRQ_BASE + 0)
34#define VOYAGER_UART0_IRQ VOYAGER_IRQ_BASE + 12 34#define IRQ_SM501_G54 (VOYAGER_IRQ_BASE + 1)
35#define VOYAGER_UART1_IRQ VOYAGER_IRQ_BASE + 13 35#define IRQ_SM501_G53 (VOYAGER_IRQ_BASE + 2)
36#define VOYAGER_AC97_IRQ VOYAGER_IRQ_BASE + 17 36#define IRQ_SM501_G52 (VOYAGER_IRQ_BASE + 3)
37#define IRQ_SM501_G51 (VOYAGER_IRQ_BASE + 4)
38#define IRQ_SM501_G50 (VOYAGER_IRQ_BASE + 5)
39#define IRQ_SM501_G49 (VOYAGER_IRQ_BASE + 6)
40#define IRQ_SM501_G48 (VOYAGER_IRQ_BASE + 7)
41#define IRQ_SM501_I2C (VOYAGER_IRQ_BASE + 8)
42#define IRQ_SM501_PW (VOYAGER_IRQ_BASE + 9)
43#define IRQ_SM501_DMA (VOYAGER_IRQ_BASE + 10)
44#define IRQ_SM501_PCI (VOYAGER_IRQ_BASE + 11)
45#define IRQ_SM501_I2S (VOYAGER_IRQ_BASE + 12)
46#define IRQ_SM501_AC (VOYAGER_IRQ_BASE + 13)
47#define IRQ_SM501_US (VOYAGER_IRQ_BASE + 14)
48#define IRQ_SM501_U1 (VOYAGER_IRQ_BASE + 15)
49#define IRQ_SM501_U0 (VOYAGER_IRQ_BASE + 16)
50#define IRQ_SM501_CV (VOYAGER_IRQ_BASE + 17)
51#define IRQ_SM501_MC (VOYAGER_IRQ_BASE + 18)
52#define IRQ_SM501_S1 (VOYAGER_IRQ_BASE + 19)
53#define IRQ_SM501_S0 (VOYAGER_IRQ_BASE + 20)
54#define IRQ_SM501_UH (VOYAGER_IRQ_BASE + 21)
55#define IRQ_SM501_2D (VOYAGER_IRQ_BASE + 22)
56#define IRQ_SM501_ZD (VOYAGER_IRQ_BASE + 23)
57#define IRQ_SM501_PV (VOYAGER_IRQ_BASE + 24)
58#define IRQ_SM501_CI (VOYAGER_IRQ_BASE + 25)
37 59
38/* ----- MISC controle register ------------------------------ */ 60/* ----- MISC controle register ------------------------------ */
39#define MISC_CTRL (0x000004 + VOYAGER_BASE) 61#define MISC_CTRL (0x000004 + VOYAGER_BASE)
@@ -313,4 +335,7 @@
313void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t); 335void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t);
314int voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t); 336int voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t);
315 337
338/* arch/sh/cchips/voyagergx/irq.c */
339void setup_voyagergx_irq(void);
340
316#endif /* _VOYAGER_GX_REG_H */ 341#endif /* _VOYAGER_GX_REG_H */