aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/cchips
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-13 12:49:04 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-13 12:49:04 -0400
commitdcf397f037f52add9945eced57ca300ab6a4413c (patch)
treee78767d164589e9097a54bf564b072fb01f80820 /arch/sh/cchips
parent6faf035cf9fdd8283c2b2b2c34b76b5445ec6fc4 (diff)
parent68ee0f9c98a42e36f9eab29155b2bb0e7e409ac6 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (124 commits) sh: allow building for both r2d boards in same binary. sh: fix r2d board detection sh: Discard .exit.text/.exit.data at runtime. sh: Fix up some section alignments in linker script. sh: Fix SH-4 DMAC CHCR masking. sh: Rip out left-over nommu cond syscall cruft. sh: Make kgdb i-cache flushing less inept. sh: kgdb section mismatches and tidying. sh: cleanup struct irqaction initializers. sh: early_printk tidying. video: pvr2fb: Add TV (RGB) support to Dreamcast PVR driver. sh: Conditionalize gUSA support. sh: Follow gUSA preempt changes in __switch_to(). sh: Tidy up gUSA preempt handling. sh: __copy_user() optimizations for small copies. sh: clkfwk: Support multi-level clock propagation. sh: Fix URAM start address on SH7785. sh: Use boot_cpu_data for CPU probe. sh: Support extended mode TLB on SH-X3. sh: Bump MAX_ACTIVE_REGIONS for SH7785. ...
Diffstat (limited to 'arch/sh/cchips')
-rw-r--r--arch/sh/cchips/Kconfig13
-rw-r--r--arch/sh/cchips/hd6446x/hd64461.c13
-rw-r--r--arch/sh/cchips/hd6446x/hd64465/setup.c7
-rw-r--r--arch/sh/cchips/voyagergx/irq.c188
4 files changed, 76 insertions, 145 deletions
diff --git a/arch/sh/cchips/Kconfig b/arch/sh/cchips/Kconfig
index 2e516e9a6ede..7892361eedc8 100644
--- a/arch/sh/cchips/Kconfig
+++ b/arch/sh/cchips/Kconfig
@@ -1,18 +1,5 @@
1menu "Companion Chips" 1menu "Companion Chips"
2 2
3config VOYAGERGX
4 bool "VoyagerGX chip support"
5 depends on SH_RTS7751R2D
6 help
7 Selecting this option will support Silicon Motion, Inc. SM501.
8 Designed to complement needs for the embedded industry, it
9 provides video and 2D capability. To reduce system cost a
10 wide variety of include I/O is supported, including analog RGB
11 and digital LCD Panel interface, 8-bit parallel interface, USB,
12 UART, IrDA, Zoom Video, AC97 or I2S, SSP, PWM, and I2C. There
13 are additional GPIO bits that can be used to interface to
14 external as well.
15
16config HD6446X_SERIES 3config HD6446X_SERIES
17 bool 4 bool
18 5
diff --git a/arch/sh/cchips/hd6446x/hd64461.c b/arch/sh/cchips/hd6446x/hd64461.c
index 97f6512aa1b7..f1a4a0763c59 100644
--- a/arch/sh/cchips/hd6446x/hd64461.c
+++ b/arch/sh/cchips/hd6446x/hd64461.c
@@ -14,6 +14,9 @@
14#include <asm/irq.h> 14#include <asm/irq.h>
15#include <asm/hd64461.h> 15#include <asm/hd64461.h>
16 16
17/* This belongs in cpu specific */
18#define INTC_ICR1 0xA4140010UL
19
17static void disable_hd64461_irq(unsigned int irq) 20static void disable_hd64461_irq(unsigned int irq)
18{ 21{
19 unsigned short nimr; 22 unsigned short nimr;
@@ -121,10 +124,15 @@ int hd64461_irq_demux(int irq)
121 } 124 }
122 } 125 }
123 } 126 }
124 return __irq_demux(irq); 127 return irq;
125} 128}
126 129
127static struct irqaction irq0 = { hd64461_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "HD64461", NULL, NULL }; 130static struct irqaction irq0 = {
131 .handler = hd64461_interrupt,
132 .flags = IRQF_DISABLED,
133 .mask = CPU_MASK_NONE,
134 .name = "HD64461",
135};
128 136
129int __init setup_hd64461(void) 137int __init setup_hd64461(void)
130{ 138{
@@ -143,6 +151,7 @@ int __init setup_hd64461(void)
143#endif 151#endif
144 outw(0xffff, HD64461_NIMR); 152 outw(0xffff, HD64461_NIMR);
145 153
154 /* IRQ 80 -> 95 belongs to HD64461 */
146 for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) { 155 for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) {
147 irq_desc[i].chip = &hd64461_irq_type; 156 irq_desc[i].chip = &hd64461_irq_type;
148 } 157 }
diff --git a/arch/sh/cchips/hd6446x/hd64465/setup.c b/arch/sh/cchips/hd6446x/hd64465/setup.c
index d126e1f30dee..5cef0db4018b 100644
--- a/arch/sh/cchips/hd6446x/hd64465/setup.c
+++ b/arch/sh/cchips/hd6446x/hd64465/setup.c
@@ -147,7 +147,12 @@ int hd64465_irq_demux(int irq)
147 return irq; 147 return irq;
148} 148}
149 149
150static struct irqaction irq0 = { hd64465_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "HD64465", NULL, NULL}; 150static struct irqaction irq0 = {
151 .handler = hd64465_interrupt,
152 .flags = IRQF_DISABLED,
153 .mask = CPU_MASK_NONE,
154 .name = "HD64465",
155};
151 156
152 157
153static int __init setup_hd64465(void) 158static int __init setup_hd64465(void)
diff --git a/arch/sh/cchips/voyagergx/irq.c b/arch/sh/cchips/voyagergx/irq.c
index d70e5c8461b5..ade303876841 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[] __initdata = {
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[] __initdata = {
94 int (*demux)(int irq, void *dev), void *dev) 53 { VOYAGER_INT_MASK, 0, 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}