X-Git-Url: http://ftp.safe.ca/?p=safe%2Fjmp%2Flinux-2.6;a=blobdiff_plain;f=arch%2Fpowerpc%2Fplatforms%2Fchrp%2Fsetup.c;h=8553cc49e0d6a9e933eff573b4ea2b2190c87195;hp=9c08ff3222900d6e0475b01967e79abfc7cda018;hb=5a0e3ad6af8660be21ca98a971cd00f331318c05;hpb=8cffc6ac66a2b251df2490702923611aa4ac1fc5 diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 9c08ff3..8553cc4 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c @@ -15,31 +15,26 @@ #include #include #include -#include #include -#include #include #include #include #include #include #include -#include +#include #include #include #include -#include #include #include #include #include -#include #include #include #include #include -#include #include #include #include @@ -53,6 +48,7 @@ #include #include "chrp.h" +#include "gg2.h" void rtas_indicator_progress(char *, unsigned short); @@ -65,15 +61,11 @@ static struct mpic *chrp_mpic; DEFINE_PER_CPU(struct timer_list, heartbeat_timer); unsigned long event_scan_interval; -/* - * XXX this should be in xmon.h, but putting it there means xmon.h - * has to include (to get irqreturn_t), which - * causes all sorts of problems. -- paulus - */ -extern irqreturn_t xmon_irq(int, void *, struct pt_regs *); - extern unsigned long loops_per_jiffy; +/* To be replaced by RTAS when available */ +static unsigned int __iomem *briq_SPOR; + #ifdef CONFIG_SMP extern struct smp_ops_t chrp_smp_ops; #endif @@ -92,6 +84,15 @@ static const char *gg2_cachemodes[4] = { "Disabled", "Write-Through", "Copy-Back", "Transparent Mode" }; +static const char *chrp_names[] = { + "Unknown", + "","","", + "Motorola", + "IBM or Longtrail", + "Genesi Pegasos", + "Total Impact Briq" +}; + void chrp_show_cpuinfo(struct seq_file *m) { int i, sdramen; @@ -99,13 +100,13 @@ void chrp_show_cpuinfo(struct seq_file *m) struct device_node *root; const char *model = ""; - root = find_path_device("/"); + root = of_find_node_by_path("/"); if (root) - model = get_property(root, "model", NULL); + model = of_get_property(root, "model", NULL); seq_printf(m, "machine\t\t: CHRP %s\n", model); /* longtrail (goldengate) stuff */ - if (!strncmp(model, "IBM,LongTrail", 13)) { + if (model && !strncmp(model, "IBM,LongTrail", 13)) { /* VLSI VAS96011/12 `Golden Gate 2' */ /* Memory banks */ sdramen = (in_le32(gg2_pci_config_base + GG2_PCI_DRAM_CTRL) @@ -149,6 +150,7 @@ void chrp_show_cpuinfo(struct seq_file *m) gg2_cachetypes[(t>>2) & 3], gg2_cachemodes[t & 3]); } + of_node_put(root); } /* @@ -192,14 +194,21 @@ static void __init sio_fixup_irq(const char *name, u8 device, u8 level, static void __init sio_init(void) { struct device_node *root; + const char *model; + + root = of_find_node_by_path("/"); + if (!root) + return; - if ((root = find_path_device("/")) && - !strncmp(get_property(root, "model", NULL), "IBM,LongTrail", 13)) { + model = of_get_property(root, "model", NULL); + if (model && !strncmp(model, "IBM,LongTrail", 13)) { /* logical device 0 (KBC/Keyboard) */ sio_fixup_irq("keyboard", 0, 1, 2); /* select logical device 1 (KBC/Mouse) */ sio_fixup_irq("mouse", 1, 12, 2); } + + of_node_put(root); } @@ -212,13 +221,12 @@ static void __init pegasos_set_l2cr(void) return; /* Enable L2 cache if needed */ - np = find_type_devices("cpu"); + np = of_find_node_by_type(NULL, "cpu"); if (np != NULL) { - unsigned int *l2cr = (unsigned int *) - get_property (np, "l2cr", NULL); + const unsigned int *l2cr = of_get_property(np, "l2cr", NULL); if (l2cr == NULL) { printk ("Pegasos l2cr : no cpu l2cr property found\n"); - return; + goto out; } if (!((*l2cr) & 0x80000000)) { printk ("Pegasos l2cr : L2 cache was not active, " @@ -227,29 +235,96 @@ static void __init pegasos_set_l2cr(void) _set_L2CR((*l2cr) | 0x80000000); } } +out: + of_node_put(np); +} + +static void briq_restart(char *cmd) +{ + local_irq_disable(); + if (briq_SPOR) + out_be32(briq_SPOR, 0); + for(;;); +} + +/* + * Per default, input/output-device points to the keyboard/screen + * If no card is installed, the built-in serial port is used as a fallback. + * But unfortunately, the firmware does not connect /chosen/{stdin,stdout} + * the the built-in serial node. Instead, a /failsafe node is created. + */ +static void chrp_init_early(void) +{ + struct device_node *node; + const char *property; + + if (strstr(cmd_line, "console=")) + return; + /* find the boot console from /chosen/stdout */ + if (!of_chosen) + return; + node = of_find_node_by_path("/"); + if (!node) + return; + property = of_get_property(node, "model", NULL); + if (!property) + goto out_put; + if (strcmp(property, "Pegasos2")) + goto out_put; + /* this is a Pegasos2 */ + property = of_get_property(of_chosen, "linux,stdout-path", NULL); + if (!property) + goto out_put; + of_node_put(node); + node = of_find_node_by_path(property); + if (!node) + return; + property = of_get_property(node, "device_type", NULL); + if (!property) + goto out_put; + if (strcmp(property, "serial")) + goto out_put; + /* + * The 9pin connector is either /failsafe + * or /pci@80000000/isa@C/serial@i2F8 + * The optional graphics card has also type 'serial' in VGA mode. + */ + property = of_get_property(node, "name", NULL); + if (!property) + goto out_put; + if (!strcmp(property, "failsafe") || !strcmp(property, "serial")) + add_preferred_console("ttyS", 0, NULL); +out_put: + of_node_put(node); } void __init chrp_setup_arch(void) { - struct device_node *root = find_path_device ("/"); - char *machine = NULL; + struct device_node *root = of_find_node_by_path("/"); + const char *machine = NULL; /* init to some ~sane value until calibrate_delay() runs */ loops_per_jiffy = 50000000/HZ; if (root) - machine = get_property(root, "model", NULL); + machine = of_get_property(root, "model", NULL); if (machine && strncmp(machine, "Pegasos", 7) == 0) { _chrp_type = _CHRP_Pegasos; } else if (machine && strncmp(machine, "IBM", 3) == 0) { _chrp_type = _CHRP_IBM; } else if (machine && strncmp(machine, "MOT", 3) == 0) { _chrp_type = _CHRP_Motorola; + } else if (machine && strncmp(machine, "TotalImpact,BRIQ-1", 18) == 0) { + _chrp_type = _CHRP_briq; + /* Map the SPOR register on briq and change the restart hook */ + briq_SPOR = ioremap(0xff0000e8, 4); + ppc_md.restart = briq_restart; } else { /* Let's assume it is an IBM chrp if all else fails */ _chrp_type = _CHRP_IBM; } - printk("chrp type = %x\n", _chrp_type); + of_node_put(root); + printk("chrp type = %x [%s]\n", _chrp_type, chrp_names[_chrp_type]); rtas_initialize(); if (rtas_token("display-character") >= 0) @@ -262,16 +337,6 @@ void __init chrp_setup_arch(void) ppc_md.set_rtc_time = rtas_set_rtc_time; } -#ifdef CONFIG_BLK_DEV_INITRD - /* this is fine for chrp */ - initrd_below_start_ok = 1; - - if (initrd_start) - ROOT_DEV = Root_RAM0; - else -#endif - ROOT_DEV = Root_SDA2; /* sda2 (sda1 is for the kernel) */ - /* On pegasos, enable the L2 cache if not already done by OF */ pegasos_set_l2cr(); @@ -298,25 +363,11 @@ void __init chrp_setup_arch(void) if (ppc_md.progress) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0); } -void -chrp_event_scan(unsigned long unused) -{ - unsigned char log[1024]; - int ret = 0; - - /* XXX: we should loop until the hardware says no more error logs -- Cort */ - rtas_call(rtas_token("event-scan"), 4, 1, &ret, 0xffffffff, 0, - __pa(log), 1024); - mod_timer(&__get_cpu_var(heartbeat_timer), - jiffies + event_scan_interval); -} - -static void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc, - struct pt_regs *regs) +static void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc) { - unsigned int cascade_irq = i8259_irq(regs); + unsigned int cascade_irq = i8259_irq(); if (cascade_irq != NO_IRQ) - generic_handle_irq(cascade_irq, regs); + generic_handle_irq(cascade_irq); desc->chip->eoi(irq); } @@ -328,7 +379,7 @@ static void __init chrp_find_openpic(void) struct device_node *np, *root; int len, i, j; int isu_size, idu_size; - unsigned int *iranges, *opprop = NULL; + const unsigned int *iranges, *opprop = NULL; int oplen = 0; unsigned long opaddr; int na = 1; @@ -338,9 +389,8 @@ static void __init chrp_find_openpic(void) return; root = of_find_node_by_path("/"); if (root) { - opprop = (unsigned int *) get_property - (root, "platform-open-pic", &oplen); - na = prom_n_addr_cells(root); + opprop = of_get_property(root, "platform-open-pic", &oplen); + na = of_n_addr_cells(root); } if (opprop && oplen >= na * sizeof(unsigned int)) { opaddr = opprop[na-1]; /* assume 32-bit */ @@ -356,7 +406,7 @@ static void __init chrp_find_openpic(void) printk(KERN_INFO "OpenPIC at %lx\n", opaddr); - iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len); + iranges = of_get_property(np, "interrupt-ranges", &len); if (iranges == NULL) len = 0; /* non-distributed mpic */ else @@ -405,10 +455,9 @@ static void __init chrp_find_openpic(void) of_node_put(np); } -#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) +#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_XMON) static struct irqaction xmon_irqaction = { .handler = xmon_irq, - .mask = CPU_MASK_NONE, .name = "XMON break", }; #endif @@ -421,7 +470,7 @@ static void __init chrp_find_8259(void) /* Look for cascade */ for_each_node_by_type(np, "interrupt-controller") - if (device_is_compatible(np, "chrp,iic")) { + if (of_device_is_compatible(np, "chrp,iic")) { pic = np; break; } @@ -441,22 +490,25 @@ static void __init chrp_find_8259(void) * Also, Pegasos-type platforms don't have a proper node to start * from anyway */ - for (np = find_devices("pci"); np != NULL; np = np->next) { - unsigned int *addrp = (unsigned int *) - get_property(np, "8259-interrupt-acknowledge", NULL); + for_each_node_by_name(np, "pci") { + const unsigned int *addrp = of_get_property(np, + "8259-interrupt-acknowledge", NULL); if (addrp == NULL) continue; - chrp_int_ack = addrp[prom_n_addr_cells(np)-1]; + chrp_int_ack = addrp[of_n_addr_cells(np)-1]; break; } + of_node_put(np); if (np == NULL) printk(KERN_WARNING "Cannot find PCI interrupt acknowledge" " address, polling\n"); i8259_init(pic, chrp_int_ack); - if (ppc_md.get_irq == NULL) + if (ppc_md.get_irq == NULL) { ppc_md.get_irq = i8259_irq; + irq_set_default_host(i8259_get_host()); + } if (chrp_mpic != NULL) { cascade_irq = irq_of_parse_and_map(pic, 0); if (cascade_irq == NO_IRQ) @@ -469,7 +521,7 @@ static void __init chrp_find_8259(void) void __init chrp_init_IRQ(void) { -#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) +#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_XMON) struct device_node *kbd; #endif chrp_find_openpic(); @@ -486,13 +538,14 @@ void __init chrp_init_IRQ(void) if (_chrp_type == _CHRP_Pegasos) ppc_md.get_irq = i8259_irq; -#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) +#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_XMON) /* see if there is a keyboard in the device tree with a parent of type "adb" */ - for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next) + for_each_node_by_name(kbd, "keyboard") if (kbd->parent && kbd->parent->type && strcmp(kbd->parent->type, "adb") == 0) break; + of_node_put(kbd); if (kbd) setup_irq(HYDRA_INT_ADB_NMI, &xmon_irqaction); #endif @@ -501,9 +554,6 @@ void __init chrp_init_IRQ(void) void __init chrp_init2(void) { - struct device_node *device; - unsigned int *p = NULL; - #ifdef CONFIG_NVRAM chrp_nvram_init(); #endif @@ -515,40 +565,6 @@ chrp_init2(void) request_region(0x80,0x10,"dma page reg"); request_region(0xc0,0x20,"dma2"); - /* Get the event scan rate for the rtas so we know how - * often it expects a heartbeat. -- Cort - */ - device = find_devices("rtas"); - if (device) - p = (unsigned int *) get_property - (device, "rtas-event-scan-rate", NULL); - if (p && *p) { - /* - * Arrange to call chrp_event_scan at least *p times - * per minute. We use 59 rather than 60 here so that - * the rate will be slightly higher than the minimum. - * This all assumes we don't do hotplug CPU on any - * machine that needs the event scans done. - */ - unsigned long interval, offset; - int cpu, ncpus; - struct timer_list *timer; - - interval = HZ * 59 / *p; - offset = HZ; - ncpus = num_online_cpus(); - event_scan_interval = ncpus * interval; - for (cpu = 0; cpu < ncpus; ++cpu) { - timer = &per_cpu(heartbeat_timer, cpu); - setup_timer(timer, chrp_event_scan, 0); - timer->expires = jiffies + offset; - add_timer_on(timer, cpu); - offset += interval; - } - printk("RTAS Event Scan Rate: %u (%lu jiffies)\n", - *p, interval); - } - if (ppc_md.progress) ppc_md.progress(" Have fun! ", 0x7777); } @@ -565,7 +581,6 @@ static int __init chrp_probe(void) ISA_DMA_THRESHOLD = ~0L; DMA_MODE_READ = 0x44; DMA_MODE_WRITE = 0x48; - isa_io_base = CHRP_ISA_IO_BASE; /* default value */ return 1; } @@ -575,9 +590,9 @@ define_machine(chrp) { .probe = chrp_probe, .setup_arch = chrp_setup_arch, .init = chrp_init2, + .init_early = chrp_init_early, .show_cpuinfo = chrp_show_cpuinfo, .init_IRQ = chrp_init_IRQ, - .pcibios_fixup = chrp_pcibios_fixup, .restart = rtas_restart, .power_off = rtas_power_off, .halt = rtas_halt,