diff options
Diffstat (limited to 'arch/m68k/amiga/config.c')
| -rw-r--r-- | arch/m68k/amiga/config.c | 285 |
1 files changed, 64 insertions, 221 deletions
diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c index 6c74751c7b8..01693df7f2f 100644 --- a/arch/m68k/amiga/config.c +++ b/arch/m68k/amiga/config.c @@ -28,8 +28,9 @@ #include <linux/keyboard.h> #include <asm/bootinfo.h> +#include <asm/bootinfo-amiga.h> +#include <asm/byteorder.h> #include <asm/setup.h> -#include <asm/system.h> #include <asm/pgtable.h> #include <asm/amigahw.h> #include <asm/amigaints.h> @@ -96,11 +97,7 @@ static void amiga_sched_init(irq_handler_t handler); static void amiga_get_model(char *model); static void amiga_get_hardware_list(struct seq_file *m); /* amiga specific timer functions */ -static unsigned long amiga_gettimeoffset(void); -static int a3000_hwclk(int, struct rtc_time *); -static int a2000_hwclk(int, struct rtc_time *); -static int amiga_set_clock_mmss(unsigned long); -static unsigned int amiga_get_ss(void); +static u32 amiga_gettimeoffset(void); extern void amiga_mksound(unsigned int count, unsigned int ticks); static void amiga_reset(void); extern void amiga_init_sound(void); @@ -138,10 +135,6 @@ static struct { } }; -static struct resource rtc_resource = { - .start = 0x00dc0000, .end = 0x00dcffff -}; - static struct resource ram_resource[NUM_MEMINFO]; @@ -149,48 +142,48 @@ static struct resource ram_resource[NUM_MEMINFO]; * Parse an Amiga-specific record in the bootinfo */ -int amiga_parse_bootinfo(const struct bi_record *record) +int __init amiga_parse_bootinfo(const struct bi_record *record) { int unknown = 0; - const unsigned long *data = record->data; + const void *data = record->data; - switch (record->tag) { + switch (be16_to_cpu(record->tag)) { case BI_AMIGA_MODEL: - amiga_model = *data; + amiga_model = be32_to_cpup(data); break; case BI_AMIGA_ECLOCK: - amiga_eclock = *data; + amiga_eclock = be32_to_cpup(data); break; case BI_AMIGA_CHIPSET: - amiga_chipset = *data; + amiga_chipset = be32_to_cpup(data); break; case BI_AMIGA_CHIP_SIZE: - amiga_chip_size = *(const int *)data; + amiga_chip_size = be32_to_cpup(data); break; case BI_AMIGA_VBLANK: - amiga_vblank = *(const unsigned char *)data; + amiga_vblank = *(const __u8 *)data; break; case BI_AMIGA_PSFREQ: - amiga_psfreq = *(const unsigned char *)data; + amiga_psfreq = *(const __u8 *)data; break; case BI_AMIGA_AUTOCON: #ifdef CONFIG_ZORRO if (zorro_num_autocon < ZORRO_NUM_AUTO) { - const struct ConfigDev *cd = (struct ConfigDev *)data; - struct zorro_dev *dev = &zorro_autocon[zorro_num_autocon++]; + const struct ConfigDev *cd = data; + struct zorro_dev_init *dev = &zorro_autocon_init[zorro_num_autocon++]; dev->rom = cd->cd_Rom; - dev->slotaddr = cd->cd_SlotAddr; - dev->slotsize = cd->cd_SlotSize; - dev->resource.start = (unsigned long)cd->cd_BoardAddr; - dev->resource.end = dev->resource.start + cd->cd_BoardSize - 1; + dev->slotaddr = be16_to_cpu(cd->cd_SlotAddr); + dev->slotsize = be16_to_cpu(cd->cd_SlotSize); + dev->boardaddr = be32_to_cpu(cd->cd_BoardAddr); + dev->boardsize = be32_to_cpu(cd->cd_BoardSize); } else - printk("amiga_parse_bootinfo: too many AutoConfig devices\n"); + pr_warn("amiga_parse_bootinfo: too many AutoConfig devices\n"); #endif /* CONFIG_ZORRO */ break; @@ -216,9 +209,9 @@ static void __init amiga_identify(void) memset(&amiga_hw_present, 0, sizeof(amiga_hw_present)); - printk("Amiga hardware found: "); + pr_info("Amiga hardware found: "); if (amiga_model >= AMI_500 && amiga_model <= AMI_DRACO) { - printk("[%s] ", amiga_models[amiga_model-AMI_500]); + pr_cont("[%s] ", amiga_models[amiga_model-AMI_500]); strcat(amiga_model_name, amiga_models[amiga_model-AMI_500]); } @@ -329,7 +322,7 @@ static void __init amiga_identify(void) #define AMIGAHW_ANNOUNCE(name, str) \ if (AMIGAHW_PRESENT(name)) \ - printk(str) + pr_cont(str) AMIGAHW_ANNOUNCE(AMI_VIDEO, "VIDEO "); AMIGAHW_ANNOUNCE(AMI_BLITTER, "BLITTER "); @@ -361,12 +354,20 @@ static void __init amiga_identify(void) AMIGAHW_ANNOUNCE(MAGIC_REKICK, "MAGIC_REKICK "); AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA "); if (AMIGAHW_PRESENT(ZORRO)) - printk("ZORRO%s ", AMIGAHW_PRESENT(ZORRO3) ? "3" : ""); - printk("\n"); + pr_cont("ZORRO%s ", AMIGAHW_PRESENT(ZORRO3) ? "3" : ""); + pr_cont("\n"); #undef AMIGAHW_ANNOUNCE } + +static unsigned long amiga_random_get_entropy(void) +{ + /* VPOSR/VHPOSR provide at least 17 bits of data changing at 1.79 MHz */ + return *(unsigned long *)&amiga_custom.vposr; +} + + /* * Setup the Amiga configuration info */ @@ -386,16 +387,7 @@ void __init config_amiga(void) mach_init_IRQ = amiga_init_IRQ; mach_get_model = amiga_get_model; mach_get_hardware_list = amiga_get_hardware_list; - mach_gettimeoffset = amiga_gettimeoffset; - if (AMIGAHW_PRESENT(A3000_CLK)) { - mach_hwclk = a3000_hwclk; - rtc_resource.name = "A3000 RTC"; - request_resource(&iomem_resource, &rtc_resource); - } else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ { - mach_hwclk = a2000_hwclk; - rtc_resource.name = "A2000 RTC"; - request_resource(&iomem_resource, &rtc_resource); - } + arch_gettimeoffset = amiga_gettimeoffset; /* * default MAX_DMA=0xffffffff on all machines. If we don't do so, the SCSI @@ -404,8 +396,6 @@ void __init config_amiga(void) */ mach_max_dma_address = 0xffffffff; - mach_set_clock_mmss = amiga_set_clock_mmss; - mach_get_ss = amiga_get_ss; mach_reset = amiga_reset; #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) mach_beep = amiga_mksound; @@ -415,6 +405,8 @@ void __init config_amiga(void) mach_heartbeat = amiga_heartbeat; #endif + mach_random_get_entropy = amiga_random_get_entropy; + /* Fill in the clock value (based on the 700 kHz E-Clock) */ amiga_colorclock = 5*amiga_eclock; /* 3.5 MHz */ @@ -432,7 +424,7 @@ void __init config_amiga(void) if (m68k_memory[i].addr < 16*1024*1024) { if (i == 0) { /* don't cut off the branch we're sitting on */ - printk("Warning: kernel runs in Zorro II memory\n"); + pr_warn("Warning: kernel runs in Zorro II memory\n"); continue; } disabled_z2mem += m68k_memory[i].size; @@ -443,8 +435,8 @@ void __init config_amiga(void) } } if (disabled_z2mem) - printk("%dK of Zorro II memory will not be used as system memory\n", - disabled_z2mem>>10); + pr_info("%dK of Zorro II memory will not be used as system memory\n", + disabled_z2mem>>10); } /* request all RAM */ @@ -480,10 +472,10 @@ static void __init amiga_sched_init(irq_handler_t timer_routine) static struct resource sched_res = { .name = "timer", .start = 0x00bfd400, .end = 0x00bfd5ff, }; - jiffy_ticks = (amiga_eclock+HZ/2)/HZ; + jiffy_ticks = DIV_ROUND_CLOSEST(amiga_eclock, HZ); if (request_resource(&mb_resources._ciab, &sched_res)) - printk("Cannot allocate ciab.ta{lo,hi}\n"); + pr_warn("Cannot allocate ciab.ta{lo,hi}\n"); ciab.cra &= 0xC0; /* turn off timer A, continuous mode, from Eclk */ ciab.talo = jiffy_ticks % 256; ciab.tahi = jiffy_ticks / 256; @@ -502,10 +494,10 @@ static void __init amiga_sched_init(irq_handler_t timer_routine) #define TICK_SIZE 10000 /* This is always executed with interrupts disabled. */ -static unsigned long amiga_gettimeoffset(void) +static u32 amiga_gettimeoffset(void) { unsigned short hi, lo, hi2; - unsigned long ticks, offset = 0; + u32 ticks, offset = 0; /* read CIA B timer A current value */ hi = ciab.tahi; @@ -527,166 +519,10 @@ static unsigned long amiga_gettimeoffset(void) ticks = jiffy_ticks - ticks; ticks = (10000 * ticks) / jiffy_ticks; - return ticks + offset; -} - -static int a3000_hwclk(int op, struct rtc_time *t) -{ - tod_3000.cntrl1 = TOD3000_CNTRL1_HOLD; - - if (!op) { /* read */ - t->tm_sec = tod_3000.second1 * 10 + tod_3000.second2; - t->tm_min = tod_3000.minute1 * 10 + tod_3000.minute2; - t->tm_hour = tod_3000.hour1 * 10 + tod_3000.hour2; - t->tm_mday = tod_3000.day1 * 10 + tod_3000.day2; - t->tm_wday = tod_3000.weekday; - t->tm_mon = tod_3000.month1 * 10 + tod_3000.month2 - 1; - t->tm_year = tod_3000.year1 * 10 + tod_3000.year2; - if (t->tm_year <= 69) - t->tm_year += 100; - } else { - tod_3000.second1 = t->tm_sec / 10; - tod_3000.second2 = t->tm_sec % 10; - tod_3000.minute1 = t->tm_min / 10; - tod_3000.minute2 = t->tm_min % 10; - tod_3000.hour1 = t->tm_hour / 10; - tod_3000.hour2 = t->tm_hour % 10; - tod_3000.day1 = t->tm_mday / 10; - tod_3000.day2 = t->tm_mday % 10; - if (t->tm_wday != -1) - tod_3000.weekday = t->tm_wday; - tod_3000.month1 = (t->tm_mon + 1) / 10; - tod_3000.month2 = (t->tm_mon + 1) % 10; - if (t->tm_year >= 100) - t->tm_year -= 100; - tod_3000.year1 = t->tm_year / 10; - tod_3000.year2 = t->tm_year % 10; - } - - tod_3000.cntrl1 = TOD3000_CNTRL1_FREE; - - return 0; -} - -static int a2000_hwclk(int op, struct rtc_time *t) -{ - int cnt = 5; - - tod_2000.cntrl1 = TOD2000_CNTRL1_HOLD; - - while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt) { - tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD; - udelay(70); - tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; - --cnt; - } - - if (!cnt) - printk(KERN_INFO "hwclk: timed out waiting for RTC (0x%x)\n", - tod_2000.cntrl1); - - if (!op) { /* read */ - t->tm_sec = tod_2000.second1 * 10 + tod_2000.second2; - t->tm_min = tod_2000.minute1 * 10 + tod_2000.minute2; - t->tm_hour = (tod_2000.hour1 & 3) * 10 + tod_2000.hour2; - t->tm_mday = tod_2000.day1 * 10 + tod_2000.day2; - t->tm_wday = tod_2000.weekday; - t->tm_mon = tod_2000.month1 * 10 + tod_2000.month2 - 1; - t->tm_year = tod_2000.year1 * 10 + tod_2000.year2; - if (t->tm_year <= 69) - t->tm_year += 100; - - if (!(tod_2000.cntrl3 & TOD2000_CNTRL3_24HMODE)) { - if (!(tod_2000.hour1 & TOD2000_HOUR1_PM) && t->tm_hour == 12) - t->tm_hour = 0; - else if ((tod_2000.hour1 & TOD2000_HOUR1_PM) && t->tm_hour != 12) - t->tm_hour += 12; - } - } else { - tod_2000.second1 = t->tm_sec / 10; - tod_2000.second2 = t->tm_sec % 10; - tod_2000.minute1 = t->tm_min / 10; - tod_2000.minute2 = t->tm_min % 10; - if (tod_2000.cntrl3 & TOD2000_CNTRL3_24HMODE) - tod_2000.hour1 = t->tm_hour / 10; - else if (t->tm_hour >= 12) - tod_2000.hour1 = TOD2000_HOUR1_PM + - (t->tm_hour - 12) / 10; - else - tod_2000.hour1 = t->tm_hour / 10; - tod_2000.hour2 = t->tm_hour % 10; - tod_2000.day1 = t->tm_mday / 10; - tod_2000.day2 = t->tm_mday % 10; - if (t->tm_wday != -1) - tod_2000.weekday = t->tm_wday; - tod_2000.month1 = (t->tm_mon + 1) / 10; - tod_2000.month2 = (t->tm_mon + 1) % 10; - if (t->tm_year >= 100) - t->tm_year -= 100; - tod_2000.year1 = t->tm_year / 10; - tod_2000.year2 = t->tm_year % 10; - } - - tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD; - - return 0; -} - -static int amiga_set_clock_mmss(unsigned long nowtime) -{ - short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; - - if (AMIGAHW_PRESENT(A3000_CLK)) { - tod_3000.cntrl1 = TOD3000_CNTRL1_HOLD; - - tod_3000.second1 = real_seconds / 10; - tod_3000.second2 = real_seconds % 10; - tod_3000.minute1 = real_minutes / 10; - tod_3000.minute2 = real_minutes % 10; - - tod_3000.cntrl1 = TOD3000_CNTRL1_FREE; - } else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ { - int cnt = 5; - - tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; - - while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt) { - tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD; - udelay(70); - tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; - --cnt; - } - - if (!cnt) - printk(KERN_INFO "set_clock_mmss: timed out waiting for RTC (0x%x)\n", tod_2000.cntrl1); - - tod_2000.second1 = real_seconds / 10; - tod_2000.second2 = real_seconds % 10; - tod_2000.minute1 = real_minutes / 10; - tod_2000.minute2 = real_minutes % 10; - - tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD; - } - - return 0; + return (ticks + offset) * 1000; } -static unsigned int amiga_get_ss(void) -{ - unsigned int s; - - if (AMIGAHW_PRESENT(A3000_CLK)) { - tod_3000.cntrl1 = TOD3000_CNTRL1_HOLD; - s = tod_3000.second1 * 10 + tod_3000.second2; - tod_3000.cntrl1 = TOD3000_CNTRL1_FREE; - } else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ { - s = tod_2000.second1 * 10 + tod_2000.second2; - } - return s; -} - -static NORET_TYPE void amiga_reset(void) - ATTRIB_NORET; +static void amiga_reset(void) __noreturn; static void amiga_reset(void) { @@ -784,26 +620,28 @@ static void amiga_mem_console_write(struct console *co, const char *s, static int __init amiga_savekmsg_setup(char *arg) { - static struct resource debug_res = { .name = "Debug" }; + bool registered; if (!MACH_IS_AMIGA || strcmp(arg, "mem")) - goto done; + return 0; - if (!AMIGAHW_PRESENT(CHIP_RAM)) { - printk("Warning: no chipram present for debugging\n"); - goto done; + if (amiga_chip_size < SAVEKMSG_MAXMEM) { + pr_err("Not enough chipram for debugging\n"); + return -ENOMEM; } - savekmsg = amiga_chip_alloc_res(SAVEKMSG_MAXMEM, &debug_res); + /* Just steal the block, the chipram allocator isn't functional yet */ + amiga_chip_size -= SAVEKMSG_MAXMEM; + savekmsg = ZTWO_VADDR(CHIP_PHYSADDR + amiga_chip_size); savekmsg->magic1 = SAVEKMSG_MAGIC1; savekmsg->magic2 = SAVEKMSG_MAGIC2; savekmsg->magicptr = ZTWO_PADDR(savekmsg); savekmsg->size = 0; + registered = !!amiga_console_driver.write; amiga_console_driver.write = amiga_mem_console_write; - register_console(&amiga_console_driver); - -done: + if (!registered) + register_console(&amiga_console_driver); return 0; } @@ -885,11 +723,16 @@ void amiga_serial_gets(struct console *co, char *s, int len) static int __init amiga_debug_setup(char *arg) { - if (MACH_IS_AMIGA && !strcmp(arg, "ser")) { - /* no initialization required (?) */ - amiga_console_driver.write = amiga_serial_console_write; + bool registered; + + if (!MACH_IS_AMIGA || strcmp(arg, "ser")) + return 0; + + /* no initialization required (?) */ + registered = !!amiga_console_driver.write; + amiga_console_driver.write = amiga_serial_console_write; + if (!registered) register_console(&amiga_console_driver); - } return 0; } |
