diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/m68k/hp300 |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/m68k/hp300')
-rw-r--r-- | arch/m68k/hp300/Makefile | 5 | ||||
-rw-r--r-- | arch/m68k/hp300/README.hp300 | 14 | ||||
-rw-r--r-- | arch/m68k/hp300/config.c | 279 | ||||
-rw-r--r-- | arch/m68k/hp300/hp300map.map | 252 | ||||
-rw-r--r-- | arch/m68k/hp300/ints.c | 175 | ||||
-rw-r--r-- | arch/m68k/hp300/ints.h | 9 | ||||
-rw-r--r-- | arch/m68k/hp300/ksyms.c | 9 | ||||
-rw-r--r-- | arch/m68k/hp300/reboot.S | 16 | ||||
-rw-r--r-- | arch/m68k/hp300/time.c | 78 | ||||
-rw-r--r-- | arch/m68k/hp300/time.h | 4 |
10 files changed, 841 insertions, 0 deletions
diff --git a/arch/m68k/hp300/Makefile b/arch/m68k/hp300/Makefile new file mode 100644 index 000000000000..89b6317899e3 --- /dev/null +++ b/arch/m68k/hp300/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | # | ||
2 | # Makefile for Linux arch/m68k/hp300 source directory | ||
3 | # | ||
4 | |||
5 | obj-y := ksyms.o config.o ints.o time.o reboot.o | ||
diff --git a/arch/m68k/hp300/README.hp300 b/arch/m68k/hp300/README.hp300 new file mode 100644 index 000000000000..47073fbd400d --- /dev/null +++ b/arch/m68k/hp300/README.hp300 | |||
@@ -0,0 +1,14 @@ | |||
1 | HP300 notes | ||
2 | ----------- | ||
3 | |||
4 | The Linux/HP web page is at <http://www.tazenda.demon.co.uk/phil/linux-hp/> | ||
5 | |||
6 | Currently only 9000/340 machines have been tested. Any amount of RAM should | ||
7 | work now but I've only tried 16MB and 12MB. | ||
8 | |||
9 | The serial console is probably broken at the moment but the Topcat/HIL keyboard | ||
10 | combination seems to work for me. Your mileage may vary. | ||
11 | |||
12 | The LANCE driver works after a fashion but only if you reset the chip before | ||
13 | every packet. This doesn't make for very speedy operation. | ||
14 | |||
diff --git a/arch/m68k/hp300/config.c b/arch/m68k/hp300/config.c new file mode 100644 index 000000000000..a0b854f3f94a --- /dev/null +++ b/arch/m68k/hp300/config.c | |||
@@ -0,0 +1,279 @@ | |||
1 | /* | ||
2 | * linux/arch/m68k/hp300/config.c | ||
3 | * | ||
4 | * Copyright (C) 1998 Philip Blundell <philb@gnu.org> | ||
5 | * | ||
6 | * This file contains the HP300-specific initialisation code. It gets | ||
7 | * called by setup.c. | ||
8 | */ | ||
9 | |||
10 | #include <linux/config.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/string.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/console.h> | ||
16 | |||
17 | #include <asm/bootinfo.h> | ||
18 | #include <asm/machdep.h> | ||
19 | #include <asm/blinken.h> | ||
20 | #include <asm/io.h> /* readb() and writeb() */ | ||
21 | #include <asm/hp300hw.h> | ||
22 | #include <asm/rtc.h> | ||
23 | |||
24 | #include "ints.h" | ||
25 | #include "time.h" | ||
26 | |||
27 | unsigned long hp300_model; | ||
28 | unsigned long hp300_uart_scode = -1; | ||
29 | unsigned char ledstate; | ||
30 | |||
31 | static char s_hp330[] __initdata = "330"; | ||
32 | static char s_hp340[] __initdata = "340"; | ||
33 | static char s_hp345[] __initdata = "345"; | ||
34 | static char s_hp360[] __initdata = "360"; | ||
35 | static char s_hp370[] __initdata = "370"; | ||
36 | static char s_hp375[] __initdata = "375"; | ||
37 | static char s_hp380[] __initdata = "380"; | ||
38 | static char s_hp385[] __initdata = "385"; | ||
39 | static char s_hp400[] __initdata = "400"; | ||
40 | static char s_hp425t[] __initdata = "425t"; | ||
41 | static char s_hp425s[] __initdata = "425s"; | ||
42 | static char s_hp425e[] __initdata = "425e"; | ||
43 | static char s_hp433t[] __initdata = "433t"; | ||
44 | static char s_hp433s[] __initdata = "433s"; | ||
45 | static char *hp300_models[] __initdata = { | ||
46 | [HP_320] = NULL, | ||
47 | [HP_330] = s_hp330, | ||
48 | [HP_340] = s_hp340, | ||
49 | [HP_345] = s_hp345, | ||
50 | [HP_350] = NULL, | ||
51 | [HP_360] = s_hp360, | ||
52 | [HP_370] = s_hp370, | ||
53 | [HP_375] = s_hp375, | ||
54 | [HP_380] = s_hp380, | ||
55 | [HP_385] = s_hp385, | ||
56 | [HP_400] = s_hp400, | ||
57 | [HP_425T] = s_hp425t, | ||
58 | [HP_425S] = s_hp425s, | ||
59 | [HP_425E] = s_hp425e, | ||
60 | [HP_433T] = s_hp433t, | ||
61 | [HP_433S] = s_hp433s, | ||
62 | }; | ||
63 | |||
64 | static char hp300_model_name[13] = "HP9000/"; | ||
65 | |||
66 | extern void hp300_reset(void); | ||
67 | extern irqreturn_t (*hp300_default_handler[])(int, void *, struct pt_regs *); | ||
68 | extern int show_hp300_interrupts(struct seq_file *, void *); | ||
69 | #ifdef CONFIG_SERIAL_8250_CONSOLE | ||
70 | extern int hp300_setup_serial_console(void) __init; | ||
71 | #endif | ||
72 | |||
73 | int __init hp300_parse_bootinfo(const struct bi_record *record) | ||
74 | { | ||
75 | int unknown = 0; | ||
76 | const unsigned long *data = record->data; | ||
77 | |||
78 | switch (record->tag) { | ||
79 | case BI_HP300_MODEL: | ||
80 | hp300_model = *data; | ||
81 | break; | ||
82 | |||
83 | case BI_HP300_UART_SCODE: | ||
84 | hp300_uart_scode = *data; | ||
85 | break; | ||
86 | |||
87 | case BI_HP300_UART_ADDR: | ||
88 | /* serial port address: ignored here */ | ||
89 | break; | ||
90 | |||
91 | default: | ||
92 | unknown = 1; | ||
93 | } | ||
94 | |||
95 | return unknown; | ||
96 | } | ||
97 | |||
98 | #ifdef CONFIG_HEARTBEAT | ||
99 | static void hp300_pulse(int x) | ||
100 | { | ||
101 | if (x) | ||
102 | blinken_leds(0x10, 0); | ||
103 | else | ||
104 | blinken_leds(0, 0x10); | ||
105 | } | ||
106 | #endif | ||
107 | |||
108 | static void hp300_get_model(char *model) | ||
109 | { | ||
110 | strcpy(model, hp300_model_name); | ||
111 | } | ||
112 | |||
113 | #define RTCBASE 0xf0420000 | ||
114 | #define RTC_DATA 0x1 | ||
115 | #define RTC_CMD 0x3 | ||
116 | |||
117 | #define RTC_BUSY 0x02 | ||
118 | #define RTC_DATA_RDY 0x01 | ||
119 | |||
120 | #define rtc_busy() (in_8(RTCBASE + RTC_CMD) & RTC_BUSY) | ||
121 | #define rtc_data_available() (in_8(RTCBASE + RTC_CMD) & RTC_DATA_RDY) | ||
122 | #define rtc_status() (in_8(RTCBASE + RTC_CMD)) | ||
123 | #define rtc_command(x) out_8(RTCBASE + RTC_CMD, (x)) | ||
124 | #define rtc_read_data() (in_8(RTCBASE + RTC_DATA)) | ||
125 | #define rtc_write_data(x) out_8(RTCBASE + RTC_DATA, (x)) | ||
126 | |||
127 | #define RTC_SETREG 0xe0 | ||
128 | #define RTC_WRITEREG 0xc2 | ||
129 | #define RTC_READREG 0xc3 | ||
130 | |||
131 | #define RTC_REG_SEC2 0 | ||
132 | #define RTC_REG_SEC1 1 | ||
133 | #define RTC_REG_MIN2 2 | ||
134 | #define RTC_REG_MIN1 3 | ||
135 | #define RTC_REG_HOUR2 4 | ||
136 | #define RTC_REG_HOUR1 5 | ||
137 | #define RTC_REG_WDAY 6 | ||
138 | #define RTC_REG_DAY2 7 | ||
139 | #define RTC_REG_DAY1 8 | ||
140 | #define RTC_REG_MON2 9 | ||
141 | #define RTC_REG_MON1 10 | ||
142 | #define RTC_REG_YEAR2 11 | ||
143 | #define RTC_REG_YEAR1 12 | ||
144 | |||
145 | #define RTC_HOUR1_24HMODE 0x8 | ||
146 | |||
147 | #define RTC_STAT_MASK 0xf0 | ||
148 | #define RTC_STAT_RDY 0x40 | ||
149 | |||
150 | static inline unsigned char hp300_rtc_read(unsigned char reg) | ||
151 | { | ||
152 | unsigned char s, ret; | ||
153 | unsigned long flags; | ||
154 | |||
155 | local_irq_save(flags); | ||
156 | |||
157 | while (rtc_busy()); | ||
158 | rtc_command(RTC_SETREG); | ||
159 | while (rtc_busy()); | ||
160 | rtc_write_data(reg); | ||
161 | while (rtc_busy()); | ||
162 | rtc_command(RTC_READREG); | ||
163 | |||
164 | do { | ||
165 | while (!rtc_data_available()); | ||
166 | s = rtc_status(); | ||
167 | ret = rtc_read_data(); | ||
168 | } while ((s & RTC_STAT_MASK) != RTC_STAT_RDY); | ||
169 | |||
170 | local_irq_restore(flags); | ||
171 | |||
172 | return ret; | ||
173 | } | ||
174 | |||
175 | static inline unsigned char hp300_rtc_write(unsigned char reg, | ||
176 | unsigned char val) | ||
177 | { | ||
178 | unsigned char s, ret; | ||
179 | unsigned long flags; | ||
180 | |||
181 | local_irq_save(flags); | ||
182 | |||
183 | while (rtc_busy()); | ||
184 | rtc_command(RTC_SETREG); | ||
185 | while (rtc_busy()); | ||
186 | rtc_write_data((val << 4) | reg); | ||
187 | while (rtc_busy()); | ||
188 | rtc_command(RTC_WRITEREG); | ||
189 | while (rtc_busy()); | ||
190 | rtc_command(RTC_READREG); | ||
191 | |||
192 | do { | ||
193 | while (!rtc_data_available()); | ||
194 | s = rtc_status(); | ||
195 | ret = rtc_read_data(); | ||
196 | } while ((s & RTC_STAT_MASK) != RTC_STAT_RDY); | ||
197 | |||
198 | local_irq_restore(flags); | ||
199 | |||
200 | return ret; | ||
201 | } | ||
202 | |||
203 | static int hp300_hwclk(int op, struct rtc_time *t) | ||
204 | { | ||
205 | if (!op) { /* read */ | ||
206 | t->tm_sec = hp300_rtc_read(RTC_REG_SEC1) * 10 + | ||
207 | hp300_rtc_read(RTC_REG_SEC2); | ||
208 | t->tm_min = hp300_rtc_read(RTC_REG_MIN1) * 10 + | ||
209 | hp300_rtc_read(RTC_REG_MIN2); | ||
210 | t->tm_hour = (hp300_rtc_read(RTC_REG_HOUR1) & 3) * 10 + | ||
211 | hp300_rtc_read(RTC_REG_HOUR2); | ||
212 | t->tm_wday = -1; | ||
213 | t->tm_mday = hp300_rtc_read(RTC_REG_DAY1) * 10 + | ||
214 | hp300_rtc_read(RTC_REG_DAY2); | ||
215 | t->tm_mon = hp300_rtc_read(RTC_REG_MON1) * 10 + | ||
216 | hp300_rtc_read(RTC_REG_MON2) - 1; | ||
217 | t->tm_year = hp300_rtc_read(RTC_REG_YEAR1) * 10 + | ||
218 | hp300_rtc_read(RTC_REG_YEAR2); | ||
219 | if (t->tm_year <= 69) | ||
220 | t->tm_year += 100; | ||
221 | } else { | ||
222 | hp300_rtc_write(RTC_REG_SEC1, t->tm_sec / 10); | ||
223 | hp300_rtc_write(RTC_REG_SEC2, t->tm_sec % 10); | ||
224 | hp300_rtc_write(RTC_REG_MIN1, t->tm_min / 10); | ||
225 | hp300_rtc_write(RTC_REG_MIN2, t->tm_min % 10); | ||
226 | hp300_rtc_write(RTC_REG_HOUR1, | ||
227 | ((t->tm_hour / 10) & 3) | RTC_HOUR1_24HMODE); | ||
228 | hp300_rtc_write(RTC_REG_HOUR2, t->tm_hour % 10); | ||
229 | hp300_rtc_write(RTC_REG_DAY1, t->tm_mday / 10); | ||
230 | hp300_rtc_write(RTC_REG_DAY2, t->tm_mday % 10); | ||
231 | hp300_rtc_write(RTC_REG_MON1, (t->tm_mon + 1) / 10); | ||
232 | hp300_rtc_write(RTC_REG_MON2, (t->tm_mon + 1) % 10); | ||
233 | if (t->tm_year >= 100) | ||
234 | t->tm_year -= 100; | ||
235 | hp300_rtc_write(RTC_REG_YEAR1, t->tm_year / 10); | ||
236 | hp300_rtc_write(RTC_REG_YEAR2, t->tm_year % 10); | ||
237 | } | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | static unsigned int hp300_get_ss(void) | ||
243 | { | ||
244 | return hp300_rtc_read(RTC_REG_SEC1) * 10 + | ||
245 | hp300_rtc_read(RTC_REG_SEC2); | ||
246 | } | ||
247 | |||
248 | void __init config_hp300(void) | ||
249 | { | ||
250 | mach_sched_init = hp300_sched_init; | ||
251 | mach_init_IRQ = hp300_init_IRQ; | ||
252 | mach_request_irq = hp300_request_irq; | ||
253 | mach_free_irq = hp300_free_irq; | ||
254 | mach_get_model = hp300_get_model; | ||
255 | mach_get_irq_list = show_hp300_interrupts; | ||
256 | mach_gettimeoffset = hp300_gettimeoffset; | ||
257 | mach_default_handler = &hp300_default_handler; | ||
258 | mach_hwclk = hp300_hwclk; | ||
259 | mach_get_ss = hp300_get_ss; | ||
260 | mach_reset = hp300_reset; | ||
261 | #ifdef CONFIG_HEARTBEAT | ||
262 | mach_heartbeat = hp300_pulse; | ||
263 | #endif | ||
264 | #ifdef CONFIG_DUMMY_CONSOLE | ||
265 | conswitchp = &dummy_con; | ||
266 | #endif | ||
267 | mach_max_dma_address = 0xffffffff; | ||
268 | |||
269 | if (hp300_model >= HP_330 && hp300_model <= HP_433S && hp300_model != HP_350) { | ||
270 | printk(KERN_INFO "Detected HP9000 model %s\n", hp300_models[hp300_model-HP_320]); | ||
271 | strcat(hp300_model_name, hp300_models[hp300_model-HP_320]); | ||
272 | } | ||
273 | else { | ||
274 | panic("Unknown HP9000 Model"); | ||
275 | } | ||
276 | #ifdef CONFIG_SERIAL_8250_CONSOLE | ||
277 | hp300_setup_serial_console(); | ||
278 | #endif | ||
279 | } | ||
diff --git a/arch/m68k/hp300/hp300map.map b/arch/m68k/hp300/hp300map.map new file mode 100644 index 000000000000..6b45f0abc957 --- /dev/null +++ b/arch/m68k/hp300/hp300map.map | |||
@@ -0,0 +1,252 @@ | |||
1 | # HP300 kernel keymap. This uses 7 modifier combinations. | ||
2 | keymaps 0-2,4-5,8,12 | ||
3 | # Change the above line into | ||
4 | # keymaps 0-2,4-6,8,12 | ||
5 | # in case you want the entries | ||
6 | # altgr control keycode 83 = Boot | ||
7 | # altgr control keycode 111 = Boot | ||
8 | # below. | ||
9 | # | ||
10 | # In fact AltGr is used very little, and one more keymap can | ||
11 | # be saved by mapping AltGr to Alt (and adapting a few entries): | ||
12 | # keycode 100 = Alt | ||
13 | # | ||
14 | keycode 1 = | ||
15 | keycode 2 = Alt | ||
16 | keycode 3 = Alt | ||
17 | keycode 4 = Shift | ||
18 | keycode 5 = Shift | ||
19 | keycode 6 = Control | ||
20 | keycode 7 = | ||
21 | keycode 8 = | ||
22 | keycode 9 = | ||
23 | keycode 10 = | ||
24 | keycode 11 = | ||
25 | keycode 12 = | ||
26 | keycode 13 = | ||
27 | keycode 14 = | ||
28 | keycode 15 = | ||
29 | keycode 16 = | ||
30 | keycode 17 = | ||
31 | keycode 18 = | ||
32 | keycode 19 = | ||
33 | keycode 20 = | ||
34 | keycode 21 = | ||
35 | keycode 22 = | ||
36 | keycode 23 = | ||
37 | keycode 24 = b | ||
38 | keycode 25 = v | ||
39 | keycode 26 = c | ||
40 | keycode 27 = x | ||
41 | keycode 28 = z | ||
42 | keycode 29 = | ||
43 | keycode 30 = | ||
44 | keycode 31 = Escape Delete | ||
45 | keycode 32 = | ||
46 | keycode 33 = | ||
47 | keycode 34 = | ||
48 | keycode 35 = | ||
49 | keycode 36 = | ||
50 | keycode 37 = | ||
51 | keycode 38 = | ||
52 | keycode 39 = | ||
53 | keycode 40 = h | ||
54 | keycode 41 = g | ||
55 | keycode 42 = f | ||
56 | keycode 43 = d | ||
57 | keycode 44 = s | ||
58 | keycode 45 = a | ||
59 | keycode 46 = | ||
60 | keycode 47 = Caps_Lock | ||
61 | keycode 48 = u | ||
62 | keycode 49 = y | ||
63 | keycode 50 = t | ||
64 | keycode 51 = r | ||
65 | keycode 52 = e | ||
66 | keycode 53 = w | ||
67 | keycode 54 = q | ||
68 | keycode 55 = Tab Tab | ||
69 | alt keycode 55 = Meta_Tab | ||
70 | keycode 56 = seven ampersand | ||
71 | keycode 57 = six asciicircum | ||
72 | keycode 58 = five percent | ||
73 | keycode 59 = four dollar | ||
74 | keycode 60 = three numbersign | ||
75 | keycode 61 = two at at | ||
76 | keycode 62 = one exclam exclam | ||
77 | keycode 63 = grave asciitilde | ||
78 | control keycode 63 = nul | ||
79 | alt keycode 63 = Meta_grave | ||
80 | keycode 64 = | ||
81 | keycode 65 = | ||
82 | keycode 66 = | ||
83 | keycode 67 = | ||
84 | keycode 68 = | ||
85 | keycode 69 = | ||
86 | keycode 70 = | ||
87 | keycode 71 = | ||
88 | keycode 72 = | ||
89 | keycode 73 = F4 | ||
90 | control keycode 73 = Console_4 | ||
91 | keycode 74 = F3 | ||
92 | control keycode 74 = Console_3 | ||
93 | keycode 75 = F2 | ||
94 | control keycode 75 = Console_2 | ||
95 | keycode 76 = F1 | ||
96 | control keycode 76 = Console_1 | ||
97 | keycode 77 = | ||
98 | keycode 78 = | ||
99 | keycode 79 = | ||
100 | keycode 80 = | ||
101 | keycode 81 = F5 | ||
102 | control keycode 81 = Console_5 | ||
103 | keycode 82 = F6 | ||
104 | control keycode 82 = Console_6 | ||
105 | keycode 83 = F7 | ||
106 | control keycode 83 = Console_7 | ||
107 | keycode 84 = F8 | ||
108 | control keycode 84 = Console_8 | ||
109 | keycode 85 = | ||
110 | keycode 86 = | ||
111 | keycode 87 = | ||
112 | keycode 88 = eight asterisk asterisk | ||
113 | keycode 89 = nine parenleft bracketleft | ||
114 | keycode 90 = zero parenright bracketright | ||
115 | keycode 91 = minus underscore | ||
116 | keycode 92 = equal plus | ||
117 | keycode 93 = BackSpace | ||
118 | keycode 94 = | ||
119 | keycode 95 = | ||
120 | keycode 96 = i | ||
121 | keycode 97 = o | ||
122 | keycode 98 = p | ||
123 | keycode 99 = bracketleft braceleft | ||
124 | keycode 100 = bracketright braceright | ||
125 | keycode 101 = backslash bar | ||
126 | control keycode 101 = Control_backslash | ||
127 | alt keycode 101 = Meta_backslash | ||
128 | keycode 102 = | ||
129 | keycode 103 = | ||
130 | keycode 104 = j | ||
131 | keycode 105 = k | ||
132 | keycode 106 = l | ||
133 | keycode 107 = semicolon colon | ||
134 | alt keycode 107 = Meta_semicolon | ||
135 | keycode 108 = apostrophe quotedbl | ||
136 | control keycode 108 = Control_g | ||
137 | alt keycode 108 = Meta_apostrophe | ||
138 | keycode 109 = Return | ||
139 | keycode 110 = | ||
140 | keycode 111 = | ||
141 | keycode 112 = m | ||
142 | keycode 113 = comma less | ||
143 | keycode 114 = period greater | ||
144 | keycode 115 = slash question | ||
145 | keycode 116 = | ||
146 | keycode 117 = | ||
147 | keycode 118 = | ||
148 | keycode 119 = | ||
149 | keycode 120 = n | ||
150 | keycode 121 = space space | ||
151 | keycode 122 = | ||
152 | keycode 123 = | ||
153 | keycode 124 = Left | ||
154 | keycode 125 = Down | ||
155 | keycode 126 = Up | ||
156 | keycode 127 = Right | ||
157 | string F1 = "\033[[A" | ||
158 | string F2 = "\033[[B" | ||
159 | string F3 = "\033[[C" | ||
160 | string F4 = "\033[[D" | ||
161 | string F5 = "\033[[E" | ||
162 | string F6 = "\033[17~" | ||
163 | string F7 = "\033[18~" | ||
164 | string F8 = "\033[19~" | ||
165 | string F9 = "\033[20~" | ||
166 | string F10 = "\033[21~" | ||
167 | string F11 = "\033[23~" | ||
168 | string F12 = "\033[24~" | ||
169 | string F13 = "\033[25~" | ||
170 | string F14 = "\033[26~" | ||
171 | string F15 = "\033[28~" | ||
172 | string F16 = "\033[29~" | ||
173 | string F17 = "\033[31~" | ||
174 | string F18 = "\033[32~" | ||
175 | string F19 = "\033[33~" | ||
176 | string F20 = "\033[34~" | ||
177 | string Find = "\033[1~" | ||
178 | string Insert = "\033[2~" | ||
179 | string Remove = "\033[3~" | ||
180 | string Select = "\033[4~" | ||
181 | string Prior = "\033[5~" | ||
182 | string Next = "\033[6~" | ||
183 | string Macro = "\033[M" | ||
184 | string Pause = "\033[P" | ||
185 | compose '`' 'A' to 'À' | ||
186 | compose '`' 'a' to 'à' | ||
187 | compose '\'' 'A' to 'Á' | ||
188 | compose '\'' 'a' to 'á' | ||
189 | compose '^' 'A' to 'Â' | ||
190 | compose '^' 'a' to 'â' | ||
191 | compose '~' 'A' to 'Ã' | ||
192 | compose '~' 'a' to 'ã' | ||
193 | compose '"' 'A' to 'Ä' | ||
194 | compose '"' 'a' to 'ä' | ||
195 | compose 'O' 'A' to 'Å' | ||
196 | compose 'o' 'a' to 'å' | ||
197 | compose '0' 'A' to 'Å' | ||
198 | compose '0' 'a' to 'å' | ||
199 | compose 'A' 'A' to 'Å' | ||
200 | compose 'a' 'a' to 'å' | ||
201 | compose 'A' 'E' to 'Æ' | ||
202 | compose 'a' 'e' to 'æ' | ||
203 | compose ',' 'C' to 'Ç' | ||
204 | compose ',' 'c' to 'ç' | ||
205 | compose '`' 'E' to 'È' | ||
206 | compose '`' 'e' to 'è' | ||
207 | compose '\'' 'E' to 'É' | ||
208 | compose '\'' 'e' to 'é' | ||
209 | compose '^' 'E' to 'Ê' | ||
210 | compose '^' 'e' to 'ê' | ||
211 | compose '"' 'E' to 'Ë' | ||
212 | compose '"' 'e' to 'ë' | ||
213 | compose '`' 'I' to 'Ì' | ||
214 | compose '`' 'i' to 'ì' | ||
215 | compose '\'' 'I' to 'Í' | ||
216 | compose '\'' 'i' to 'í' | ||
217 | compose '^' 'I' to 'Î' | ||
218 | compose '^' 'i' to 'î' | ||
219 | compose '"' 'I' to 'Ï' | ||
220 | compose '"' 'i' to 'ï' | ||
221 | compose '-' 'D' to 'Ð' | ||
222 | compose '-' 'd' to 'ð' | ||
223 | compose '~' 'N' to 'Ñ' | ||
224 | compose '~' 'n' to 'ñ' | ||
225 | compose '`' 'O' to 'Ò' | ||
226 | compose '`' 'o' to 'ò' | ||
227 | compose '\'' 'O' to 'Ó' | ||
228 | compose '\'' 'o' to 'ó' | ||
229 | compose '^' 'O' to 'Ô' | ||
230 | compose '^' 'o' to 'ô' | ||
231 | compose '~' 'O' to 'Õ' | ||
232 | compose '~' 'o' to 'õ' | ||
233 | compose '"' 'O' to 'Ö' | ||
234 | compose '"' 'o' to 'ö' | ||
235 | compose '/' 'O' to 'Ø' | ||
236 | compose '/' 'o' to 'ø' | ||
237 | compose '`' 'U' to 'Ù' | ||
238 | compose '`' 'u' to 'ù' | ||
239 | compose '\'' 'U' to 'Ú' | ||
240 | compose '\'' 'u' to 'ú' | ||
241 | compose '^' 'U' to 'Û' | ||
242 | compose '^' 'u' to 'û' | ||
243 | compose '"' 'U' to 'Ü' | ||
244 | compose '"' 'u' to 'ü' | ||
245 | compose '\'' 'Y' to 'Ý' | ||
246 | compose '\'' 'y' to 'ý' | ||
247 | compose 'T' 'H' to 'Þ' | ||
248 | compose 't' 'h' to 'þ' | ||
249 | compose 's' 's' to 'ß' | ||
250 | compose '"' 'y' to 'ÿ' | ||
251 | compose 's' 'z' to 'ß' | ||
252 | compose 'i' 'j' to 'ÿ' | ||
diff --git a/arch/m68k/hp300/ints.c b/arch/m68k/hp300/ints.c new file mode 100644 index 000000000000..0c5bb403e893 --- /dev/null +++ b/arch/m68k/hp300/ints.c | |||
@@ -0,0 +1,175 @@ | |||
1 | /* | ||
2 | * linux/arch/m68k/hp300/ints.c | ||
3 | * | ||
4 | * Copyright (C) 1998 Philip Blundell <philb@gnu.org> | ||
5 | * | ||
6 | * This file contains the HP300-specific interrupt handling. | ||
7 | * We only use the autovector interrupts, and therefore we need to | ||
8 | * maintain lists of devices sharing each ipl. | ||
9 | * [ipl list code added by Peter Maydell <pmaydell@chiark.greenend.org.uk> 06/1998] | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/types.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/sched.h> | ||
16 | #include <linux/kernel_stat.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/spinlock.h> | ||
19 | #include <asm/machdep.h> | ||
20 | #include <asm/irq.h> | ||
21 | #include <asm/io.h> | ||
22 | #include <asm/system.h> | ||
23 | #include <asm/traps.h> | ||
24 | #include <asm/ptrace.h> | ||
25 | #include <asm/errno.h> | ||
26 | #include "ints.h" | ||
27 | |||
28 | /* Each ipl has a linked list of interrupt service routines. | ||
29 | * Service routines are added via hp300_request_irq() and removed | ||
30 | * via hp300_free_irq(). The device driver should set IRQ_FLG_FAST | ||
31 | * if it needs to be serviced early (eg FIFOless UARTs); this will | ||
32 | * cause it to be added at the front of the queue rather than | ||
33 | * the back. | ||
34 | * Currently IRQ_FLG_SLOW and flags=0 are treated identically; if | ||
35 | * we needed three levels of priority we could distinguish them | ||
36 | * but this strikes me as mildly ugly... | ||
37 | */ | ||
38 | |||
39 | /* we start with no entries in any list */ | ||
40 | static irq_node_t *hp300_irq_list[HP300_NUM_IRQS]; | ||
41 | |||
42 | static spinlock_t irqlist_lock; | ||
43 | |||
44 | /* This handler receives all interrupts, dispatching them to the registered handlers */ | ||
45 | static irqreturn_t hp300_int_handler(int irq, void *dev_id, struct pt_regs *fp) | ||
46 | { | ||
47 | irq_node_t *t; | ||
48 | /* We just give every handler on the chain an opportunity to handle | ||
49 | * the interrupt, in priority order. | ||
50 | */ | ||
51 | for(t = hp300_irq_list[irq]; t; t=t->next) | ||
52 | t->handler(irq, t->dev_id, fp); | ||
53 | /* We could put in some accounting routines, checks for stray interrupts, | ||
54 | * etc, in here. Note that currently we can't tell whether or not | ||
55 | * a handler handles the interrupt, though. | ||
56 | */ | ||
57 | return IRQ_HANDLED; | ||
58 | } | ||
59 | |||
60 | static irqreturn_t hp300_badint(int irq, void *dev_id, struct pt_regs *fp) | ||
61 | { | ||
62 | num_spurious += 1; | ||
63 | return IRQ_NONE; | ||
64 | } | ||
65 | |||
66 | irqreturn_t (*hp300_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = { | ||
67 | [0] = hp300_badint, | ||
68 | [1] = hp300_int_handler, | ||
69 | [2] = hp300_int_handler, | ||
70 | [3] = hp300_int_handler, | ||
71 | [4] = hp300_int_handler, | ||
72 | [5] = hp300_int_handler, | ||
73 | [6] = hp300_int_handler, | ||
74 | [7] = hp300_int_handler | ||
75 | }; | ||
76 | |||
77 | /* dev_id had better be unique to each handler because it's the only way we have | ||
78 | * to distinguish handlers when removing them... | ||
79 | * | ||
80 | * It would be pretty easy to support IRQ_FLG_LOCK (handler is not replacable) | ||
81 | * and IRQ_FLG_REPLACE (handler replaces existing one with this dev_id) | ||
82 | * if we wanted to. IRQ_FLG_FAST is needed for devices where interrupt latency | ||
83 | * matters (eg the dreaded FIFOless UART...) | ||
84 | */ | ||
85 | int hp300_request_irq(unsigned int irq, | ||
86 | irqreturn_t (*handler) (int, void *, struct pt_regs *), | ||
87 | unsigned long flags, const char *devname, void *dev_id) | ||
88 | { | ||
89 | irq_node_t *t, *n = new_irq_node(); | ||
90 | |||
91 | if (!n) /* oops, no free nodes */ | ||
92 | return -ENOMEM; | ||
93 | |||
94 | spin_lock_irqsave(&irqlist_lock, flags); | ||
95 | |||
96 | if (!hp300_irq_list[irq]) { | ||
97 | /* no list yet */ | ||
98 | hp300_irq_list[irq] = n; | ||
99 | n->next = NULL; | ||
100 | } else if (flags & IRQ_FLG_FAST) { | ||
101 | /* insert at head of list */ | ||
102 | n->next = hp300_irq_list[irq]; | ||
103 | hp300_irq_list[irq] = n; | ||
104 | } else { | ||
105 | /* insert at end of list */ | ||
106 | for(t = hp300_irq_list[irq]; t->next; t = t->next) | ||
107 | /* do nothing */; | ||
108 | n->next = NULL; | ||
109 | t->next = n; | ||
110 | } | ||
111 | |||
112 | /* Fill in n appropriately */ | ||
113 | n->handler = handler; | ||
114 | n->flags = flags; | ||
115 | n->dev_id = dev_id; | ||
116 | n->devname = devname; | ||
117 | spin_unlock_irqrestore(&irqlist_lock, flags); | ||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | void hp300_free_irq(unsigned int irq, void *dev_id) | ||
122 | { | ||
123 | irq_node_t *t; | ||
124 | unsigned long flags; | ||
125 | |||
126 | spin_lock_irqsave(&irqlist_lock, flags); | ||
127 | |||
128 | t = hp300_irq_list[irq]; | ||
129 | if (!t) /* no handlers at all for that IRQ */ | ||
130 | { | ||
131 | printk(KERN_ERR "hp300_free_irq: attempt to remove nonexistent handler for IRQ %d\n", irq); | ||
132 | spin_unlock_irqrestore(&irqlist_lock, flags); | ||
133 | return; | ||
134 | } | ||
135 | |||
136 | if (t->dev_id == dev_id) | ||
137 | { /* removing first handler on chain */ | ||
138 | t->flags = IRQ_FLG_STD; /* we probably don't really need these */ | ||
139 | t->dev_id = NULL; | ||
140 | t->devname = NULL; | ||
141 | t->handler = NULL; /* frees this irq_node_t */ | ||
142 | hp300_irq_list[irq] = t->next; | ||
143 | spin_unlock_irqrestore(&irqlist_lock, flags); | ||
144 | return; | ||
145 | } | ||
146 | |||
147 | /* OK, must be removing from middle of the chain */ | ||
148 | |||
149 | for (t = hp300_irq_list[irq]; t->next && t->next->dev_id != dev_id; t = t->next) | ||
150 | /* do nothing */; | ||
151 | if (!t->next) | ||
152 | { | ||
153 | printk(KERN_ERR "hp300_free_irq: attempt to remove nonexistent handler for IRQ %d\n", irq); | ||
154 | spin_unlock_irqrestore(&irqlist_lock, flags); | ||
155 | return; | ||
156 | } | ||
157 | /* remove the entry after t: */ | ||
158 | t->next->flags = IRQ_FLG_STD; | ||
159 | t->next->dev_id = NULL; | ||
160 | t->next->devname = NULL; | ||
161 | t->next->handler = NULL; | ||
162 | t->next = t->next->next; | ||
163 | |||
164 | spin_unlock_irqrestore(&irqlist_lock, flags); | ||
165 | } | ||
166 | |||
167 | int show_hp300_interrupts(struct seq_file *p, void *v) | ||
168 | { | ||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | void __init hp300_init_IRQ(void) | ||
173 | { | ||
174 | spin_lock_init(&irqlist_lock); | ||
175 | } | ||
diff --git a/arch/m68k/hp300/ints.h b/arch/m68k/hp300/ints.h new file mode 100644 index 000000000000..8cfabe2f3840 --- /dev/null +++ b/arch/m68k/hp300/ints.h | |||
@@ -0,0 +1,9 @@ | |||
1 | extern void hp300_init_IRQ(void); | ||
2 | extern void (*hp300_handlers[8])(int, void *, struct pt_regs *); | ||
3 | extern void hp300_free_irq(unsigned int irq, void *dev_id); | ||
4 | extern int hp300_request_irq(unsigned int irq, | ||
5 | irqreturn_t (*handler) (int, void *, struct pt_regs *), | ||
6 | unsigned long flags, const char *devname, void *dev_id); | ||
7 | |||
8 | /* number of interrupts, includes 0 (what's that?) */ | ||
9 | #define HP300_NUM_IRQS 8 | ||
diff --git a/arch/m68k/hp300/ksyms.c b/arch/m68k/hp300/ksyms.c new file mode 100644 index 000000000000..8202830763d1 --- /dev/null +++ b/arch/m68k/hp300/ksyms.c | |||
@@ -0,0 +1,9 @@ | |||
1 | /* | ||
2 | * linux/arch/m68k/hp300/ksyms.c | ||
3 | * | ||
4 | * Copyright (C) 1998 Philip Blundell <philb@gnu.org> | ||
5 | * | ||
6 | * This file contains the HP300-specific kernel symbols. None yet. :-) | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
diff --git a/arch/m68k/hp300/reboot.S b/arch/m68k/hp300/reboot.S new file mode 100644 index 000000000000..52eb852e6b04 --- /dev/null +++ b/arch/m68k/hp300/reboot.S | |||
@@ -0,0 +1,16 @@ | |||
1 | /* | ||
2 | * linux/arch/m68k/hp300/reboot.S | ||
3 | * | ||
4 | * Copyright (C) 1998 Philip Blundell <philb@gnu.org> | ||
5 | * | ||
6 | * Do the dirty work of rebooting the machine. Basically we need to undo all the | ||
7 | * good stuff that head.S did when we started up. The caches and MMU must be | ||
8 | * disabled and then we jump back to the PROM. This is a bit gruesome but we put | ||
9 | * a brave face on it. | ||
10 | */ | ||
11 | |||
12 | /* XXX Doesn't work yet. Not sure why and can't be bothered to fix it at the moment. */ | ||
13 | |||
14 | .globl hp300_reset | ||
15 | hp300_reset: | ||
16 | jmp hp300_reset | ||
diff --git a/arch/m68k/hp300/time.c b/arch/m68k/hp300/time.c new file mode 100644 index 000000000000..8da5b1b31e61 --- /dev/null +++ b/arch/m68k/hp300/time.c | |||
@@ -0,0 +1,78 @@ | |||
1 | /* | ||
2 | * linux/arch/m68k/hp300/time.c | ||
3 | * | ||
4 | * Copyright (C) 1998 Philip Blundell <philb@gnu.org> | ||
5 | * | ||
6 | * This file contains the HP300-specific time handling code. | ||
7 | */ | ||
8 | |||
9 | #include <asm/ptrace.h> | ||
10 | #include <linux/types.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/sched.h> | ||
13 | #include <linux/kernel_stat.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <asm/machdep.h> | ||
16 | #include <asm/irq.h> | ||
17 | #include <asm/io.h> | ||
18 | #include <asm/system.h> | ||
19 | #include <asm/traps.h> | ||
20 | #include <asm/blinken.h> | ||
21 | #include "ints.h" | ||
22 | |||
23 | /* Clock hardware definitions */ | ||
24 | |||
25 | #define CLOCKBASE 0xf05f8000 | ||
26 | |||
27 | #define CLKCR1 0x1 | ||
28 | #define CLKCR2 0x3 | ||
29 | #define CLKCR3 CLKCR1 | ||
30 | #define CLKSR CLKCR2 | ||
31 | #define CLKMSB1 0x5 | ||
32 | #define CLKMSB2 0x9 | ||
33 | #define CLKMSB3 0xD | ||
34 | |||
35 | /* This is for machines which generate the exact clock. */ | ||
36 | #define USECS_PER_JIFFY (1000000/HZ) | ||
37 | |||
38 | #define INTVAL ((10000 / 4) - 1) | ||
39 | |||
40 | static irqreturn_t hp300_tick(int irq, void *dev_id, struct pt_regs *regs) | ||
41 | { | ||
42 | unsigned long tmp; | ||
43 | irqreturn_t (*vector)(int, void *, struct pt_regs *) = dev_id; | ||
44 | in_8(CLOCKBASE + CLKSR); | ||
45 | asm volatile ("movpw %1@(5),%0" : "=d" (tmp) : "a" (CLOCKBASE)); | ||
46 | /* Turn off the network and SCSI leds */ | ||
47 | blinken_leds(0, 0xe0); | ||
48 | return vector(irq, NULL, regs); | ||
49 | } | ||
50 | |||
51 | unsigned long hp300_gettimeoffset(void) | ||
52 | { | ||
53 | /* Read current timer 1 value */ | ||
54 | unsigned char lsb, msb1, msb2; | ||
55 | unsigned short ticks; | ||
56 | |||
57 | msb1 = in_8(CLOCKBASE + 5); | ||
58 | lsb = in_8(CLOCKBASE + 7); | ||
59 | msb2 = in_8(CLOCKBASE + 5); | ||
60 | if (msb1 != msb2) | ||
61 | /* A carry happened while we were reading. Read it again */ | ||
62 | lsb = in_8(CLOCKBASE + 7); | ||
63 | ticks = INTVAL - ((msb2 << 8) | lsb); | ||
64 | return (USECS_PER_JIFFY * ticks) / INTVAL; | ||
65 | } | ||
66 | |||
67 | void __init hp300_sched_init(irqreturn_t (*vector)(int, void *, struct pt_regs *)) | ||
68 | { | ||
69 | out_8(CLOCKBASE + CLKCR2, 0x1); /* select CR1 */ | ||
70 | out_8(CLOCKBASE + CLKCR1, 0x1); /* reset */ | ||
71 | |||
72 | asm volatile(" movpw %0,%1@(5)" : : "d" (INTVAL), "a" (CLOCKBASE)); | ||
73 | |||
74 | cpu_request_irq(6, hp300_tick, IRQ_FLG_STD, "timer tick", vector); | ||
75 | |||
76 | out_8(CLOCKBASE + CLKCR2, 0x1); /* select CR1 */ | ||
77 | out_8(CLOCKBASE + CLKCR1, 0x40); /* enable irq */ | ||
78 | } | ||
diff --git a/arch/m68k/hp300/time.h b/arch/m68k/hp300/time.h new file mode 100644 index 000000000000..8ef9987b49ab --- /dev/null +++ b/arch/m68k/hp300/time.h | |||
@@ -0,0 +1,4 @@ | |||
1 | extern void hp300_sched_init(irqreturn_t (*vector)(int, void *, struct pt_regs *)); | ||
2 | extern unsigned long hp300_gettimeoffset (void); | ||
3 | |||
4 | |||