diff options
author | Kristoffer Ericson <kristoffer.ericson@gmail.com> | 2007-07-17 00:52:38 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2007-07-19 23:18:19 -0400 |
commit | 4aafae27d0ce73f8507b8983b36006b734aa343a (patch) | |
tree | 0bdaf22415bf272a4cb9d7e061a4d860f114abe4 /arch/sh/cchips/hd6446x/hd64461.c | |
parent | e6c972f21828f16d12704e5cf67d6f79c26cb53b (diff) |
sh: hd64461 tidying.
Kill off the hd64461 io.c, as all of the hd64461 users are now
using the generic I/O routines.
[ hd64461/ moved to hd64461.c by Paul ]
Signed-off-by: Kristoffer Ericson <kristoffer.ericson@gmail.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/cchips/hd6446x/hd64461.c')
-rw-r--r-- | arch/sh/cchips/hd6446x/hd64461.c | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/arch/sh/cchips/hd6446x/hd64461.c b/arch/sh/cchips/hd6446x/hd64461.c new file mode 100644 index 000000000000..97f6512aa1b7 --- /dev/null +++ b/arch/sh/cchips/hd6446x/hd64461.c | |||
@@ -0,0 +1,161 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000 YAEGASHI Takeshi | ||
3 | * Hitachi HD64461 companion chip support | ||
4 | */ | ||
5 | |||
6 | #include <linux/sched.h> | ||
7 | #include <linux/module.h> | ||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/param.h> | ||
10 | #include <linux/interrupt.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/irq.h> | ||
13 | #include <asm/io.h> | ||
14 | #include <asm/irq.h> | ||
15 | #include <asm/hd64461.h> | ||
16 | |||
17 | static void disable_hd64461_irq(unsigned int irq) | ||
18 | { | ||
19 | unsigned short nimr; | ||
20 | unsigned short mask = 1 << (irq - HD64461_IRQBASE); | ||
21 | |||
22 | nimr = inw(HD64461_NIMR); | ||
23 | nimr |= mask; | ||
24 | outw(nimr, HD64461_NIMR); | ||
25 | } | ||
26 | |||
27 | static void enable_hd64461_irq(unsigned int irq) | ||
28 | { | ||
29 | unsigned short nimr; | ||
30 | unsigned short mask = 1 << (irq - HD64461_IRQBASE); | ||
31 | |||
32 | nimr = inw(HD64461_NIMR); | ||
33 | nimr &= ~mask; | ||
34 | outw(nimr, HD64461_NIMR); | ||
35 | } | ||
36 | |||
37 | static void mask_and_ack_hd64461(unsigned int irq) | ||
38 | { | ||
39 | disable_hd64461_irq(irq); | ||
40 | #ifdef CONFIG_HD64461_ENABLER | ||
41 | if (irq == HD64461_IRQBASE + 13) | ||
42 | outb(0x00, HD64461_PCC1CSCR); | ||
43 | #endif | ||
44 | } | ||
45 | |||
46 | static void end_hd64461_irq(unsigned int irq) | ||
47 | { | ||
48 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
49 | enable_hd64461_irq(irq); | ||
50 | } | ||
51 | |||
52 | static unsigned int startup_hd64461_irq(unsigned int irq) | ||
53 | { | ||
54 | enable_hd64461_irq(irq); | ||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | static void shutdown_hd64461_irq(unsigned int irq) | ||
59 | { | ||
60 | disable_hd64461_irq(irq); | ||
61 | } | ||
62 | |||
63 | static struct hw_interrupt_type hd64461_irq_type = { | ||
64 | .typename = "HD64461-IRQ", | ||
65 | .startup = startup_hd64461_irq, | ||
66 | .shutdown = shutdown_hd64461_irq, | ||
67 | .enable = enable_hd64461_irq, | ||
68 | .disable = disable_hd64461_irq, | ||
69 | .ack = mask_and_ack_hd64461, | ||
70 | .end = end_hd64461_irq, | ||
71 | }; | ||
72 | |||
73 | static irqreturn_t hd64461_interrupt(int irq, void *dev_id) | ||
74 | { | ||
75 | printk(KERN_INFO | ||
76 | "HD64461: spurious interrupt, nirr: 0x%x nimr: 0x%x\n", | ||
77 | inw(HD64461_NIRR), inw(HD64461_NIMR)); | ||
78 | |||
79 | return IRQ_NONE; | ||
80 | } | ||
81 | |||
82 | static struct { | ||
83 | int (*func) (int, void *); | ||
84 | void *dev; | ||
85 | } hd64461_demux[HD64461_IRQ_NUM]; | ||
86 | |||
87 | void hd64461_register_irq_demux(int irq, | ||
88 | int (*demux) (int irq, void *dev), void *dev) | ||
89 | { | ||
90 | hd64461_demux[irq - HD64461_IRQBASE].func = demux; | ||
91 | hd64461_demux[irq - HD64461_IRQBASE].dev = dev; | ||
92 | } | ||
93 | |||
94 | EXPORT_SYMBOL(hd64461_register_irq_demux); | ||
95 | |||
96 | void hd64461_unregister_irq_demux(int irq) | ||
97 | { | ||
98 | hd64461_demux[irq - HD64461_IRQBASE].func = 0; | ||
99 | } | ||
100 | |||
101 | EXPORT_SYMBOL(hd64461_unregister_irq_demux); | ||
102 | |||
103 | int hd64461_irq_demux(int irq) | ||
104 | { | ||
105 | if (irq == CONFIG_HD64461_IRQ) { | ||
106 | unsigned short bit; | ||
107 | unsigned short nirr = inw(HD64461_NIRR); | ||
108 | unsigned short nimr = inw(HD64461_NIMR); | ||
109 | int i; | ||
110 | |||
111 | nirr &= ~nimr; | ||
112 | for (bit = 1, i = 0; i < 16; bit <<= 1, i++) | ||
113 | if (nirr & bit) | ||
114 | break; | ||
115 | if (i == 16) | ||
116 | irq = CONFIG_HD64461_IRQ; | ||
117 | else { | ||
118 | irq = HD64461_IRQBASE + i; | ||
119 | if (hd64461_demux[i].func != 0) { | ||
120 | irq = hd64461_demux[i].func(irq, hd64461_demux[i].dev); | ||
121 | } | ||
122 | } | ||
123 | } | ||
124 | return __irq_demux(irq); | ||
125 | } | ||
126 | |||
127 | static struct irqaction irq0 = { hd64461_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "HD64461", NULL, NULL }; | ||
128 | |||
129 | int __init setup_hd64461(void) | ||
130 | { | ||
131 | int i; | ||
132 | |||
133 | if (!MACH_HD64461) | ||
134 | return 0; | ||
135 | |||
136 | printk(KERN_INFO | ||
137 | "HD64461 configured at 0x%x on irq %d(mapped into %d to %d)\n", | ||
138 | CONFIG_HD64461_IOBASE, CONFIG_HD64461_IRQ, HD64461_IRQBASE, | ||
139 | HD64461_IRQBASE + 15); | ||
140 | |||
141 | #if defined(CONFIG_CPU_SUBTYPE_SH7709) /* Should be at processor specific part.. */ | ||
142 | outw(0x2240, INTC_ICR1); | ||
143 | #endif | ||
144 | outw(0xffff, HD64461_NIMR); | ||
145 | |||
146 | for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) { | ||
147 | irq_desc[i].chip = &hd64461_irq_type; | ||
148 | } | ||
149 | |||
150 | setup_irq(CONFIG_HD64461_IRQ, &irq0); | ||
151 | |||
152 | #ifdef CONFIG_HD64461_ENABLER | ||
153 | printk(KERN_INFO "HD64461: enabling PCMCIA devices\n"); | ||
154 | outb(0x4c, HD64461_PCC1CSCIER); | ||
155 | outb(0x00, HD64461_PCC1CSCR); | ||
156 | #endif | ||
157 | |||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | module_init(setup_hd64461); | ||