| 1 | |
| 2 | |
| 3 | * linux/arch/m68k/kernel/setup.c
|
| 4 | *
|
| 5 | * Copyright (C) 1995 Hamish Macdonald
|
| 6 |
|
| 7 |
|
| 8 | |
| 9 | * This file handles the architecture-dependent parts of system setup
|
| 10 |
|
| 11 |
|
| 12 | #include <linux/kernel.h>
|
| 13 | #include <linux/cpu.h>
|
| 14 | #include <linux/mm.h>
|
| 15 | #include <linux/sched.h>
|
| 16 | #include <linux/delay.h>
|
| 17 | #include <linux/interrupt.h>
|
| 18 | #include <linux/fs.h>
|
| 19 | #include <linux/console.h>
|
| 20 | #include <linux/errno.h>
|
| 21 | #include <linux/string.h>
|
| 22 | #include <linux/init.h>
|
| 23 | #include <linux/memblock.h>
|
| 24 | #include <linux/proc_fs.h>
|
| 25 | #include <linux/seq_file.h>
|
| 26 | #include <linux/module.h>
|
| 27 | #include <linux/nvram.h>
|
| 28 | #include <linux/initrd.h>
|
| 29 | #include <linux/random.h>
|
| 30 |
|
| 31 | #include <asm/bootinfo.h>
|
| 32 | #include <asm/byteorder.h>
|
| 33 | #include <asm/sections.h>
|
| 34 | #include <asm/setup.h>
|
| 35 | #include <asm/fpu.h>
|
| 36 | #include <asm/irq.h>
|
| 37 | #include <asm/io.h>
|
| 38 | #include <asm/machdep.h>
|
| 39 | #ifdef CONFIG_AMIGA
|
| 40 | #include <asm/amigahw.h>
|
| 41 | #endif
|
| 42 | #include <asm/atarihw.h>
|
| 43 | #ifdef CONFIG_ATARI
|
| 44 | #include <asm/atari_stram.h>
|
| 45 | #endif
|
| 46 | #ifdef CONFIG_SUN3X
|
| 47 | #include <asm/dvma.h>
|
| 48 | #endif
|
| 49 | #include <asm/macintosh.h>
|
| 50 | #include <asm/natfeat.h>
|
| 51 | #include <asm/config.h>
|
| 52 |
|
| 53 | #if !FPSTATESIZE || !NR_IRQS
|
| 54 | #warning No CPU/platform type selected, your kernel will not work!
|
| 55 | #warning Are you building an allnoconfig kernel?
|
| 56 | #endif
|
| 57 |
|
| 58 | unsigned long m68k_machtype;
|
| 59 | EXPORT_SYMBOL(m68k_machtype);
|
| 60 | unsigned long m68k_cputype;
|
| 61 | EXPORT_SYMBOL(m68k_cputype);
|
| 62 | unsigned long m68k_fputype;
|
| 63 | unsigned long m68k_mmutype;
|
| 64 | EXPORT_SYMBOL(m68k_mmutype);
|
| 65 | #ifdef CONFIG_VME
|
| 66 | unsigned long vme_brdtype;
|
| 67 | EXPORT_SYMBOL(vme_brdtype);
|
| 68 | #endif
|
| 69 |
|
| 70 | int m68k_is040or060;
|
| 71 | EXPORT_SYMBOL(m68k_is040or060);
|
| 72 |
|
| 73 | extern unsigned long availmem;
|
| 74 |
|
| 75 | int m68k_num_memory;
|
| 76 | EXPORT_SYMBOL(m68k_num_memory);
|
| 77 | int m68k_realnum_memory;
|
| 78 | EXPORT_SYMBOL(m68k_realnum_memory);
|
| 79 | unsigned long m68k_memoffset;
|
| 80 | struct m68k_mem_info m68k_memory[NUM_MEMINFO];
|
| 81 | EXPORT_SYMBOL(m68k_memory);
|
| 82 |
|
| 83 | static struct m68k_mem_info m68k_ramdisk __initdata;
|
| 84 |
|
| 85 | static char m68k_command_line[CL_SIZE] __initdata;
|
| 86 |
|
| 87 | void (*mach_sched_init) (void) __initdata = NULL;
|
| 88 |
|
| 89 | void (*mach_init_IRQ) (void) __initdata = NULL;
|
| 90 | void (*mach_get_model) (char *model);
|
| 91 | void (*mach_get_hardware_list) (struct seq_file *m);
|
| 92 | void (*mach_reset)( void );
|
| 93 | void (*mach_halt)( void );
|
| 94 | #ifdef CONFIG_HEARTBEAT
|
| 95 | void (*mach_heartbeat) (int);
|
| 96 | EXPORT_SYMBOL(mach_heartbeat);
|
| 97 | #endif
|
| 98 | #ifdef CONFIG_M68K_L2_CACHE
|
| 99 | void (*mach_l2_flush) (int);
|
| 100 | #endif
|
| 101 | #if defined(CONFIG_ISA) && defined(MULTI_ISA)
|
| 102 | int isa_type;
|
| 103 | int isa_sex;
|
| 104 | EXPORT_SYMBOL(isa_type);
|
| 105 | EXPORT_SYMBOL(isa_sex);
|
| 106 | #endif
|
| 107 |
|
| 108 | #define MASK_256K 0xfffc0000
|
| 109 |
|
| 110 | static void __init m68k_parse_bootinfo(const struct bi_record *record)
|
| 111 | {
|
| 112 | const struct bi_record *first_record = record;
|
| 113 | uint16_t tag;
|
| 114 |
|
| 115 | while ((tag = be16_to_cpu(record->tag)) != BI_LAST) {
|
| 116 | int unknown = 0;
|
| 117 | const void *data = record->data;
|
| 118 | uint16_t size = be16_to_cpu(record->size);
|
| 119 |
|
| 120 | switch (tag) {
|
| 121 | case BI_MACHTYPE:
|
| 122 | case BI_CPUTYPE:
|
| 123 | case BI_FPUTYPE:
|
| 124 | case BI_MMUTYPE:
|
| 125 |
|
| 126 | break;
|
| 127 |
|
| 128 | case BI_MEMCHUNK:
|
| 129 | if (m68k_num_memory < NUM_MEMINFO) {
|
| 130 | const struct mem_info *m = data;
|
| 131 | m68k_memory[m68k_num_memory].addr =
|
| 132 | be32_to_cpu(m->addr);
|
| 133 | m68k_memory[m68k_num_memory].size =
|
| 134 | be32_to_cpu(m->size);
|
| 135 | m68k_num_memory++;
|
| 136 | } else
|
| 137 | pr_warn("%s: too many memory chunks\n",
|
| 138 | __func__);
|
| 139 | break;
|
| 140 |
|
| 141 | case BI_RAMDISK:
|
| 142 | {
|
| 143 | const struct mem_info *m = data;
|
| 144 | m68k_ramdisk.addr = be32_to_cpu(m->addr);
|
| 145 | m68k_ramdisk.size = be32_to_cpu(m->size);
|
| 146 | }
|
| 147 | break;
|
| 148 |
|
| 149 | case BI_COMMAND_LINE:
|
| 150 | strscpy(m68k_command_line, data);
|
| 151 | break;
|
| 152 |
|
| 153 | case BI_RNG_SEED: {
|
| 154 | u16 len = be16_to_cpup(data);
|
| 155 | add_bootloader_randomness(data + 2, len);
|
| 156 | |
| 157 | * Zero the data to preserve forward secrecy, and zero the
|
| 158 | * length to prevent kexec from using it.
|
| 159 |
|
| 160 | memzero_explicit((void *)data, len + 2);
|
| 161 | break;
|
| 162 | }
|
| 163 |
|
| 164 | default:
|
| 165 | if (MACH_IS_AMIGA)
|
| 166 | unknown = amiga_parse_bootinfo(record);
|
| 167 | else if (MACH_IS_ATARI)
|
| 168 | unknown = atari_parse_bootinfo(record);
|
| 169 | else if (MACH_IS_MAC)
|
| 170 | unknown = mac_parse_bootinfo(record);
|
| 171 | else if (MACH_IS_Q40)
|
| 172 | unknown = q40_parse_bootinfo(record);
|
| 173 | else if (MACH_IS_BVME6000)
|
| 174 | unknown = bvme6000_parse_bootinfo(record);
|
| 175 | else if (MACH_IS_MVME16x)
|
| 176 | unknown = mvme16x_parse_bootinfo(record);
|
| 177 | else if (MACH_IS_MVME147)
|
| 178 | unknown = mvme147_parse_bootinfo(record);
|
| 179 | else if (MACH_IS_HP300)
|
| 180 | unknown = hp300_parse_bootinfo(record);
|
| 181 | else if (MACH_IS_APOLLO)
|
| 182 | unknown = apollo_parse_bootinfo(record);
|
| 183 | else if (MACH_IS_VIRT)
|
| 184 | unknown = virt_parse_bootinfo(record);
|
| 185 | else
|
| 186 | unknown = 1;
|
| 187 | }
|
| 188 | if (unknown)
|
| 189 | pr_warn("%s: unknown tag 0x%04x ignored\n", __func__,
|
| 190 | tag);
|
| 191 | record = (struct bi_record *)((unsigned long)record + size);
|
| 192 | }
|
| 193 |
|
| 194 | save_bootinfo(first_record);
|
| 195 |
|
| 196 | m68k_realnum_memory = m68k_num_memory;
|
| 197 | #ifdef CONFIG_SINGLE_MEMORY_CHUNK
|
| 198 | if (m68k_num_memory > 1) {
|
| 199 | pr_warn("%s: ignoring last %i chunks of physical memory\n",
|
| 200 | __func__, (m68k_num_memory - 1));
|
| 201 | m68k_num_memory = 1;
|
| 202 | }
|
| 203 | #endif
|
| 204 | }
|
| 205 |
|
| 206 | void __init setup_arch(char **cmdline_p)
|
| 207 | {
|
| 208 |
|
| 209 | if (!CPU_IS_COLDFIRE)
|
| 210 | m68k_parse_bootinfo((const struct bi_record *)_end);
|
| 211 |
|
| 212 | if (CPU_IS_040)
|
| 213 | m68k_is040or060 = 4;
|
| 214 | else if (CPU_IS_060)
|
| 215 | m68k_is040or060 = 6;
|
| 216 |
|
| 217 | |
| 218 | * be confused by software FPU emulation. BEWARE.
|
| 219 | * We should really do our own FPU check at startup.
|
| 220 | * [what do we do with buggy 68LC040s? if we have problems
|
| 221 | * with them, we should add a test to check_bugs() below]
|
| 222 | #if defined(CONFIG_FPU) && !defined(CONFIG_M68KFPU_EMU_ONLY)
|
| 223 |
|
| 224 | if (m68k_fputype & (FPU_68881|FPU_68882|FPU_68040|FPU_68060|FPU_COLDFIRE)) {
|
| 225 | volatile int zero = 0;
|
| 226 | asm volatile ("frestore %0" : : "m" (zero));
|
| 227 | }
|
| 228 | #endif
|
| 229 |
|
| 230 | if (CPU_IS_060) {
|
| 231 | u32 pcr;
|
| 232 |
|
| 233 | asm (".chip 68060; movec %%pcr,%0; .chip 68k"
|
| 234 | : "=d" (pcr));
|
| 235 | if (((pcr >> 8) & 0xff) <= 5) {
|
| 236 | pr_warn("Enabling workaround for errata I14\n");
|
| 237 | asm (".chip 68060; movec %0,%%pcr; .chip 68k"
|
| 238 | : : "d" (pcr | 0x20));
|
| 239 | }
|
| 240 | }
|
| 241 |
|
| 242 | setup_initial_init_mm((void *)PAGE_OFFSET, _etext, _edata, _end);
|
| 243 |
|
| 244 | #if defined(CONFIG_BOOTPARAM)
|
| 245 | strscpy(m68k_command_line, CONFIG_BOOTPARAM_STRING, CL_SIZE);
|
| 246 | #endif
|
| 247 | process_uboot_commandline(&m68k_command_line[0], CL_SIZE);
|
| 248 | *cmdline_p = m68k_command_line;
|
| 249 | memcpy(boot_command_line, *cmdline_p, CL_SIZE);
|
| 250 | |
| 251 | * Initialise the static keys early as they may be enabled by the
|
| 252 | * cpufeature code and early parameters.
|
| 253 |
|
| 254 | jump_label_init();
|
| 255 | parse_early_param();
|
| 256 |
|
| 257 | switch (m68k_machtype) {
|
| 258 | #ifdef CONFIG_AMIGA
|
| 259 | case MACH_AMIGA:
|
| 260 | config_amiga();
|
| 261 | break;
|
| 262 | #endif
|
| 263 | #ifdef CONFIG_ATARI
|
| 264 | case MACH_ATARI:
|
| 265 | config_atari();
|
| 266 | break;
|
| 267 | #endif
|
| 268 | #ifdef CONFIG_MAC
|
| 269 | case MACH_MAC:
|
| 270 | config_mac();
|
| 271 | break;
|
| 272 | #endif
|
| 273 | #ifdef CONFIG_SUN3
|
| 274 | case MACH_SUN3:
|
| 275 | config_sun3();
|
| 276 | break;
|
| 277 | #endif
|
| 278 | #ifdef CONFIG_APOLLO
|
| 279 | case MACH_APOLLO:
|
| 280 | config_apollo();
|
| 281 | break;
|
| 282 | #endif
|
| 283 | #ifdef CONFIG_MVME147
|
| 284 | case MACH_MVME147:
|
| 285 | config_mvme147();
|
| 286 | break;
|
| 287 | #endif
|
| 288 | #ifdef CONFIG_MVME16x
|
| 289 | case MACH_MVME16x:
|
| 290 | config_mvme16x();
|
| 291 | break;
|
| 292 | #endif
|
| 293 | #ifdef CONFIG_BVME6000
|
| 294 | case MACH_BVME6000:
|
| 295 | config_bvme6000();
|
| 296 | break;
|
| 297 | #endif
|
| 298 | #ifdef CONFIG_HP300
|
| 299 | case MACH_HP300:
|
| 300 | config_hp300();
|
| 301 | break;
|
| 302 | #endif
|
| 303 | #ifdef CONFIG_Q40
|
| 304 | case MACH_Q40:
|
| 305 | config_q40();
|
| 306 | break;
|
| 307 | #endif
|
| 308 | #ifdef CONFIG_SUN3X
|
| 309 | case MACH_SUN3X:
|
| 310 | config_sun3x();
|
| 311 | break;
|
| 312 | #endif
|
| 313 | #ifdef CONFIG_COLDFIRE
|
| 314 | case MACH_M54XX:
|
| 315 | case MACH_M5441X:
|
| 316 | cf_bootmem_alloc();
|
| 317 | cf_mmu_context_init();
|
| 318 | config_BSP(NULL, 0);
|
| 319 | break;
|
| 320 | #endif
|
| 321 | #ifdef CONFIG_VIRT
|
| 322 | case MACH_VIRT:
|
| 323 | config_virt();
|
| 324 | break;
|
| 325 | #endif
|
| 326 | default:
|
| 327 | panic("No configuration setup");
|
| 328 | }
|
| 329 |
|
| 330 | if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && m68k_ramdisk.size)
|
| 331 | memblock_reserve(m68k_ramdisk.addr, m68k_ramdisk.size);
|
| 332 |
|
| 333 | paging_init();
|
| 334 |
|
| 335 | if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && m68k_ramdisk.size) {
|
| 336 | initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr);
|
| 337 | initrd_end = initrd_start + m68k_ramdisk.size;
|
| 338 | pr_info("initrd: %08lx - %08lx\n", initrd_start, initrd_end);
|
| 339 | }
|
| 340 |
|
| 341 | #ifdef CONFIG_NATFEAT
|
| 342 | nf_init();
|
| 343 | #endif
|
| 344 |
|
| 345 | #ifdef CONFIG_ATARI
|
| 346 | if (MACH_IS_ATARI)
|
| 347 | atari_stram_reserve_pages((void *)availmem);
|
| 348 | #endif
|
| 349 | #ifdef CONFIG_SUN3X
|
| 350 | if (MACH_IS_SUN3X) {
|
| 351 | dvma_init();
|
| 352 | }
|
| 353 | #endif
|
| 354 |
|
| 355 |
|
| 356 | #if defined(CONFIG_ISA) && defined(MULTI_ISA)
|
| 357 | if (MACH_IS_Q40) {
|
| 358 | isa_type = ISA_TYPE_Q40;
|
| 359 | isa_sex = 0;
|
| 360 | }
|
| 361 | #ifdef CONFIG_AMIGA_PCMCIA
|
| 362 | if (MACH_IS_AMIGA && AMIGAHW_PRESENT(PCMCIA)) {
|
| 363 | isa_type = ISA_TYPE_AG;
|
| 364 | isa_sex = 1;
|
| 365 | }
|
| 366 | #endif
|
| 367 | #ifdef CONFIG_ATARI_ROM_ISA
|
| 368 | if (MACH_IS_ATARI) {
|
| 369 | isa_type = ISA_TYPE_ENEC;
|
| 370 | isa_sex = 0;
|
| 371 | }
|
| 372 | #endif
|
| 373 | #endif
|
| 374 | }
|
| 375 |
|
| 376 | static int show_cpuinfo(struct seq_file *m, void *v)
|
| 377 | {
|
| 378 | const char *cpu, *mmu, *fpu;
|
| 379 | unsigned long clockfreq, clockfactor;
|
| 380 |
|
| 381 | #define LOOP_CYCLES_68020 (8)
|
| 382 | #define LOOP_CYCLES_68030 (8)
|
| 383 | #define LOOP_CYCLES_68040 (3)
|
| 384 | #define LOOP_CYCLES_68060 (1)
|
| 385 | #define LOOP_CYCLES_COLDFIRE (2)
|
| 386 |
|
| 387 | if (CPU_IS_020) {
|
| 388 | cpu = "68020";
|
| 389 | clockfactor = LOOP_CYCLES_68020;
|
| 390 | } else if (CPU_IS_030) {
|
| 391 | cpu = "68030";
|
| 392 | clockfactor = LOOP_CYCLES_68030;
|
| 393 | } else if (CPU_IS_040) {
|
| 394 | cpu = "68040";
|
| 395 | clockfactor = LOOP_CYCLES_68040;
|
| 396 | } else if (CPU_IS_060) {
|
| 397 | cpu = "68060";
|
| 398 | clockfactor = LOOP_CYCLES_68060;
|
| 399 | } else if (CPU_IS_COLDFIRE) {
|
| 400 | cpu = "ColdFire";
|
| 401 | clockfactor = LOOP_CYCLES_COLDFIRE;
|
| 402 | } else {
|
| 403 | cpu = "680x0";
|
| 404 | clockfactor = 0;
|
| 405 | }
|
| 406 |
|
| 407 | #ifdef CONFIG_M68KFPU_EMU_ONLY
|
| 408 | fpu = "none(soft float)";
|
| 409 | #else
|
| 410 | if (m68k_fputype & FPU_68881)
|
| 411 | fpu = "68881";
|
| 412 | else if (m68k_fputype & FPU_68882)
|
| 413 | fpu = "68882";
|
| 414 | else if (m68k_fputype & FPU_68040)
|
| 415 | fpu = "68040";
|
| 416 | else if (m68k_fputype & FPU_68060)
|
| 417 | fpu = "68060";
|
| 418 | else if (m68k_fputype & FPU_SUNFPA)
|
| 419 | fpu = "Sun FPA";
|
| 420 | else if (m68k_fputype & FPU_COLDFIRE)
|
| 421 | fpu = "ColdFire";
|
| 422 | else
|
| 423 | fpu = "none";
|
| 424 | #endif
|
| 425 |
|
| 426 | if (m68k_mmutype & MMU_68851)
|
| 427 | mmu = "68851";
|
| 428 | else if (m68k_mmutype & MMU_68030)
|
| 429 | mmu = "68030";
|
| 430 | else if (m68k_mmutype & MMU_68040)
|
| 431 | mmu = "68040";
|
| 432 | else if (m68k_mmutype & MMU_68060)
|
| 433 | mmu = "68060";
|
| 434 | else if (m68k_mmutype & MMU_SUN3)
|
| 435 | mmu = "Sun-3";
|
| 436 | else if (m68k_mmutype & MMU_APOLLO)
|
| 437 | mmu = "Apollo";
|
| 438 | else if (m68k_mmutype & MMU_COLDFIRE)
|
| 439 | mmu = "ColdFire";
|
| 440 | else
|
| 441 | mmu = "unknown";
|
| 442 |
|
| 443 | clockfreq = loops_per_jiffy * HZ * clockfactor;
|
| 444 |
|
| 445 | seq_printf(m, "CPU:\t\t%s\n"
|
| 446 | "MMU:\t\t%s\n"
|
| 447 | "FPU:\t\t%s\n"
|
| 448 | "Clocking:\t%lu.%1luMHz\n"
|
| 449 | "BogoMips:\t%lu.%02lu\n"
|
| 450 | "Calibration:\t%lu loops\n",
|
| 451 | cpu, mmu, fpu,
|
| 452 | clockfreq/1000000,(clockfreq/100000)%10,
|
| 453 | loops_per_jiffy/(500000/HZ),(loops_per_jiffy/(5000/HZ))%100,
|
| 454 | loops_per_jiffy);
|
| 455 | return 0;
|
| 456 | }
|
| 457 |
|
| 458 | static void *c_start(struct seq_file *m, loff_t *pos)
|
| 459 | {
|
| 460 | return *pos < 1 ? (void *)1 : NULL;
|
| 461 | }
|
| 462 | static void *c_next(struct seq_file *m, void *v, loff_t *pos)
|
| 463 | {
|
| 464 | ++*pos;
|
| 465 | return NULL;
|
| 466 | }
|
| 467 | static void c_stop(struct seq_file *m, void *v)
|
| 468 | {
|
| 469 | }
|
| 470 | const struct seq_operations cpuinfo_op = {
|
| 471 | .start = c_start,
|
| 472 | .next = c_next,
|
| 473 | .stop = c_stop,
|
| 474 | .show = show_cpuinfo,
|
| 475 | };
|
| 476 |
|
| 477 | #ifdef CONFIG_PROC_HARDWARE
|
| 478 | static int hardware_proc_show(struct seq_file *m, void *v)
|
| 479 | {
|
| 480 | char model[80];
|
| 481 | unsigned long mem;
|
| 482 | int i;
|
| 483 |
|
| 484 | if (mach_get_model)
|
| 485 | mach_get_model(model);
|
| 486 | else
|
| 487 | strscpy(model, "Unknown m68k");
|
| 488 |
|
| 489 | seq_printf(m, "Model:\t\t%s\n", model);
|
| 490 | for (mem = 0, i = 0; i < m68k_num_memory; i++)
|
| 491 | mem += m68k_memory[i].size;
|
| 492 | seq_printf(m, "System Memory:\t%ldK\n", mem >> 10);
|
| 493 |
|
| 494 | if (mach_get_hardware_list)
|
| 495 | mach_get_hardware_list(m);
|
| 496 |
|
| 497 | return 0;
|
| 498 | }
|
| 499 |
|
| 500 | static int __init proc_hardware_init(void)
|
| 501 | {
|
| 502 | proc_create_single("hardware", 0, NULL, hardware_proc_show);
|
| 503 | return 0;
|
| 504 | }
|
| 505 | module_init(proc_hardware_init);
|
| 506 | #endif
|
| 507 |
|
| 508 | void __init arch_cpu_finalize_init(void)
|
| 509 | {
|
| 510 | #if defined(CONFIG_FPU) && !defined(CONFIG_M68KFPU_EMU)
|
| 511 | if (m68k_fputype == 0) {
|
| 512 | pr_emerg("*** YOU DO NOT HAVE A FLOATING POINT UNIT, "
|
| 513 | "WHICH IS REQUIRED BY LINUX/M68K ***\n");
|
| 514 | pr_emerg("Upgrade your hardware or join the FPU "
|
| 515 | "emulation project\n");
|
| 516 | panic("no FPU");
|
| 517 | }
|
| 518 | #endif
|
| 519 | }
|
| 520 |
|
| 521 | #ifdef CONFIG_ADB
|
| 522 | static int __init adb_probe_sync_enable (char *str) {
|
| 523 | extern int __adb_probe_sync;
|
| 524 | __adb_probe_sync = 1;
|
| 525 | return 1;
|
| 526 | }
|
| 527 |
|
| 528 | __setup("adb_sync", adb_probe_sync_enable);
|
| 529 | #endif
|
| 530 |
|
| 531 | #if IS_ENABLED(CONFIG_NVRAM)
|
| 532 | #ifdef CONFIG_MAC
|
| 533 | static unsigned char m68k_nvram_read_byte(int addr)
|
| 534 | {
|
| 535 | if (MACH_IS_MAC)
|
| 536 | return mac_pram_read_byte(addr);
|
| 537 | return 0xff;
|
| 538 | }
|
| 539 |
|
| 540 | static void m68k_nvram_write_byte(unsigned char val, int addr)
|
| 541 | {
|
| 542 | if (MACH_IS_MAC)
|
| 543 | mac_pram_write_byte(val, addr);
|
| 544 | }
|
| 545 | #endif
|
| 546 |
|
| 547 | #ifdef CONFIG_ATARI
|
| 548 | static ssize_t m68k_nvram_read(char *buf, size_t count, loff_t *ppos)
|
| 549 | {
|
| 550 | if (MACH_IS_ATARI)
|
| 551 | return atari_nvram_read(buf, count, ppos);
|
| 552 | else if (MACH_IS_MAC)
|
| 553 | return nvram_read_bytes(buf, count, ppos);
|
| 554 | return -EINVAL;
|
| 555 | }
|
| 556 |
|
| 557 | static ssize_t m68k_nvram_write(char *buf, size_t count, loff_t *ppos)
|
| 558 | {
|
| 559 | if (MACH_IS_ATARI)
|
| 560 | return atari_nvram_write(buf, count, ppos);
|
| 561 | else if (MACH_IS_MAC)
|
| 562 | return nvram_write_bytes(buf, count, ppos);
|
| 563 | return -EINVAL;
|
| 564 | }
|
| 565 |
|
| 566 | static long m68k_nvram_set_checksum(void)
|
| 567 | {
|
| 568 | if (MACH_IS_ATARI)
|
| 569 | return atari_nvram_set_checksum();
|
| 570 | return -EINVAL;
|
| 571 | }
|
| 572 |
|
| 573 | static long m68k_nvram_initialize(void)
|
| 574 | {
|
| 575 | if (MACH_IS_ATARI)
|
| 576 | return atari_nvram_initialize();
|
| 577 | return -EINVAL;
|
| 578 | }
|
| 579 | #endif
|
| 580 |
|
| 581 | static ssize_t m68k_nvram_get_size(void)
|
| 582 | {
|
| 583 | if (MACH_IS_ATARI)
|
| 584 | return atari_nvram_get_size();
|
| 585 | else if (MACH_IS_MAC)
|
| 586 | return mac_pram_get_size();
|
| 587 | return -ENODEV;
|
| 588 | }
|
| 589 |
|
| 590 | |
| 591 | * Mac and PowerMac device drivers just use .read_byte.
|
| 592 |
|
| 593 | const struct nvram_ops arch_nvram_ops = {
|
| 594 | #ifdef CONFIG_MAC
|
| 595 | .read_byte = m68k_nvram_read_byte,
|
| 596 | .write_byte = m68k_nvram_write_byte,
|
| 597 | #endif
|
| 598 | #ifdef CONFIG_ATARI
|
| 599 | .read = m68k_nvram_read,
|
| 600 | .write = m68k_nvram_write,
|
| 601 | .set_checksum = m68k_nvram_set_checksum,
|
| 602 | .initialize = m68k_nvram_initialize,
|
| 603 | #endif
|
| 604 | .get_size = m68k_nvram_get_size,
|
| 605 | };
|
| 606 | EXPORT_SYMBOL(arch_nvram_ops);
|
| 607 | #endif
|