aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68k/atari
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/m68k/atari
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/atari')
-rw-r--r--arch/m68k/atari/Makefile10
-rw-r--r--arch/m68k/atari/ataints.c648
-rw-r--r--arch/m68k/atari/atari_ksyms.c35
-rw-r--r--arch/m68k/atari/atasound.c109
-rw-r--r--arch/m68k/atari/atasound.h33
-rw-r--r--arch/m68k/atari/config.c726
-rw-r--r--arch/m68k/atari/debug.c347
-rw-r--r--arch/m68k/atari/hades-pci.c444
-rw-r--r--arch/m68k/atari/stdma.c196
-rw-r--r--arch/m68k/atari/stram.c1247
-rw-r--r--arch/m68k/atari/time.c348
11 files changed, 4143 insertions, 0 deletions
diff --git a/arch/m68k/atari/Makefile b/arch/m68k/atari/Makefile
new file mode 100644
index 000000000000..8cb6236b39db
--- /dev/null
+++ b/arch/m68k/atari/Makefile
@@ -0,0 +1,10 @@
1#
2# Makefile for Linux arch/m68k/atari source directory
3#
4
5obj-y := config.o time.o debug.o ataints.o stdma.o \
6 atasound.o stram.o atari_ksyms.o
7
8ifeq ($(CONFIG_PCI),y)
9obj-$(CONFIG_HADES) += hades-pci.o
10endif
diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c
new file mode 100644
index 000000000000..076f47917842
--- /dev/null
+++ b/arch/m68k/atari/ataints.c
@@ -0,0 +1,648 @@
1/*
2 * arch/m68k/atari/ataints.c -- Atari Linux interrupt handling code
3 *
4 * 5/2/94 Roman Hodek:
5 * Added support for TT interrupts; setup for TT SCU (may someone has
6 * twiddled there and we won't get the right interrupts :-()
7 *
8 * Major change: The device-independent code in m68k/ints.c didn't know
9 * about non-autovec ints yet. It hardcoded the number of possible ints to
10 * 7 (IRQ1...IRQ7). But the Atari has lots of non-autovec ints! I made the
11 * number of possible ints a constant defined in interrupt.h, which is
12 * 47 for the Atari. So we can call request_irq() for all Atari interrupts
13 * just the normal way. Additionally, all vectors >= 48 are initialized to
14 * call trap() instead of inthandler(). This must be changed here, too.
15 *
16 * 1995-07-16 Lars Brinkhoff <f93labr@dd.chalmers.se>:
17 * Corrected a bug in atari_add_isr() which rejected all SCC
18 * interrupt sources if there were no TT MFP!
19 *
20 * 12/13/95: New interface functions atari_level_triggered_int() and
21 * atari_register_vme_int() as support for level triggered VME interrupts.
22 *
23 * 02/12/96: (Roman)
24 * Total rewrite of Atari interrupt handling, for new scheme see comments
25 * below.
26 *
27 * 1996-09-03 lars brinkhoff <f93labr@dd.chalmers.se>:
28 * Added new function atari_unregister_vme_int(), and
29 * modified atari_register_vme_int() as well as IS_VALID_INTNO()
30 * to work with it.
31 *
32 * This file is subject to the terms and conditions of the GNU General Public
33 * License. See the file COPYING in the main directory of this archive
34 * for more details.
35 *
36 */
37
38#include <linux/types.h>
39#include <linux/kernel.h>
40#include <linux/kernel_stat.h>
41#include <linux/init.h>
42#include <linux/seq_file.h>
43
44#include <asm/system.h>
45#include <asm/traps.h>
46
47#include <asm/atarihw.h>
48#include <asm/atariints.h>
49#include <asm/atari_stdma.h>
50#include <asm/irq.h>
51#include <asm/entry.h>
52
53
54/*
55 * Atari interrupt handling scheme:
56 * --------------------------------
57 *
58 * All interrupt source have an internal number (defined in
59 * <asm/atariints.h>): Autovector interrupts are 1..7, then follow ST-MFP,
60 * TT-MFP, SCC, and finally VME interrupts. Vector numbers for the latter can
61 * be allocated by atari_register_vme_int().
62 *
63 * Each interrupt can be of three types:
64 *
65 * - SLOW: The handler runs with all interrupts enabled, except the one it
66 * was called by (to avoid reentering). This should be the usual method.
67 * But it is currently possible only for MFP ints, since only the MFP
68 * offers an easy way to mask interrupts.
69 *
70 * - FAST: The handler runs with all interrupts disabled. This should be used
71 * only for really fast handlers, that just do actions immediately
72 * necessary, and let the rest do a bottom half or task queue.
73 *
74 * - PRIORITIZED: The handler can be interrupted by higher-level ints
75 * (greater IPL, no MFP priorities!). This is the method of choice for ints
76 * which should be slow, but are not from a MFP.
77 *
78 * The feature of more than one handler for one int source is still there, but
79 * only applicable if all handers are of the same type. To not slow down
80 * processing of ints with only one handler by the chaining feature, the list
81 * calling function atari_call_irq_list() is only plugged in at the time the
82 * second handler is registered.
83 *
84 * Implementation notes: For fast-as-possible int handling, there are separate
85 * entry points for each type (slow/fast/prio). The assembler handler calls
86 * the irq directly in the usual case, no C wrapper is involved. In case of
87 * multiple handlers, atari_call_irq_list() is registered as handler and calls
88 * in turn the real irq's. To ease access from assembler level to the irq
89 * function pointer and accompanying data, these two are stored in a separate
90 * array, irq_handler[]. The rest of data (type, name) are put into a second
91 * array, irq_param, that is accessed from C only. For each slow interrupt (32
92 * in all) there are separate handler functions, which makes it possible to
93 * hard-code the MFP register address and value, are necessary to mask the
94 * int. If there'd be only one generic function, lots of calculations would be
95 * needed to determine MFP register and int mask from the vector number :-(
96 *
97 * Furthermore, slow ints may not lower the IPL below its previous value
98 * (before the int happened). This is needed so that an int of class PRIO, on
99 * that this int may be stacked, cannot be reentered. This feature is
100 * implemented as follows: If the stack frame format is 1 (throwaway), the int
101 * is not stacked, and the IPL is anded with 0xfbff, resulting in a new level
102 * 2, which still blocks the HSYNC, but no interrupts of interest. If the
103 * frame format is 0, the int is nested, and the old IPL value can be found in
104 * the sr copy in the frame.
105 */
106
107
108#define NUM_INT_SOURCES (8 + NUM_ATARI_SOURCES)
109
110typedef void (*asm_irq_handler)(void);
111
112struct irqhandler {
113 irqreturn_t (*handler)(int, void *, struct pt_regs *);
114 void *dev_id;
115};
116
117struct irqparam {
118 unsigned long flags;
119 const char *devname;
120};
121
122/*
123 * Array with irq's and their parameter data. This array is accessed from low
124 * level assembler code, so an element size of 8 allows usage of index scaling
125 * addressing mode.
126 */
127static struct irqhandler irq_handler[NUM_INT_SOURCES];
128
129/*
130 * This array hold the rest of parameters of int handlers: type
131 * (slow,fast,prio) and the name of the handler. These values are only
132 * accessed from C
133 */
134static struct irqparam irq_param[NUM_INT_SOURCES];
135
136/*
137 * Bitmap for free interrupt vector numbers
138 * (new vectors starting from 0x70 can be allocated by
139 * atari_register_vme_int())
140 */
141static int free_vme_vec_bitmap;
142
143/* check for valid int number (complex, sigh...) */
144#define IS_VALID_INTNO(n) \
145 ((n) > 0 && \
146 /* autovec and ST-MFP ok anyway */ \
147 (((n) < TTMFP_SOURCE_BASE) || \
148 /* TT-MFP ok if present */ \
149 ((n) >= TTMFP_SOURCE_BASE && (n) < SCC_SOURCE_BASE && \
150 ATARIHW_PRESENT(TT_MFP)) || \
151 /* SCC ok if present and number even */ \
152 ((n) >= SCC_SOURCE_BASE && (n) < VME_SOURCE_BASE && \
153 !((n) & 1) && ATARIHW_PRESENT(SCC)) || \
154 /* greater numbers ok if they are registered VME vectors */ \
155 ((n) >= VME_SOURCE_BASE && (n) < VME_SOURCE_BASE + VME_MAX_SOURCES && \
156 free_vme_vec_bitmap & (1 << ((n) - VME_SOURCE_BASE)))))
157
158
159/*
160 * Here start the assembler entry points for interrupts
161 */
162
163#define IRQ_NAME(nr) atari_slow_irq_##nr##_handler(void)
164
165#define BUILD_SLOW_IRQ(n) \
166asmlinkage void IRQ_NAME(n); \
167/* Dummy function to allow asm with operands. */ \
168void atari_slow_irq_##n##_dummy (void) { \
169__asm__ (__ALIGN_STR "\n" \
170"atari_slow_irq_" #n "_handler:\t" \
171" addl %6,%5\n" /* preempt_count() += HARDIRQ_OFFSET */ \
172 SAVE_ALL_INT "\n" \
173 GET_CURRENT(%%d0) "\n" \
174" andb #~(1<<(%c3&7)),%a4:w\n" /* mask this interrupt */ \
175 /* get old IPL from stack frame */ \
176" bfextu %%sp@(%c2){#5,#3},%%d0\n" \
177" movew %%sr,%%d1\n" \
178" bfins %%d0,%%d1{#21,#3}\n" \
179" movew %%d1,%%sr\n" /* set IPL = previous value */ \
180" addql #1,%a0\n" \
181" lea %a1,%%a0\n" \
182" pea %%sp@\n" /* push addr of frame */ \
183" movel %%a0@(4),%%sp@-\n" /* push handler data */ \
184" pea (%c3+8)\n" /* push int number */ \
185" movel %%a0@,%%a0\n" \
186" jbsr %%a0@\n" /* call the handler */ \
187" addql #8,%%sp\n" \
188" addql #4,%%sp\n" \
189" orw #0x0600,%%sr\n" \
190" andw #0xfeff,%%sr\n" /* set IPL = 6 again */ \
191" orb #(1<<(%c3&7)),%a4:w\n" /* now unmask the int again */ \
192" jbra ret_from_interrupt\n" \
193 : : "i" (&kstat_cpu(0).irqs[n+8]), "i" (&irq_handler[n+8]), \
194 "n" (PT_OFF_SR), "n" (n), \
195 "i" (n & 8 ? (n & 16 ? &tt_mfp.int_mk_a : &mfp.int_mk_a) \
196 : (n & 16 ? &tt_mfp.int_mk_b : &mfp.int_mk_b)), \
197 "m" (preempt_count()), "di" (HARDIRQ_OFFSET) \
198); \
199 for (;;); /* fake noreturn */ \
200}
201
202BUILD_SLOW_IRQ(0);
203BUILD_SLOW_IRQ(1);
204BUILD_SLOW_IRQ(2);
205BUILD_SLOW_IRQ(3);
206BUILD_SLOW_IRQ(4);
207BUILD_SLOW_IRQ(5);
208BUILD_SLOW_IRQ(6);
209BUILD_SLOW_IRQ(7);
210BUILD_SLOW_IRQ(8);
211BUILD_SLOW_IRQ(9);
212BUILD_SLOW_IRQ(10);
213BUILD_SLOW_IRQ(11);
214BUILD_SLOW_IRQ(12);
215BUILD_SLOW_IRQ(13);
216BUILD_SLOW_IRQ(14);
217BUILD_SLOW_IRQ(15);
218BUILD_SLOW_IRQ(16);
219BUILD_SLOW_IRQ(17);
220BUILD_SLOW_IRQ(18);
221BUILD_SLOW_IRQ(19);
222BUILD_SLOW_IRQ(20);
223BUILD_SLOW_IRQ(21);
224BUILD_SLOW_IRQ(22);
225BUILD_SLOW_IRQ(23);
226BUILD_SLOW_IRQ(24);
227BUILD_SLOW_IRQ(25);
228BUILD_SLOW_IRQ(26);
229BUILD_SLOW_IRQ(27);
230BUILD_SLOW_IRQ(28);
231BUILD_SLOW_IRQ(29);
232BUILD_SLOW_IRQ(30);
233BUILD_SLOW_IRQ(31);
234
235asm_irq_handler slow_handlers[32] = {
236 [0] = atari_slow_irq_0_handler,
237 [1] = atari_slow_irq_1_handler,
238 [2] = atari_slow_irq_2_handler,
239 [3] = atari_slow_irq_3_handler,
240 [4] = atari_slow_irq_4_handler,
241 [5] = atari_slow_irq_5_handler,
242 [6] = atari_slow_irq_6_handler,
243 [7] = atari_slow_irq_7_handler,
244 [8] = atari_slow_irq_8_handler,
245 [9] = atari_slow_irq_9_handler,
246 [10] = atari_slow_irq_10_handler,
247 [11] = atari_slow_irq_11_handler,
248 [12] = atari_slow_irq_12_handler,
249 [13] = atari_slow_irq_13_handler,
250 [14] = atari_slow_irq_14_handler,
251 [15] = atari_slow_irq_15_handler,
252 [16] = atari_slow_irq_16_handler,
253 [17] = atari_slow_irq_17_handler,
254 [18] = atari_slow_irq_18_handler,
255 [19] = atari_slow_irq_19_handler,
256 [20] = atari_slow_irq_20_handler,
257 [21] = atari_slow_irq_21_handler,
258 [22] = atari_slow_irq_22_handler,
259 [23] = atari_slow_irq_23_handler,
260 [24] = atari_slow_irq_24_handler,
261 [25] = atari_slow_irq_25_handler,
262 [26] = atari_slow_irq_26_handler,
263 [27] = atari_slow_irq_27_handler,
264 [28] = atari_slow_irq_28_handler,
265 [29] = atari_slow_irq_29_handler,
266 [30] = atari_slow_irq_30_handler,
267 [31] = atari_slow_irq_31_handler
268};
269
270asmlinkage void atari_fast_irq_handler( void );
271asmlinkage void atari_prio_irq_handler( void );
272
273/* Dummy function to allow asm with operands. */
274void atari_fast_prio_irq_dummy (void) {
275__asm__ (__ALIGN_STR "\n"
276"atari_fast_irq_handler:\n\t"
277 "orw #0x700,%%sr\n" /* disable all interrupts */
278"atari_prio_irq_handler:\n\t"
279 "addl %3,%2\n\t" /* preempt_count() += HARDIRQ_OFFSET */
280 SAVE_ALL_INT "\n\t"
281 GET_CURRENT(%%d0) "\n\t"
282 /* get vector number from stack frame and convert to source */
283 "bfextu %%sp@(%c1){#4,#10},%%d0\n\t"
284 "subw #(0x40-8),%%d0\n\t"
285 "jpl 1f\n\t"
286 "addw #(0x40-8-0x18),%%d0\n"
287 "1:\tlea %a0,%%a0\n\t"
288 "addql #1,%%a0@(%%d0:l:4)\n\t"
289 "lea irq_handler,%%a0\n\t"
290 "lea %%a0@(%%d0:l:8),%%a0\n\t"
291 "pea %%sp@\n\t" /* push frame address */
292 "movel %%a0@(4),%%sp@-\n\t" /* push handler data */
293 "movel %%d0,%%sp@-\n\t" /* push int number */
294 "movel %%a0@,%%a0\n\t"
295 "jsr %%a0@\n\t" /* and call the handler */
296 "addql #8,%%sp\n\t"
297 "addql #4,%%sp\n\t"
298 "jbra ret_from_interrupt"
299 : : "i" (&kstat_cpu(0).irqs), "n" (PT_OFF_FORMATVEC),
300 "m" (preempt_count()), "di" (HARDIRQ_OFFSET)
301);
302 for (;;);
303}
304
305/* GK:
306 * HBL IRQ handler for Falcon. Nobody needs it :-)
307 * ++andreas: raise ipl to disable further HBLANK interrupts.
308 */
309asmlinkage void falcon_hblhandler(void);
310asm(".text\n"
311__ALIGN_STR "\n\t"
312"falcon_hblhandler:\n\t"
313 "orw #0x200,%sp@\n\t" /* set saved ipl to 2 */
314 "rte");
315
316/* Defined in entry.S; only increments 'num_spurious' */
317asmlinkage void bad_interrupt(void);
318
319extern void atari_microwire_cmd( int cmd );
320
321extern int atari_SCC_reset_done;
322
323/*
324 * void atari_init_IRQ (void)
325 *
326 * Parameters: None
327 *
328 * Returns: Nothing
329 *
330 * This function should be called during kernel startup to initialize
331 * the atari IRQ handling routines.
332 */
333
334void __init atari_init_IRQ(void)
335{
336 int i;
337
338 /* initialize the vector table */
339 for (i = 0; i < NUM_INT_SOURCES; ++i) {
340 vectors[IRQ_SOURCE_TO_VECTOR(i)] = bad_interrupt;
341 }
342
343 /* Initialize the MFP(s) */
344
345#ifdef ATARI_USE_SOFTWARE_EOI
346 mfp.vec_adr = 0x48; /* Software EOI-Mode */
347#else
348 mfp.vec_adr = 0x40; /* Automatic EOI-Mode */
349#endif
350 mfp.int_en_a = 0x00; /* turn off MFP-Ints */
351 mfp.int_en_b = 0x00;
352 mfp.int_mk_a = 0xff; /* no Masking */
353 mfp.int_mk_b = 0xff;
354
355 if (ATARIHW_PRESENT(TT_MFP)) {
356#ifdef ATARI_USE_SOFTWARE_EOI
357 tt_mfp.vec_adr = 0x58; /* Software EOI-Mode */
358#else
359 tt_mfp.vec_adr = 0x50; /* Automatic EOI-Mode */
360#endif
361 tt_mfp.int_en_a = 0x00; /* turn off MFP-Ints */
362 tt_mfp.int_en_b = 0x00;
363 tt_mfp.int_mk_a = 0xff; /* no Masking */
364 tt_mfp.int_mk_b = 0xff;
365 }
366
367 if (ATARIHW_PRESENT(SCC) && !atari_SCC_reset_done) {
368 scc.cha_a_ctrl = 9;
369 MFPDELAY();
370 scc.cha_a_ctrl = (char) 0xc0; /* hardware reset */
371 }
372
373 if (ATARIHW_PRESENT(SCU)) {
374 /* init the SCU if present */
375 tt_scu.sys_mask = 0x10; /* enable VBL (for the cursor) and
376 * disable HSYNC interrupts (who
377 * needs them?) MFP and SCC are
378 * enabled in VME mask
379 */
380 tt_scu.vme_mask = 0x60; /* enable MFP and SCC ints */
381 }
382 else {
383 /* If no SCU and no Hades, the HSYNC interrupt needs to be
384 * disabled this way. (Else _inthandler in kernel/sys_call.S
385 * gets overruns)
386 */
387
388 if (!MACH_IS_HADES)
389 vectors[VEC_INT2] = falcon_hblhandler;
390 }
391
392 if (ATARIHW_PRESENT(PCM_8BIT) && ATARIHW_PRESENT(MICROWIRE)) {
393 /* Initialize the LM1992 Sound Controller to enable
394 the PSG sound. This is misplaced here, it should
395 be in an atasound_init(), that doesn't exist yet. */
396 atari_microwire_cmd(MW_LM1992_PSG_HIGH);
397 }
398
399 stdma_init();
400
401 /* Initialize the PSG: all sounds off, both ports output */
402 sound_ym.rd_data_reg_sel = 7;
403 sound_ym.wd_data = 0xff;
404}
405
406
407static irqreturn_t atari_call_irq_list( int irq, void *dev_id, struct pt_regs *fp )
408{
409 irq_node_t *node;
410
411 for (node = (irq_node_t *)dev_id; node; node = node->next)
412 node->handler(irq, node->dev_id, fp);
413 return IRQ_HANDLED;
414}
415
416
417/*
418 * atari_request_irq : add an interrupt service routine for a particular
419 * machine specific interrupt source.
420 * If the addition was successful, it returns 0.
421 */
422
423int atari_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),
424 unsigned long flags, const char *devname, void *dev_id)
425{
426 int vector;
427 unsigned long oflags = flags;
428
429 /*
430 * The following is a hack to make some PCI card drivers work,
431 * which set the SA_SHIRQ flag.
432 */
433
434 flags &= ~SA_SHIRQ;
435
436 if (flags == SA_INTERRUPT) {
437 printk ("%s: SA_INTERRUPT changed to IRQ_TYPE_SLOW for %s\n",
438 __FUNCTION__, devname);
439 flags = IRQ_TYPE_SLOW;
440 }
441 if (flags < IRQ_TYPE_SLOW || flags > IRQ_TYPE_PRIO) {
442 printk ("%s: Bad irq type 0x%lx <0x%lx> requested from %s\n",
443 __FUNCTION__, flags, oflags, devname);
444 return -EINVAL;
445 }
446 if (!IS_VALID_INTNO(irq)) {
447 printk ("%s: Unknown irq %d requested from %s\n",
448 __FUNCTION__, irq, devname);
449 return -ENXIO;
450 }
451 vector = IRQ_SOURCE_TO_VECTOR(irq);
452
453 /*
454 * Check type/source combination: slow ints are (currently)
455 * only possible for MFP-interrupts.
456 */
457 if (flags == IRQ_TYPE_SLOW &&
458 (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE)) {
459 printk ("%s: Slow irq requested for non-MFP source %d from %s\n",
460 __FUNCTION__, irq, devname);
461 return -EINVAL;
462 }
463
464 if (vectors[vector] == bad_interrupt) {
465 /* int has no handler yet */
466 irq_handler[irq].handler = handler;
467 irq_handler[irq].dev_id = dev_id;
468 irq_param[irq].flags = flags;
469 irq_param[irq].devname = devname;
470 vectors[vector] =
471 (flags == IRQ_TYPE_SLOW) ? slow_handlers[irq-STMFP_SOURCE_BASE] :
472 (flags == IRQ_TYPE_FAST) ? atari_fast_irq_handler :
473 atari_prio_irq_handler;
474 /* If MFP int, also enable and umask it */
475 atari_turnon_irq(irq);
476 atari_enable_irq(irq);
477
478 return 0;
479 }
480 else if (irq_param[irq].flags == flags) {
481 /* old handler is of same type -> handlers can be chained */
482 irq_node_t *node;
483 unsigned long flags;
484
485 local_irq_save(flags);
486
487 if (irq_handler[irq].handler != atari_call_irq_list) {
488 /* Only one handler yet, make a node for this first one */
489 if (!(node = new_irq_node()))
490 return -ENOMEM;
491 node->handler = irq_handler[irq].handler;
492 node->dev_id = irq_handler[irq].dev_id;
493 node->devname = irq_param[irq].devname;
494 node->next = NULL;
495
496 irq_handler[irq].handler = atari_call_irq_list;
497 irq_handler[irq].dev_id = node;
498 irq_param[irq].devname = "chained";
499 }
500
501 if (!(node = new_irq_node()))
502 return -ENOMEM;
503 node->handler = handler;
504 node->dev_id = dev_id;
505 node->devname = devname;
506 /* new handlers are put in front of the queue */
507 node->next = irq_handler[irq].dev_id;
508 irq_handler[irq].dev_id = node;
509
510 local_irq_restore(flags);
511 return 0;
512 } else {
513 printk ("%s: Irq %d allocated by other type int (call from %s)\n",
514 __FUNCTION__, irq, devname);
515 return -EBUSY;
516 }
517}
518
519void atari_free_irq(unsigned int irq, void *dev_id)
520{
521 unsigned long flags;
522 int vector;
523 irq_node_t **list, *node;
524
525 if (!IS_VALID_INTNO(irq)) {
526 printk("%s: Unknown irq %d\n", __FUNCTION__, irq);
527 return;
528 }
529
530 vector = IRQ_SOURCE_TO_VECTOR(irq);
531 if (vectors[vector] == bad_interrupt)
532 goto not_found;
533
534 local_irq_save(flags);
535
536 if (irq_handler[irq].handler != atari_call_irq_list) {
537 /* It's the only handler for the interrupt */
538 if (irq_handler[irq].dev_id != dev_id) {
539 local_irq_restore(flags);
540 goto not_found;
541 }
542 irq_handler[irq].handler = NULL;
543 irq_handler[irq].dev_id = NULL;
544 irq_param[irq].devname = NULL;
545 vectors[vector] = bad_interrupt;
546 /* If MFP int, also disable it */
547 atari_disable_irq(irq);
548 atari_turnoff_irq(irq);
549
550 local_irq_restore(flags);
551 return;
552 }
553
554 /* The interrupt is chained, find the irq on the list */
555 for(list = (irq_node_t **)&irq_handler[irq].dev_id; *list; list = &(*list)->next) {
556 if ((*list)->dev_id == dev_id) break;
557 }
558 if (!*list) {
559 local_irq_restore(flags);
560 goto not_found;
561 }
562
563 (*list)->handler = NULL; /* Mark it as free for reallocation */
564 *list = (*list)->next;
565
566 /* If there's now only one handler, unchain the interrupt, i.e. plug in
567 * the handler directly again and omit atari_call_irq_list */
568 node = (irq_node_t *)irq_handler[irq].dev_id;
569 if (node && !node->next) {
570 irq_handler[irq].handler = node->handler;
571 irq_handler[irq].dev_id = node->dev_id;
572 irq_param[irq].devname = node->devname;
573 node->handler = NULL; /* Mark it as free for reallocation */
574 }
575
576 local_irq_restore(flags);
577 return;
578
579not_found:
580 printk("%s: tried to remove invalid irq\n", __FUNCTION__);
581 return;
582}
583
584
585/*
586 * atari_register_vme_int() returns the number of a free interrupt vector for
587 * hardware with a programmable int vector (probably a VME board).
588 */
589
590unsigned long atari_register_vme_int(void)
591{
592 int i;
593
594 for(i = 0; i < 32; i++)
595 if((free_vme_vec_bitmap & (1 << i)) == 0)
596 break;
597
598 if(i == 16)
599 return 0;
600
601 free_vme_vec_bitmap |= 1 << i;
602 return (VME_SOURCE_BASE + i);
603}
604
605
606void atari_unregister_vme_int(unsigned long irq)
607{
608 if(irq >= VME_SOURCE_BASE && irq < VME_SOURCE_BASE + VME_MAX_SOURCES) {
609 irq -= VME_SOURCE_BASE;
610 free_vme_vec_bitmap &= ~(1 << irq);
611 }
612}
613
614
615int show_atari_interrupts(struct seq_file *p, void *v)
616{
617 int i;
618
619 for (i = 0; i < NUM_INT_SOURCES; ++i) {
620 if (vectors[IRQ_SOURCE_TO_VECTOR(i)] == bad_interrupt)
621 continue;
622 if (i < STMFP_SOURCE_BASE)
623 seq_printf(p, "auto %2d: %10u ",
624 i, kstat_cpu(0).irqs[i]);
625 else
626 seq_printf(p, "vec $%02x: %10u ",
627 IRQ_SOURCE_TO_VECTOR(i),
628 kstat_cpu(0).irqs[i]);
629
630 if (irq_handler[i].handler != atari_call_irq_list) {
631 seq_printf(p, "%s\n", irq_param[i].devname);
632 }
633 else {
634 irq_node_t *n;
635 for( n = (irq_node_t *)irq_handler[i].dev_id; n; n = n->next ) {
636 seq_printf(p, "%s\n", n->devname);
637 if (n->next)
638 seq_puts(p, " " );
639 }
640 }
641 }
642 if (num_spurious)
643 seq_printf(p, "spurio.: %10u\n", num_spurious);
644
645 return 0;
646}
647
648
diff --git a/arch/m68k/atari/atari_ksyms.c b/arch/m68k/atari/atari_ksyms.c
new file mode 100644
index 000000000000..a04757151538
--- /dev/null
+++ b/arch/m68k/atari/atari_ksyms.c
@@ -0,0 +1,35 @@
1#include <linux/module.h>
2
3#include <asm/ptrace.h>
4#include <asm/traps.h>
5#include <asm/atarihw.h>
6#include <asm/atariints.h>
7#include <asm/atarikb.h>
8#include <asm/atari_joystick.h>
9#include <asm/atari_stdma.h>
10#include <asm/atari_stram.h>
11
12extern void atari_microwire_cmd( int cmd );
13extern int atari_MFP_init_done;
14extern int atari_SCC_init_done;
15extern int atari_SCC_reset_done;
16
17EXPORT_SYMBOL(atari_mch_cookie);
18EXPORT_SYMBOL(atari_mch_type);
19EXPORT_SYMBOL(atari_hw_present);
20EXPORT_SYMBOL(atari_switches);
21EXPORT_SYMBOL(atari_dont_touch_floppy_select);
22EXPORT_SYMBOL(atari_register_vme_int);
23EXPORT_SYMBOL(atari_unregister_vme_int);
24EXPORT_SYMBOL(stdma_lock);
25EXPORT_SYMBOL(stdma_release);
26EXPORT_SYMBOL(stdma_others_waiting);
27EXPORT_SYMBOL(stdma_islocked);
28EXPORT_SYMBOL(atari_stram_alloc);
29EXPORT_SYMBOL(atari_stram_free);
30
31EXPORT_SYMBOL(atari_MFP_init_done);
32EXPORT_SYMBOL(atari_SCC_init_done);
33EXPORT_SYMBOL(atari_SCC_reset_done);
34
35EXPORT_SYMBOL(atari_microwire_cmd);
diff --git a/arch/m68k/atari/atasound.c b/arch/m68k/atari/atasound.c
new file mode 100644
index 000000000000..ee04250eb56b
--- /dev/null
+++ b/arch/m68k/atari/atasound.c
@@ -0,0 +1,109 @@
1/*
2 * linux/arch/m68k/atari/atasound.c
3 *
4 * ++Geert: Moved almost all stuff to linux/drivers/sound/
5 *
6 * The author of atari_nosound, atari_mksound and atari_microwire_cmd is
7 * unknown. (++roman: That's me... :-)
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file COPYING in the main directory of this archive
11 * for more details.
12 *
13 * 1998-05-31 ++andreas: atari_mksound rewritten to always use the envelope,
14 * no timer, atari_nosound removed.
15 *
16 */
17
18
19#include <linux/sched.h>
20#include <linux/timer.h>
21#include <linux/major.h>
22#include <linux/fcntl.h>
23#include <linux/errno.h>
24#include <linux/mm.h>
25
26#include <asm/atarihw.h>
27#include <asm/system.h>
28#include <asm/irq.h>
29#include <asm/pgtable.h>
30#include <asm/atariints.h>
31
32
33/*
34 * stuff from the old atasound.c
35 */
36
37void atari_microwire_cmd (int cmd)
38{
39 tt_microwire.mask = 0x7ff;
40 tt_microwire.data = MW_LM1992_ADDR | cmd;
41
42 /* Busy wait for data being completely sent :-( */
43 while( tt_microwire.mask != 0x7ff)
44 ;
45}
46
47
48/* PSG base frequency */
49#define PSG_FREQ 125000
50/* PSG envelope base frequency times 10 */
51#define PSG_ENV_FREQ_10 78125
52
53void atari_mksound (unsigned int hz, unsigned int ticks)
54{
55 /* Generates sound of some frequency for some number of clock
56 ticks. */
57 unsigned long flags;
58 unsigned char tmp;
59 int period;
60
61 local_irq_save(flags);
62
63
64 /* Disable generator A in mixer control. */
65 sound_ym.rd_data_reg_sel = 7;
66 tmp = sound_ym.rd_data_reg_sel;
67 tmp |= 011;
68 sound_ym.wd_data = tmp;
69
70 if (hz) {
71 /* Convert from frequency value to PSG period value (base
72 frequency 125 kHz). */
73
74 period = PSG_FREQ / hz;
75
76 if (period > 0xfff) period = 0xfff;
77
78 /* Set generator A frequency to hz. */
79 sound_ym.rd_data_reg_sel = 0;
80 sound_ym.wd_data = period & 0xff;
81 sound_ym.rd_data_reg_sel = 1;
82 sound_ym.wd_data = (period >> 8) & 0xf;
83 if (ticks) {
84 /* Set length of envelope (max 8 sec). */
85 int length = (ticks * PSG_ENV_FREQ_10) / HZ / 10;
86
87 if (length > 0xffff) length = 0xffff;
88 sound_ym.rd_data_reg_sel = 11;
89 sound_ym.wd_data = length & 0xff;
90 sound_ym.rd_data_reg_sel = 12;
91 sound_ym.wd_data = length >> 8;
92 /* Envelope form: max -> min single. */
93 sound_ym.rd_data_reg_sel = 13;
94 sound_ym.wd_data = 0;
95 /* Use envelope for generator A. */
96 sound_ym.rd_data_reg_sel = 8;
97 sound_ym.wd_data = 0x10;
98 } else {
99 /* Set generator A level to maximum, no envelope. */
100 sound_ym.rd_data_reg_sel = 8;
101 sound_ym.wd_data = 15;
102 }
103 /* Turn on generator A in mixer control. */
104 sound_ym.rd_data_reg_sel = 7;
105 tmp &= ~1;
106 sound_ym.wd_data = tmp;
107 }
108 local_irq_restore(flags);
109}
diff --git a/arch/m68k/atari/atasound.h b/arch/m68k/atari/atasound.h
new file mode 100644
index 000000000000..1362762b8c0f
--- /dev/null
+++ b/arch/m68k/atari/atasound.h
@@ -0,0 +1,33 @@
1/*
2 * Minor numbers for the sound driver.
3 *
4 * Unfortunately Creative called the codec chip of SB as a DSP. For this
5 * reason the /dev/dsp is reserved for digitized audio use. There is a
6 * device for true DSP processors but it will be called something else.
7 * In v3.0 it's /dev/sndproc but this could be a temporary solution.
8 */
9
10#define SND_NDEVS 256 /* Number of supported devices */
11#define SND_DEV_CTL 0 /* Control port /dev/mixer */
12#define SND_DEV_SEQ 1 /* Sequencer output /dev/sequencer (FM
13 synthesizer and MIDI output) */
14#define SND_DEV_MIDIN 2 /* Raw midi access */
15#define SND_DEV_DSP 3 /* Digitized voice /dev/dsp */
16#define SND_DEV_AUDIO 4 /* Sparc compatible /dev/audio */
17#define SND_DEV_DSP16 5 /* Like /dev/dsp but 16 bits/sample */
18#define SND_DEV_STATUS 6 /* /dev/sndstat */
19/* #7 not in use now. Was in 2.4. Free for use after v3.0. */
20#define SND_DEV_SEQ2 8 /* /dev/sequencer, level 2 interface */
21#define SND_DEV_SNDPROC 9 /* /dev/sndproc for programmable devices */
22#define SND_DEV_PSS SND_DEV_SNDPROC
23
24#define DSP_DEFAULT_SPEED 8000
25
26#define ON 1
27#define OFF 0
28
29#define MAX_AUDIO_DEV 5
30#define MAX_MIXER_DEV 2
31#define MAX_SYNTH_DEV 3
32#define MAX_MIDI_DEV 6
33#define MAX_TIMER_DEV 3
diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c
new file mode 100644
index 000000000000..9261d2deeaf5
--- /dev/null
+++ b/arch/m68k/atari/config.c
@@ -0,0 +1,726 @@
1/*
2 * linux/arch/m68k/atari/config.c
3 *
4 * Copyright (C) 1994 Bjoern Brauel
5 *
6 * 5/2/94 Roman Hodek:
7 * Added setting of time_adj to get a better clock.
8 *
9 * 5/14/94 Roman Hodek:
10 * gettod() for TT
11 *
12 * 5/15/94 Roman Hodek:
13 * hard_reset_now() for Atari (and others?)
14 *
15 * 94/12/30 Andreas Schwab:
16 * atari_sched_init fixed to get precise clock.
17 *
18 * This file is subject to the terms and conditions of the GNU General Public
19 * License. See the file COPYING in the main directory of this archive
20 * for more details.
21 */
22
23/*
24 * Miscellaneous atari stuff
25 */
26
27#include <linux/config.h>
28#include <linux/types.h>
29#include <linux/mm.h>
30#include <linux/console.h>
31#include <linux/init.h>
32#include <linux/delay.h>
33#include <linux/ioport.h>
34#include <linux/vt_kern.h>
35
36#include <asm/bootinfo.h>
37#include <asm/setup.h>
38#include <asm/atarihw.h>
39#include <asm/atariints.h>
40#include <asm/atari_stram.h>
41#include <asm/system.h>
42#include <asm/machdep.h>
43#include <asm/hwtest.h>
44#include <asm/io.h>
45
46u_long atari_mch_cookie;
47u_long atari_mch_type;
48struct atari_hw_present atari_hw_present;
49u_long atari_switches;
50int atari_dont_touch_floppy_select;
51int atari_rtc_year_offset;
52
53/* local function prototypes */
54static void atari_reset( void );
55#ifdef CONFIG_ATARI_FLOPPY
56extern void atari_floppy_setup(char *, int *);
57#endif
58static void atari_get_model(char *model);
59static int atari_get_hardware_list(char *buffer);
60
61/* atari specific irq functions */
62extern void atari_init_IRQ (void);
63extern int atari_request_irq (unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),
64 unsigned long flags, const char *devname, void *dev_id);
65extern void atari_free_irq (unsigned int irq, void *dev_id);
66extern void atari_enable_irq (unsigned int);
67extern void atari_disable_irq (unsigned int);
68extern int show_atari_interrupts (struct seq_file *, void *);
69extern void atari_mksound( unsigned int count, unsigned int ticks );
70#ifdef CONFIG_HEARTBEAT
71static void atari_heartbeat( int on );
72#endif
73
74/* atari specific timer functions (in time.c) */
75extern void atari_sched_init(irqreturn_t (*)(int, void *, struct pt_regs *));
76extern unsigned long atari_gettimeoffset (void);
77extern int atari_mste_hwclk (int, struct rtc_time *);
78extern int atari_tt_hwclk (int, struct rtc_time *);
79extern int atari_mste_set_clock_mmss (unsigned long);
80extern int atari_tt_set_clock_mmss (unsigned long);
81
82/* atari specific debug functions (in debug.c) */
83extern void atari_debug_init(void);
84
85
86/* I've moved hwreg_present() and hwreg_present_bywrite() out into
87 * mm/hwtest.c, to avoid having multiple copies of the same routine
88 * in the kernel [I wanted them in hp300 and they were already used
89 * in the nubus code. NB: I don't have an Atari so this might (just
90 * conceivably) break something.
91 * I've preserved the #if 0 version of hwreg_present_bywrite() here
92 * for posterity.
93 * -- Peter Maydell <pmaydell@chiark.greenend.org.uk>, 05/1998
94 */
95
96#if 0
97static int __init
98hwreg_present_bywrite(volatile void *regp, unsigned char val)
99{
100 int ret;
101 long save_sp, save_vbr;
102 static long tmp_vectors[3] = { [2] = (long)&&after_test };
103
104 __asm__ __volatile__
105 ( "movec %/vbr,%2\n\t" /* save vbr value */
106 "movec %4,%/vbr\n\t" /* set up temporary vectors */
107 "movel %/sp,%1\n\t" /* save sp */
108 "moveq #0,%0\n\t" /* assume not present */
109 "moveb %5,%3@\n\t" /* write the hardware reg */
110 "cmpb %3@,%5\n\t" /* compare it */
111 "seq %0" /* comes here only if reg */
112 /* is present */
113 : "=d&" (ret), "=r&" (save_sp), "=r&" (save_vbr)
114 : "a" (regp), "r" (tmp_vectors), "d" (val)
115 );
116 after_test:
117 __asm__ __volatile__
118 ( "movel %0,%/sp\n\t" /* restore sp */
119 "movec %1,%/vbr" /* restore vbr */
120 : : "r" (save_sp), "r" (save_vbr) : "sp"
121 );
122
123 return( ret );
124}
125#endif
126
127
128/* ++roman: This is a more elaborate test for an SCC chip, since the plain
129 * Medusa board generates DTACK at the SCC's standard addresses, but a SCC
130 * board in the Medusa is possible. Also, the addresses where the ST_ESCC
131 * resides generate DTACK without the chip, too.
132 * The method is to write values into the interrupt vector register, that
133 * should be readable without trouble (from channel A!).
134 */
135
136static int __init scc_test( volatile char *ctla )
137{
138 if (!hwreg_present( ctla ))
139 return( 0 );
140 MFPDELAY();
141
142 *ctla = 2; MFPDELAY();
143 *ctla = 0x40; MFPDELAY();
144
145 *ctla = 2; MFPDELAY();
146 if (*ctla != 0x40) return( 0 );
147 MFPDELAY();
148
149 *ctla = 2; MFPDELAY();
150 *ctla = 0x60; MFPDELAY();
151
152 *ctla = 2; MFPDELAY();
153 if (*ctla != 0x60) return( 0 );
154
155 return( 1 );
156}
157
158
159 /*
160 * Parse an Atari-specific record in the bootinfo
161 */
162
163int __init atari_parse_bootinfo(const struct bi_record *record)
164{
165 int unknown = 0;
166 const u_long *data = record->data;
167
168 switch (record->tag) {
169 case BI_ATARI_MCH_COOKIE:
170 atari_mch_cookie = *data;
171 break;
172 case BI_ATARI_MCH_TYPE:
173 atari_mch_type = *data;
174 break;
175 default:
176 unknown = 1;
177 }
178 return(unknown);
179}
180
181
182/* Parse the Atari-specific switches= option. */
183void __init atari_switches_setup( const char *str, unsigned len )
184{
185 char switches[len+1];
186 char *p;
187 int ovsc_shift;
188 char *args = switches;
189
190 /* copy string to local array, strsep works destructively... */
191 strlcpy( switches, str, sizeof(switches) );
192 atari_switches = 0;
193
194 /* parse the options */
195 while ((p = strsep(&args, ",")) != NULL) {
196 if (!*p) continue;
197 ovsc_shift = 0;
198 if (strncmp( p, "ov_", 3 ) == 0) {
199 p += 3;
200 ovsc_shift = ATARI_SWITCH_OVSC_SHIFT;
201 }
202
203 if (strcmp( p, "ikbd" ) == 0) {
204 /* RTS line of IKBD ACIA */
205 atari_switches |= ATARI_SWITCH_IKBD << ovsc_shift;
206 }
207 else if (strcmp( p, "midi" ) == 0) {
208 /* RTS line of MIDI ACIA */
209 atari_switches |= ATARI_SWITCH_MIDI << ovsc_shift;
210 }
211 else if (strcmp( p, "snd6" ) == 0) {
212 atari_switches |= ATARI_SWITCH_SND6 << ovsc_shift;
213 }
214 else if (strcmp( p, "snd7" ) == 0) {
215 atari_switches |= ATARI_SWITCH_SND7 << ovsc_shift;
216 }
217 }
218}
219
220
221 /*
222 * Setup the Atari configuration info
223 */
224
225void __init config_atari(void)
226{
227 unsigned short tos_version;
228
229 memset(&atari_hw_present, 0, sizeof(atari_hw_present));
230
231 atari_debug_init();
232
233 ioport_resource.end = 0xFFFFFFFF; /* Change size of I/O space from 64KB
234 to 4GB. */
235
236 mach_sched_init = atari_sched_init;
237 mach_init_IRQ = atari_init_IRQ;
238 mach_request_irq = atari_request_irq;
239 mach_free_irq = atari_free_irq;
240 enable_irq = atari_enable_irq;
241 disable_irq = atari_disable_irq;
242 mach_get_model = atari_get_model;
243 mach_get_hardware_list = atari_get_hardware_list;
244 mach_get_irq_list = show_atari_interrupts;
245 mach_gettimeoffset = atari_gettimeoffset;
246 mach_reset = atari_reset;
247#ifdef CONFIG_ATARI_FLOPPY
248 mach_floppy_setup = atari_floppy_setup;
249#endif
250#ifdef CONFIG_DUMMY_CONSOLE
251 conswitchp = &dummy_con;
252#endif
253 mach_max_dma_address = 0xffffff;
254#if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
255 mach_beep = atari_mksound;
256#endif
257#ifdef CONFIG_HEARTBEAT
258 mach_heartbeat = atari_heartbeat;
259#endif
260
261 /* Set switches as requested by the user */
262 if (atari_switches & ATARI_SWITCH_IKBD)
263 acia.key_ctrl = ACIA_DIV64 | ACIA_D8N1S | ACIA_RHTID;
264 if (atari_switches & ATARI_SWITCH_MIDI)
265 acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S | ACIA_RHTID;
266 if (atari_switches & (ATARI_SWITCH_SND6|ATARI_SWITCH_SND7)) {
267 sound_ym.rd_data_reg_sel = 14;
268 sound_ym.wd_data = sound_ym.rd_data_reg_sel |
269 ((atari_switches&ATARI_SWITCH_SND6) ? 0x40 : 0) |
270 ((atari_switches&ATARI_SWITCH_SND7) ? 0x80 : 0);
271 }
272
273 /* ++bjoern:
274 * Determine hardware present
275 */
276
277 printk( "Atari hardware found: " );
278 if (MACH_IS_MEDUSA || MACH_IS_HADES) {
279 /* There's no Atari video hardware on the Medusa, but all the
280 * addresses below generate a DTACK so no bus error occurs! */
281 }
282 else if (hwreg_present( f030_xreg )) {
283 ATARIHW_SET(VIDEL_SHIFTER);
284 printk( "VIDEL " );
285 /* This is a temporary hack: If there is Falcon video
286 * hardware, we assume that the ST-DMA serves SCSI instead of
287 * ACSI. In the future, there should be a better method for
288 * this...
289 */
290 ATARIHW_SET(ST_SCSI);
291 printk( "STDMA-SCSI " );
292 }
293 else if (hwreg_present( tt_palette )) {
294 ATARIHW_SET(TT_SHIFTER);
295 printk( "TT_SHIFTER " );
296 }
297 else if (hwreg_present( &shifter.bas_hi )) {
298 if (hwreg_present( &shifter.bas_lo ) &&
299 (shifter.bas_lo = 0x0aau, shifter.bas_lo == 0x0aau)) {
300 ATARIHW_SET(EXTD_SHIFTER);
301 printk( "EXTD_SHIFTER " );
302 }
303 else {
304 ATARIHW_SET(STND_SHIFTER);
305 printk( "STND_SHIFTER " );
306 }
307 }
308 if (hwreg_present( &mfp.par_dt_reg )) {
309 ATARIHW_SET(ST_MFP);
310 printk( "ST_MFP " );
311 }
312 if (hwreg_present( &tt_mfp.par_dt_reg )) {
313 ATARIHW_SET(TT_MFP);
314 printk( "TT_MFP " );
315 }
316 if (hwreg_present( &tt_scsi_dma.dma_addr_hi )) {
317 ATARIHW_SET(SCSI_DMA);
318 printk( "TT_SCSI_DMA " );
319 }
320 if (!MACH_IS_HADES && hwreg_present( &st_dma.dma_hi )) {
321 ATARIHW_SET(STND_DMA);
322 printk( "STND_DMA " );
323 }
324 if (MACH_IS_MEDUSA || /* The ST-DMA address registers aren't readable
325 * on all Medusas, so the test below may fail */
326 (hwreg_present( &st_dma.dma_vhi ) &&
327 (st_dma.dma_vhi = 0x55) && (st_dma.dma_hi = 0xaa) &&
328 st_dma.dma_vhi == 0x55 && st_dma.dma_hi == 0xaa &&
329 (st_dma.dma_vhi = 0xaa) && (st_dma.dma_hi = 0x55) &&
330 st_dma.dma_vhi == 0xaa && st_dma.dma_hi == 0x55)) {
331 ATARIHW_SET(EXTD_DMA);
332 printk( "EXTD_DMA " );
333 }
334 if (hwreg_present( &tt_scsi.scsi_data )) {
335 ATARIHW_SET(TT_SCSI);
336 printk( "TT_SCSI " );
337 }
338 if (hwreg_present( &sound_ym.rd_data_reg_sel )) {
339 ATARIHW_SET(YM_2149);
340 printk( "YM2149 " );
341 }
342 if (!MACH_IS_MEDUSA && !MACH_IS_HADES &&
343 hwreg_present( &tt_dmasnd.ctrl )) {
344 ATARIHW_SET(PCM_8BIT);
345 printk( "PCM " );
346 }
347 if (!MACH_IS_HADES && hwreg_present( &falcon_codec.unused5 )) {
348 ATARIHW_SET(CODEC);
349 printk( "CODEC " );
350 }
351 if (hwreg_present( &dsp56k_host_interface.icr )) {
352 ATARIHW_SET(DSP56K);
353 printk( "DSP56K " );
354 }
355 if (hwreg_present( &tt_scc_dma.dma_ctrl ) &&
356#if 0
357 /* This test sucks! Who knows some better? */
358 (tt_scc_dma.dma_ctrl = 0x01, (tt_scc_dma.dma_ctrl & 1) == 1) &&
359 (tt_scc_dma.dma_ctrl = 0x00, (tt_scc_dma.dma_ctrl & 1) == 0)
360#else
361 !MACH_IS_MEDUSA && !MACH_IS_HADES
362#endif
363 ) {
364 ATARIHW_SET(SCC_DMA);
365 printk( "SCC_DMA " );
366 }
367 if (scc_test( &scc.cha_a_ctrl )) {
368 ATARIHW_SET(SCC);
369 printk( "SCC " );
370 }
371 if (scc_test( &st_escc.cha_b_ctrl )) {
372 ATARIHW_SET( ST_ESCC );
373 printk( "ST_ESCC " );
374 }
375 if (MACH_IS_HADES)
376 {
377 ATARIHW_SET( VME );
378 printk( "VME " );
379 }
380 else if (hwreg_present( &tt_scu.sys_mask )) {
381 ATARIHW_SET(SCU);
382 /* Assume a VME bus if there's a SCU */
383 ATARIHW_SET( VME );
384 printk( "VME SCU " );
385 }
386 if (hwreg_present( (void *)(0xffff9210) )) {
387 ATARIHW_SET(ANALOG_JOY);
388 printk( "ANALOG_JOY " );
389 }
390 if (!MACH_IS_HADES && hwreg_present( blitter.halftone )) {
391 ATARIHW_SET(BLITTER);
392 printk( "BLITTER " );
393 }
394 if (hwreg_present((void *)0xfff00039)) {
395 ATARIHW_SET(IDE);
396 printk( "IDE " );
397 }
398#if 1 /* This maybe wrong */
399 if (!MACH_IS_MEDUSA && !MACH_IS_HADES &&
400 hwreg_present( &tt_microwire.data ) &&
401 hwreg_present( &tt_microwire.mask ) &&
402 (tt_microwire.mask = 0x7ff,
403 udelay(1),
404 tt_microwire.data = MW_LM1992_PSG_HIGH | MW_LM1992_ADDR,
405 udelay(1),
406 tt_microwire.data != 0)) {
407 ATARIHW_SET(MICROWIRE);
408 while (tt_microwire.mask != 0x7ff) ;
409 printk( "MICROWIRE " );
410 }
411#endif
412 if (hwreg_present( &tt_rtc.regsel )) {
413 ATARIHW_SET(TT_CLK);
414 printk( "TT_CLK " );
415 mach_hwclk = atari_tt_hwclk;
416 mach_set_clock_mmss = atari_tt_set_clock_mmss;
417 }
418 if (!MACH_IS_HADES && hwreg_present( &mste_rtc.sec_ones)) {
419 ATARIHW_SET(MSTE_CLK);
420 printk( "MSTE_CLK ");
421 mach_hwclk = atari_mste_hwclk;
422 mach_set_clock_mmss = atari_mste_set_clock_mmss;
423 }
424 if (!MACH_IS_MEDUSA && !MACH_IS_HADES &&
425 hwreg_present( &dma_wd.fdc_speed ) &&
426 hwreg_write( &dma_wd.fdc_speed, 0 )) {
427 ATARIHW_SET(FDCSPEED);
428 printk( "FDC_SPEED ");
429 }
430 if (!MACH_IS_HADES && !ATARIHW_PRESENT(ST_SCSI)) {
431 ATARIHW_SET(ACSI);
432 printk( "ACSI " );
433 }
434 printk("\n");
435
436 if (CPU_IS_040_OR_060)
437 /* Now it seems to be safe to turn of the tt0 transparent
438 * translation (the one that must not be turned off in
439 * head.S...)
440 */
441 __asm__ volatile ("moveq #0,%/d0\n\t"
442 ".chip 68040\n\t"
443 "movec %%d0,%%itt0\n\t"
444 "movec %%d0,%%dtt0\n\t"
445 ".chip 68k"
446 : /* no outputs */
447 : /* no inputs */
448 : "d0");
449
450 /* allocator for memory that must reside in st-ram */
451 atari_stram_init ();
452
453 /* Set up a mapping for the VMEbus address region:
454 *
455 * VME is either at phys. 0xfexxxxxx (TT) or 0xa00000..0xdfffff
456 * (MegaSTE) In both cases, the whole 16 MB chunk is mapped at
457 * 0xfe000000 virt., because this can be done with a single
458 * transparent translation. On the 68040, lots of often unused
459 * page tables would be needed otherwise. On a MegaSTE or similar,
460 * the highest byte is stripped off by hardware due to the 24 bit
461 * design of the bus.
462 */
463
464 if (CPU_IS_020_OR_030) {
465 unsigned long tt1_val;
466 tt1_val = 0xfe008543; /* Translate 0xfexxxxxx, enable, cache
467 * inhibit, read and write, FDC mask = 3,
468 * FDC val = 4 -> Supervisor only */
469 __asm__ __volatile__ ( ".chip 68030\n\t"
470 "pmove %0@,%/tt1\n\t"
471 ".chip 68k"
472 : : "a" (&tt1_val) );
473 }
474 else {
475 __asm__ __volatile__
476 ( "movel %0,%/d0\n\t"
477 ".chip 68040\n\t"
478 "movec %%d0,%%itt1\n\t"
479 "movec %%d0,%%dtt1\n\t"
480 ".chip 68k"
481 :
482 : "g" (0xfe00a040) /* Translate 0xfexxxxxx, enable,
483 * supervisor only, non-cacheable/
484 * serialized, writable */
485 : "d0" );
486
487 }
488
489 /* Fetch tos version at Physical 2 */
490 /* We my not be able to access this address if the kernel is
491 loaded to st ram, since the first page is unmapped. On the
492 Medusa this is always the case and there is nothing we can do
493 about this, so we just assume the smaller offset. For the TT
494 we use the fact that in head.S we have set up a mapping
495 0xFFxxxxxx -> 0x00xxxxxx, so that the first 16MB is accessible
496 in the last 16MB of the address space. */
497 tos_version = (MACH_IS_MEDUSA || MACH_IS_HADES) ?
498 0xfff : *(unsigned short *)0xff000002;
499 atari_rtc_year_offset = (tos_version < 0x306) ? 70 : 68;
500}
501
502#ifdef CONFIG_HEARTBEAT
503static void atari_heartbeat( int on )
504{
505 unsigned char tmp;
506 unsigned long flags;
507
508 if (atari_dont_touch_floppy_select)
509 return;
510
511 local_irq_save(flags);
512 sound_ym.rd_data_reg_sel = 14; /* Select PSG Port A */
513 tmp = sound_ym.rd_data_reg_sel;
514 sound_ym.wd_data = on ? (tmp & ~0x02) : (tmp | 0x02);
515 local_irq_restore(flags);
516}
517#endif
518
519/* ++roman:
520 *
521 * This function does a reset on machines that lack the ability to
522 * assert the processor's _RESET signal somehow via hardware. It is
523 * based on the fact that you can find the initial SP and PC values
524 * after a reset at physical addresses 0 and 4. This works pretty well
525 * for Atari machines, since the lowest 8 bytes of physical memory are
526 * really ROM (mapped by hardware). For other 680x0 machines: don't
527 * know if it works...
528 *
529 * To get the values at addresses 0 and 4, the MMU better is turned
530 * off first. After that, we have to jump into physical address space
531 * (the PC before the pmove statement points to the virtual address of
532 * the code). Getting that physical address is not hard, but the code
533 * becomes a bit complex since I've tried to ensure that the jump
534 * statement after the pmove is in the cache already (otherwise the
535 * processor can't fetch it!). For that, the code first jumps to the
536 * jump statement with the (virtual) address of the pmove section in
537 * an address register . The jump statement is surely in the cache
538 * now. After that, that physical address of the reset code is loaded
539 * into the same address register, pmove is done and the same jump
540 * statements goes to the reset code. Since there are not many
541 * statements between the two jumps, I hope it stays in the cache.
542 *
543 * The C code makes heavy use of the GCC features that you can get the
544 * address of a C label. No hope to compile this with another compiler
545 * than GCC!
546 */
547
548/* ++andreas: no need for complicated code, just depend on prefetch */
549
550static void atari_reset (void)
551{
552 long tc_val = 0;
553 long reset_addr;
554
555 /* On the Medusa, phys. 0x4 may contain garbage because it's no
556 ROM. See above for explanation why we cannot use PTOV(4). */
557 reset_addr = MACH_IS_HADES ? 0x7fe00030 :
558 MACH_IS_MEDUSA || MACH_IS_AB40 ? 0xe00030 :
559 *(unsigned long *) 0xff000004;
560
561 /* reset ACIA for switch off OverScan, if it's active */
562 if (atari_switches & ATARI_SWITCH_OVSC_IKBD)
563 acia.key_ctrl = ACIA_RESET;
564 if (atari_switches & ATARI_SWITCH_OVSC_MIDI)
565 acia.mid_ctrl = ACIA_RESET;
566
567 /* processor independent: turn off interrupts and reset the VBR;
568 * the caches must be left enabled, else prefetching the final jump
569 * instruction doesn't work. */
570 local_irq_disable();
571 __asm__ __volatile__
572 ("moveq #0,%/d0\n\t"
573 "movec %/d0,%/vbr"
574 : : : "d0" );
575
576 if (CPU_IS_040_OR_060) {
577 unsigned long jmp_addr040 = virt_to_phys(&&jmp_addr_label040);
578 if (CPU_IS_060) {
579 /* 68060: clear PCR to turn off superscalar operation */
580 __asm__ __volatile__
581 ("moveq #0,%/d0\n\t"
582 ".chip 68060\n\t"
583 "movec %%d0,%%pcr\n\t"
584 ".chip 68k"
585 : : : "d0" );
586 }
587
588 __asm__ __volatile__
589 ("movel %0,%/d0\n\t"
590 "andl #0xff000000,%/d0\n\t"
591 "orw #0xe020,%/d0\n\t" /* map 16 MB, enable, cacheable */
592 ".chip 68040\n\t"
593 "movec %%d0,%%itt0\n\t"
594 "movec %%d0,%%dtt0\n\t"
595 ".chip 68k\n\t"
596 "jmp %0@\n\t"
597 : /* no outputs */
598 : "a" (jmp_addr040)
599 : "d0" );
600 jmp_addr_label040:
601 __asm__ __volatile__
602 ("moveq #0,%/d0\n\t"
603 "nop\n\t"
604 ".chip 68040\n\t"
605 "cinva %%bc\n\t"
606 "nop\n\t"
607 "pflusha\n\t"
608 "nop\n\t"
609 "movec %%d0,%%tc\n\t"
610 "nop\n\t"
611 /* the following setup of transparent translations is needed on the
612 * Afterburner040 to successfully reboot. Other machines shouldn't
613 * care about a different tt regs setup, they also didn't care in
614 * the past that the regs weren't turned off. */
615 "movel #0xffc000,%%d0\n\t" /* whole insn space cacheable */
616 "movec %%d0,%%itt0\n\t"
617 "movec %%d0,%%itt1\n\t"
618 "orw #0x40,%/d0\n\t" /* whole data space non-cacheable/ser. */
619 "movec %%d0,%%dtt0\n\t"
620 "movec %%d0,%%dtt1\n\t"
621 ".chip 68k\n\t"
622 "jmp %0@"
623 : /* no outputs */
624 : "a" (reset_addr)
625 : "d0");
626 }
627 else
628 __asm__ __volatile__
629 ("pmove %0@,%/tc\n\t"
630 "jmp %1@"
631 : /* no outputs */
632 : "a" (&tc_val), "a" (reset_addr));
633}
634
635
636static void atari_get_model(char *model)
637{
638 strcpy(model, "Atari ");
639 switch (atari_mch_cookie >> 16) {
640 case ATARI_MCH_ST:
641 if (ATARIHW_PRESENT(MSTE_CLK))
642 strcat (model, "Mega ST");
643 else
644 strcat (model, "ST");
645 break;
646 case ATARI_MCH_STE:
647 if (MACH_IS_MSTE)
648 strcat (model, "Mega STE");
649 else
650 strcat (model, "STE");
651 break;
652 case ATARI_MCH_TT:
653 if (MACH_IS_MEDUSA)
654 /* Medusa has TT _MCH cookie */
655 strcat (model, "Medusa");
656 else if (MACH_IS_HADES)
657 strcat(model, "Hades");
658 else
659 strcat (model, "TT");
660 break;
661 case ATARI_MCH_FALCON:
662 strcat (model, "Falcon");
663 if (MACH_IS_AB40)
664 strcat (model, " (with Afterburner040)");
665 break;
666 default:
667 sprintf (model + strlen (model), "(unknown mach cookie 0x%lx)",
668 atari_mch_cookie);
669 break;
670 }
671}
672
673
674static int atari_get_hardware_list(char *buffer)
675{
676 int len = 0, i;
677
678 for (i = 0; i < m68k_num_memory; i++)
679 len += sprintf (buffer+len, "\t%3ld MB at 0x%08lx (%s)\n",
680 m68k_memory[i].size >> 20, m68k_memory[i].addr,
681 (m68k_memory[i].addr & 0xff000000 ?
682 "alternate RAM" : "ST-RAM"));
683
684#define ATARIHW_ANNOUNCE(name,str) \
685 if (ATARIHW_PRESENT(name)) \
686 len += sprintf (buffer + len, "\t%s\n", str)
687
688 len += sprintf (buffer + len, "Detected hardware:\n");
689 ATARIHW_ANNOUNCE(STND_SHIFTER, "ST Shifter");
690 ATARIHW_ANNOUNCE(EXTD_SHIFTER, "STe Shifter");
691 ATARIHW_ANNOUNCE(TT_SHIFTER, "TT Shifter");
692 ATARIHW_ANNOUNCE(VIDEL_SHIFTER, "Falcon Shifter");
693 ATARIHW_ANNOUNCE(YM_2149, "Programmable Sound Generator");
694 ATARIHW_ANNOUNCE(PCM_8BIT, "PCM 8 Bit Sound");
695 ATARIHW_ANNOUNCE(CODEC, "CODEC Sound");
696 ATARIHW_ANNOUNCE(TT_SCSI, "SCSI Controller NCR5380 (TT style)");
697 ATARIHW_ANNOUNCE(ST_SCSI, "SCSI Controller NCR5380 (Falcon style)");
698 ATARIHW_ANNOUNCE(ACSI, "ACSI Interface");
699 ATARIHW_ANNOUNCE(IDE, "IDE Interface");
700 ATARIHW_ANNOUNCE(FDCSPEED, "8/16 Mhz Switch for FDC");
701 ATARIHW_ANNOUNCE(ST_MFP, "Multi Function Peripheral MFP 68901");
702 ATARIHW_ANNOUNCE(TT_MFP, "Second Multi Function Peripheral MFP 68901");
703 ATARIHW_ANNOUNCE(SCC, "Serial Communications Controller SCC 8530");
704 ATARIHW_ANNOUNCE(ST_ESCC, "Extended Serial Communications Controller SCC 85230");
705 ATARIHW_ANNOUNCE(ANALOG_JOY, "Paddle Interface");
706 ATARIHW_ANNOUNCE(MICROWIRE, "MICROWIRE(tm) Interface");
707 ATARIHW_ANNOUNCE(STND_DMA, "DMA Controller (24 bit)");
708 ATARIHW_ANNOUNCE(EXTD_DMA, "DMA Controller (32 bit)");
709 ATARIHW_ANNOUNCE(SCSI_DMA, "DMA Controller for NCR5380");
710 ATARIHW_ANNOUNCE(SCC_DMA, "DMA Controller for SCC");
711 ATARIHW_ANNOUNCE(TT_CLK, "Clock Chip MC146818A");
712 ATARIHW_ANNOUNCE(MSTE_CLK, "Clock Chip RP5C15");
713 ATARIHW_ANNOUNCE(SCU, "System Control Unit");
714 ATARIHW_ANNOUNCE(BLITTER, "Blitter");
715 ATARIHW_ANNOUNCE(VME, "VME Bus");
716 ATARIHW_ANNOUNCE(DSP56K, "DSP56001 processor");
717
718 return(len);
719}
720
721/*
722 * Local variables:
723 * c-indent-level: 4
724 * tab-width: 8
725 * End:
726 */
diff --git a/arch/m68k/atari/debug.c b/arch/m68k/atari/debug.c
new file mode 100644
index 000000000000..ace05f79d968
--- /dev/null
+++ b/arch/m68k/atari/debug.c
@@ -0,0 +1,347 @@
1/*
2 * linux/arch/m68k/atari/debug.c
3 *
4 * Atari debugging and serial console stuff
5 *
6 * Assembled of parts of former atari/config.c 97-12-18 by Roman Hodek
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file COPYING in the main directory of this archive
10 * for more details.
11 */
12
13#include <linux/config.h>
14#include <linux/types.h>
15#include <linux/tty.h>
16#include <linux/console.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19
20#include <asm/atarihw.h>
21#include <asm/atariints.h>
22
23extern char m68k_debug_device[];
24
25/* Flag that Modem1 port is already initialized and used */
26int atari_MFP_init_done;
27/* Flag that Modem1 port is already initialized and used */
28int atari_SCC_init_done;
29/* Can be set somewhere, if a SCC master reset has already be done and should
30 * not be repeated; used by kgdb */
31int atari_SCC_reset_done;
32
33static struct console atari_console_driver = {
34 .name = "debug",
35 .flags = CON_PRINTBUFFER,
36 .index = -1,
37};
38
39
40static inline void ata_mfp_out (char c)
41{
42 while (!(mfp.trn_stat & 0x80)) /* wait for tx buf empty */
43 barrier ();
44 mfp.usart_dta = c;
45}
46
47void atari_mfp_console_write (struct console *co, const char *str,
48 unsigned int count)
49{
50 while (count--) {
51 if (*str == '\n')
52 ata_mfp_out( '\r' );
53 ata_mfp_out( *str++ );
54 }
55}
56
57static inline void ata_scc_out (char c)
58{
59 do {
60 MFPDELAY();
61 } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */
62 MFPDELAY();
63 scc.cha_b_data = c;
64}
65
66void atari_scc_console_write (struct console *co, const char *str,
67 unsigned int count)
68{
69 while (count--) {
70 if (*str == '\n')
71 ata_scc_out( '\r' );
72 ata_scc_out( *str++ );
73 }
74}
75
76static inline void ata_midi_out (char c)
77{
78 while (!(acia.mid_ctrl & ACIA_TDRE)) /* wait for tx buf empty */
79 barrier ();
80 acia.mid_data = c;
81}
82
83void atari_midi_console_write (struct console *co, const char *str,
84 unsigned int count)
85{
86 while (count--) {
87 if (*str == '\n')
88 ata_midi_out( '\r' );
89 ata_midi_out( *str++ );
90 }
91}
92
93static int ata_par_out (char c)
94{
95 unsigned char tmp;
96 /* This a some-seconds timeout in case no printer is connected */
97 unsigned long i = loops_per_jiffy > 1 ? loops_per_jiffy : 10000000/HZ;
98
99 while( (mfp.par_dt_reg & 1) && --i ) /* wait for BUSY == L */
100 ;
101 if (!i) return( 0 );
102
103 sound_ym.rd_data_reg_sel = 15; /* select port B */
104 sound_ym.wd_data = c; /* put char onto port */
105 sound_ym.rd_data_reg_sel = 14; /* select port A */
106 tmp = sound_ym.rd_data_reg_sel;
107 sound_ym.wd_data = tmp & ~0x20; /* set strobe L */
108 MFPDELAY(); /* wait a bit */
109 sound_ym.wd_data = tmp | 0x20; /* set strobe H */
110 return( 1 );
111}
112
113static void atari_par_console_write (struct console *co, const char *str,
114 unsigned int count)
115{
116 static int printer_present = 1;
117
118 if (!printer_present)
119 return;
120
121 while (count--) {
122 if (*str == '\n')
123 if (!ata_par_out( '\r' )) {
124 printer_present = 0;
125 return;
126 }
127 if (!ata_par_out( *str++ )) {
128 printer_present = 0;
129 return;
130 }
131 }
132}
133
134#ifdef CONFIG_SERIAL_CONSOLE
135int atari_mfp_console_wait_key(struct console *co)
136{
137 while( !(mfp.rcv_stat & 0x80) ) /* wait for rx buf filled */
138 barrier();
139 return( mfp.usart_dta );
140}
141
142int atari_scc_console_wait_key(struct console *co)
143{
144 do {
145 MFPDELAY();
146 } while( !(scc.cha_b_ctrl & 0x01) ); /* wait for rx buf filled */
147 MFPDELAY();
148 return( scc.cha_b_data );
149}
150
151int atari_midi_console_wait_key(struct console *co)
152{
153 while( !(acia.mid_ctrl & ACIA_RDRF) ) /* wait for rx buf filled */
154 barrier();
155 return( acia.mid_data );
156}
157#endif
158
159/* The following two functions do a quick'n'dirty initialization of the MFP or
160 * SCC serial ports. They're used by the debugging interface, kgdb, and the
161 * serial console code. */
162#ifndef CONFIG_SERIAL_CONSOLE
163static void __init atari_init_mfp_port( int cflag )
164#else
165void atari_init_mfp_port( int cflag )
166#endif
167{
168 /* timer values for 1200...115200 bps; > 38400 select 110, 134, or 150
169 * bps, resp., and work only correct if there's a RSVE or RSSPEED */
170 static int baud_table[9] = { 16, 11, 8, 4, 2, 1, 175, 143, 128 };
171 int baud = cflag & CBAUD;
172 int parity = (cflag & PARENB) ? ((cflag & PARODD) ? 0x04 : 0x06) : 0;
173 int csize = ((cflag & CSIZE) == CS7) ? 0x20 : 0x00;
174
175 if (cflag & CBAUDEX)
176 baud += B38400;
177 if (baud < B1200 || baud > B38400+2)
178 baud = B9600; /* use default 9600bps for non-implemented rates */
179 baud -= B1200; /* baud_table[] starts at 1200bps */
180
181 mfp.trn_stat &= ~0x01; /* disable TX */
182 mfp.usart_ctr = parity | csize | 0x88; /* 1:16 clk mode, 1 stop bit */
183 mfp.tim_ct_cd &= 0x70; /* stop timer D */
184 mfp.tim_dt_d = baud_table[baud];
185 mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */
186 mfp.trn_stat |= 0x01; /* enable TX */
187
188 atari_MFP_init_done = 1;
189}
190
191#define SCC_WRITE(reg,val) \
192 do { \
193 scc.cha_b_ctrl = (reg); \
194 MFPDELAY(); \
195 scc.cha_b_ctrl = (val); \
196 MFPDELAY(); \
197 } while(0)
198
199/* loops_per_jiffy isn't initialized yet, so we can't use udelay(). This does a
200 * delay of ~ 60us. */
201#define LONG_DELAY() \
202 do { \
203 int i; \
204 for( i = 100; i > 0; --i ) \
205 MFPDELAY(); \
206 } while(0)
207
208#ifndef CONFIG_SERIAL_CONSOLE
209static void __init atari_init_scc_port( int cflag )
210#else
211void atari_init_scc_port( int cflag )
212#endif
213{
214 extern int atari_SCC_reset_done;
215 static int clksrc_table[9] =
216 /* reg 11: 0x50 = BRG, 0x00 = RTxC, 0x28 = TRxC */
217 { 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 };
218 static int brgsrc_table[9] =
219 /* reg 14: 0 = RTxC, 2 = PCLK */
220 { 2, 2, 2, 2, 2, 2, 0, 2, 2 };
221 static int clkmode_table[9] =
222 /* reg 4: 0x40 = x16, 0x80 = x32, 0xc0 = x64 */
223 { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x80 };
224 static int div_table[9] =
225 /* reg12 (BRG low) */
226 { 208, 138, 103, 50, 24, 11, 1, 0, 0 };
227
228 int baud = cflag & CBAUD;
229 int clksrc, clkmode, div, reg3, reg5;
230
231 if (cflag & CBAUDEX)
232 baud += B38400;
233 if (baud < B1200 || baud > B38400+2)
234 baud = B9600; /* use default 9600bps for non-implemented rates */
235 baud -= B1200; /* tables starts at 1200bps */
236
237 clksrc = clksrc_table[baud];
238 clkmode = clkmode_table[baud];
239 div = div_table[baud];
240 if (ATARIHW_PRESENT(TT_MFP) && baud >= 6) {
241 /* special treatment for TT, where rates >= 38400 are done via TRxC */
242 clksrc = 0x28; /* TRxC */
243 clkmode = baud == 6 ? 0xc0 :
244 baud == 7 ? 0x80 : /* really 76800bps */
245 0x40; /* really 153600bps */
246 div = 0;
247 }
248
249 reg3 = (cflag & CSIZE) == CS8 ? 0xc0 : 0x40;
250 reg5 = (cflag & CSIZE) == CS8 ? 0x60 : 0x20 | 0x82 /* assert DTR/RTS */;
251
252 (void)scc.cha_b_ctrl; /* reset reg pointer */
253 SCC_WRITE( 9, 0xc0 ); /* reset */
254 LONG_DELAY(); /* extra delay after WR9 access */
255 SCC_WRITE( 4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 |
256 0x04 /* 1 stopbit */ |
257 clkmode );
258 SCC_WRITE( 3, reg3 );
259 SCC_WRITE( 5, reg5 );
260 SCC_WRITE( 9, 0 ); /* no interrupts */
261 LONG_DELAY(); /* extra delay after WR9 access */
262 SCC_WRITE( 10, 0 ); /* NRZ mode */
263 SCC_WRITE( 11, clksrc ); /* main clock source */
264 SCC_WRITE( 12, div ); /* BRG value */
265 SCC_WRITE( 13, 0 ); /* BRG high byte */
266 SCC_WRITE( 14, brgsrc_table[baud] );
267 SCC_WRITE( 14, brgsrc_table[baud] | (div ? 1 : 0) );
268 SCC_WRITE( 3, reg3 | 1 );
269 SCC_WRITE( 5, reg5 | 8 );
270
271 atari_SCC_reset_done = 1;
272 atari_SCC_init_done = 1;
273}
274
275#ifndef CONFIG_SERIAL_CONSOLE
276static void __init atari_init_midi_port( int cflag )
277#else
278void atari_init_midi_port( int cflag )
279#endif
280{
281 int baud = cflag & CBAUD;
282 int csize = ((cflag & CSIZE) == CS8) ? 0x10 : 0x00;
283 /* warning 7N1 isn't possible! (instead 7O2 is used...) */
284 int parity = (cflag & PARENB) ? ((cflag & PARODD) ? 0x0c : 0x08) : 0x04;
285 int div;
286
287 /* 4800 selects 7812.5, 115200 selects 500000, all other (incl. 9600 as
288 * default) the standard MIDI speed 31250. */
289 if (cflag & CBAUDEX)
290 baud += B38400;
291 if (baud == B4800)
292 div = ACIA_DIV64; /* really 7812.5 bps */
293 else if (baud == B38400+2 /* 115200 */)
294 div = ACIA_DIV1; /* really 500 kbps (does that work??) */
295 else
296 div = ACIA_DIV16; /* 31250 bps, standard for MIDI */
297
298 /* RTS low, ints disabled */
299 acia.mid_ctrl = div | csize | parity |
300 ((atari_switches & ATARI_SWITCH_MIDI) ?
301 ACIA_RHTID : ACIA_RLTID);
302}
303
304void __init atari_debug_init(void)
305{
306 if (!strcmp( m68k_debug_device, "ser" )) {
307 /* defaults to ser2 for a Falcon and ser1 otherwise */
308 strcpy( m68k_debug_device, MACH_IS_FALCON ? "ser2" : "ser1" );
309
310 }
311
312 if (!strcmp( m68k_debug_device, "ser1" )) {
313 /* ST-MFP Modem1 serial port */
314 atari_init_mfp_port( B9600|CS8 );
315 atari_console_driver.write = atari_mfp_console_write;
316 }
317 else if (!strcmp( m68k_debug_device, "ser2" )) {
318 /* SCC Modem2 serial port */
319 atari_init_scc_port( B9600|CS8 );
320 atari_console_driver.write = atari_scc_console_write;
321 }
322 else if (!strcmp( m68k_debug_device, "midi" )) {
323 /* MIDI port */
324 atari_init_midi_port( B9600|CS8 );
325 atari_console_driver.write = atari_midi_console_write;
326 }
327 else if (!strcmp( m68k_debug_device, "par" )) {
328 /* parallel printer */
329 atari_turnoff_irq( IRQ_MFP_BUSY ); /* avoid ints */
330 sound_ym.rd_data_reg_sel = 7; /* select mixer control */
331 sound_ym.wd_data = 0xff; /* sound off, ports are output */
332 sound_ym.rd_data_reg_sel = 15; /* select port B */
333 sound_ym.wd_data = 0; /* no char */
334 sound_ym.rd_data_reg_sel = 14; /* select port A */
335 sound_ym.wd_data = sound_ym.rd_data_reg_sel | 0x20; /* strobe H */
336 atari_console_driver.write = atari_par_console_write;
337 }
338 if (atari_console_driver.write)
339 register_console(&atari_console_driver);
340}
341
342/*
343 * Local variables:
344 * c-indent-level: 4
345 * tab-width: 8
346 * End:
347 */
diff --git a/arch/m68k/atari/hades-pci.c b/arch/m68k/atari/hades-pci.c
new file mode 100644
index 000000000000..8888debf71ec
--- /dev/null
+++ b/arch/m68k/atari/hades-pci.c
@@ -0,0 +1,444 @@
1/*
2 * hades-pci.c - Hardware specific PCI BIOS functions the Hades Atari clone.
3 *
4 * Written by Wout Klaren.
5 */
6
7#include <linux/config.h>
8#include <linux/init.h>
9#include <linux/kernel.h>
10#include <asm/io.h>
11
12#if 0
13# define DBG_DEVS(args) printk args
14#else
15# define DBG_DEVS(args)
16#endif
17
18#if defined(CONFIG_PCI) && defined(CONFIG_HADES)
19
20#include <linux/slab.h>
21#include <linux/mm.h>
22#include <linux/pci.h>
23
24#include <asm/atarihw.h>
25#include <asm/atariints.h>
26#include <asm/byteorder.h>
27#include <asm/pci.h>
28
29#define HADES_MEM_BASE 0x80000000
30#define HADES_MEM_SIZE 0x20000000
31#define HADES_CONFIG_BASE 0xA0000000
32#define HADES_CONFIG_SIZE 0x10000000
33#define HADES_IO_BASE 0xB0000000
34#define HADES_IO_SIZE 0x10000000
35#define HADES_VIRT_IO_SIZE 0x00010000 /* Only 64k is remapped and actually used. */
36
37#define N_SLOTS 4 /* Number of PCI slots. */
38
39static const char pci_mem_name[] = "PCI memory space";
40static const char pci_io_name[] = "PCI I/O space";
41static const char pci_config_name[] = "PCI config space";
42
43static struct resource config_space = {
44 .name = pci_config_name,
45 .start = HADES_CONFIG_BASE,
46 .end = HADES_CONFIG_BASE + HADES_CONFIG_SIZE - 1
47};
48static struct resource io_space = {
49 .name = pci_io_name,
50 .start = HADES_IO_BASE,
51 .end = HADES_IO_BASE + HADES_IO_SIZE - 1
52};
53
54static const unsigned long pci_conf_base_phys[] = {
55 0xA0080000, 0xA0040000, 0xA0020000, 0xA0010000
56};
57static unsigned long pci_conf_base_virt[N_SLOTS];
58static unsigned long pci_io_base_virt;
59
60/*
61 * static void *mk_conf_addr(unsigned char bus, unsigned char device_fn,
62 * unsigned char where)
63 *
64 * Calculate the address of the PCI configuration area of the given
65 * device.
66 *
67 * BUG: boards with multiple functions are probably not correctly
68 * supported.
69 */
70
71static void *mk_conf_addr(struct pci_dev *dev, int where)
72{
73 int device = dev->devfn >> 3, function = dev->devfn & 7;
74 void *result;
75
76 DBG_DEVS(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, pci_addr=0x%p)\n",
77 dev->bus->number, dev->devfn, where, pci_addr));
78
79 if (device > 3)
80 {
81 DBG_DEVS(("mk_conf_addr: device (%d) > 3, returning NULL\n", device));
82 return NULL;
83 }
84
85 if (dev->bus->number != 0)
86 {
87 DBG_DEVS(("mk_conf_addr: bus (%d) > 0, returning NULL\n", device));
88 return NULL;
89 }
90
91 result = (void *) (pci_conf_base_virt[device] | (function << 8) | (where));
92 DBG_DEVS(("mk_conf_addr: returning pci_addr 0x%lx\n", (unsigned long) result));
93 return result;
94}
95
96static int hades_read_config_byte(struct pci_dev *dev, int where, u8 *value)
97{
98 volatile unsigned char *pci_addr;
99
100 *value = 0xff;
101
102 if ((pci_addr = (unsigned char *) mk_conf_addr(dev, where)) == NULL)
103 return PCIBIOS_DEVICE_NOT_FOUND;
104
105 *value = *pci_addr;
106
107 return PCIBIOS_SUCCESSFUL;
108}
109
110static int hades_read_config_word(struct pci_dev *dev, int where, u16 *value)
111{
112 volatile unsigned short *pci_addr;
113
114 *value = 0xffff;
115
116 if (where & 0x1)
117 return PCIBIOS_BAD_REGISTER_NUMBER;
118
119 if ((pci_addr = (unsigned short *) mk_conf_addr(dev, where)) == NULL)
120 return PCIBIOS_DEVICE_NOT_FOUND;
121
122 *value = le16_to_cpu(*pci_addr);
123
124 return PCIBIOS_SUCCESSFUL;
125}
126
127static int hades_read_config_dword(struct pci_dev *dev, int where, u32 *value)
128{
129 volatile unsigned int *pci_addr;
130 unsigned char header_type;
131 int result;
132
133 *value = 0xffffffff;
134
135 if (where & 0x3)
136 return PCIBIOS_BAD_REGISTER_NUMBER;
137
138 if ((pci_addr = (unsigned int *) mk_conf_addr(dev, where)) == NULL)
139 return PCIBIOS_DEVICE_NOT_FOUND;
140
141 *value = le32_to_cpu(*pci_addr);
142
143 /*
144 * Check if the value is an address on the bus. If true, add the
145 * base address of the PCI memory or PCI I/O area on the Hades.
146 */
147
148 if ((result = hades_read_config_byte(dev, PCI_HEADER_TYPE,
149 &header_type)) != PCIBIOS_SUCCESSFUL)
150 return result;
151
152 if (((where >= PCI_BASE_ADDRESS_0) && (where <= PCI_BASE_ADDRESS_1)) ||
153 ((header_type != PCI_HEADER_TYPE_BRIDGE) && ((where >= PCI_BASE_ADDRESS_2) &&
154 (where <= PCI_BASE_ADDRESS_5))))
155 {
156 if ((*value & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
157 {
158 /*
159 * Base address register that contains an I/O address. If the
160 * address is valid on the Hades (0 <= *value < HADES_VIRT_IO_SIZE),
161 * add 'pci_io_base_virt' to the value.
162 */
163
164 if (*value < HADES_VIRT_IO_SIZE)
165 *value += pci_io_base_virt;
166 }
167 else
168 {
169 /*
170 * Base address register that contains an memory address. If the
171 * address is valid on the Hades (0 <= *value < HADES_MEM_SIZE),
172 * add HADES_MEM_BASE to the value.
173 */
174
175 if (*value == 0)
176 {
177 /*
178 * Base address is 0. Test if this base
179 * address register is used.
180 */
181
182 *pci_addr = 0xffffffff;
183 if (*pci_addr != 0)
184 {
185 *pci_addr = *value;
186 if (*value < HADES_MEM_SIZE)
187 *value += HADES_MEM_BASE;
188 }
189 }
190 else
191 {
192 if (*value < HADES_MEM_SIZE)
193 *value += HADES_MEM_BASE;
194 }
195 }
196 }
197
198 return PCIBIOS_SUCCESSFUL;
199}
200
201static int hades_write_config_byte(struct pci_dev *dev, int where, u8 value)
202{
203 volatile unsigned char *pci_addr;
204
205 if ((pci_addr = (unsigned char *) mk_conf_addr(dev, where)) == NULL)
206 return PCIBIOS_DEVICE_NOT_FOUND;
207
208 *pci_addr = value;
209
210 return PCIBIOS_SUCCESSFUL;
211}
212
213static int hades_write_config_word(struct pci_dev *dev, int where, u16 value)
214{
215 volatile unsigned short *pci_addr;
216
217 if ((pci_addr = (unsigned short *) mk_conf_addr(dev, where)) == NULL)
218 return PCIBIOS_DEVICE_NOT_FOUND;
219
220 *pci_addr = cpu_to_le16(value);
221
222 return PCIBIOS_SUCCESSFUL;
223}
224
225static int hades_write_config_dword(struct pci_dev *dev, int where, u32 value)
226{
227 volatile unsigned int *pci_addr;
228 unsigned char header_type;
229 int result;
230
231 if ((pci_addr = (unsigned int *) mk_conf_addr(dev, where)) == NULL)
232 return PCIBIOS_DEVICE_NOT_FOUND;
233
234 /*
235 * Check if the value is an address on the bus. If true, subtract the
236 * base address of the PCI memory or PCI I/O area on the Hades.
237 */
238
239 if ((result = hades_read_config_byte(dev, PCI_HEADER_TYPE,
240 &header_type)) != PCIBIOS_SUCCESSFUL)
241 return result;
242
243 if (((where >= PCI_BASE_ADDRESS_0) && (where <= PCI_BASE_ADDRESS_1)) ||
244 ((header_type != PCI_HEADER_TYPE_BRIDGE) && ((where >= PCI_BASE_ADDRESS_2) &&
245 (where <= PCI_BASE_ADDRESS_5))))
246 {
247 if ((value & PCI_BASE_ADDRESS_SPACE) ==
248 PCI_BASE_ADDRESS_SPACE_IO)
249 {
250 /*
251 * I/O address. Check if the address is valid address on
252 * the Hades (pci_io_base_virt <= value < pci_io_base_virt +
253 * HADES_VIRT_IO_SIZE) or if the value is 0xffffffff. If not
254 * true do not write the base address register. If it is a
255 * valid base address subtract 'pci_io_base_virt' from the value.
256 */
257
258 if ((value >= pci_io_base_virt) && (value < (pci_io_base_virt +
259 HADES_VIRT_IO_SIZE)))
260 value -= pci_io_base_virt;
261 else
262 {
263 if (value != 0xffffffff)
264 return PCIBIOS_SET_FAILED;
265 }
266 }
267 else
268 {
269 /*
270 * Memory address. Check if the address is valid address on
271 * the Hades (HADES_MEM_BASE <= value < HADES_MEM_BASE + HADES_MEM_SIZE) or
272 * if the value is 0xffffffff. If not true do not write
273 * the base address register. If it is a valid base address
274 * subtract HADES_MEM_BASE from the value.
275 */
276
277 if ((value >= HADES_MEM_BASE) && (value < (HADES_MEM_BASE + HADES_MEM_SIZE)))
278 value -= HADES_MEM_BASE;
279 else
280 {
281 if (value != 0xffffffff)
282 return PCIBIOS_SET_FAILED;
283 }
284 }
285 }
286
287 *pci_addr = cpu_to_le32(value);
288
289 return PCIBIOS_SUCCESSFUL;
290}
291
292/*
293 * static inline void hades_fixup(void)
294 *
295 * Assign IRQ numbers as used by Linux to the interrupt pins
296 * of the PCI cards.
297 */
298
299static void __init hades_fixup(int pci_modify)
300{
301 char irq_tab[4] = {
302 [0] = IRQ_TT_MFP_IO0, /* Slot 0. */
303 [1] = IRQ_TT_MFP_IO1, /* Slot 1. */
304 [2] = IRQ_TT_MFP_SCC, /* Slot 2. */
305 [3] = IRQ_TT_MFP_SCSIDMA /* Slot 3. */
306 };
307 struct pci_dev *dev = NULL;
308 unsigned char slot;
309
310 /*
311 * Go through all devices, fixing up irqs as we see fit:
312 */
313
314 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
315 {
316 if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE)
317 {
318 slot = PCI_SLOT(dev->devfn); /* Determine slot number. */
319 dev->irq = irq_tab[slot];
320 if (pci_modify)
321 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
322 }
323 }
324}
325
326/*
327 * static void hades_conf_device(struct pci_dev *dev)
328 *
329 * Machine dependent Configure the given device.
330 *
331 * Parameters:
332 *
333 * dev - the pci device.
334 */
335
336static void __init hades_conf_device(struct pci_dev *dev)
337{
338 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0);
339}
340
341static struct pci_ops hades_pci_ops = {
342 .read_byte = hades_read_config_byte,
343 .read_word = hades_read_config_word,
344 .read_dword = hades_read_config_dword,
345 .write_byte = hades_write_config_byte,
346 .write_word = hades_write_config_word,
347 .write_dword = hades_write_config_dword
348};
349
350/*
351 * struct pci_bus_info *init_hades_pci(void)
352 *
353 * Machine specific initialisation:
354 *
355 * - Allocate and initialise a 'pci_bus_info' structure
356 * - Initialise hardware
357 *
358 * Result: pointer to 'pci_bus_info' structure.
359 */
360
361struct pci_bus_info * __init init_hades_pci(void)
362{
363 struct pci_bus_info *bus;
364 int i;
365
366 /*
367 * Remap I/O and configuration space.
368 */
369
370 pci_io_base_virt = (unsigned long) ioremap(HADES_IO_BASE, HADES_VIRT_IO_SIZE);
371
372 for (i = 0; i < N_SLOTS; i++)
373 pci_conf_base_virt[i] = (unsigned long) ioremap(pci_conf_base_phys[i], 0x10000);
374
375 /*
376 * Allocate memory for bus info structure.
377 */
378
379 bus = kmalloc(sizeof(struct pci_bus_info), GFP_KERNEL);
380 if (!bus)
381 return NULL;
382 memset(bus, 0, sizeof(struct pci_bus_info));
383
384 /*
385 * Claim resources. The m68k has no separate I/O space, both
386 * PCI memory space and PCI I/O space are in memory space. Therefore
387 * the I/O resources are requested in memory space as well.
388 */
389
390 if (request_resource(&iomem_resource, &config_space) != 0)
391 {
392 kfree(bus);
393 return NULL;
394 }
395
396 if (request_resource(&iomem_resource, &io_space) != 0)
397 {
398 release_resource(&config_space);
399 kfree(bus);
400 return NULL;
401 }
402
403 bus->mem_space.start = HADES_MEM_BASE;
404 bus->mem_space.end = HADES_MEM_BASE + HADES_MEM_SIZE - 1;
405 bus->mem_space.name = pci_mem_name;
406#if 1
407 if (request_resource(&iomem_resource, &bus->mem_space) != 0)
408 {
409 release_resource(&io_space);
410 release_resource(&config_space);
411 kfree(bus);
412 return NULL;
413 }
414#endif
415 bus->io_space.start = pci_io_base_virt;
416 bus->io_space.end = pci_io_base_virt + HADES_VIRT_IO_SIZE - 1;
417 bus->io_space.name = pci_io_name;
418#if 1
419 if (request_resource(&ioport_resource, &bus->io_space) != 0)
420 {
421 release_resource(&bus->mem_space);
422 release_resource(&io_space);
423 release_resource(&config_space);
424 kfree(bus);
425 return NULL;
426 }
427#endif
428 /*
429 * Set hardware dependent functions.
430 */
431
432 bus->m68k_pci_ops = &hades_pci_ops;
433 bus->fixup = hades_fixup;
434 bus->conf_device = hades_conf_device;
435
436 /*
437 * Select high to low edge for PCI interrupts.
438 */
439
440 tt_mfp.active_edge &= ~0x27;
441
442 return bus;
443}
444#endif
diff --git a/arch/m68k/atari/stdma.c b/arch/m68k/atari/stdma.c
new file mode 100644
index 000000000000..288f5e6a124e
--- /dev/null
+++ b/arch/m68k/atari/stdma.c
@@ -0,0 +1,196 @@
1/*
2 * linux/arch/m68k/atari/stmda.c
3 *
4 * Copyright (C) 1994 Roman Hodek
5 *
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file COPYING in the main directory of this archive
9 * for more details.
10 */
11
12
13/* This file contains some function for controlling the access to the */
14/* ST-DMA chip that may be shared between devices. Currently we have: */
15/* TT: Floppy and ACSI bus */
16/* Falcon: Floppy and SCSI */
17/* */
18/* The controlling functions set up a wait queue for access to the */
19/* ST-DMA chip. Callers to stdma_lock() that cannot granted access are */
20/* put onto a queue and waked up later if the owner calls */
21/* stdma_release(). Additionally, the caller gives his interrupt */
22/* service routine to stdma_lock(). */
23/* */
24/* On the Falcon, the IDE bus uses just the ACSI/Floppy interrupt, but */
25/* not the ST-DMA chip itself. So falhd.c needs not to lock the */
26/* chip. The interrupt is routed to falhd.c if IDE is configured, the */
27/* model is a Falcon and the interrupt was caused by the HD controller */
28/* (can be determined by looking at its status register). */
29
30
31#include <linux/types.h>
32#include <linux/kdev_t.h>
33#include <linux/genhd.h>
34#include <linux/sched.h>
35#include <linux/init.h>
36#include <linux/interrupt.h>
37#include <linux/wait.h>
38
39#include <asm/atari_stdma.h>
40#include <asm/atariints.h>
41#include <asm/atarihw.h>
42#include <asm/io.h>
43#include <asm/irq.h>
44
45static int stdma_locked; /* the semaphore */
46 /* int func to be called */
47static irqreturn_t (*stdma_isr)(int, void *, struct pt_regs *);
48static void *stdma_isr_data; /* data passed to isr */
49static DECLARE_WAIT_QUEUE_HEAD(stdma_wait); /* wait queue for ST-DMA */
50
51
52
53
54/***************************** Prototypes *****************************/
55
56static irqreturn_t stdma_int (int irq, void *dummy, struct pt_regs *fp);
57
58/************************* End of Prototypes **************************/
59
60
61
62/*
63 * Function: void stdma_lock( isrfunc isr, void *data )
64 *
65 * Purpose: Tries to get a lock on the ST-DMA chip that is used by more
66 * then one device driver. Waits on stdma_wait until lock is free.
67 * stdma_lock() may not be called from an interrupt! You have to
68 * get the lock in your main routine and release it when your
69 * request is finished.
70 *
71 * Inputs: A interrupt function that is called until the lock is
72 * released.
73 *
74 * Returns: nothing
75 *
76 */
77
78void stdma_lock(irqreturn_t (*handler)(int, void *, struct pt_regs *),
79 void *data)
80{
81 unsigned long flags;
82
83 local_irq_save(flags); /* protect lock */
84
85 /* Since the DMA is used for file system purposes, we
86 have to sleep uninterruptible (there may be locked
87 buffers) */
88 wait_event(stdma_wait, !stdma_locked);
89
90 stdma_locked = 1;
91 stdma_isr = handler;
92 stdma_isr_data = data;
93 local_irq_restore(flags);
94}
95
96
97/*
98 * Function: void stdma_release( void )
99 *
100 * Purpose: Releases the lock on the ST-DMA chip.
101 *
102 * Inputs: none
103 *
104 * Returns: nothing
105 *
106 */
107
108void stdma_release(void)
109{
110 unsigned long flags;
111
112 local_irq_save(flags);
113
114 stdma_locked = 0;
115 stdma_isr = NULL;
116 stdma_isr_data = NULL;
117 wake_up(&stdma_wait);
118
119 local_irq_restore(flags);
120}
121
122
123/*
124 * Function: int stdma_others_waiting( void )
125 *
126 * Purpose: Check if someone waits for the ST-DMA lock.
127 *
128 * Inputs: none
129 *
130 * Returns: 0 if no one is waiting, != 0 otherwise
131 *
132 */
133
134int stdma_others_waiting(void)
135{
136 return waitqueue_active(&stdma_wait);
137}
138
139
140/*
141 * Function: int stdma_islocked( void )
142 *
143 * Purpose: Check if the ST-DMA is currently locked.
144 * Note: Returned status is only valid if ints are disabled while calling and
145 * as long as they remain disabled.
146 * If called with ints enabled, status can change only from locked to
147 * unlocked, because ints may not lock the ST-DMA.
148 *
149 * Inputs: none
150 *
151 * Returns: != 0 if locked, 0 otherwise
152 *
153 */
154
155int stdma_islocked(void)
156{
157 return stdma_locked;
158}
159
160
161/*
162 * Function: void stdma_init( void )
163 *
164 * Purpose: Initialize the ST-DMA chip access controlling.
165 * It sets up the interrupt and its service routine. The int is registered
166 * as slow int, client devices have to live with that (no problem
167 * currently).
168 *
169 * Inputs: none
170 *
171 * Return: nothing
172 *
173 */
174
175void __init stdma_init(void)
176{
177 stdma_isr = NULL;
178 request_irq(IRQ_MFP_FDC, stdma_int, IRQ_TYPE_SLOW,
179 "ST-DMA: floppy/ACSI/IDE/Falcon-SCSI", stdma_int);
180}
181
182
183/*
184 * Function: void stdma_int()
185 *
186 * Purpose: The interrupt routine for the ST-DMA. It calls the isr
187 * registered by stdma_lock().
188 *
189 */
190
191static irqreturn_t stdma_int(int irq, void *dummy, struct pt_regs *fp)
192{
193 if (stdma_isr)
194 (*stdma_isr)(irq, stdma_isr_data, fp);
195 return IRQ_HANDLED;
196}
diff --git a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c
new file mode 100644
index 000000000000..5a3c106b40c8
--- /dev/null
+++ b/arch/m68k/atari/stram.c
@@ -0,0 +1,1247 @@
1/*
2 * arch/m68k/atari/stram.c: Functions for ST-RAM allocations
3 *
4 * Copyright 1994-97 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
8 * for more details.
9 */
10
11#include <linux/config.h>
12#include <linux/types.h>
13#include <linux/kernel.h>
14#include <linux/mm.h>
15#include <linux/kdev_t.h>
16#include <linux/major.h>
17#include <linux/init.h>
18#include <linux/swap.h>
19#include <linux/slab.h>
20#include <linux/vmalloc.h>
21#include <linux/pagemap.h>
22#include <linux/shm.h>
23#include <linux/bootmem.h>
24#include <linux/mount.h>
25#include <linux/blkdev.h>
26
27#include <asm/setup.h>
28#include <asm/machdep.h>
29#include <asm/page.h>
30#include <asm/pgtable.h>
31#include <asm/atarihw.h>
32#include <asm/atari_stram.h>
33#include <asm/io.h>
34#include <asm/semaphore.h>
35
36#include <linux/swapops.h>
37
38#undef DEBUG
39
40#ifdef DEBUG
41#define DPRINTK(fmt,args...) printk( fmt, ##args )
42#else
43#define DPRINTK(fmt,args...)
44#endif
45
46#if defined(CONFIG_PROC_FS) && defined(CONFIG_STRAM_PROC)
47/* abbrev for the && above... */
48#define DO_PROC
49#include <linux/proc_fs.h>
50#endif
51
52/* Pre-swapping comments:
53 *
54 * ++roman:
55 *
56 * New version of ST-Ram buffer allocation. Instead of using the
57 * 1 MB - 4 KB that remain when the ST-Ram chunk starts at $1000
58 * (1 MB granularity!), such buffers are reserved like this:
59 *
60 * - If the kernel resides in ST-Ram anyway, we can take the buffer
61 * from behind the current kernel data space the normal way
62 * (incrementing start_mem).
63 *
64 * - If the kernel is in TT-Ram, stram_init() initializes start and
65 * end of the available region. Buffers are allocated from there
66 * and mem_init() later marks the such used pages as reserved.
67 * Since each TT-Ram chunk is at least 4 MB in size, I hope there
68 * won't be an overrun of the ST-Ram region by normal kernel data
69 * space.
70 *
71 * For that, ST-Ram may only be allocated while kernel initialization
72 * is going on, or exactly: before mem_init() is called. There is also
73 * no provision now for freeing ST-Ram buffers. It seems that isn't
74 * really needed.
75 *
76 */
77
78/*
79 * New Nov 1997: Use ST-RAM as swap space!
80 *
81 * In the past, there were often problems with modules that require ST-RAM
82 * buffers. Such drivers have to use __get_dma_pages(), which unfortunately
83 * often isn't very successful in allocating more than 1 page :-( [1] The net
84 * result was that most of the time you couldn't insmod such modules (ataflop,
85 * ACSI, SCSI on Falcon, Atari internal framebuffer, not to speak of acsi_slm,
86 * which needs a 1 MB buffer... :-).
87 *
88 * To overcome this limitation, ST-RAM can now be turned into a very
89 * high-speed swap space. If a request for an ST-RAM buffer comes, the kernel
90 * now tries to unswap some pages on that swap device to make some free (and
91 * contiguous) space. This works much better in comparison to
92 * __get_dma_pages(), since used swap pages can be selectively freed by either
93 * moving them to somewhere else in swap space, or by reading them back into
94 * system memory. Ok, there operation of unswapping isn't really cheap (for
95 * each page, one has to go through the page tables of all processes), but it
96 * doesn't happen that often (only when allocation ST-RAM, i.e. when loading a
97 * module that needs ST-RAM). But it at least makes it possible to load such
98 * modules!
99 *
100 * It could also be that overall system performance increases a bit due to
101 * ST-RAM swapping, since slow ST-RAM isn't used anymore for holding data or
102 * executing code in. It's then just a (very fast, compared to disk) back
103 * storage for not-so-often needed data. (But this effect must be compared
104 * with the loss of total memory...) Don't know if the effect is already
105 * visible on a TT, where the speed difference between ST- and TT-RAM isn't
106 * that dramatic, but it should on machines where TT-RAM is really much faster
107 * (e.g. Afterburner).
108 *
109 * [1]: __get_free_pages() does a fine job if you only want one page, but if
110 * you want more (contiguous) pages, it can give you such a block only if
111 * there's already a free one. The algorithm can't try to free buffers or swap
112 * out something in order to make more free space, since all that page-freeing
113 * mechanisms work "target-less", i.e. they just free something, but not in a
114 * specific place. I.e., __get_free_pages() can't do anything to free
115 * *adjacent* pages :-( This situation becomes even worse for DMA memory,
116 * since the freeing algorithms are also blind to DMA capability of pages.
117 */
118
119/* 1998-10-20: ++andreas
120 unswap_by_move disabled because it does not handle swapped shm pages.
121*/
122
123/* 2000-05-01: ++andreas
124 Integrated with bootmem. Remove all traces of unswap_by_move.
125*/
126
127#ifdef CONFIG_STRAM_SWAP
128#define ALIGN_IF_SWAP(x) PAGE_ALIGN(x)
129#else
130#define ALIGN_IF_SWAP(x) (x)
131#endif
132
133/* get index of swap page at address 'addr' */
134#define SWAP_NR(addr) (((addr) - swap_start) >> PAGE_SHIFT)
135
136/* get address of swap page #'nr' */
137#define SWAP_ADDR(nr) (swap_start + ((nr) << PAGE_SHIFT))
138
139/* get number of pages for 'n' bytes (already page-aligned) */
140#define N_PAGES(n) ((n) >> PAGE_SHIFT)
141
142/* The following two numbers define the maximum fraction of ST-RAM in total
143 * memory, below that the kernel would automatically use ST-RAM as swap
144 * space. This decision can be overridden with stram_swap= */
145#define MAX_STRAM_FRACTION_NOM 1
146#define MAX_STRAM_FRACTION_DENOM 3
147
148/* Start and end (virtual) of ST-RAM */
149static void *stram_start, *stram_end;
150
151/* set after memory_init() executed and allocations via start_mem aren't
152 * possible anymore */
153static int mem_init_done;
154
155/* set if kernel is in ST-RAM */
156static int kernel_in_stram;
157
158typedef struct stram_block {
159 struct stram_block *next;
160 void *start;
161 unsigned long size;
162 unsigned flags;
163 const char *owner;
164} BLOCK;
165
166/* values for flags field */
167#define BLOCK_FREE 0x01 /* free structure in the BLOCKs pool */
168#define BLOCK_KMALLOCED 0x02 /* structure allocated by kmalloc() */
169#define BLOCK_GFP 0x08 /* block allocated with __get_dma_pages() */
170#define BLOCK_INSWAP 0x10 /* block allocated in swap space */
171
172/* list of allocated blocks */
173static BLOCK *alloc_list;
174
175/* We can't always use kmalloc() to allocate BLOCK structures, since
176 * stram_alloc() can be called rather early. So we need some pool of
177 * statically allocated structures. 20 of them is more than enough, so in most
178 * cases we never should need to call kmalloc(). */
179#define N_STATIC_BLOCKS 20
180static BLOCK static_blocks[N_STATIC_BLOCKS];
181
182#ifdef CONFIG_STRAM_SWAP
183/* max. number of bytes to use for swapping
184 * 0 = no ST-RAM swapping
185 * -1 = do swapping (to whole ST-RAM) if it's less than MAX_STRAM_FRACTION of
186 * total memory
187 */
188static int max_swap_size = -1;
189
190/* start and end of swapping area */
191static void *swap_start, *swap_end;
192
193/* The ST-RAM's swap info structure */
194static struct swap_info_struct *stram_swap_info;
195
196/* The ST-RAM's swap type */
197static int stram_swap_type;
198
199/* Semaphore for get_stram_region. */
200static DECLARE_MUTEX(stram_swap_sem);
201
202/* major and minor device number of the ST-RAM device; for the major, we use
203 * the same as Amiga z2ram, which is really similar and impossible on Atari,
204 * and for the minor a relatively odd number to avoid the user creating and
205 * using that device. */
206#define STRAM_MAJOR Z2RAM_MAJOR
207#define STRAM_MINOR 13
208
209/* Some impossible pointer value */
210#define MAGIC_FILE_P (struct file *)0xffffdead
211
212#ifdef DO_PROC
213static unsigned stat_swap_read;
214static unsigned stat_swap_write;
215static unsigned stat_swap_force;
216#endif /* DO_PROC */
217
218#endif /* CONFIG_STRAM_SWAP */
219
220/***************************** Prototypes *****************************/
221
222#ifdef CONFIG_STRAM_SWAP
223static int swap_init(void *start_mem, void *swap_data);
224static void *get_stram_region( unsigned long n_pages );
225static void free_stram_region( unsigned long offset, unsigned long n_pages
226 );
227static int in_some_region(void *addr);
228static unsigned long find_free_region( unsigned long n_pages, unsigned long
229 *total_free, unsigned long
230 *region_free );
231static void do_stram_request(request_queue_t *);
232static int stram_open( struct inode *inode, struct file *filp );
233static int stram_release( struct inode *inode, struct file *filp );
234static void reserve_region(void *start, void *end);
235#endif
236static BLOCK *add_region( void *addr, unsigned long size );
237static BLOCK *find_region( void *addr );
238static int remove_region( BLOCK *block );
239
240/************************* End of Prototypes **************************/
241
242
243/* ------------------------------------------------------------------------ */
244/* Public Interface */
245/* ------------------------------------------------------------------------ */
246
247/*
248 * This init function is called very early by atari/config.c
249 * It initializes some internal variables needed for stram_alloc()
250 */
251void __init atari_stram_init(void)
252{
253 int i;
254
255 /* initialize static blocks */
256 for( i = 0; i < N_STATIC_BLOCKS; ++i )
257 static_blocks[i].flags = BLOCK_FREE;
258
259 /* determine whether kernel code resides in ST-RAM (then ST-RAM is the
260 * first memory block at virtual 0x0) */
261 stram_start = phys_to_virt(0);
262 kernel_in_stram = (stram_start == 0);
263
264 for( i = 0; i < m68k_num_memory; ++i ) {
265 if (m68k_memory[i].addr == 0) {
266 /* skip first 2kB or page (supervisor-only!) */
267 stram_end = stram_start + m68k_memory[i].size;
268 return;
269 }
270 }
271 /* Should never come here! (There is always ST-Ram!) */
272 panic( "atari_stram_init: no ST-RAM found!" );
273}
274
275
276/*
277 * This function is called from setup_arch() to reserve the pages needed for
278 * ST-RAM management.
279 */
280void __init atari_stram_reserve_pages(void *start_mem)
281{
282#ifdef CONFIG_STRAM_SWAP
283 /* if max_swap_size is negative (i.e. no stram_swap= option given),
284 * determine at run time whether to use ST-RAM swapping */
285 if (max_swap_size < 0)
286 /* Use swapping if ST-RAM doesn't make up more than MAX_STRAM_FRACTION
287 * of total memory. In that case, the max. size is set to 16 MB,
288 * because ST-RAM can never be bigger than that.
289 * Also, never use swapping on a Hades, there's no separate ST-RAM in
290 * that machine. */
291 max_swap_size =
292 (!MACH_IS_HADES &&
293 (N_PAGES(stram_end-stram_start)*MAX_STRAM_FRACTION_DENOM <=
294 ((unsigned long)high_memory>>PAGE_SHIFT)*MAX_STRAM_FRACTION_NOM)) ? 16*1024*1024 : 0;
295 DPRINTK( "atari_stram_reserve_pages: max_swap_size = %d\n", max_swap_size );
296#endif
297
298 /* always reserve first page of ST-RAM, the first 2 kB are
299 * supervisor-only! */
300 if (!kernel_in_stram)
301 reserve_bootmem (0, PAGE_SIZE);
302
303#ifdef CONFIG_STRAM_SWAP
304 {
305 void *swap_data;
306
307 start_mem = (void *) PAGE_ALIGN ((unsigned long) start_mem);
308 /* determine first page to use as swap: if the kernel is
309 in TT-RAM, this is the first page of (usable) ST-RAM;
310 otherwise just use the end of kernel data (= start_mem) */
311 swap_start = !kernel_in_stram ? stram_start + PAGE_SIZE : start_mem;
312 /* decrement by one page, rest of kernel assumes that first swap page
313 * is always reserved and maybe doesn't handle swp_entry == 0
314 * correctly */
315 swap_start -= PAGE_SIZE;
316 swap_end = stram_end;
317 if (swap_end-swap_start > max_swap_size)
318 swap_end = swap_start + max_swap_size;
319 DPRINTK( "atari_stram_reserve_pages: swapping enabled; "
320 "swap=%p-%p\n", swap_start, swap_end);
321
322 /* reserve some amount of memory for maintainance of
323 * swapping itself: one page for each 2048 (PAGE_SIZE/2)
324 * swap pages. (2 bytes for each page) */
325 swap_data = start_mem;
326 start_mem += ((SWAP_NR(swap_end) + PAGE_SIZE/2 - 1)
327 >> (PAGE_SHIFT-1)) << PAGE_SHIFT;
328 /* correct swap_start if necessary */
329 if (swap_start + PAGE_SIZE == swap_data)
330 swap_start = start_mem - PAGE_SIZE;
331
332 if (!swap_init( start_mem, swap_data )) {
333 printk( KERN_ERR "ST-RAM swap space initialization failed\n" );
334 max_swap_size = 0;
335 return;
336 }
337 /* reserve region for swapping meta-data */
338 reserve_region(swap_data, start_mem);
339 /* reserve swapping area itself */
340 reserve_region(swap_start + PAGE_SIZE, swap_end);
341
342 /*
343 * If the whole ST-RAM is used for swapping, there are no allocatable
344 * dma pages left. But unfortunately, some shared parts of the kernel
345 * (particularly the SCSI mid-level) call __get_dma_pages()
346 * unconditionally :-( These calls then fail, and scsi.c even doesn't
347 * check for NULL return values and just crashes. The quick fix for
348 * this (instead of doing much clean up work in the SCSI code) is to
349 * pretend all pages are DMA-able by setting mach_max_dma_address to
350 * ULONG_MAX. This doesn't change any functionality so far, since
351 * get_dma_pages() shouldn't be used on Atari anyway anymore (better
352 * use atari_stram_alloc()), and the Atari SCSI drivers don't need DMA
353 * memory. But unfortunately there's now no kind of warning (even not
354 * a NULL return value) if you use get_dma_pages() nevertheless :-(
355 * You just will get non-DMA-able memory...
356 */
357 mach_max_dma_address = 0xffffffff;
358 }
359#endif
360}
361
362void atari_stram_mem_init_hook (void)
363{
364 mem_init_done = 1;
365}
366
367
368/*
369 * This is main public interface: somehow allocate a ST-RAM block
370 * There are three strategies:
371 *
372 * - If we're before mem_init(), we have to make a static allocation. The
373 * region is taken in the kernel data area (if the kernel is in ST-RAM) or
374 * from the start of ST-RAM (if the kernel is in TT-RAM) and added to the
375 * rsvd_stram_* region. The ST-RAM is somewhere in the middle of kernel
376 * address space in the latter case.
377 *
378 * - If mem_init() already has been called and ST-RAM swapping is enabled,
379 * try to get the memory from the (pseudo) swap-space, either free already
380 * or by moving some other pages out of the swap.
381 *
382 * - If mem_init() already has been called, and ST-RAM swapping is not
383 * enabled, the only possibility is to try with __get_dma_pages(). This has
384 * the disadvantage that it's very hard to get more than 1 page, and it is
385 * likely to fail :-(
386 *
387 */
388void *atari_stram_alloc(long size, const char *owner)
389{
390 void *addr = NULL;
391 BLOCK *block;
392 int flags;
393
394 DPRINTK("atari_stram_alloc(size=%08lx,owner=%s)\n", size, owner);
395
396 size = ALIGN_IF_SWAP(size);
397 DPRINTK( "atari_stram_alloc: rounded size = %08lx\n", size );
398#ifdef CONFIG_STRAM_SWAP
399 if (max_swap_size) {
400 /* If swapping is active: make some free space in the swap
401 "device". */
402 DPRINTK( "atari_stram_alloc: after mem_init, swapping ok, "
403 "calling get_region\n" );
404 addr = get_stram_region( N_PAGES(size) );
405 flags = BLOCK_INSWAP;
406 }
407 else
408#endif
409 if (!mem_init_done)
410 return alloc_bootmem_low(size);
411 else {
412 /* After mem_init() and no swapping: can only resort to
413 * __get_dma_pages() */
414 addr = (void *)__get_dma_pages(GFP_KERNEL, get_order(size));
415 flags = BLOCK_GFP;
416 DPRINTK( "atari_stram_alloc: after mem_init, swapping off, "
417 "get_pages=%p\n", addr );
418 }
419
420 if (addr) {
421 if (!(block = add_region( addr, size ))) {
422 /* out of memory for BLOCK structure :-( */
423 DPRINTK( "atari_stram_alloc: out of mem for BLOCK -- "
424 "freeing again\n" );
425#ifdef CONFIG_STRAM_SWAP
426 if (flags == BLOCK_INSWAP)
427 free_stram_region( SWAP_NR(addr), N_PAGES(size) );
428 else
429#endif
430 free_pages((unsigned long)addr, get_order(size));
431 return( NULL );
432 }
433 block->owner = owner;
434 block->flags |= flags;
435 }
436 return( addr );
437}
438
439void atari_stram_free( void *addr )
440
441{
442 BLOCK *block;
443
444 DPRINTK( "atari_stram_free(addr=%p)\n", addr );
445
446 if (!(block = find_region( addr ))) {
447 printk( KERN_ERR "Attempt to free non-allocated ST-RAM block at %p "
448 "from %p\n", addr, __builtin_return_address(0) );
449 return;
450 }
451 DPRINTK( "atari_stram_free: found block (%p): size=%08lx, owner=%s, "
452 "flags=%02x\n", block, block->size, block->owner, block->flags );
453
454#ifdef CONFIG_STRAM_SWAP
455 if (!max_swap_size) {
456#endif
457 if (block->flags & BLOCK_GFP) {
458 DPRINTK("atari_stram_free: is kmalloced, order_size=%d\n",
459 get_order(block->size));
460 free_pages((unsigned long)addr, get_order(block->size));
461 }
462 else
463 goto fail;
464#ifdef CONFIG_STRAM_SWAP
465 }
466 else if (block->flags & BLOCK_INSWAP) {
467 DPRINTK( "atari_stram_free: is swap-alloced\n" );
468 free_stram_region( SWAP_NR(block->start), N_PAGES(block->size) );
469 }
470 else
471 goto fail;
472#endif
473 remove_region( block );
474 return;
475
476 fail:
477 printk( KERN_ERR "atari_stram_free: cannot free block at %p "
478 "(called from %p)\n", addr, __builtin_return_address(0) );
479}
480
481
482#ifdef CONFIG_STRAM_SWAP
483
484
485/* ------------------------------------------------------------------------ */
486/* Main Swapping Functions */
487/* ------------------------------------------------------------------------ */
488
489
490/*
491 * Initialize ST-RAM swap device
492 * (lots copied and modified from sys_swapon() in mm/swapfile.c)
493 */
494static int __init swap_init(void *start_mem, void *swap_data)
495{
496 static struct dentry fake_dentry;
497 static struct vfsmount fake_vfsmnt;
498 struct swap_info_struct *p;
499 struct inode swap_inode;
500 unsigned int type;
501 void *addr;
502 int i, j, k, prev;
503
504 DPRINTK("swap_init(start_mem=%p, swap_data=%p)\n",
505 start_mem, swap_data);
506
507 /* need at least one page for swapping to (and this also isn't very
508 * much... :-) */
509 if (swap_end - swap_start < 2*PAGE_SIZE) {
510 printk( KERN_WARNING "stram_swap_init: swap space too small\n" );
511 return( 0 );
512 }
513
514 /* find free slot in swap_info */
515 for( p = swap_info, type = 0; type < nr_swapfiles; type++, p++ )
516 if (!(p->flags & SWP_USED))
517 break;
518 if (type >= MAX_SWAPFILES) {
519 printk( KERN_WARNING "stram_swap_init: max. number of "
520 "swap devices exhausted\n" );
521 return( 0 );
522 }
523 if (type >= nr_swapfiles)
524 nr_swapfiles = type+1;
525
526 stram_swap_info = p;
527 stram_swap_type = type;
528
529 /* fake some dir cache entries to give us some name in /dev/swaps */
530 fake_dentry.d_parent = &fake_dentry;
531 fake_dentry.d_name.name = "stram (internal)";
532 fake_dentry.d_name.len = 16;
533 fake_vfsmnt.mnt_parent = &fake_vfsmnt;
534
535 p->flags = SWP_USED;
536 p->swap_file = &fake_dentry;
537 p->swap_vfsmnt = &fake_vfsmnt;
538 p->swap_map = swap_data;
539 p->cluster_nr = 0;
540 p->next = -1;
541 p->prio = 0x7ff0; /* a rather high priority, but not the higest
542 * to give the user a chance to override */
543
544 /* call stram_open() directly, avoids at least the overhead in
545 * constructing a dummy file structure... */
546 swap_inode.i_rdev = MKDEV( STRAM_MAJOR, STRAM_MINOR );
547 stram_open( &swap_inode, MAGIC_FILE_P );
548 p->max = SWAP_NR(swap_end);
549
550 /* initialize swap_map: set regions that are already allocated or belong
551 * to kernel data space to SWAP_MAP_BAD, otherwise to free */
552 j = 0; /* # of free pages */
553 k = 0; /* # of already allocated pages (from pre-mem_init stram_alloc()) */
554 p->lowest_bit = 0;
555 p->highest_bit = 0;
556 for( i = 1, addr = SWAP_ADDR(1); i < p->max;
557 i++, addr += PAGE_SIZE ) {
558 if (in_some_region( addr )) {
559 p->swap_map[i] = SWAP_MAP_BAD;
560 ++k;
561 }
562 else if (kernel_in_stram && addr < start_mem ) {
563 p->swap_map[i] = SWAP_MAP_BAD;
564 }
565 else {
566 p->swap_map[i] = 0;
567 ++j;
568 if (!p->lowest_bit) p->lowest_bit = i;
569 p->highest_bit = i;
570 }
571 }
572 /* first page always reserved (and doesn't really belong to swap space) */
573 p->swap_map[0] = SWAP_MAP_BAD;
574
575 /* now swapping to this device ok */
576 p->pages = j + k;
577 swap_list_lock();
578 nr_swap_pages += j;
579 p->flags = SWP_WRITEOK;
580
581 /* insert swap space into swap_list */
582 prev = -1;
583 for (i = swap_list.head; i >= 0; i = swap_info[i].next) {
584 if (p->prio >= swap_info[i].prio) {
585 break;
586 }
587 prev = i;
588 }
589 p->next = i;
590 if (prev < 0) {
591 swap_list.head = swap_list.next = p - swap_info;
592 } else {
593 swap_info[prev].next = p - swap_info;
594 }
595 swap_list_unlock();
596
597 printk( KERN_INFO "Using %dk (%d pages) of ST-RAM as swap space.\n",
598 p->pages << 2, p->pages );
599 return( 1 );
600}
601
602
603/*
604 * The swap entry has been read in advance, and we return 1 to indicate
605 * that the page has been used or is no longer needed.
606 *
607 * Always set the resulting pte to be nowrite (the same as COW pages
608 * after one process has exited). We don't know just how many PTEs will
609 * share this swap entry, so be cautious and let do_wp_page work out
610 * what to do if a write is requested later.
611 */
612static inline void unswap_pte(struct vm_area_struct * vma, unsigned long
613 address, pte_t *dir, swp_entry_t entry,
614 struct page *page)
615{
616 pte_t pte = *dir;
617
618 if (pte_none(pte))
619 return;
620 if (pte_present(pte)) {
621 /* If this entry is swap-cached, then page must already
622 hold the right address for any copies in physical
623 memory */
624 if (pte_page(pte) != page)
625 return;
626 /* We will be removing the swap cache in a moment, so... */
627 set_pte(dir, pte_mkdirty(pte));
628 return;
629 }
630 if (pte_val(pte) != entry.val)
631 return;
632
633 DPRINTK("unswap_pte: replacing entry %08lx by new page %p",
634 entry.val, page);
635 set_pte(dir, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
636 swap_free(entry);
637 get_page(page);
638 inc_mm_counter(vma->vm_mm, rss);
639}
640
641static inline void unswap_pmd(struct vm_area_struct * vma, pmd_t *dir,
642 unsigned long address, unsigned long size,
643 unsigned long offset, swp_entry_t entry,
644 struct page *page)
645{
646 pte_t * pte;
647 unsigned long end;
648
649 if (pmd_none(*dir))
650 return;
651 if (pmd_bad(*dir)) {
652 pmd_ERROR(*dir);
653 pmd_clear(dir);
654 return;
655 }
656 pte = pte_offset_kernel(dir, address);
657 offset += address & PMD_MASK;
658 address &= ~PMD_MASK;
659 end = address + size;
660 if (end > PMD_SIZE)
661 end = PMD_SIZE;
662 do {
663 unswap_pte(vma, offset+address-vma->vm_start, pte, entry, page);
664 address += PAGE_SIZE;
665 pte++;
666 } while (address < end);
667}
668
669static inline void unswap_pgd(struct vm_area_struct * vma, pgd_t *dir,
670 unsigned long address, unsigned long size,
671 swp_entry_t entry, struct page *page)
672{
673 pmd_t * pmd;
674 unsigned long offset, end;
675
676 if (pgd_none(*dir))
677 return;
678 if (pgd_bad(*dir)) {
679 pgd_ERROR(*dir);
680 pgd_clear(dir);
681 return;
682 }
683 pmd = pmd_offset(dir, address);
684 offset = address & PGDIR_MASK;
685 address &= ~PGDIR_MASK;
686 end = address + size;
687 if (end > PGDIR_SIZE)
688 end = PGDIR_SIZE;
689 do {
690 unswap_pmd(vma, pmd, address, end - address, offset, entry,
691 page);
692 address = (address + PMD_SIZE) & PMD_MASK;
693 pmd++;
694 } while (address < end);
695}
696
697static void unswap_vma(struct vm_area_struct * vma, pgd_t *pgdir,
698 swp_entry_t entry, struct page *page)
699{
700 unsigned long start = vma->vm_start, end = vma->vm_end;
701
702 do {
703 unswap_pgd(vma, pgdir, start, end - start, entry, page);
704 start = (start + PGDIR_SIZE) & PGDIR_MASK;
705 pgdir++;
706 } while (start < end);
707}
708
709static void unswap_process(struct mm_struct * mm, swp_entry_t entry,
710 struct page *page)
711{
712 struct vm_area_struct* vma;
713
714 /*
715 * Go through process' page directory.
716 */
717 if (!mm)
718 return;
719 for (vma = mm->mmap; vma; vma = vma->vm_next) {
720 pgd_t * pgd = pgd_offset(mm, vma->vm_start);
721 unswap_vma(vma, pgd, entry, page);
722 }
723}
724
725
726static int unswap_by_read(unsigned short *map, unsigned long max,
727 unsigned long start, unsigned long n_pages)
728{
729 struct task_struct *p;
730 struct page *page;
731 swp_entry_t entry;
732 unsigned long i;
733
734 DPRINTK( "unswapping %lu..%lu by reading in\n",
735 start, start+n_pages-1 );
736
737 for( i = start; i < start+n_pages; ++i ) {
738 if (map[i] == SWAP_MAP_BAD) {
739 printk( KERN_ERR "get_stram_region: page %lu already "
740 "reserved??\n", i );
741 continue;
742 }
743
744 if (map[i]) {
745 entry = swp_entry(stram_swap_type, i);
746 DPRINTK("unswap: map[i=%lu]=%u nr_swap=%ld\n",
747 i, map[i], nr_swap_pages);
748
749 swap_device_lock(stram_swap_info);
750 map[i]++;
751 swap_device_unlock(stram_swap_info);
752 /* Get a page for the entry, using the existing
753 swap cache page if there is one. Otherwise,
754 get a clean page and read the swap into it. */
755 page = read_swap_cache_async(entry, NULL, 0);
756 if (!page) {
757 swap_free(entry);
758 return -ENOMEM;
759 }
760 read_lock(&tasklist_lock);
761 for_each_process(p)
762 unswap_process(p->mm, entry, page);
763 read_unlock(&tasklist_lock);
764 shmem_unuse(entry, page);
765 /* Now get rid of the extra reference to the
766 temporary page we've been using. */
767 if (PageSwapCache(page))
768 delete_from_swap_cache(page);
769 __free_page(page);
770 #ifdef DO_PROC
771 stat_swap_force++;
772 #endif
773 }
774
775 DPRINTK( "unswap: map[i=%lu]=%u nr_swap=%ld\n",
776 i, map[i], nr_swap_pages );
777 swap_list_lock();
778 swap_device_lock(stram_swap_info);
779 map[i] = SWAP_MAP_BAD;
780 if (stram_swap_info->lowest_bit == i)
781 stram_swap_info->lowest_bit++;
782 if (stram_swap_info->highest_bit == i)
783 stram_swap_info->highest_bit--;
784 --nr_swap_pages;
785 swap_device_unlock(stram_swap_info);
786 swap_list_unlock();
787 }
788
789 return 0;
790}
791
792/*
793 * reserve a region in ST-RAM swap space for an allocation
794 */
795static void *get_stram_region( unsigned long n_pages )
796{
797 unsigned short *map = stram_swap_info->swap_map;
798 unsigned long max = stram_swap_info->max;
799 unsigned long start, total_free, region_free;
800 int err;
801 void *ret = NULL;
802
803 DPRINTK( "get_stram_region(n_pages=%lu)\n", n_pages );
804
805 down(&stram_swap_sem);
806
807 /* disallow writing to the swap device now */
808 stram_swap_info->flags = SWP_USED;
809
810 /* find a region of n_pages pages in the swap space including as much free
811 * pages as possible (and excluding any already-reserved pages). */
812 if (!(start = find_free_region( n_pages, &total_free, &region_free )))
813 goto end;
814 DPRINTK( "get_stram_region: region starts at %lu, has %lu free pages\n",
815 start, region_free );
816
817 err = unswap_by_read(map, max, start, n_pages);
818 if (err)
819 goto end;
820
821 ret = SWAP_ADDR(start);
822 end:
823 /* allow using swap device again */
824 stram_swap_info->flags = SWP_WRITEOK;
825 up(&stram_swap_sem);
826 DPRINTK( "get_stram_region: returning %p\n", ret );
827 return( ret );
828}
829
830
831/*
832 * free a reserved region in ST-RAM swap space
833 */
834static void free_stram_region( unsigned long offset, unsigned long n_pages )
835{
836 unsigned short *map = stram_swap_info->swap_map;
837
838 DPRINTK( "free_stram_region(offset=%lu,n_pages=%lu)\n", offset, n_pages );
839
840 if (offset < 1 || offset + n_pages > stram_swap_info->max) {
841 printk( KERN_ERR "free_stram_region: Trying to free non-ST-RAM\n" );
842 return;
843 }
844
845 swap_list_lock();
846 swap_device_lock(stram_swap_info);
847 /* un-reserve the freed pages */
848 for( ; n_pages > 0; ++offset, --n_pages ) {
849 if (map[offset] != SWAP_MAP_BAD)
850 printk( KERN_ERR "free_stram_region: Swap page %lu was not "
851 "reserved\n", offset );
852 map[offset] = 0;
853 }
854
855 /* update swapping meta-data */
856 if (offset < stram_swap_info->lowest_bit)
857 stram_swap_info->lowest_bit = offset;
858 if (offset+n_pages-1 > stram_swap_info->highest_bit)
859 stram_swap_info->highest_bit = offset+n_pages-1;
860 if (stram_swap_info->prio > swap_info[swap_list.next].prio)
861 swap_list.next = swap_list.head;
862 nr_swap_pages += n_pages;
863 swap_device_unlock(stram_swap_info);
864 swap_list_unlock();
865}
866
867
868/* ------------------------------------------------------------------------ */
869/* Utility Functions for Swapping */
870/* ------------------------------------------------------------------------ */
871
872
873/* is addr in some of the allocated regions? */
874static int in_some_region(void *addr)
875{
876 BLOCK *p;
877
878 for( p = alloc_list; p; p = p->next ) {
879 if (p->start <= addr && addr < p->start + p->size)
880 return( 1 );
881 }
882 return( 0 );
883}
884
885
886static unsigned long find_free_region(unsigned long n_pages,
887 unsigned long *total_free,
888 unsigned long *region_free)
889{
890 unsigned short *map = stram_swap_info->swap_map;
891 unsigned long max = stram_swap_info->max;
892 unsigned long head, tail, max_start;
893 long nfree, max_free;
894
895 /* first scan the swap space for a suitable place for the allocation */
896 head = 1;
897 max_start = 0;
898 max_free = -1;
899 *total_free = 0;
900
901 start_over:
902 /* increment tail until final window size reached, and count free pages */
903 nfree = 0;
904 for( tail = head; tail-head < n_pages && tail < max; ++tail ) {
905 if (map[tail] == SWAP_MAP_BAD) {
906 head = tail+1;
907 goto start_over;
908 }
909 if (!map[tail]) {
910 ++nfree;
911 ++*total_free;
912 }
913 }
914 if (tail-head < n_pages)
915 goto out;
916 if (nfree > max_free) {
917 max_start = head;
918 max_free = nfree;
919 if (max_free >= n_pages)
920 /* don't need more free pages... :-) */
921 goto out;
922 }
923
924 /* now shift the window and look for the area where as much pages as
925 * possible are free */
926 while( tail < max ) {
927 nfree -= (map[head++] == 0);
928 if (map[tail] == SWAP_MAP_BAD) {
929 head = tail+1;
930 goto start_over;
931 }
932 if (!map[tail]) {
933 ++nfree;
934 ++*total_free;
935 }
936 ++tail;
937 if (nfree > max_free) {
938 max_start = head;
939 max_free = nfree;
940 if (max_free >= n_pages)
941 /* don't need more free pages... :-) */
942 goto out;
943 }
944 }
945
946 out:
947 if (max_free < 0) {
948 printk( KERN_NOTICE "get_stram_region: ST-RAM too full or fragmented "
949 "-- can't allocate %lu pages\n", n_pages );
950 return( 0 );
951 }
952
953 *region_free = max_free;
954 return( max_start );
955}
956
957
958/* setup parameters from command line */
959void __init stram_swap_setup(char *str, int *ints)
960{
961 if (ints[0] >= 1)
962 max_swap_size = ((ints[1] < 0 ? 0 : ints[1]) * 1024) & PAGE_MASK;
963}
964
965
966/* ------------------------------------------------------------------------ */
967/* ST-RAM device */
968/* ------------------------------------------------------------------------ */
969
970static int refcnt;
971
972static void do_stram_request(request_queue_t *q)
973{
974 struct request *req;
975
976 while ((req = elv_next_request(q)) != NULL) {
977 void *start = swap_start + (req->sector << 9);
978 unsigned long len = req->current_nr_sectors << 9;
979 if ((start + len) > swap_end) {
980 printk( KERN_ERR "stram: bad access beyond end of device: "
981 "block=%ld, count=%d\n",
982 req->sector,
983 req->current_nr_sectors );
984 end_request(req, 0);
985 continue;
986 }
987
988 if (req->cmd == READ) {
989 memcpy(req->buffer, start, len);
990#ifdef DO_PROC
991 stat_swap_read += N_PAGES(len);
992#endif
993 }
994 else {
995 memcpy(start, req->buffer, len);
996#ifdef DO_PROC
997 stat_swap_write += N_PAGES(len);
998#endif
999 }
1000 end_request(req, 1);
1001 }
1002}
1003
1004
1005static int stram_open( struct inode *inode, struct file *filp )
1006{
1007 if (filp != MAGIC_FILE_P) {
1008 printk( KERN_NOTICE "Only kernel can open ST-RAM device\n" );
1009 return( -EPERM );
1010 }
1011 if (refcnt)
1012 return( -EBUSY );
1013 ++refcnt;
1014 return( 0 );
1015}
1016
1017static int stram_release( struct inode *inode, struct file *filp )
1018{
1019 if (filp != MAGIC_FILE_P) {
1020 printk( KERN_NOTICE "Only kernel can close ST-RAM device\n" );
1021 return( -EPERM );
1022 }
1023 if (refcnt > 0)
1024 --refcnt;
1025 return( 0 );
1026}
1027
1028
1029static struct block_device_operations stram_fops = {
1030 .open = stram_open,
1031 .release = stram_release,
1032};
1033
1034static struct gendisk *stram_disk;
1035static struct request_queue *stram_queue;
1036static DEFINE_SPINLOCK(stram_lock);
1037
1038int __init stram_device_init(void)
1039{
1040 if (!MACH_IS_ATARI)
1041 /* no point in initializing this, I hope */
1042 return -ENXIO;
1043
1044 if (!max_swap_size)
1045 /* swapping not enabled */
1046 return -ENXIO;
1047 stram_disk = alloc_disk(1);
1048 if (!stram_disk)
1049 return -ENOMEM;
1050
1051 if (register_blkdev(STRAM_MAJOR, "stram")) {
1052 put_disk(stram_disk);
1053 return -ENXIO;
1054 }
1055
1056 stram_queue = blk_init_queue(do_stram_request, &stram_lock);
1057 if (!stram_queue) {
1058 unregister_blkdev(STRAM_MAJOR, "stram");
1059 put_disk(stram_disk);
1060 return -ENOMEM;
1061 }
1062
1063 stram_disk->major = STRAM_MAJOR;
1064 stram_disk->first_minor = STRAM_MINOR;
1065 stram_disk->fops = &stram_fops;
1066 stram_disk->queue = stram_queue;
1067 sprintf(stram_disk->disk_name, "stram");
1068 set_capacity(stram_disk, (swap_end - swap_start)/512);
1069 add_disk(stram_disk);
1070 return 0;
1071}
1072
1073
1074
1075/* ------------------------------------------------------------------------ */
1076/* Misc Utility Functions */
1077/* ------------------------------------------------------------------------ */
1078
1079/* reserve a range of pages */
1080static void reserve_region(void *start, void *end)
1081{
1082 reserve_bootmem (virt_to_phys(start), end - start);
1083}
1084
1085#endif /* CONFIG_STRAM_SWAP */
1086
1087
1088/* ------------------------------------------------------------------------ */
1089/* Region Management */
1090/* ------------------------------------------------------------------------ */
1091
1092
1093/* insert a region into the alloced list (sorted) */
1094static BLOCK *add_region( void *addr, unsigned long size )
1095{
1096 BLOCK **p, *n = NULL;
1097 int i;
1098
1099 for( i = 0; i < N_STATIC_BLOCKS; ++i ) {
1100 if (static_blocks[i].flags & BLOCK_FREE) {
1101 n = &static_blocks[i];
1102 n->flags = 0;
1103 break;
1104 }
1105 }
1106 if (!n && mem_init_done) {
1107 /* if statics block pool exhausted and we can call kmalloc() already
1108 * (after mem_init()), try that */
1109 n = kmalloc( sizeof(BLOCK), GFP_KERNEL );
1110 if (n)
1111 n->flags = BLOCK_KMALLOCED;
1112 }
1113 if (!n) {
1114 printk( KERN_ERR "Out of memory for ST-RAM descriptor blocks\n" );
1115 return( NULL );
1116 }
1117 n->start = addr;
1118 n->size = size;
1119
1120 for( p = &alloc_list; *p; p = &((*p)->next) )
1121 if ((*p)->start > addr) break;
1122 n->next = *p;
1123 *p = n;
1124
1125 return( n );
1126}
1127
1128
1129/* find a region (by start addr) in the alloced list */
1130static BLOCK *find_region( void *addr )
1131{
1132 BLOCK *p;
1133
1134 for( p = alloc_list; p; p = p->next ) {
1135 if (p->start == addr)
1136 return( p );
1137 if (p->start > addr)
1138 break;
1139 }
1140 return( NULL );
1141}
1142
1143
1144/* remove a block from the alloced list */
1145static int remove_region( BLOCK *block )
1146{
1147 BLOCK **p;
1148
1149 for( p = &alloc_list; *p; p = &((*p)->next) )
1150 if (*p == block) break;
1151 if (!*p)
1152 return( 0 );
1153
1154 *p = block->next;
1155 if (block->flags & BLOCK_KMALLOCED)
1156 kfree( block );
1157 else
1158 block->flags |= BLOCK_FREE;
1159 return( 1 );
1160}
1161
1162
1163
1164/* ------------------------------------------------------------------------ */
1165/* /proc statistics file stuff */
1166/* ------------------------------------------------------------------------ */
1167
1168#ifdef DO_PROC
1169
1170#define PRINT_PROC(fmt,args...) len += sprintf( buf+len, fmt, ##args )
1171
1172int get_stram_list( char *buf )
1173{
1174 int len = 0;
1175 BLOCK *p;
1176#ifdef CONFIG_STRAM_SWAP
1177 int i;
1178 unsigned short *map = stram_swap_info->swap_map;
1179 unsigned long max = stram_swap_info->max;
1180 unsigned free = 0, used = 0, rsvd = 0;
1181#endif
1182
1183#ifdef CONFIG_STRAM_SWAP
1184 if (max_swap_size) {
1185 for( i = 1; i < max; ++i ) {
1186 if (!map[i])
1187 ++free;
1188 else if (map[i] == SWAP_MAP_BAD)
1189 ++rsvd;
1190 else
1191 ++used;
1192 }
1193 PRINT_PROC(
1194 "Total ST-RAM: %8u kB\n"
1195 "Total ST-RAM swap: %8lu kB\n"
1196 "Free swap: %8u kB\n"
1197 "Used swap: %8u kB\n"
1198 "Allocated swap: %8u kB\n"
1199 "Swap Reads: %8u\n"
1200 "Swap Writes: %8u\n"
1201 "Swap Forced Reads: %8u\n",
1202 (stram_end - stram_start) >> 10,
1203 (max-1) << (PAGE_SHIFT-10),
1204 free << (PAGE_SHIFT-10),
1205 used << (PAGE_SHIFT-10),
1206 rsvd << (PAGE_SHIFT-10),
1207 stat_swap_read,
1208 stat_swap_write,
1209 stat_swap_force );
1210 }
1211 else {
1212#endif
1213 PRINT_PROC( "ST-RAM swapping disabled\n" );
1214 PRINT_PROC("Total ST-RAM: %8u kB\n",
1215 (stram_end - stram_start) >> 10);
1216#ifdef CONFIG_STRAM_SWAP
1217 }
1218#endif
1219
1220 PRINT_PROC( "Allocated regions:\n" );
1221 for( p = alloc_list; p; p = p->next ) {
1222 if (len + 50 >= PAGE_SIZE)
1223 break;
1224 PRINT_PROC("0x%08lx-0x%08lx: %s (",
1225 virt_to_phys(p->start),
1226 virt_to_phys(p->start+p->size-1),
1227 p->owner);
1228 if (p->flags & BLOCK_GFP)
1229 PRINT_PROC( "page-alloced)\n" );
1230 else if (p->flags & BLOCK_INSWAP)
1231 PRINT_PROC( "in swap)\n" );
1232 else
1233 PRINT_PROC( "??)\n" );
1234 }
1235
1236 return( len );
1237}
1238
1239#endif
1240
1241
1242/*
1243 * Local variables:
1244 * c-indent-level: 4
1245 * tab-width: 4
1246 * End:
1247 */
diff --git a/arch/m68k/atari/time.c b/arch/m68k/atari/time.c
new file mode 100644
index 000000000000..6df7fb60dfea
--- /dev/null
+++ b/arch/m68k/atari/time.c
@@ -0,0 +1,348 @@
1/*
2 * linux/arch/m68k/atari/time.c
3 *
4 * Atari time and real time clock stuff
5 *
6 * Assembled of parts of former atari/config.c 97-12-18 by Roman Hodek
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file COPYING in the main directory of this archive
10 * for more details.
11 */
12
13#include <linux/types.h>
14#include <linux/mc146818rtc.h>
15#include <linux/interrupt.h>
16#include <linux/init.h>
17#include <linux/rtc.h>
18#include <linux/bcd.h>
19
20#include <asm/atariints.h>
21
22void __init
23atari_sched_init(irqreturn_t (*timer_routine)(int, void *, struct pt_regs *))
24{
25 /* set Timer C data Register */
26 mfp.tim_dt_c = INT_TICKS;
27 /* start timer C, div = 1:100 */
28 mfp.tim_ct_cd = (mfp.tim_ct_cd & 15) | 0x60;
29 /* install interrupt service routine for MFP Timer C */
30 request_irq(IRQ_MFP_TIMC, timer_routine, IRQ_TYPE_SLOW,
31 "timer", timer_routine);
32}
33
34/* ++andreas: gettimeoffset fixed to check for pending interrupt */
35
36#define TICK_SIZE 10000
37
38/* This is always executed with interrupts disabled. */
39unsigned long atari_gettimeoffset (void)
40{
41 unsigned long ticks, offset = 0;
42
43 /* read MFP timer C current value */
44 ticks = mfp.tim_dt_c;
45 /* The probability of underflow is less than 2% */
46 if (ticks > INT_TICKS - INT_TICKS / 50)
47 /* Check for pending timer interrupt */
48 if (mfp.int_pn_b & (1 << 5))
49 offset = TICK_SIZE;
50
51 ticks = INT_TICKS - ticks;
52 ticks = ticks * 10000L / INT_TICKS;
53
54 return ticks + offset;
55}
56
57
58static void mste_read(struct MSTE_RTC *val)
59{
60#define COPY(v) val->v=(mste_rtc.v & 0xf)
61 do {
62 COPY(sec_ones) ; COPY(sec_tens) ; COPY(min_ones) ;
63 COPY(min_tens) ; COPY(hr_ones) ; COPY(hr_tens) ;
64 COPY(weekday) ; COPY(day_ones) ; COPY(day_tens) ;
65 COPY(mon_ones) ; COPY(mon_tens) ; COPY(year_ones) ;
66 COPY(year_tens) ;
67 /* prevent from reading the clock while it changed */
68 } while (val->sec_ones != (mste_rtc.sec_ones & 0xf));
69#undef COPY
70}
71
72static void mste_write(struct MSTE_RTC *val)
73{
74#define COPY(v) mste_rtc.v=val->v
75 do {
76 COPY(sec_ones) ; COPY(sec_tens) ; COPY(min_ones) ;
77 COPY(min_tens) ; COPY(hr_ones) ; COPY(hr_tens) ;
78 COPY(weekday) ; COPY(day_ones) ; COPY(day_tens) ;
79 COPY(mon_ones) ; COPY(mon_tens) ; COPY(year_ones) ;
80 COPY(year_tens) ;
81 /* prevent from writing the clock while it changed */
82 } while (val->sec_ones != (mste_rtc.sec_ones & 0xf));
83#undef COPY
84}
85
86#define RTC_READ(reg) \
87 ({ unsigned char __val; \
88 (void) atari_writeb(reg,&tt_rtc.regsel); \
89 __val = tt_rtc.data; \
90 __val; \
91 })
92
93#define RTC_WRITE(reg,val) \
94 do { \
95 atari_writeb(reg,&tt_rtc.regsel); \
96 tt_rtc.data = (val); \
97 } while(0)
98
99
100#define HWCLK_POLL_INTERVAL 5
101
102int atari_mste_hwclk( int op, struct rtc_time *t )
103{
104 int hour, year;
105 int hr24=0;
106 struct MSTE_RTC val;
107
108 mste_rtc.mode=(mste_rtc.mode | 1);
109 hr24=mste_rtc.mon_tens & 1;
110 mste_rtc.mode=(mste_rtc.mode & ~1);
111
112 if (op) {
113 /* write: prepare values */
114
115 val.sec_ones = t->tm_sec % 10;
116 val.sec_tens = t->tm_sec / 10;
117 val.min_ones = t->tm_min % 10;
118 val.min_tens = t->tm_min / 10;
119 hour = t->tm_hour;
120 if (!hr24) {
121 if (hour > 11)
122 hour += 20 - 12;
123 if (hour == 0 || hour == 20)
124 hour += 12;
125 }
126 val.hr_ones = hour % 10;
127 val.hr_tens = hour / 10;
128 val.day_ones = t->tm_mday % 10;
129 val.day_tens = t->tm_mday / 10;
130 val.mon_ones = (t->tm_mon+1) % 10;
131 val.mon_tens = (t->tm_mon+1) / 10;
132 year = t->tm_year - 80;
133 val.year_ones = year % 10;
134 val.year_tens = year / 10;
135 val.weekday = t->tm_wday;
136 mste_write(&val);
137 mste_rtc.mode=(mste_rtc.mode | 1);
138 val.year_ones = (year % 4); /* leap year register */
139 mste_rtc.mode=(mste_rtc.mode & ~1);
140 }
141 else {
142 mste_read(&val);
143 t->tm_sec = val.sec_ones + val.sec_tens * 10;
144 t->tm_min = val.min_ones + val.min_tens * 10;
145 hour = val.hr_ones + val.hr_tens * 10;
146 if (!hr24) {
147 if (hour == 12 || hour == 12 + 20)
148 hour -= 12;
149 if (hour >= 20)
150 hour += 12 - 20;
151 }
152 t->tm_hour = hour;
153 t->tm_mday = val.day_ones + val.day_tens * 10;
154 t->tm_mon = val.mon_ones + val.mon_tens * 10 - 1;
155 t->tm_year = val.year_ones + val.year_tens * 10 + 80;
156 t->tm_wday = val.weekday;
157 }
158 return 0;
159}
160
161int atari_tt_hwclk( int op, struct rtc_time *t )
162{
163 int sec=0, min=0, hour=0, day=0, mon=0, year=0, wday=0;
164 unsigned long flags;
165 unsigned char ctrl;
166 int pm = 0;
167
168 ctrl = RTC_READ(RTC_CONTROL); /* control registers are
169 * independent from the UIP */
170
171 if (op) {
172 /* write: prepare values */
173
174 sec = t->tm_sec;
175 min = t->tm_min;
176 hour = t->tm_hour;
177 day = t->tm_mday;
178 mon = t->tm_mon + 1;
179 year = t->tm_year - atari_rtc_year_offset;
180 wday = t->tm_wday + (t->tm_wday >= 0);
181
182 if (!(ctrl & RTC_24H)) {
183 if (hour > 11) {
184 pm = 0x80;
185 if (hour != 12)
186 hour -= 12;
187 }
188 else if (hour == 0)
189 hour = 12;
190 }
191
192 if (!(ctrl & RTC_DM_BINARY)) {
193 BIN_TO_BCD(sec);
194 BIN_TO_BCD(min);
195 BIN_TO_BCD(hour);
196 BIN_TO_BCD(day);
197 BIN_TO_BCD(mon);
198 BIN_TO_BCD(year);
199 if (wday >= 0) BIN_TO_BCD(wday);
200 }
201 }
202
203 /* Reading/writing the clock registers is a bit critical due to
204 * the regular update cycle of the RTC. While an update is in
205 * progress, registers 0..9 shouldn't be touched.
206 * The problem is solved like that: If an update is currently in
207 * progress (the UIP bit is set), the process sleeps for a while
208 * (50ms). This really should be enough, since the update cycle
209 * normally needs 2 ms.
210 * If the UIP bit reads as 0, we have at least 244 usecs until the
211 * update starts. This should be enough... But to be sure,
212 * additionally the RTC_SET bit is set to prevent an update cycle.
213 */
214
215 while( RTC_READ(RTC_FREQ_SELECT) & RTC_UIP ) {
216 current->state = TASK_INTERRUPTIBLE;
217 schedule_timeout(HWCLK_POLL_INTERVAL);
218 }
219
220 local_irq_save(flags);
221 RTC_WRITE( RTC_CONTROL, ctrl | RTC_SET );
222 if (!op) {
223 sec = RTC_READ( RTC_SECONDS );
224 min = RTC_READ( RTC_MINUTES );
225 hour = RTC_READ( RTC_HOURS );
226 day = RTC_READ( RTC_DAY_OF_MONTH );
227 mon = RTC_READ( RTC_MONTH );
228 year = RTC_READ( RTC_YEAR );
229 wday = RTC_READ( RTC_DAY_OF_WEEK );
230 }
231 else {
232 RTC_WRITE( RTC_SECONDS, sec );
233 RTC_WRITE( RTC_MINUTES, min );
234 RTC_WRITE( RTC_HOURS, hour + pm);
235 RTC_WRITE( RTC_DAY_OF_MONTH, day );
236 RTC_WRITE( RTC_MONTH, mon );
237 RTC_WRITE( RTC_YEAR, year );
238 if (wday >= 0) RTC_WRITE( RTC_DAY_OF_WEEK, wday );
239 }
240 RTC_WRITE( RTC_CONTROL, ctrl & ~RTC_SET );
241 local_irq_restore(flags);
242
243 if (!op) {
244 /* read: adjust values */
245
246 if (hour & 0x80) {
247 hour &= ~0x80;
248 pm = 1;
249 }
250
251 if (!(ctrl & RTC_DM_BINARY)) {
252 BCD_TO_BIN(sec);
253 BCD_TO_BIN(min);
254 BCD_TO_BIN(hour);
255 BCD_TO_BIN(day);
256 BCD_TO_BIN(mon);
257 BCD_TO_BIN(year);
258 BCD_TO_BIN(wday);
259 }
260
261 if (!(ctrl & RTC_24H)) {
262 if (!pm && hour == 12)
263 hour = 0;
264 else if (pm && hour != 12)
265 hour += 12;
266 }
267
268 t->tm_sec = sec;
269 t->tm_min = min;
270 t->tm_hour = hour;
271 t->tm_mday = day;
272 t->tm_mon = mon - 1;
273 t->tm_year = year + atari_rtc_year_offset;
274 t->tm_wday = wday - 1;
275 }
276
277 return( 0 );
278}
279
280
281int atari_mste_set_clock_mmss (unsigned long nowtime)
282{
283 short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
284 struct MSTE_RTC val;
285 unsigned char rtc_minutes;
286
287 mste_read(&val);
288 rtc_minutes= val.min_ones + val.min_tens * 10;
289 if ((rtc_minutes < real_minutes
290 ? real_minutes - rtc_minutes
291 : rtc_minutes - real_minutes) < 30)
292 {
293 val.sec_ones = real_seconds % 10;
294 val.sec_tens = real_seconds / 10;
295 val.min_ones = real_minutes % 10;
296 val.min_tens = real_minutes / 10;
297 mste_write(&val);
298 }
299 else
300 return -1;
301 return 0;
302}
303
304int atari_tt_set_clock_mmss (unsigned long nowtime)
305{
306 int retval = 0;
307 short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
308 unsigned char save_control, save_freq_select, rtc_minutes;
309
310 save_control = RTC_READ (RTC_CONTROL); /* tell the clock it's being set */
311 RTC_WRITE (RTC_CONTROL, save_control | RTC_SET);
312
313 save_freq_select = RTC_READ (RTC_FREQ_SELECT); /* stop and reset prescaler */
314 RTC_WRITE (RTC_FREQ_SELECT, save_freq_select | RTC_DIV_RESET2);
315
316 rtc_minutes = RTC_READ (RTC_MINUTES);
317 if (!(save_control & RTC_DM_BINARY))
318 BCD_TO_BIN (rtc_minutes);
319
320 /* Since we're only adjusting minutes and seconds, don't interfere
321 with hour overflow. This avoids messing with unknown time zones
322 but requires your RTC not to be off by more than 30 minutes. */
323 if ((rtc_minutes < real_minutes
324 ? real_minutes - rtc_minutes
325 : rtc_minutes - real_minutes) < 30)
326 {
327 if (!(save_control & RTC_DM_BINARY))
328 {
329 BIN_TO_BCD (real_seconds);
330 BIN_TO_BCD (real_minutes);
331 }
332 RTC_WRITE (RTC_SECONDS, real_seconds);
333 RTC_WRITE (RTC_MINUTES, real_minutes);
334 }
335 else
336 retval = -1;
337
338 RTC_WRITE (RTC_FREQ_SELECT, save_freq_select);
339 RTC_WRITE (RTC_CONTROL, save_control);
340 return retval;
341}
342
343/*
344 * Local variables:
345 * c-indent-level: 4
346 * tab-width: 8
347 * End:
348 */