.. | .. |
---|
17 | 17 | #include <linux/mm.h> |
---|
18 | 18 | #include <linux/seq_file.h> |
---|
19 | 19 | #include <linux/tty.h> |
---|
| 20 | +#include <linux/clocksource.h> |
---|
20 | 21 | #include <linux/console.h> |
---|
21 | 22 | #include <linux/rtc.h> |
---|
22 | 23 | #include <linux/init.h> |
---|
.. | .. |
---|
31 | 32 | #include <asm/bootinfo-amiga.h> |
---|
32 | 33 | #include <asm/byteorder.h> |
---|
33 | 34 | #include <asm/setup.h> |
---|
34 | | -#include <asm/pgtable.h> |
---|
35 | 35 | #include <asm/amigahw.h> |
---|
36 | 36 | #include <asm/amigaints.h> |
---|
37 | 37 | #include <asm/irq.h> |
---|
.. | .. |
---|
95 | 95 | static void amiga_sched_init(irq_handler_t handler); |
---|
96 | 96 | static void amiga_get_model(char *model); |
---|
97 | 97 | static void amiga_get_hardware_list(struct seq_file *m); |
---|
98 | | -/* amiga specific timer functions */ |
---|
99 | | -static u32 amiga_gettimeoffset(void); |
---|
100 | 98 | extern void amiga_mksound(unsigned int count, unsigned int ticks); |
---|
101 | 99 | static void amiga_reset(void); |
---|
102 | 100 | extern void amiga_init_sound(void); |
---|
.. | .. |
---|
216 | 214 | |
---|
217 | 215 | switch (amiga_model) { |
---|
218 | 216 | case AMI_UNKNOWN: |
---|
219 | | - goto Generic; |
---|
| 217 | + break; |
---|
220 | 218 | |
---|
221 | 219 | case AMI_600: |
---|
222 | 220 | case AMI_1200: |
---|
223 | 221 | AMIGAHW_SET(A1200_IDE); |
---|
224 | 222 | AMIGAHW_SET(PCMCIA); |
---|
| 223 | + fallthrough; |
---|
225 | 224 | case AMI_500: |
---|
226 | 225 | case AMI_500PLUS: |
---|
227 | 226 | case AMI_1000: |
---|
228 | 227 | case AMI_2000: |
---|
229 | 228 | case AMI_2500: |
---|
230 | 229 | AMIGAHW_SET(A2000_CLK); /* Is this correct for all models? */ |
---|
231 | | - goto Generic; |
---|
| 230 | + break; |
---|
232 | 231 | |
---|
233 | 232 | case AMI_3000: |
---|
234 | 233 | case AMI_3000T: |
---|
235 | 234 | AMIGAHW_SET(AMBER_FF); |
---|
236 | 235 | AMIGAHW_SET(MAGIC_REKICK); |
---|
237 | | - /* fall through */ |
---|
| 236 | + fallthrough; |
---|
238 | 237 | case AMI_3000PLUS: |
---|
239 | 238 | AMIGAHW_SET(A3000_SCSI); |
---|
240 | 239 | AMIGAHW_SET(A3000_CLK); |
---|
241 | 240 | AMIGAHW_SET(ZORRO3); |
---|
242 | | - goto Generic; |
---|
| 241 | + break; |
---|
243 | 242 | |
---|
244 | 243 | case AMI_4000T: |
---|
245 | 244 | AMIGAHW_SET(A4000_SCSI); |
---|
246 | | - /* fall through */ |
---|
| 245 | + fallthrough; |
---|
247 | 246 | case AMI_4000: |
---|
248 | 247 | AMIGAHW_SET(A4000_IDE); |
---|
249 | 248 | AMIGAHW_SET(A3000_CLK); |
---|
250 | 249 | AMIGAHW_SET(ZORRO3); |
---|
251 | | - goto Generic; |
---|
| 250 | + break; |
---|
252 | 251 | |
---|
253 | 252 | case AMI_CDTV: |
---|
254 | 253 | case AMI_CD32: |
---|
255 | 254 | AMIGAHW_SET(CD_ROM); |
---|
256 | 255 | AMIGAHW_SET(A2000_CLK); /* Is this correct? */ |
---|
257 | | - goto Generic; |
---|
258 | | - |
---|
259 | | - Generic: |
---|
260 | | - AMIGAHW_SET(AMI_VIDEO); |
---|
261 | | - AMIGAHW_SET(AMI_BLITTER); |
---|
262 | | - AMIGAHW_SET(AMI_AUDIO); |
---|
263 | | - AMIGAHW_SET(AMI_FLOPPY); |
---|
264 | | - AMIGAHW_SET(AMI_KEYBOARD); |
---|
265 | | - AMIGAHW_SET(AMI_MOUSE); |
---|
266 | | - AMIGAHW_SET(AMI_SERIAL); |
---|
267 | | - AMIGAHW_SET(AMI_PARALLEL); |
---|
268 | | - AMIGAHW_SET(CHIP_RAM); |
---|
269 | | - AMIGAHW_SET(PAULA); |
---|
270 | | - |
---|
271 | | - switch (amiga_chipset) { |
---|
272 | | - case CS_OCS: |
---|
273 | | - case CS_ECS: |
---|
274 | | - case CS_AGA: |
---|
275 | | - switch (amiga_custom.deniseid & 0xf) { |
---|
276 | | - case 0x0c: |
---|
277 | | - AMIGAHW_SET(DENISE_HR); |
---|
278 | | - break; |
---|
279 | | - case 0x08: |
---|
280 | | - AMIGAHW_SET(LISA); |
---|
281 | | - break; |
---|
282 | | - } |
---|
283 | | - break; |
---|
284 | | - default: |
---|
285 | | - AMIGAHW_SET(DENISE); |
---|
286 | | - break; |
---|
287 | | - } |
---|
288 | | - switch ((amiga_custom.vposr>>8) & 0x7f) { |
---|
289 | | - case 0x00: |
---|
290 | | - AMIGAHW_SET(AGNUS_PAL); |
---|
291 | | - break; |
---|
292 | | - case 0x10: |
---|
293 | | - AMIGAHW_SET(AGNUS_NTSC); |
---|
294 | | - break; |
---|
295 | | - case 0x20: |
---|
296 | | - case 0x21: |
---|
297 | | - AMIGAHW_SET(AGNUS_HR_PAL); |
---|
298 | | - break; |
---|
299 | | - case 0x30: |
---|
300 | | - case 0x31: |
---|
301 | | - AMIGAHW_SET(AGNUS_HR_NTSC); |
---|
302 | | - break; |
---|
303 | | - case 0x22: |
---|
304 | | - case 0x23: |
---|
305 | | - AMIGAHW_SET(ALICE_PAL); |
---|
306 | | - break; |
---|
307 | | - case 0x32: |
---|
308 | | - case 0x33: |
---|
309 | | - AMIGAHW_SET(ALICE_NTSC); |
---|
310 | | - break; |
---|
311 | | - } |
---|
312 | | - AMIGAHW_SET(ZORRO); |
---|
313 | 256 | break; |
---|
314 | 257 | |
---|
315 | 258 | case AMI_DRACO: |
---|
.. | .. |
---|
318 | 261 | default: |
---|
319 | 262 | panic("Unknown Amiga Model"); |
---|
320 | 263 | } |
---|
| 264 | + |
---|
| 265 | + AMIGAHW_SET(AMI_VIDEO); |
---|
| 266 | + AMIGAHW_SET(AMI_BLITTER); |
---|
| 267 | + AMIGAHW_SET(AMI_AUDIO); |
---|
| 268 | + AMIGAHW_SET(AMI_FLOPPY); |
---|
| 269 | + AMIGAHW_SET(AMI_KEYBOARD); |
---|
| 270 | + AMIGAHW_SET(AMI_MOUSE); |
---|
| 271 | + AMIGAHW_SET(AMI_SERIAL); |
---|
| 272 | + AMIGAHW_SET(AMI_PARALLEL); |
---|
| 273 | + AMIGAHW_SET(CHIP_RAM); |
---|
| 274 | + AMIGAHW_SET(PAULA); |
---|
| 275 | + |
---|
| 276 | + switch (amiga_chipset) { |
---|
| 277 | + case CS_OCS: |
---|
| 278 | + case CS_ECS: |
---|
| 279 | + case CS_AGA: |
---|
| 280 | + switch (amiga_custom.deniseid & 0xf) { |
---|
| 281 | + case 0x0c: |
---|
| 282 | + AMIGAHW_SET(DENISE_HR); |
---|
| 283 | + break; |
---|
| 284 | + case 0x08: |
---|
| 285 | + AMIGAHW_SET(LISA); |
---|
| 286 | + break; |
---|
| 287 | + default: |
---|
| 288 | + AMIGAHW_SET(DENISE); |
---|
| 289 | + break; |
---|
| 290 | + } |
---|
| 291 | + break; |
---|
| 292 | + } |
---|
| 293 | + switch ((amiga_custom.vposr>>8) & 0x7f) { |
---|
| 294 | + case 0x00: |
---|
| 295 | + AMIGAHW_SET(AGNUS_PAL); |
---|
| 296 | + break; |
---|
| 297 | + case 0x10: |
---|
| 298 | + AMIGAHW_SET(AGNUS_NTSC); |
---|
| 299 | + break; |
---|
| 300 | + case 0x20: |
---|
| 301 | + case 0x21: |
---|
| 302 | + AMIGAHW_SET(AGNUS_HR_PAL); |
---|
| 303 | + break; |
---|
| 304 | + case 0x30: |
---|
| 305 | + case 0x31: |
---|
| 306 | + AMIGAHW_SET(AGNUS_HR_NTSC); |
---|
| 307 | + break; |
---|
| 308 | + case 0x22: |
---|
| 309 | + case 0x23: |
---|
| 310 | + AMIGAHW_SET(ALICE_PAL); |
---|
| 311 | + break; |
---|
| 312 | + case 0x32: |
---|
| 313 | + case 0x33: |
---|
| 314 | + AMIGAHW_SET(ALICE_NTSC); |
---|
| 315 | + break; |
---|
| 316 | + } |
---|
| 317 | + AMIGAHW_SET(ZORRO); |
---|
321 | 318 | |
---|
322 | 319 | #define AMIGAHW_ANNOUNCE(name, str) \ |
---|
323 | 320 | if (AMIGAHW_PRESENT(name)) \ |
---|
.. | .. |
---|
386 | 383 | mach_init_IRQ = amiga_init_IRQ; |
---|
387 | 384 | mach_get_model = amiga_get_model; |
---|
388 | 385 | mach_get_hardware_list = amiga_get_hardware_list; |
---|
389 | | - arch_gettimeoffset = amiga_gettimeoffset; |
---|
390 | 386 | |
---|
391 | 387 | /* |
---|
392 | 388 | * default MAX_DMA=0xffffffff on all machines. If we don't do so, the SCSI |
---|
.. | .. |
---|
464 | 460 | *(unsigned char *)ZTWO_VADDR(0xde0002) |= 0x80; |
---|
465 | 461 | } |
---|
466 | 462 | |
---|
| 463 | +static u64 amiga_read_clk(struct clocksource *cs); |
---|
| 464 | + |
---|
| 465 | +static struct clocksource amiga_clk = { |
---|
| 466 | + .name = "ciab", |
---|
| 467 | + .rating = 250, |
---|
| 468 | + .read = amiga_read_clk, |
---|
| 469 | + .mask = CLOCKSOURCE_MASK(32), |
---|
| 470 | + .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
---|
| 471 | +}; |
---|
| 472 | + |
---|
467 | 473 | static unsigned short jiffy_ticks; |
---|
| 474 | +static u32 clk_total, clk_offset; |
---|
| 475 | + |
---|
| 476 | +static irqreturn_t ciab_timer_handler(int irq, void *dev_id) |
---|
| 477 | +{ |
---|
| 478 | + irq_handler_t timer_routine = dev_id; |
---|
| 479 | + |
---|
| 480 | + clk_total += jiffy_ticks; |
---|
| 481 | + clk_offset = 0; |
---|
| 482 | + timer_routine(0, NULL); |
---|
| 483 | + |
---|
| 484 | + return IRQ_HANDLED; |
---|
| 485 | +} |
---|
468 | 486 | |
---|
469 | 487 | static void __init amiga_sched_init(irq_handler_t timer_routine) |
---|
470 | 488 | { |
---|
.. | .. |
---|
484 | 502 | * Please don't change this to use ciaa, as it interferes with the |
---|
485 | 503 | * SCSI code. We'll have to take a look at this later |
---|
486 | 504 | */ |
---|
487 | | - if (request_irq(IRQ_AMIGA_CIAB_TA, timer_routine, 0, "timer", NULL)) |
---|
| 505 | + if (request_irq(IRQ_AMIGA_CIAB_TA, ciab_timer_handler, IRQF_TIMER, |
---|
| 506 | + "timer", timer_routine)) |
---|
488 | 507 | pr_err("Couldn't register timer interrupt\n"); |
---|
489 | 508 | /* start timer */ |
---|
490 | 509 | ciab.cra |= 0x11; |
---|
| 510 | + |
---|
| 511 | + clocksource_register_hz(&amiga_clk, amiga_eclock); |
---|
491 | 512 | } |
---|
492 | 513 | |
---|
493 | | -#define TICK_SIZE 10000 |
---|
494 | | - |
---|
495 | | -/* This is always executed with interrupts disabled. */ |
---|
496 | | -static u32 amiga_gettimeoffset(void) |
---|
| 514 | +static u64 amiga_read_clk(struct clocksource *cs) |
---|
497 | 515 | { |
---|
498 | 516 | unsigned short hi, lo, hi2; |
---|
499 | | - u32 ticks, offset = 0; |
---|
| 517 | + unsigned long flags; |
---|
| 518 | + u32 ticks; |
---|
| 519 | + |
---|
| 520 | + local_irq_save(flags); |
---|
500 | 521 | |
---|
501 | 522 | /* read CIA B timer A current value */ |
---|
502 | 523 | hi = ciab.tahi; |
---|
.. | .. |
---|
513 | 534 | if (ticks > jiffy_ticks / 2) |
---|
514 | 535 | /* check for pending interrupt */ |
---|
515 | 536 | if (cia_set_irq(&ciab_base, 0) & CIA_ICR_TA) |
---|
516 | | - offset = 10000; |
---|
| 537 | + clk_offset = jiffy_ticks; |
---|
517 | 538 | |
---|
518 | 539 | ticks = jiffy_ticks - ticks; |
---|
519 | | - ticks = (10000 * ticks) / jiffy_ticks; |
---|
| 540 | + ticks += clk_offset + clk_total; |
---|
520 | 541 | |
---|
521 | | - return (ticks + offset) * 1000; |
---|
| 542 | + local_irq_restore(flags); |
---|
| 543 | + |
---|
| 544 | + return ticks; |
---|
522 | 545 | } |
---|
523 | 546 | |
---|
524 | 547 | static void amiga_reset(void) __noreturn; |
---|
.. | .. |
---|
603 | 626 | unsigned long magic2; /* SAVEKMSG_MAGIC2 */ |
---|
604 | 627 | unsigned long magicptr; /* address of magic1 */ |
---|
605 | 628 | unsigned long size; |
---|
606 | | - char data[0]; |
---|
| 629 | + char data[]; |
---|
607 | 630 | }; |
---|
608 | 631 | |
---|
609 | 632 | static struct savekmsg *savekmsg; |
---|