aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-20 20:35:25 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-20 20:35:25 -0400
commitc2e68052429fdf87702fccd272951282bef1c60a (patch)
treeb9f3bf3918526af068ed264190a85fb18dd3d8b0
parentd6f410bdbcb435c744c4f8259d6659ae2c6e447a (diff)
parent1256efd5519a8eca2dfa6039ce5cf58f44d1626d (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6: [SPARC64]: fix section mismatch warning in mdesc.c [SPARC64]: fix section mismatch warning in pci_sunv4 [SPARC64]: Stop using drivers/char/rtc.c [SPARC64]: Convert parport to of_platform_driver. [SPARC]: Implement fb_is_primary_device(). [SPARC64]: Fix virq decomposition. [SPARC64]: Use KERN_ERR in IRQ manipulation error printks. [SPARC64]: Do not flood log with failed DS messages. [SPARC64]: Add proper multicast support to VNET driver. [SPARC64]: Handle multiple domain-services-port nodes properly. [SPARC64]: Improve VIO device naming further. [SPARC]: Make sure dev_archdata is filled in for all devices. [SPARC]: Define minimal struct dev_archdata, similarly to sparc64. [SPARC]: Fix serial console device detection.
-rw-r--r--arch/sparc/kernel/ebus.c5
-rw-r--r--arch/sparc/kernel/of_device.c5
-rw-r--r--arch/sparc/kernel/process.c8
-rw-r--r--arch/sparc/kernel/prom.c131
-rw-r--r--arch/sparc/kernel/setup.c65
-rw-r--r--arch/sparc/prom/console.c116
-rw-r--r--arch/sparc/prom/misc.c4
-rw-r--r--arch/sparc64/kernel/ds.c249
-rw-r--r--arch/sparc64/kernel/ebus.c5
-rw-r--r--arch/sparc64/kernel/irq.c72
-rw-r--r--arch/sparc64/kernel/isa.c5
-rw-r--r--arch/sparc64/kernel/mdesc.c6
-rw-r--r--arch/sparc64/kernel/of_device.c5
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c4
-rw-r--r--arch/sparc64/kernel/power.c2
-rw-r--r--arch/sparc64/kernel/process.c6
-rw-r--r--arch/sparc64/kernel/prom.c56
-rw-r--r--arch/sparc64/kernel/setup.c70
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c1
-rw-r--r--arch/sparc64/kernel/time.c79
-rw-r--r--arch/sparc64/kernel/vio.c35
-rw-r--r--arch/sparc64/prom/console.c85
-rw-r--r--arch/sparc64/prom/misc.c4
-rw-r--r--arch/sparc64/prom/tree.c8
-rw-r--r--drivers/char/Kconfig2
-rw-r--r--drivers/char/rtc.c30
-rw-r--r--drivers/net/sunvnet.c137
-rw-r--r--drivers/net/sunvnet.h11
-rw-r--r--drivers/sbus/sbus.c5
-rw-r--r--drivers/serial/suncore.c123
-rw-r--r--drivers/serial/suncore.h2
-rw-r--r--drivers/serial/sunhv.c13
-rw-r--r--drivers/serial/sunsab.c22
-rw-r--r--drivers/serial/sunsu.c23
-rw-r--r--drivers/serial/sunzilog.c24
-rw-r--r--drivers/video/aty/atyfb_base.c4
-rw-r--r--drivers/video/igafb.c4
-rw-r--r--include/asm-sparc/device.h14
-rw-r--r--include/asm-sparc/fb.h9
-rw-r--r--include/asm-sparc/oplib.h26
-rw-r--r--include/asm-sparc/prom.h4
-rw-r--r--include/asm-sparc64/fb.h9
-rw-r--r--include/asm-sparc64/oplib.h28
-rw-r--r--include/asm-sparc64/parport.h233
-rw-r--r--include/asm-sparc64/prom.h4
-rw-r--r--include/asm-sparc64/system.h6
46 files changed, 926 insertions, 833 deletions
diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c
index 7bb86b9cdaa3..ac352eb6dff3 100644
--- a/arch/sparc/kernel/ebus.c
+++ b/arch/sparc/kernel/ebus.c
@@ -148,6 +148,7 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d
148{ 148{
149 const struct linux_prom_registers *regs; 149 const struct linux_prom_registers *regs;
150 struct linux_ebus_child *child; 150 struct linux_ebus_child *child;
151 struct dev_archdata *sd;
151 const int *irqs; 152 const int *irqs;
152 int i, n, len; 153 int i, n, len;
153 unsigned long baseaddr; 154 unsigned long baseaddr;
@@ -234,6 +235,10 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d
234 } 235 }
235 } 236 }
236 237
238 sd = &dev->ofdev.dev.archdata;
239 sd->prom_node = dp;
240 sd->op = &dev->ofdev;
241
237 dev->ofdev.node = dp; 242 dev->ofdev.node = dp;
238 dev->ofdev.dev.parent = &dev->bus->ofdev.dev; 243 dev->ofdev.dev.parent = &dev->bus->ofdev.dev;
239 dev->ofdev.dev.bus = &ebus_bus_type; 244 dev->ofdev.dev.bus = &ebus_bus_type;
diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c
index 7176040caba0..36383f73d685 100644
--- a/arch/sparc/kernel/of_device.c
+++ b/arch/sparc/kernel/of_device.c
@@ -420,11 +420,16 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
420{ 420{
421 struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL); 421 struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL);
422 const struct linux_prom_irqs *intr; 422 const struct linux_prom_irqs *intr;
423 struct dev_archdata *sd;
423 int len, i; 424 int len, i;
424 425
425 if (!op) 426 if (!op)
426 return NULL; 427 return NULL;
427 428
429 sd = &op->dev.archdata;
430 sd->prom_node = dp;
431 sd->op = op;
432
428 op->node = dp; 433 op->node = dp;
429 434
430 op->clock_freq = of_getintprop_default(dp, "clock-frequency", 435 op->clock_freq = of_getintprop_default(dp, "clock-frequency",
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index 8c37f8f5adb7..33f7a3ddb104 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -39,6 +39,7 @@
39#include <asm/processor.h> 39#include <asm/processor.h>
40#include <asm/psr.h> 40#include <asm/psr.h>
41#include <asm/elf.h> 41#include <asm/elf.h>
42#include <asm/prom.h>
42#include <asm/unistd.h> 43#include <asm/unistd.h>
43 44
44/* 45/*
@@ -150,7 +151,7 @@ void machine_halt(void)
150 local_irq_enable(); 151 local_irq_enable();
151 mdelay(8); 152 mdelay(8);
152 local_irq_disable(); 153 local_irq_disable();
153 if (!serial_console && prom_palette) 154 if (prom_palette)
154 prom_palette (1); 155 prom_palette (1);
155 prom_halt(); 156 prom_halt();
156 panic("Halt failed!"); 157 panic("Halt failed!");
@@ -166,7 +167,7 @@ void machine_restart(char * cmd)
166 167
167 p = strchr (reboot_command, '\n'); 168 p = strchr (reboot_command, '\n');
168 if (p) *p = 0; 169 if (p) *p = 0;
169 if (!serial_console && prom_palette) 170 if (prom_palette)
170 prom_palette (1); 171 prom_palette (1);
171 if (cmd) 172 if (cmd)
172 prom_reboot(cmd); 173 prom_reboot(cmd);
@@ -179,7 +180,8 @@ void machine_restart(char * cmd)
179void machine_power_off(void) 180void machine_power_off(void)
180{ 181{
181#ifdef CONFIG_SUN_AUXIO 182#ifdef CONFIG_SUN_AUXIO
182 if (auxio_power_register && (!serial_console || scons_pwroff)) 183 if (auxio_power_register &&
184 (strcmp(of_console_device->type, "serial") || scons_pwroff))
183 *auxio_power_register |= AUXIO_POWER_OFF; 185 *auxio_power_register |= AUXIO_POWER_OFF;
184#endif 186#endif
185 machine_halt(); 187 machine_halt();
diff --git a/arch/sparc/kernel/prom.c b/arch/sparc/kernel/prom.c
index 012f98346bcd..e3a537650db1 100644
--- a/arch/sparc/kernel/prom.c
+++ b/arch/sparc/kernel/prom.c
@@ -397,6 +397,135 @@ static struct device_node * __init build_tree(struct device_node *parent, phandl
397 return dp; 397 return dp;
398} 398}
399 399
400struct device_node *of_console_device;
401EXPORT_SYMBOL(of_console_device);
402
403char *of_console_path;
404EXPORT_SYMBOL(of_console_path);
405
406char *of_console_options;
407EXPORT_SYMBOL(of_console_options);
408
409extern void restore_current(void);
410
411static void __init of_console_init(void)
412{
413 char *msg = "OF stdout device is: %s\n";
414 struct device_node *dp;
415 unsigned long flags;
416 const char *type;
417 phandle node;
418 int skip, fd;
419
420 of_console_path = prom_early_alloc(256);
421
422 switch (prom_vers) {
423 case PROM_V0:
424 case PROM_SUN4:
425 skip = 0;
426 switch (*romvec->pv_stdout) {
427 case PROMDEV_SCREEN:
428 type = "display";
429 break;
430
431 case PROMDEV_TTYB:
432 skip = 1;
433 /* FALLTHRU */
434
435 case PROMDEV_TTYA:
436 type = "serial";
437 break;
438
439 default:
440 prom_printf("Invalid PROM_V0 stdout value %u\n",
441 *romvec->pv_stdout);
442 prom_halt();
443 }
444
445 for_each_node_by_type(dp, type) {
446 if (!skip--)
447 break;
448 }
449 if (!dp) {
450 prom_printf("Cannot find PROM_V0 console node.\n");
451 prom_halt();
452 }
453 of_console_device = dp;
454
455 strcpy(of_console_path, dp->full_name);
456 if (!strcmp(type, "serial")) {
457 strcat(of_console_path,
458 (skip ? ":b" : ":a"));
459 }
460 break;
461
462 default:
463 case PROM_V2:
464 case PROM_V3:
465 fd = *romvec->pv_v2bootargs.fd_stdout;
466
467 spin_lock_irqsave(&prom_lock, flags);
468 node = (*romvec->pv_v2devops.v2_inst2pkg)(fd);
469 restore_current();
470 spin_unlock_irqrestore(&prom_lock, flags);
471
472 if (!node) {
473 prom_printf("Cannot resolve stdout node from "
474 "instance %08x.\n", fd);
475 prom_halt();
476 }
477 dp = of_find_node_by_phandle(node);
478 type = of_get_property(dp, "device_type", NULL);
479
480 if (!type) {
481 prom_printf("Console stdout lacks "
482 "device_type property.\n");
483 prom_halt();
484 }
485
486 if (strcmp(type, "display") && strcmp(type, "serial")) {
487 prom_printf("Console device_type is neither display "
488 "nor serial.\n");
489 prom_halt();
490 }
491
492 of_console_device = dp;
493
494 if (prom_vers == PROM_V2) {
495 strcpy(of_console_path, dp->full_name);
496 switch (*romvec->pv_stdout) {
497 case PROMDEV_TTYA:
498 strcat(of_console_path, ":a");
499 break;
500 case PROMDEV_TTYB:
501 strcat(of_console_path, ":b");
502 break;
503 }
504 } else {
505 const char *path;
506
507 dp = of_find_node_by_path("/");
508 path = of_get_property(dp, "stdout-path", NULL);
509 if (!path) {
510 prom_printf("No stdout-path in root node.\n");
511 prom_halt();
512 }
513 strcpy(of_console_path, path);
514 }
515 break;
516 }
517
518 of_console_options = strrchr(of_console_path, ':');
519 if (of_console_options) {
520 of_console_options++;
521 if (*of_console_options == '\0')
522 of_console_options = NULL;
523 }
524
525 prom_printf(msg, of_console_path);
526 printk(msg, of_console_path);
527}
528
400void __init prom_build_devicetree(void) 529void __init prom_build_devicetree(void)
401{ 530{
402 struct device_node **nextp; 531 struct device_node **nextp;
@@ -409,6 +538,8 @@ void __init prom_build_devicetree(void)
409 allnodes->child = build_tree(allnodes, 538 allnodes->child = build_tree(allnodes,
410 prom_getchild(allnodes->node), 539 prom_getchild(allnodes->node),
411 &nextp); 540 &nextp);
541 of_console_init();
542
412 printk("PROM: Built device tree with %u bytes of memory.\n", 543 printk("PROM: Built device tree with %u bytes of memory.\n",
413 prom_early_allocated); 544 prom_early_allocated);
414} 545}
diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c
index 64c0ed98820a..f8228383895a 100644
--- a/arch/sparc/kernel/setup.c
+++ b/arch/sparc/kernel/setup.c
@@ -146,31 +146,6 @@ static void __init process_switch(char c)
146 } 146 }
147} 147}
148 148
149static void __init process_console(char *commands)
150{
151 serial_console = 0;
152 commands += 8;
153 /* Linux-style serial */
154 if (!strncmp(commands, "ttyS", 4))
155 serial_console = simple_strtoul(commands + 4, NULL, 10) + 1;
156 else if (!strncmp(commands, "tty", 3)) {
157 char c = *(commands + 3);
158 /* Solaris-style serial */
159 if (c == 'a' || c == 'b')
160 serial_console = c - 'a' + 1;
161 /* else Linux-style fbcon, not serial */
162 }
163#if defined(CONFIG_PROM_CONSOLE)
164 if (!strncmp(commands, "prom", 4)) {
165 char *p;
166
167 for (p = commands - 8; *p && *p != ' '; p++)
168 *p = ' ';
169 conswitchp = &prom_con;
170 }
171#endif
172}
173
174static void __init boot_flags_init(char *commands) 149static void __init boot_flags_init(char *commands)
175{ 150{
176 while (*commands) { 151 while (*commands) {
@@ -187,9 +162,7 @@ static void __init boot_flags_init(char *commands)
187 process_switch(*commands++); 162 process_switch(*commands++);
188 continue; 163 continue;
189 } 164 }
190 if (!strncmp(commands, "console=", 8)) { 165 if (!strncmp(commands, "mem=", 4)) {
191 process_console(commands);
192 } else if (!strncmp(commands, "mem=", 4)) {
193 /* 166 /*
194 * "mem=XXX[kKmM] overrides the PROM-reported 167 * "mem=XXX[kKmM] overrides the PROM-reported
195 * memory size. 168 * memory size.
@@ -341,41 +314,6 @@ void __init setup_arch(char **cmdline_p)
341 smp_setup_cpu_possible_map(); 314 smp_setup_cpu_possible_map();
342} 315}
343 316
344static int __init set_preferred_console(void)
345{
346 int idev, odev;
347
348 /* The user has requested a console so this is already set up. */
349 if (serial_console >= 0)
350 return -EBUSY;
351
352 idev = prom_query_input_device();
353 odev = prom_query_output_device();
354 if (idev == PROMDEV_IKBD && odev == PROMDEV_OSCREEN) {
355 serial_console = 0;
356 } else if (idev == PROMDEV_ITTYA && odev == PROMDEV_OTTYA) {
357 serial_console = 1;
358 } else if (idev == PROMDEV_ITTYB && odev == PROMDEV_OTTYB) {
359 serial_console = 2;
360 } else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OTTYA) {
361 prom_printf("MrCoffee ttya\n");
362 serial_console = 1;
363 } else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OSCREEN) {
364 serial_console = 0;
365 prom_printf("MrCoffee keyboard\n");
366 } else {
367 prom_printf("Confusing console (idev %d, odev %d)\n",
368 idev, odev);
369 serial_console = 1;
370 }
371
372 if (serial_console)
373 return add_preferred_console("ttyS", serial_console - 1, NULL);
374
375 return -ENODEV;
376}
377console_initcall(set_preferred_console);
378
379extern char *sparc_cpu_type; 317extern char *sparc_cpu_type;
380extern char *sparc_fpu_type; 318extern char *sparc_fpu_type;
381 319
@@ -461,7 +399,6 @@ void sun_do_break(void)
461 prom_cmdline(); 399 prom_cmdline();
462} 400}
463 401
464int serial_console = -1;
465int stop_a_enabled = 1; 402int stop_a_enabled = 1;
466 403
467static int __init topology_init(void) 404static int __init topology_init(void)
diff --git a/arch/sparc/prom/console.c b/arch/sparc/prom/console.c
index 4e6e41d3291d..8d1cfb0d5068 100644
--- a/arch/sparc/prom/console.c
+++ b/arch/sparc/prom/console.c
@@ -102,119 +102,3 @@ prom_putchar(char c)
102 while(prom_nbputchar(c) == -1) ; 102 while(prom_nbputchar(c) == -1) ;
103 return; 103 return;
104} 104}
105
106/* Query for input device type */
107enum prom_input_device
108prom_query_input_device(void)
109{
110 unsigned long flags;
111 int st_p;
112 char propb[64];
113 char *p;
114 int propl;
115
116 switch(prom_vers) {
117 case PROM_V0:
118 case PROM_V2:
119 case PROM_SUN4:
120 default:
121 switch(*romvec->pv_stdin) {
122 case PROMDEV_KBD: return PROMDEV_IKBD;
123 case PROMDEV_TTYA: return PROMDEV_ITTYA;
124 case PROMDEV_TTYB: return PROMDEV_ITTYB;
125 default:
126 return PROMDEV_I_UNK;
127 };
128 case PROM_V3:
129 spin_lock_irqsave(&prom_lock, flags);
130 st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdin);
131 restore_current();
132 spin_unlock_irqrestore(&prom_lock, flags);
133 if(prom_node_has_property(st_p, "keyboard"))
134 return PROMDEV_IKBD;
135 if (prom_getproperty(st_p, "name", propb, sizeof(propb)) != -1) {
136 if(strncmp(propb, "keyboard", sizeof("serial")) == 0)
137 return PROMDEV_IKBD;
138 }
139 if (prom_getproperty(st_p, "device_type", propb, sizeof(propb)) != -1) {
140 if(strncmp(propb, "serial", sizeof("serial")))
141 return PROMDEV_I_UNK;
142 }
143 propl = prom_getproperty(prom_root_node, "stdin-path", propb, sizeof(propb));
144 if(propl > 2) {
145 p = propb;
146 while(*p) p++; p -= 2;
147 if(p[0] == ':') {
148 if(p[1] == 'a')
149 return PROMDEV_ITTYA;
150 else if(p[1] == 'b')
151 return PROMDEV_ITTYB;
152 }
153 }
154 return PROMDEV_I_UNK;
155 }
156}
157
158/* Query for output device type */
159
160enum prom_output_device
161prom_query_output_device(void)
162{
163 unsigned long flags;
164 int st_p;
165 char propb[64];
166 char *p;
167 int propl;
168
169 switch(prom_vers) {
170 case PROM_V0:
171 case PROM_SUN4:
172 switch(*romvec->pv_stdin) {
173 case PROMDEV_SCREEN: return PROMDEV_OSCREEN;
174 case PROMDEV_TTYA: return PROMDEV_OTTYA;
175 case PROMDEV_TTYB: return PROMDEV_OTTYB;
176 };
177 break;
178 case PROM_V2:
179 case PROM_V3:
180 spin_lock_irqsave(&prom_lock, flags);
181 st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdout);
182 restore_current();
183 spin_unlock_irqrestore(&prom_lock, flags);
184 propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb));
185 if (propl == sizeof("display") &&
186 strncmp("display", propb, sizeof("display")) == 0)
187 {
188 return PROMDEV_OSCREEN;
189 }
190 if(prom_vers == PROM_V3) {
191 if(propl >= 0 &&
192 strncmp("serial", propb, sizeof("serial")) != 0)
193 return PROMDEV_O_UNK;
194 propl = prom_getproperty(prom_root_node, "stdout-path",
195 propb, sizeof(propb));
196 if(propl == CON_SIZE_JMC &&
197 strncmp(propb, con_name_jmc, CON_SIZE_JMC) == 0)
198 return PROMDEV_OTTYA;
199 if(propl > 2) {
200 p = propb;
201 while(*p) p++; p-= 2;
202 if(p[0]==':') {
203 if(p[1] == 'a')
204 return PROMDEV_OTTYA;
205 else if(p[1] == 'b')
206 return PROMDEV_OTTYB;
207 }
208 }
209 } else {
210 switch(*romvec->pv_stdin) {
211 case PROMDEV_TTYA: return PROMDEV_OTTYA;
212 case PROMDEV_TTYB: return PROMDEV_OTTYB;
213 };
214 }
215 break;
216 default:
217 ;
218 };
219 return PROMDEV_O_UNK;
220}
diff --git a/arch/sparc/prom/misc.c b/arch/sparc/prom/misc.c
index 1942c7c05cb1..37cff5f54704 100644
--- a/arch/sparc/prom/misc.c
+++ b/arch/sparc/prom/misc.c
@@ -58,7 +58,7 @@ prom_cmdline(void)
58 extern void install_linux_ticker(void); 58 extern void install_linux_ticker(void);
59 unsigned long flags; 59 unsigned long flags;
60 60
61 if(!serial_console && prom_palette) 61 if (prom_palette)
62 prom_palette (1); 62 prom_palette (1);
63 spin_lock_irqsave(&prom_lock, flags); 63 spin_lock_irqsave(&prom_lock, flags);
64 install_obp_ticker(); 64 install_obp_ticker();
@@ -69,7 +69,7 @@ prom_cmdline(void)
69#ifdef CONFIG_SUN_AUXIO 69#ifdef CONFIG_SUN_AUXIO
70 set_auxio(AUXIO_LED, 0); 70 set_auxio(AUXIO_LED, 0);
71#endif 71#endif
72 if(!serial_console && prom_palette) 72 if (prom_palette)
73 prom_palette (0); 73 prom_palette (0);
74} 74}
75 75
diff --git a/arch/sparc64/kernel/ds.c b/arch/sparc64/kernel/ds.c
index 1a2062ecb0bc..9f472a79d37e 100644
--- a/arch/sparc64/kernel/ds.c
+++ b/arch/sparc64/kernel/ds.c
@@ -124,10 +124,11 @@ struct ds_data_nack {
124 __u64 result; 124 __u64 result;
125}; 125};
126 126
127struct ds_info;
127struct ds_cap_state { 128struct ds_cap_state {
128 __u64 handle; 129 __u64 handle;
129 130
130 void (*data)(struct ldc_channel *lp, 131 void (*data)(struct ds_info *dp,
131 struct ds_cap_state *cp, 132 struct ds_cap_state *cp,
132 void *buf, int len); 133 void *buf, int len);
133 134
@@ -139,27 +140,27 @@ struct ds_cap_state {
139#define CAP_STATE_REGISTERED 0x02 140#define CAP_STATE_REGISTERED 0x02
140}; 141};
141 142
142static void md_update_data(struct ldc_channel *lp, struct ds_cap_state *cp, 143static void md_update_data(struct ds_info *dp, struct ds_cap_state *cp,
143 void *buf, int len); 144 void *buf, int len);
144static void domain_shutdown_data(struct ldc_channel *lp, 145static void domain_shutdown_data(struct ds_info *dp,
145 struct ds_cap_state *cp, 146 struct ds_cap_state *cp,
146 void *buf, int len); 147 void *buf, int len);
147static void domain_panic_data(struct ldc_channel *lp, 148static void domain_panic_data(struct ds_info *dp,
148 struct ds_cap_state *cp, 149 struct ds_cap_state *cp,
149 void *buf, int len); 150 void *buf, int len);
150#ifdef CONFIG_HOTPLUG_CPU 151#ifdef CONFIG_HOTPLUG_CPU
151static void dr_cpu_data(struct ldc_channel *lp, 152static void dr_cpu_data(struct ds_info *dp,
152 struct ds_cap_state *cp, 153 struct ds_cap_state *cp,
153 void *buf, int len); 154 void *buf, int len);
154#endif 155#endif
155static void ds_pri_data(struct ldc_channel *lp, 156static void ds_pri_data(struct ds_info *dp,
156 struct ds_cap_state *cp, 157 struct ds_cap_state *cp,
157 void *buf, int len); 158 void *buf, int len);
158static void ds_var_data(struct ldc_channel *lp, 159static void ds_var_data(struct ds_info *dp,
159 struct ds_cap_state *cp, 160 struct ds_cap_state *cp,
160 void *buf, int len); 161 void *buf, int len);
161 162
162struct ds_cap_state ds_states[] = { 163struct ds_cap_state ds_states_template[] = {
163 { 164 {
164 .service_id = "md-update", 165 .service_id = "md-update",
165 .data = md_update_data, 166 .data = md_update_data,
@@ -200,30 +201,38 @@ struct ds_info {
200#define DS_HS_START 0x01 201#define DS_HS_START 0x01
201#define DS_HS_DONE 0x02 202#define DS_HS_DONE 0x02
202 203
204 u64 id;
205
203 void *rcv_buf; 206 void *rcv_buf;
204 int rcv_buf_len; 207 int rcv_buf_len;
208
209 struct ds_cap_state *ds_states;
210 int num_ds_states;
211
212 struct ds_info *next;
205}; 213};
206 214
207static struct ds_info *ds_info; 215static struct ds_info *ds_info_list;
208 216
209static struct ds_cap_state *find_cap(u64 handle) 217static struct ds_cap_state *find_cap(struct ds_info *dp, u64 handle)
210{ 218{
211 unsigned int index = handle >> 32; 219 unsigned int index = handle >> 32;
212 220
213 if (index >= ARRAY_SIZE(ds_states)) 221 if (index >= dp->num_ds_states)
214 return NULL; 222 return NULL;
215 return &ds_states[index]; 223 return &dp->ds_states[index];
216} 224}
217 225
218static struct ds_cap_state *find_cap_by_string(const char *name) 226static struct ds_cap_state *find_cap_by_string(struct ds_info *dp,
227 const char *name)
219{ 228{
220 int i; 229 int i;
221 230
222 for (i = 0; i < ARRAY_SIZE(ds_states); i++) { 231 for (i = 0; i < dp->num_ds_states; i++) {
223 if (strcmp(ds_states[i].service_id, name)) 232 if (strcmp(dp->ds_states[i].service_id, name))
224 continue; 233 continue;
225 234
226 return &ds_states[i]; 235 return &dp->ds_states[i];
227 } 236 }
228 return NULL; 237 return NULL;
229} 238}
@@ -264,10 +273,11 @@ struct ds_md_update_res {
264 __u32 result; 273 __u32 result;
265}; 274};
266 275
267static void md_update_data(struct ldc_channel *lp, 276static void md_update_data(struct ds_info *dp,
268 struct ds_cap_state *dp, 277 struct ds_cap_state *cp,
269 void *buf, int len) 278 void *buf, int len)
270{ 279{
280 struct ldc_channel *lp = dp->lp;
271 struct ds_data *dpkt = buf; 281 struct ds_data *dpkt = buf;
272 struct ds_md_update_req *rp; 282 struct ds_md_update_req *rp;
273 struct { 283 struct {
@@ -277,14 +287,14 @@ static void md_update_data(struct ldc_channel *lp,
277 287
278 rp = (struct ds_md_update_req *) (dpkt + 1); 288 rp = (struct ds_md_update_req *) (dpkt + 1);
279 289
280 printk(KERN_INFO PFX "Machine description update.\n"); 290 printk(KERN_INFO "ds-%lu: Machine description update.\n", dp->id);
281 291
282 mdesc_update(); 292 mdesc_update();
283 293
284 memset(&pkt, 0, sizeof(pkt)); 294 memset(&pkt, 0, sizeof(pkt));
285 pkt.data.tag.type = DS_DATA; 295 pkt.data.tag.type = DS_DATA;
286 pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag); 296 pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag);
287 pkt.data.handle = dp->handle; 297 pkt.data.handle = cp->handle;
288 pkt.res.req_num = rp->req_num; 298 pkt.res.req_num = rp->req_num;
289 pkt.res.result = DS_OK; 299 pkt.res.result = DS_OK;
290 300
@@ -302,10 +312,11 @@ struct ds_shutdown_res {
302 char reason[1]; 312 char reason[1];
303}; 313};
304 314
305static void domain_shutdown_data(struct ldc_channel *lp, 315static void domain_shutdown_data(struct ds_info *dp,
306 struct ds_cap_state *dp, 316 struct ds_cap_state *cp,
307 void *buf, int len) 317 void *buf, int len)
308{ 318{
319 struct ldc_channel *lp = dp->lp;
309 struct ds_data *dpkt = buf; 320 struct ds_data *dpkt = buf;
310 struct ds_shutdown_req *rp; 321 struct ds_shutdown_req *rp;
311 struct { 322 struct {
@@ -315,13 +326,13 @@ static void domain_shutdown_data(struct ldc_channel *lp,
315 326
316 rp = (struct ds_shutdown_req *) (dpkt + 1); 327 rp = (struct ds_shutdown_req *) (dpkt + 1);
317 328
318 printk(KERN_ALERT PFX "Shutdown request from " 329 printk(KERN_ALERT "ds-%lu: Shutdown request from "
319 "LDOM manager received.\n"); 330 "LDOM manager received.\n", dp->id);
320 331
321 memset(&pkt, 0, sizeof(pkt)); 332 memset(&pkt, 0, sizeof(pkt));
322 pkt.data.tag.type = DS_DATA; 333 pkt.data.tag.type = DS_DATA;
323 pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag); 334 pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag);
324 pkt.data.handle = dp->handle; 335 pkt.data.handle = cp->handle;
325 pkt.res.req_num = rp->req_num; 336 pkt.res.req_num = rp->req_num;
326 pkt.res.result = DS_OK; 337 pkt.res.result = DS_OK;
327 pkt.res.reason[0] = 0; 338 pkt.res.reason[0] = 0;
@@ -341,10 +352,11 @@ struct ds_panic_res {
341 char reason[1]; 352 char reason[1];
342}; 353};
343 354
344static void domain_panic_data(struct ldc_channel *lp, 355static void domain_panic_data(struct ds_info *dp,
345 struct ds_cap_state *dp, 356 struct ds_cap_state *cp,
346 void *buf, int len) 357 void *buf, int len)
347{ 358{
359 struct ldc_channel *lp = dp->lp;
348 struct ds_data *dpkt = buf; 360 struct ds_data *dpkt = buf;
349 struct ds_panic_req *rp; 361 struct ds_panic_req *rp;
350 struct { 362 struct {
@@ -354,13 +366,13 @@ static void domain_panic_data(struct ldc_channel *lp,
354 366
355 rp = (struct ds_panic_req *) (dpkt + 1); 367 rp = (struct ds_panic_req *) (dpkt + 1);
356 368
357 printk(KERN_ALERT PFX "Panic request from " 369 printk(KERN_ALERT "ds-%lu: Panic request from "
358 "LDOM manager received.\n"); 370 "LDOM manager received.\n", dp->id);
359 371
360 memset(&pkt, 0, sizeof(pkt)); 372 memset(&pkt, 0, sizeof(pkt));
361 pkt.data.tag.type = DS_DATA; 373 pkt.data.tag.type = DS_DATA;
362 pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag); 374 pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag);
363 pkt.data.handle = dp->handle; 375 pkt.data.handle = cp->handle;
364 pkt.res.req_num = rp->req_num; 376 pkt.res.req_num = rp->req_num;
365 pkt.res.result = DS_OK; 377 pkt.res.result = DS_OK;
366 pkt.res.reason[0] = 0; 378 pkt.res.reason[0] = 0;
@@ -403,10 +415,11 @@ struct dr_cpu_resp_entry {
403 __u32 str_off; 415 __u32 str_off;
404}; 416};
405 417
406static void __dr_cpu_send_error(struct ds_cap_state *cp, struct ds_data *data) 418static void __dr_cpu_send_error(struct ds_info *dp,
419 struct ds_cap_state *cp,
420 struct ds_data *data)
407{ 421{
408 struct dr_cpu_tag *tag = (struct dr_cpu_tag *) (data + 1); 422 struct dr_cpu_tag *tag = (struct dr_cpu_tag *) (data + 1);
409 struct ds_info *dp = ds_info;
410 struct { 423 struct {
411 struct ds_data data; 424 struct ds_data data;
412 struct dr_cpu_tag tag; 425 struct dr_cpu_tag tag;
@@ -428,12 +441,14 @@ static void __dr_cpu_send_error(struct ds_cap_state *cp, struct ds_data *data)
428 __ds_send(dp->lp, &pkt, msg_len); 441 __ds_send(dp->lp, &pkt, msg_len);
429} 442}
430 443
431static void dr_cpu_send_error(struct ds_cap_state *cp, struct ds_data *data) 444static void dr_cpu_send_error(struct ds_info *dp,
445 struct ds_cap_state *cp,
446 struct ds_data *data)
432{ 447{
433 unsigned long flags; 448 unsigned long flags;
434 449
435 spin_lock_irqsave(&ds_lock, flags); 450 spin_lock_irqsave(&ds_lock, flags);
436 __dr_cpu_send_error(cp, data); 451 __dr_cpu_send_error(dp, cp, data);
437 spin_unlock_irqrestore(&ds_lock, flags); 452 spin_unlock_irqrestore(&ds_lock, flags);
438} 453}
439 454
@@ -511,7 +526,9 @@ static void dr_cpu_mark(struct ds_data *resp, int cpu, int ncpus,
511 } 526 }
512} 527}
513 528
514static int dr_cpu_configure(struct ds_cap_state *cp, u64 req_num, 529static int dr_cpu_configure(struct ds_info *dp,
530 struct ds_cap_state *cp,
531 u64 req_num,
515 cpumask_t *mask) 532 cpumask_t *mask)
516{ 533{
517 struct ds_data *resp; 534 struct ds_data *resp;
@@ -533,7 +550,8 @@ static int dr_cpu_configure(struct ds_cap_state *cp, u64 req_num,
533 for_each_cpu_mask(cpu, *mask) { 550 for_each_cpu_mask(cpu, *mask) {
534 int err; 551 int err;
535 552
536 printk(KERN_INFO PFX "Starting cpu %d...\n", cpu); 553 printk(KERN_INFO "ds-%lu: Starting cpu %d...\n",
554 dp->id, cpu);
537 err = cpu_up(cpu); 555 err = cpu_up(cpu);
538 if (err) { 556 if (err) {
539 __u32 res = DR_CPU_RES_FAILURE; 557 __u32 res = DR_CPU_RES_FAILURE;
@@ -548,14 +566,14 @@ static int dr_cpu_configure(struct ds_cap_state *cp, u64 req_num,
548 res = DR_CPU_RES_CPU_NOT_RESPONDING; 566 res = DR_CPU_RES_CPU_NOT_RESPONDING;
549 } 567 }
550 568
551 printk(KERN_INFO PFX "CPU startup failed err=%d\n", 569 printk(KERN_INFO "ds-%lu: CPU startup failed err=%d\n",
552 err); 570 dp->id, err);
553 dr_cpu_mark(resp, cpu, ncpus, res, stat); 571 dr_cpu_mark(resp, cpu, ncpus, res, stat);
554 } 572 }
555 } 573 }
556 574
557 spin_lock_irqsave(&ds_lock, flags); 575 spin_lock_irqsave(&ds_lock, flags);
558 __ds_send(ds_info->lp, resp, resp_len); 576 __ds_send(dp->lp, resp, resp_len);
559 spin_unlock_irqrestore(&ds_lock, flags); 577 spin_unlock_irqrestore(&ds_lock, flags);
560 578
561 kfree(resp); 579 kfree(resp);
@@ -566,7 +584,9 @@ static int dr_cpu_configure(struct ds_cap_state *cp, u64 req_num,
566 return 0; 584 return 0;
567} 585}
568 586
569static int dr_cpu_unconfigure(struct ds_cap_state *cp, u64 req_num, 587static int dr_cpu_unconfigure(struct ds_info *dp,
588 struct ds_cap_state *cp,
589 u64 req_num,
570 cpumask_t *mask) 590 cpumask_t *mask)
571{ 591{
572 struct ds_data *resp; 592 struct ds_data *resp;
@@ -586,8 +606,8 @@ static int dr_cpu_unconfigure(struct ds_cap_state *cp, u64 req_num,
586 for_each_cpu_mask(cpu, *mask) { 606 for_each_cpu_mask(cpu, *mask) {
587 int err; 607 int err;
588 608
589 printk(KERN_INFO PFX "CPU[%d]: Shutting down cpu %d...\n", 609 printk(KERN_INFO "ds-%lu: Shutting down cpu %d...\n",
590 smp_processor_id(), cpu); 610 dp->id, cpu);
591 err = cpu_down(cpu); 611 err = cpu_down(cpu);
592 if (err) 612 if (err)
593 dr_cpu_mark(resp, cpu, ncpus, 613 dr_cpu_mark(resp, cpu, ncpus,
@@ -596,7 +616,7 @@ static int dr_cpu_unconfigure(struct ds_cap_state *cp, u64 req_num,
596 } 616 }
597 617
598 spin_lock_irqsave(&ds_lock, flags); 618 spin_lock_irqsave(&ds_lock, flags);
599 __ds_send(ds_info->lp, resp, resp_len); 619 __ds_send(dp->lp, resp, resp_len);
600 spin_unlock_irqrestore(&ds_lock, flags); 620 spin_unlock_irqrestore(&ds_lock, flags);
601 621
602 kfree(resp); 622 kfree(resp);
@@ -604,7 +624,7 @@ static int dr_cpu_unconfigure(struct ds_cap_state *cp, u64 req_num,
604 return 0; 624 return 0;
605} 625}
606 626
607static void dr_cpu_data(struct ldc_channel *lp, 627static void dr_cpu_data(struct ds_info *dp,
608 struct ds_cap_state *cp, 628 struct ds_cap_state *cp,
609 void *buf, int len) 629 void *buf, int len)
610{ 630{
@@ -623,7 +643,7 @@ static void dr_cpu_data(struct ldc_channel *lp,
623 break; 643 break;
624 644
625 default: 645 default:
626 dr_cpu_send_error(cp, data); 646 dr_cpu_send_error(dp, cp, data);
627 return; 647 return;
628 } 648 }
629 649
@@ -639,12 +659,12 @@ static void dr_cpu_data(struct ldc_channel *lp,
639 } 659 }
640 660
641 if (tag->type == DR_CPU_CONFIGURE) 661 if (tag->type == DR_CPU_CONFIGURE)
642 err = dr_cpu_configure(cp, req_num, &mask); 662 err = dr_cpu_configure(dp, cp, req_num, &mask);
643 else 663 else
644 err = dr_cpu_unconfigure(cp, req_num, &mask); 664 err = dr_cpu_unconfigure(dp, cp, req_num, &mask);
645 665
646 if (err) 666 if (err)
647 dr_cpu_send_error(cp, data); 667 dr_cpu_send_error(dp, cp, data);
648} 668}
649#endif /* CONFIG_HOTPLUG_CPU */ 669#endif /* CONFIG_HOTPLUG_CPU */
650 670
@@ -656,8 +676,8 @@ struct ds_pri_msg {
656#define DS_PRI_UPDATE 0x02 676#define DS_PRI_UPDATE 0x02
657}; 677};
658 678
659static void ds_pri_data(struct ldc_channel *lp, 679static void ds_pri_data(struct ds_info *dp,
660 struct ds_cap_state *dp, 680 struct ds_cap_state *cp,
661 void *buf, int len) 681 void *buf, int len)
662{ 682{
663 struct ds_data *dpkt = buf; 683 struct ds_data *dpkt = buf;
@@ -665,8 +685,8 @@ static void ds_pri_data(struct ldc_channel *lp,
665 685
666 rp = (struct ds_pri_msg *) (dpkt + 1); 686 rp = (struct ds_pri_msg *) (dpkt + 1);
667 687
668 printk(KERN_INFO PFX "PRI REQ [%lx:%lx], len=%d\n", 688 printk(KERN_INFO "ds-%lu: PRI REQ [%lx:%lx], len=%d\n",
669 rp->req_num, rp->type, len); 689 dp->id, rp->req_num, rp->type, len);
670} 690}
671 691
672struct ds_var_hdr { 692struct ds_var_hdr {
@@ -701,8 +721,8 @@ static DEFINE_MUTEX(ds_var_mutex);
701static int ds_var_doorbell; 721static int ds_var_doorbell;
702static int ds_var_response; 722static int ds_var_response;
703 723
704static void ds_var_data(struct ldc_channel *lp, 724static void ds_var_data(struct ds_info *dp,
705 struct ds_cap_state *dp, 725 struct ds_cap_state *cp,
706 void *buf, int len) 726 void *buf, int len)
707{ 727{
708 struct ds_data *dpkt = buf; 728 struct ds_data *dpkt = buf;
@@ -721,14 +741,35 @@ static void ds_var_data(struct ldc_channel *lp,
721 741
722void ldom_set_var(const char *var, const char *value) 742void ldom_set_var(const char *var, const char *value)
723{ 743{
724 struct ds_info *dp = ds_info;
725 struct ds_cap_state *cp; 744 struct ds_cap_state *cp;
745 struct ds_info *dp;
746 unsigned long flags;
747
748 spin_lock_irqsave(&ds_lock, flags);
749 cp = NULL;
750 for (dp = ds_info_list; dp; dp = dp->next) {
751 struct ds_cap_state *tmp;
752
753 tmp = find_cap_by_string(dp, "var-config");
754 if (tmp && tmp->state == CAP_STATE_REGISTERED) {
755 cp = tmp;
756 break;
757 }
758 }
759 if (!cp) {
760 for (dp = ds_info_list; dp; dp = dp->next) {
761 struct ds_cap_state *tmp;
726 762
727 cp = find_cap_by_string("var-config"); 763 tmp = find_cap_by_string(dp, "var-config-backup");
728 if (cp->state != CAP_STATE_REGISTERED) 764 if (tmp && tmp->state == CAP_STATE_REGISTERED) {
729 cp = find_cap_by_string("var-config-backup"); 765 cp = tmp;
766 break;
767 }
768 }
769 }
770 spin_unlock_irqrestore(&ds_lock, flags);
730 771
731 if (cp->state == CAP_STATE_REGISTERED) { 772 if (cp) {
732 union { 773 union {
733 struct { 774 struct {
734 struct ds_data data; 775 struct ds_data data;
@@ -736,7 +777,6 @@ void ldom_set_var(const char *var, const char *value)
736 } header; 777 } header;
737 char all[512]; 778 char all[512];
738 } pkt; 779 } pkt;
739 unsigned long flags;
740 char *base, *p; 780 char *base, *p;
741 int msg_len, loops; 781 int msg_len, loops;
742 782
@@ -777,9 +817,9 @@ void ldom_set_var(const char *var, const char *value)
777 817
778 if (ds_var_doorbell == 0 || 818 if (ds_var_doorbell == 0 ||
779 ds_var_response != DS_VAR_SUCCESS) 819 ds_var_response != DS_VAR_SUCCESS)
780 printk(KERN_ERR PFX "var-config [%s:%s] " 820 printk(KERN_ERR "ds-%lu: var-config [%s:%s] "
781 "failed, response(%d).\n", 821 "failed, response(%d).\n",
782 var, value, 822 dp->id, var, value,
783 ds_var_response); 823 ds_var_response);
784 } else { 824 } else {
785 printk(KERN_ERR PFX "var-config not registered so " 825 printk(KERN_ERR PFX "var-config not registered so "
@@ -811,8 +851,8 @@ void ldom_power_off(void)
811 851
812static void ds_conn_reset(struct ds_info *dp) 852static void ds_conn_reset(struct ds_info *dp)
813{ 853{
814 printk(KERN_ERR PFX "ds_conn_reset() from %p\n", 854 printk(KERN_ERR "ds-%lu: ds_conn_reset() from %p\n",
815 __builtin_return_address(0)); 855 dp->id, __builtin_return_address(0));
816} 856}
817 857
818static int register_services(struct ds_info *dp) 858static int register_services(struct ds_info *dp)
@@ -820,12 +860,12 @@ static int register_services(struct ds_info *dp)
820 struct ldc_channel *lp = dp->lp; 860 struct ldc_channel *lp = dp->lp;
821 int i; 861 int i;
822 862
823 for (i = 0; i < ARRAY_SIZE(ds_states); i++) { 863 for (i = 0; i < dp->num_ds_states; i++) {
824 struct { 864 struct {
825 struct ds_reg_req req; 865 struct ds_reg_req req;
826 u8 id_buf[256]; 866 u8 id_buf[256];
827 } pbuf; 867 } pbuf;
828 struct ds_cap_state *cp = &ds_states[i]; 868 struct ds_cap_state *cp = &dp->ds_states[i];
829 int err, msg_len; 869 int err, msg_len;
830 u64 new_count; 870 u64 new_count;
831 871
@@ -870,28 +910,26 @@ static int ds_handshake(struct ds_info *dp, struct ds_msg_tag *pkt)
870 910
871 if (pkt->type == DS_REG_ACK) { 911 if (pkt->type == DS_REG_ACK) {
872 struct ds_reg_ack *ap = (struct ds_reg_ack *) pkt; 912 struct ds_reg_ack *ap = (struct ds_reg_ack *) pkt;
873 struct ds_cap_state *cp = find_cap(ap->handle); 913 struct ds_cap_state *cp = find_cap(dp, ap->handle);
874 914
875 if (!cp) { 915 if (!cp) {
876 printk(KERN_ERR PFX "REG ACK for unknown handle %lx\n", 916 printk(KERN_ERR "ds-%lu: REG ACK for unknown "
877 ap->handle); 917 "handle %lx\n", dp->id, ap->handle);
878 return 0; 918 return 0;
879 } 919 }
880 printk(KERN_INFO PFX "Registered %s service.\n", 920 printk(KERN_INFO "ds-%lu: Registered %s service.\n",
881 cp->service_id); 921 dp->id, cp->service_id);
882 cp->state = CAP_STATE_REGISTERED; 922 cp->state = CAP_STATE_REGISTERED;
883 } else if (pkt->type == DS_REG_NACK) { 923 } else if (pkt->type == DS_REG_NACK) {
884 struct ds_reg_nack *np = (struct ds_reg_nack *) pkt; 924 struct ds_reg_nack *np = (struct ds_reg_nack *) pkt;
885 struct ds_cap_state *cp = find_cap(np->handle); 925 struct ds_cap_state *cp = find_cap(dp, np->handle);
886 926
887 if (!cp) { 927 if (!cp) {
888 printk(KERN_ERR PFX "REG NACK for " 928 printk(KERN_ERR "ds-%lu: REG NACK for "
889 "unknown handle %lx\n", 929 "unknown handle %lx\n",
890 np->handle); 930 dp->id, np->handle);
891 return 0; 931 return 0;
892 } 932 }
893 printk(KERN_INFO PFX "Could not register %s service\n",
894 cp->service_id);
895 cp->state = CAP_STATE_UNKNOWN; 933 cp->state = CAP_STATE_UNKNOWN;
896 } 934 }
897 935
@@ -922,6 +960,7 @@ static DECLARE_WAIT_QUEUE_HEAD(ds_wait);
922 960
923struct ds_queue_entry { 961struct ds_queue_entry {
924 struct list_head list; 962 struct list_head list;
963 struct ds_info *dp;
925 int req_len; 964 int req_len;
926 int __pad; 965 int __pad;
927 u64 req[0]; 966 u64 req[0];
@@ -930,7 +969,6 @@ struct ds_queue_entry {
930static void process_ds_work(void) 969static void process_ds_work(void)
931{ 970{
932 struct ds_queue_entry *qp, *tmp; 971 struct ds_queue_entry *qp, *tmp;
933 static struct ds_info *dp;
934 unsigned long flags; 972 unsigned long flags;
935 LIST_HEAD(todo); 973 LIST_HEAD(todo);
936 974
@@ -939,22 +977,22 @@ static void process_ds_work(void)
939 INIT_LIST_HEAD(&ds_work_list); 977 INIT_LIST_HEAD(&ds_work_list);
940 spin_unlock_irqrestore(&ds_lock, flags); 978 spin_unlock_irqrestore(&ds_lock, flags);
941 979
942 dp = ds_info;
943
944 list_for_each_entry_safe(qp, tmp, &todo, list) { 980 list_for_each_entry_safe(qp, tmp, &todo, list) {
945 struct ds_data *dpkt = (struct ds_data *) qp->req; 981 struct ds_data *dpkt = (struct ds_data *) qp->req;
946 struct ds_cap_state *cp = find_cap(dpkt->handle); 982 struct ds_info *dp = qp->dp;
983 struct ds_cap_state *cp = find_cap(dp, dpkt->handle);
947 int req_len = qp->req_len; 984 int req_len = qp->req_len;
948 985
949 if (!cp) { 986 if (!cp) {
950 printk(KERN_ERR PFX "Data for unknown handle %lu\n", 987 printk(KERN_ERR "ds-%lu: Data for unknown "
951 dpkt->handle); 988 "handle %lu\n",
989 dp->id, dpkt->handle);
952 990
953 spin_lock_irqsave(&ds_lock, flags); 991 spin_lock_irqsave(&ds_lock, flags);
954 __send_ds_nack(dp, dpkt->handle); 992 __send_ds_nack(dp, dpkt->handle);
955 spin_unlock_irqrestore(&ds_lock, flags); 993 spin_unlock_irqrestore(&ds_lock, flags);
956 } else { 994 } else {
957 cp->data(dp->lp, cp, dpkt, req_len); 995 cp->data(dp, cp, dpkt, req_len);
958 } 996 }
959 997
960 list_del(&qp->list); 998 list_del(&qp->list);
@@ -990,6 +1028,7 @@ static int ds_data(struct ds_info *dp, struct ds_msg_tag *pkt, int len)
990 if (!qp) { 1028 if (!qp) {
991 __send_ds_nack(dp, dpkt->handle); 1029 __send_ds_nack(dp, dpkt->handle);
992 } else { 1030 } else {
1031 qp->dp = dp;
993 memcpy(&qp->req, pkt, len); 1032 memcpy(&qp->req, pkt, len);
994 list_add_tail(&qp->list, &ds_work_list); 1033 list_add_tail(&qp->list, &ds_work_list);
995 wake_up(&ds_wait); 1034 wake_up(&ds_wait);
@@ -1019,8 +1058,8 @@ static void ds_reset(struct ds_info *dp)
1019 1058
1020 dp->hs_state = 0; 1059 dp->hs_state = 0;
1021 1060
1022 for (i = 0; i < ARRAY_SIZE(ds_states); i++) { 1061 for (i = 0; i < dp->num_ds_states; i++) {
1023 struct ds_cap_state *cp = &ds_states[i]; 1062 struct ds_cap_state *cp = &dp->ds_states[i];
1024 1063
1025 cp->state = CAP_STATE_UNKNOWN; 1064 cp->state = CAP_STATE_UNKNOWN;
1026 } 1065 }
@@ -1048,7 +1087,8 @@ static void ds_event(void *arg, int event)
1048 } 1087 }
1049 1088
1050 if (event != LDC_EVENT_DATA_READY) { 1089 if (event != LDC_EVENT_DATA_READY) {
1051 printk(KERN_WARNING PFX "Unexpected LDC event %d\n", event); 1090 printk(KERN_WARNING "ds-%lu: Unexpected LDC event %d\n",
1091 dp->id, event);
1052 spin_unlock_irqrestore(&ds_lock, flags); 1092 spin_unlock_irqrestore(&ds_lock, flags);
1053 return; 1093 return;
1054 } 1094 }
@@ -1099,9 +1139,11 @@ static int __devinit ds_probe(struct vio_dev *vdev,
1099 .mtu = 4096, 1139 .mtu = 4096,
1100 .mode = LDC_MODE_STREAM, 1140 .mode = LDC_MODE_STREAM,
1101 }; 1141 };
1142 struct mdesc_handle *hp;
1102 struct ldc_channel *lp; 1143 struct ldc_channel *lp;
1103 struct ds_info *dp; 1144 struct ds_info *dp;
1104 int err; 1145 const u64 *val;
1146 int err, i;
1105 1147
1106 if (ds_version_printed++ == 0) 1148 if (ds_version_printed++ == 0)
1107 printk(KERN_INFO "%s", version); 1149 printk(KERN_INFO "%s", version);
@@ -1111,19 +1153,37 @@ static int __devinit ds_probe(struct vio_dev *vdev,
1111 if (!dp) 1153 if (!dp)
1112 goto out_err; 1154 goto out_err;
1113 1155
1156 hp = mdesc_grab();
1157 val = mdesc_get_property(hp, vdev->mp, "id", NULL);
1158 if (val)
1159 dp->id = *val;
1160 mdesc_release(hp);
1161
1114 dp->rcv_buf = kzalloc(4096, GFP_KERNEL); 1162 dp->rcv_buf = kzalloc(4096, GFP_KERNEL);
1115 if (!dp->rcv_buf) 1163 if (!dp->rcv_buf)
1116 goto out_free_dp; 1164 goto out_free_dp;
1117 1165
1118 dp->rcv_buf_len = 4096; 1166 dp->rcv_buf_len = 4096;
1119 1167
1168 dp->ds_states = kzalloc(sizeof(ds_states_template),
1169 GFP_KERNEL);
1170 if (!dp->ds_states)
1171 goto out_free_rcv_buf;
1172
1173 memcpy(dp->ds_states, ds_states_template,
1174 sizeof(ds_states_template));
1175 dp->num_ds_states = ARRAY_SIZE(ds_states_template);
1176
1177 for (i = 0; i < dp->num_ds_states; i++)
1178 dp->ds_states[i].handle = ((u64)i << 32);
1179
1120 ds_cfg.tx_irq = vdev->tx_irq; 1180 ds_cfg.tx_irq = vdev->tx_irq;
1121 ds_cfg.rx_irq = vdev->rx_irq; 1181 ds_cfg.rx_irq = vdev->rx_irq;
1122 1182
1123 lp = ldc_alloc(vdev->channel_id, &ds_cfg, dp); 1183 lp = ldc_alloc(vdev->channel_id, &ds_cfg, dp);
1124 if (IS_ERR(lp)) { 1184 if (IS_ERR(lp)) {
1125 err = PTR_ERR(lp); 1185 err = PTR_ERR(lp);
1126 goto out_free_rcv_buf; 1186 goto out_free_ds_states;
1127 } 1187 }
1128 dp->lp = lp; 1188 dp->lp = lp;
1129 1189
@@ -1131,13 +1191,19 @@ static int __devinit ds_probe(struct vio_dev *vdev,
1131 if (err) 1191 if (err)
1132 goto out_free_ldc; 1192 goto out_free_ldc;
1133 1193
1134 ds_info = dp; 1194 spin_lock_irq(&ds_lock);
1195 dp->next = ds_info_list;
1196 ds_info_list = dp;
1197 spin_unlock_irq(&ds_lock);
1135 1198
1136 return err; 1199 return err;
1137 1200
1138out_free_ldc: 1201out_free_ldc:
1139 ldc_free(dp->lp); 1202 ldc_free(dp->lp);
1140 1203
1204out_free_ds_states:
1205 kfree(dp->ds_states);
1206
1141out_free_rcv_buf: 1207out_free_rcv_buf:
1142 kfree(dp->rcv_buf); 1208 kfree(dp->rcv_buf);
1143 1209
@@ -1172,11 +1238,6 @@ static struct vio_driver ds_driver = {
1172 1238
1173static int __init ds_init(void) 1239static int __init ds_init(void)
1174{ 1240{
1175 int i;
1176
1177 for (i = 0; i < ARRAY_SIZE(ds_states); i++)
1178 ds_states[i].handle = ((u64)i << 32);
1179
1180 kthread_run(ds_thread, NULL, "kldomd"); 1241 kthread_run(ds_thread, NULL, "kldomd");
1181 1242
1182 return vio_register_driver(&ds_driver); 1243 return vio_register_driver(&ds_driver);
diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c
index ad55a9bb50dd..6d2956179cde 100644
--- a/arch/sparc64/kernel/ebus.c
+++ b/arch/sparc64/kernel/ebus.c
@@ -362,6 +362,7 @@ static int __init child_regs_nonstandard(struct linux_ebus_device *dev)
362static void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev) 362static void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev)
363{ 363{
364 struct linux_ebus_child *child; 364 struct linux_ebus_child *child;
365 struct dev_archdata *sd;
365 struct of_device *op; 366 struct of_device *op;
366 int i, len; 367 int i, len;
367 368
@@ -387,6 +388,10 @@ static void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_de
387 dev->irqs[i] = op->irqs[i]; 388 dev->irqs[i] = op->irqs[i];
388 } 389 }
389 390
391 sd = &dev->ofdev.dev.archdata;
392 sd->prom_node = dp;
393 sd->op = &dev->ofdev;
394
390 dev->ofdev.node = dp; 395 dev->ofdev.node = dp;
391 dev->ofdev.dev.parent = &dev->bus->ofdev.dev; 396 dev->ofdev.dev.parent = &dev->bus->ofdev.dev;
392 dev->ofdev.dev.bus = &ebus_bus_type; 397 dev->ofdev.dev.bus = &ebus_bus_type;
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index c72795666a62..db31bf6b42db 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -87,7 +87,11 @@ struct ino_bucket ivector_table[NUM_IVECS] __attribute__ ((aligned (SMP_CACHE_BY
87 */ 87 */
88#define irq_work(__cpu) &(trap_block[(__cpu)].irq_worklist) 88#define irq_work(__cpu) &(trap_block[(__cpu)].irq_worklist)
89 89
90static unsigned int virt_to_real_irq_table[NR_IRQS]; 90static struct {
91 unsigned int irq;
92 unsigned int dev_handle;
93 unsigned int dev_ino;
94} virt_to_real_irq_table[NR_IRQS];
91 95
92static unsigned char virt_irq_alloc(unsigned int real_irq) 96static unsigned char virt_irq_alloc(unsigned int real_irq)
93{ 97{
@@ -96,7 +100,7 @@ static unsigned char virt_irq_alloc(unsigned int real_irq)
96 BUILD_BUG_ON(NR_IRQS >= 256); 100 BUILD_BUG_ON(NR_IRQS >= 256);
97 101
98 for (ent = 1; ent < NR_IRQS; ent++) { 102 for (ent = 1; ent < NR_IRQS; ent++) {
99 if (!virt_to_real_irq_table[ent]) 103 if (!virt_to_real_irq_table[ent].irq)
100 break; 104 break;
101 } 105 }
102 if (ent >= NR_IRQS) { 106 if (ent >= NR_IRQS) {
@@ -104,7 +108,7 @@ static unsigned char virt_irq_alloc(unsigned int real_irq)
104 return 0; 108 return 0;
105 } 109 }
106 110
107 virt_to_real_irq_table[ent] = real_irq; 111 virt_to_real_irq_table[ent].irq = real_irq;
108 112
109 return ent; 113 return ent;
110} 114}
@@ -117,8 +121,8 @@ static void virt_irq_free(unsigned int virt_irq)
117 if (virt_irq >= NR_IRQS) 121 if (virt_irq >= NR_IRQS)
118 return; 122 return;
119 123
120 real_irq = virt_to_real_irq_table[virt_irq]; 124 real_irq = virt_to_real_irq_table[virt_irq].irq;
121 virt_to_real_irq_table[virt_irq] = 0; 125 virt_to_real_irq_table[virt_irq].irq = 0;
122 126
123 __bucket(real_irq)->virt_irq = 0; 127 __bucket(real_irq)->virt_irq = 0;
124} 128}
@@ -126,7 +130,7 @@ static void virt_irq_free(unsigned int virt_irq)
126 130
127static unsigned int virt_to_real_irq(unsigned char virt_irq) 131static unsigned int virt_to_real_irq(unsigned char virt_irq)
128{ 132{
129 return virt_to_real_irq_table[virt_irq]; 133 return virt_to_real_irq_table[virt_irq].irq;
130} 134}
131 135
132/* 136/*
@@ -336,15 +340,15 @@ static void sun4v_irq_enable(unsigned int virt_irq)
336 340
337 err = sun4v_intr_settarget(ino, cpuid); 341 err = sun4v_intr_settarget(ino, cpuid);
338 if (err != HV_EOK) 342 if (err != HV_EOK)
339 printk("sun4v_intr_settarget(%x,%lu): err(%d)\n", 343 printk(KERN_ERR "sun4v_intr_settarget(%x,%lu): "
340 ino, cpuid, err); 344 "err(%d)\n", ino, cpuid, err);
341 err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE); 345 err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE);
342 if (err != HV_EOK) 346 if (err != HV_EOK)
343 printk("sun4v_intr_setstate(%x): " 347 printk(KERN_ERR "sun4v_intr_setstate(%x): "
344 "err(%d)\n", ino, err); 348 "err(%d)\n", ino, err);
345 err = sun4v_intr_setenabled(ino, HV_INTR_ENABLED); 349 err = sun4v_intr_setenabled(ino, HV_INTR_ENABLED);
346 if (err != HV_EOK) 350 if (err != HV_EOK)
347 printk("sun4v_intr_setenabled(%x): err(%d)\n", 351 printk(KERN_ERR "sun4v_intr_setenabled(%x): err(%d)\n",
348 ino, err); 352 ino, err);
349 } 353 }
350} 354}
@@ -362,8 +366,8 @@ static void sun4v_set_affinity(unsigned int virt_irq, cpumask_t mask)
362 366
363 err = sun4v_intr_settarget(ino, cpuid); 367 err = sun4v_intr_settarget(ino, cpuid);
364 if (err != HV_EOK) 368 if (err != HV_EOK)
365 printk("sun4v_intr_settarget(%x,%lu): err(%d)\n", 369 printk(KERN_ERR "sun4v_intr_settarget(%x,%lu): "
366 ino, cpuid, err); 370 "err(%d)\n", ino, cpuid, err);
367 } 371 }
368} 372}
369 373
@@ -377,7 +381,7 @@ static void sun4v_irq_disable(unsigned int virt_irq)
377 381
378 err = sun4v_intr_setenabled(ino, HV_INTR_DISABLED); 382 err = sun4v_intr_setenabled(ino, HV_INTR_DISABLED);
379 if (err != HV_EOK) 383 if (err != HV_EOK)
380 printk("sun4v_intr_setenabled(%x): " 384 printk(KERN_ERR "sun4v_intr_setenabled(%x): "
381 "err(%d)\n", ino, err); 385 "err(%d)\n", ino, err);
382 } 386 }
383} 387}
@@ -410,7 +414,7 @@ static void sun4v_irq_end(unsigned int virt_irq)
410 414
411 err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE); 415 err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE);
412 if (err != HV_EOK) 416 if (err != HV_EOK)
413 printk("sun4v_intr_setstate(%x): " 417 printk(KERN_ERR "sun4v_intr_setstate(%x): "
414 "err(%d)\n", ino, err); 418 "err(%d)\n", ino, err);
415 } 419 }
416} 420}
@@ -418,7 +422,6 @@ static void sun4v_irq_end(unsigned int virt_irq)
418static void sun4v_virq_enable(unsigned int virt_irq) 422static void sun4v_virq_enable(unsigned int virt_irq)
419{ 423{
420 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); 424 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
421 unsigned int ino = bucket - &ivector_table[0];
422 425
423 if (likely(bucket)) { 426 if (likely(bucket)) {
424 unsigned long cpuid, dev_handle, dev_ino; 427 unsigned long cpuid, dev_handle, dev_ino;
@@ -426,24 +429,24 @@ static void sun4v_virq_enable(unsigned int virt_irq)
426 429
427 cpuid = irq_choose_cpu(virt_irq); 430 cpuid = irq_choose_cpu(virt_irq);
428 431
429 dev_handle = ino & IMAP_IGN; 432 dev_handle = virt_to_real_irq_table[virt_irq].dev_handle;
430 dev_ino = ino & IMAP_INO; 433 dev_ino = virt_to_real_irq_table[virt_irq].dev_ino;
431 434
432 err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); 435 err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid);
433 if (err != HV_EOK) 436 if (err != HV_EOK)
434 printk("sun4v_vintr_set_target(%lx,%lx,%lu): " 437 printk(KERN_ERR "sun4v_vintr_set_target(%lx,%lx,%lu): "
435 "err(%d)\n", 438 "err(%d)\n",
436 dev_handle, dev_ino, cpuid, err); 439 dev_handle, dev_ino, cpuid, err);
437 err = sun4v_vintr_set_state(dev_handle, dev_ino, 440 err = sun4v_vintr_set_state(dev_handle, dev_ino,
438 HV_INTR_STATE_IDLE); 441 HV_INTR_STATE_IDLE);
439 if (err != HV_EOK) 442 if (err != HV_EOK)
440 printk("sun4v_vintr_set_state(%lx,%lx," 443 printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx,"
441 "HV_INTR_STATE_IDLE): err(%d)\n", 444 "HV_INTR_STATE_IDLE): err(%d)\n",
442 dev_handle, dev_ino, err); 445 dev_handle, dev_ino, err);
443 err = sun4v_vintr_set_valid(dev_handle, dev_ino, 446 err = sun4v_vintr_set_valid(dev_handle, dev_ino,
444 HV_INTR_ENABLED); 447 HV_INTR_ENABLED);
445 if (err != HV_EOK) 448 if (err != HV_EOK)
446 printk("sun4v_vintr_set_state(%lx,%lx," 449 printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx,"
447 "HV_INTR_ENABLED): err(%d)\n", 450 "HV_INTR_ENABLED): err(%d)\n",
448 dev_handle, dev_ino, err); 451 dev_handle, dev_ino, err);
449 } 452 }
@@ -452,7 +455,6 @@ static void sun4v_virq_enable(unsigned int virt_irq)
452static void sun4v_virt_set_affinity(unsigned int virt_irq, cpumask_t mask) 455static void sun4v_virt_set_affinity(unsigned int virt_irq, cpumask_t mask)
453{ 456{
454 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); 457 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
455 unsigned int ino = bucket - &ivector_table[0];
456 458
457 if (likely(bucket)) { 459 if (likely(bucket)) {
458 unsigned long cpuid, dev_handle, dev_ino; 460 unsigned long cpuid, dev_handle, dev_ino;
@@ -460,12 +462,12 @@ static void sun4v_virt_set_affinity(unsigned int virt_irq, cpumask_t mask)
460 462
461 cpuid = irq_choose_cpu(virt_irq); 463 cpuid = irq_choose_cpu(virt_irq);
462 464
463 dev_handle = ino & IMAP_IGN; 465 dev_handle = virt_to_real_irq_table[virt_irq].dev_handle;
464 dev_ino = ino & IMAP_INO; 466 dev_ino = virt_to_real_irq_table[virt_irq].dev_ino;
465 467
466 err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); 468 err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid);
467 if (err != HV_EOK) 469 if (err != HV_EOK)
468 printk("sun4v_vintr_set_target(%lx,%lx,%lu): " 470 printk(KERN_ERR "sun4v_vintr_set_target(%lx,%lx,%lu): "
469 "err(%d)\n", 471 "err(%d)\n",
470 dev_handle, dev_ino, cpuid, err); 472 dev_handle, dev_ino, cpuid, err);
471 } 473 }
@@ -474,19 +476,18 @@ static void sun4v_virt_set_affinity(unsigned int virt_irq, cpumask_t mask)
474static void sun4v_virq_disable(unsigned int virt_irq) 476static void sun4v_virq_disable(unsigned int virt_irq)
475{ 477{
476 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); 478 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
477 unsigned int ino = bucket - &ivector_table[0];
478 479
479 if (likely(bucket)) { 480 if (likely(bucket)) {
480 unsigned long dev_handle, dev_ino; 481 unsigned long dev_handle, dev_ino;
481 int err; 482 int err;
482 483
483 dev_handle = ino & IMAP_IGN; 484 dev_handle = virt_to_real_irq_table[virt_irq].dev_handle;
484 dev_ino = ino & IMAP_INO; 485 dev_ino = virt_to_real_irq_table[virt_irq].dev_ino;
485 486
486 err = sun4v_vintr_set_valid(dev_handle, dev_ino, 487 err = sun4v_vintr_set_valid(dev_handle, dev_ino,
487 HV_INTR_DISABLED); 488 HV_INTR_DISABLED);
488 if (err != HV_EOK) 489 if (err != HV_EOK)
489 printk("sun4v_vintr_set_state(%lx,%lx," 490 printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx,"
490 "HV_INTR_DISABLED): err(%d)\n", 491 "HV_INTR_DISABLED): err(%d)\n",
491 dev_handle, dev_ino, err); 492 dev_handle, dev_ino, err);
492 } 493 }
@@ -495,7 +496,6 @@ static void sun4v_virq_disable(unsigned int virt_irq)
495static void sun4v_virq_end(unsigned int virt_irq) 496static void sun4v_virq_end(unsigned int virt_irq)
496{ 497{
497 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); 498 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
498 unsigned int ino = bucket - &ivector_table[0];
499 struct irq_desc *desc = irq_desc + virt_irq; 499 struct irq_desc *desc = irq_desc + virt_irq;
500 500
501 if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))) 501 if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
@@ -505,13 +505,13 @@ static void sun4v_virq_end(unsigned int virt_irq)
505 unsigned long dev_handle, dev_ino; 505 unsigned long dev_handle, dev_ino;
506 int err; 506 int err;
507 507
508 dev_handle = ino & IMAP_IGN; 508 dev_handle = virt_to_real_irq_table[virt_irq].dev_handle;
509 dev_ino = ino & IMAP_INO; 509 dev_ino = virt_to_real_irq_table[virt_irq].dev_ino;
510 510
511 err = sun4v_vintr_set_state(dev_handle, dev_ino, 511 err = sun4v_vintr_set_state(dev_handle, dev_ino,
512 HV_INTR_STATE_IDLE); 512 HV_INTR_STATE_IDLE);
513 if (err != HV_EOK) 513 if (err != HV_EOK)
514 printk("sun4v_vintr_set_state(%lx,%lx," 514 printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx,"
515 "HV_INTR_STATE_IDLE): err(%d)\n", 515 "HV_INTR_STATE_IDLE): err(%d)\n",
516 dev_handle, dev_ino, err); 516 dev_handle, dev_ino, err);
517 } 517 }
@@ -700,6 +700,7 @@ unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino)
700unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) 700unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
701{ 701{
702 unsigned long sysino, hv_err; 702 unsigned long sysino, hv_err;
703 unsigned int virq;
703 704
704 BUG_ON(devhandle & devino); 705 BUG_ON(devhandle & devino);
705 706
@@ -713,7 +714,12 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
713 prom_halt(); 714 prom_halt();
714 } 715 }
715 716
716 return sun4v_build_common(sysino, &sun4v_virq); 717 virq = sun4v_build_common(sysino, &sun4v_virq);
718
719 virt_to_real_irq_table[virq].dev_handle = devhandle;
720 virt_to_real_irq_table[virq].dev_ino = devino;
721
722 return virq;
717} 723}
718 724
719#ifdef CONFIG_PCI_MSI 725#ifdef CONFIG_PCI_MSI
diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c
index 6a6882e57ff2..1a1043fcf97d 100644
--- a/arch/sparc64/kernel/isa.c
+++ b/arch/sparc64/kernel/isa.c
@@ -79,6 +79,7 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
79 79
80 while (dp) { 80 while (dp) {
81 struct sparc_isa_device *isa_dev; 81 struct sparc_isa_device *isa_dev;
82 struct dev_archdata *sd;
82 83
83 isa_dev = kzalloc(sizeof(*isa_dev), GFP_KERNEL); 84 isa_dev = kzalloc(sizeof(*isa_dev), GFP_KERNEL);
84 if (!isa_dev) { 85 if (!isa_dev) {
@@ -86,6 +87,10 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
86 return; 87 return;
87 } 88 }
88 89
90 sd = &isa_dev->ofdev.dev.archdata;
91 sd->prom_node = dp;
92 sd->op = &isa_dev->ofdev;
93
89 isa_dev->ofdev.node = dp; 94 isa_dev->ofdev.node = dp;
90 isa_dev->ofdev.dev.parent = &isa_br->ofdev.dev; 95 isa_dev->ofdev.dev.parent = &isa_br->ofdev.dev;
91 isa_dev->ofdev.dev.bus = &isa_bus_type; 96 isa_dev->ofdev.dev.bus = &isa_bus_type;
diff --git a/arch/sparc64/kernel/mdesc.c b/arch/sparc64/kernel/mdesc.c
index 13a79fe5115b..cce4d0ddf5d5 100644
--- a/arch/sparc64/kernel/mdesc.c
+++ b/arch/sparc64/kernel/mdesc.c
@@ -83,7 +83,7 @@ static void mdesc_handle_init(struct mdesc_handle *hp,
83 hp->handle_size = handle_size; 83 hp->handle_size = handle_size;
84} 84}
85 85
86static struct mdesc_handle *mdesc_bootmem_alloc(unsigned int mdesc_size) 86static struct mdesc_handle * __init mdesc_bootmem_alloc(unsigned int mdesc_size)
87{ 87{
88 struct mdesc_handle *hp; 88 struct mdesc_handle *hp;
89 unsigned int handle_size, alloc_size; 89 unsigned int handle_size, alloc_size;
@@ -123,7 +123,7 @@ static void mdesc_bootmem_free(struct mdesc_handle *hp)
123 } 123 }
124} 124}
125 125
126static struct mdesc_mem_ops bootmem_mdesc_memops = { 126static struct mdesc_mem_ops bootmem_mdesc_ops = {
127 .alloc = mdesc_bootmem_alloc, 127 .alloc = mdesc_bootmem_alloc,
128 .free = mdesc_bootmem_free, 128 .free = mdesc_bootmem_free,
129}; 129};
@@ -860,7 +860,7 @@ void __init sun4v_mdesc_init(void)
860 860
861 printk("MDESC: Size is %lu bytes.\n", len); 861 printk("MDESC: Size is %lu bytes.\n", len);
862 862
863 hp = mdesc_alloc(len, &bootmem_mdesc_memops); 863 hp = mdesc_alloc(len, &bootmem_mdesc_ops);
864 if (hp == NULL) { 864 if (hp == NULL) {
865 prom_printf("MDESC: alloc of %lu bytes failed.\n", len); 865 prom_printf("MDESC: alloc of %lu bytes failed.\n", len);
866 prom_halt(); 866 prom_halt();
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c
index 7b0dce9604ee..4cc77485f536 100644
--- a/arch/sparc64/kernel/of_device.c
+++ b/arch/sparc64/kernel/of_device.c
@@ -752,11 +752,16 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
752{ 752{
753 struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL); 753 struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL);
754 const unsigned int *irq; 754 const unsigned int *irq;
755 struct dev_archdata *sd;
755 int len, i; 756 int len, i;
756 757
757 if (!op) 758 if (!op)
758 return NULL; 759 return NULL;
759 760
761 sd = &op->dev.archdata;
762 sd->prom_node = dp;
763 sd->op = op;
764
760 op->node = dp; 765 op->node = dp;
761 766
762 op->clock_freq = of_getintprop_default(dp, "clock-frequency", 767 op->clock_freq = of_getintprop_default(dp, "clock-frequency",
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index 6b3fe2c1d65e..639cf06ca372 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -1129,7 +1129,7 @@ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm)
1129} 1129}
1130#endif /* !(CONFIG_PCI_MSI) */ 1130#endif /* !(CONFIG_PCI_MSI) */
1131 1131
1132static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 devhandle) 1132static void __init pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 devhandle)
1133{ 1133{
1134 struct pci_pbm_info *pbm; 1134 struct pci_pbm_info *pbm;
1135 1135
@@ -1163,7 +1163,7 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node
1163 pci_sun4v_msi_init(pbm); 1163 pci_sun4v_msi_init(pbm);
1164} 1164}
1165 1165
1166void sun4v_pci_init(struct device_node *dp, char *model_name) 1166void __init sun4v_pci_init(struct device_node *dp, char *model_name)
1167{ 1167{
1168 static int hvapi_negotiated = 0; 1168 static int hvapi_negotiated = 0;
1169 struct pci_controller_info *p; 1169 struct pci_controller_info *p;
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c
index b00feb01c16f..881a09ee4c4c 100644
--- a/arch/sparc64/kernel/power.c
+++ b/arch/sparc64/kernel/power.c
@@ -46,7 +46,7 @@ static void (*poweroff_method)(void) = machine_alt_power_off;
46void machine_power_off(void) 46void machine_power_off(void)
47{ 47{
48 sstate_poweroff(); 48 sstate_poweroff();
49 if (!serial_console || scons_pwroff) { 49 if (strcmp(of_console_device->type, "serial") || scons_pwroff) {
50 if (power_reg) { 50 if (power_reg) {
51 /* Both register bits seem to have the 51 /* Both register bits seem to have the
52 * same effect, so until I figure out 52 * same effect, so until I figure out
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 93557507ec9f..fd7899ba1d70 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -119,7 +119,7 @@ extern void (*prom_keyboard)(void);
119void machine_halt(void) 119void machine_halt(void)
120{ 120{
121 sstate_halt(); 121 sstate_halt();
122 if (!serial_console && prom_palette) 122 if (prom_palette)
123 prom_palette (1); 123 prom_palette (1);
124 if (prom_keyboard) 124 if (prom_keyboard)
125 prom_keyboard(); 125 prom_keyboard();
@@ -130,7 +130,7 @@ void machine_halt(void)
130void machine_alt_power_off(void) 130void machine_alt_power_off(void)
131{ 131{
132 sstate_poweroff(); 132 sstate_poweroff();
133 if (!serial_console && prom_palette) 133 if (prom_palette)
134 prom_palette(1); 134 prom_palette(1);
135 if (prom_keyboard) 135 if (prom_keyboard)
136 prom_keyboard(); 136 prom_keyboard();
@@ -145,7 +145,7 @@ void machine_restart(char * cmd)
145 sstate_reboot(); 145 sstate_reboot();
146 p = strchr (reboot_command, '\n'); 146 p = strchr (reboot_command, '\n');
147 if (p) *p = 0; 147 if (p) *p = 0;
148 if (!serial_console && prom_palette) 148 if (prom_palette)
149 prom_palette (1); 149 prom_palette (1);
150 if (prom_keyboard) 150 if (prom_keyboard)
151 prom_keyboard(); 151 prom_keyboard();
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
index 2b2017ce2267..f4e0a9ad9be3 100644
--- a/arch/sparc64/kernel/prom.c
+++ b/arch/sparc64/kernel/prom.c
@@ -1646,6 +1646,60 @@ static void __init of_fill_in_cpu_data(void)
1646 smp_fill_in_sib_core_maps(); 1646 smp_fill_in_sib_core_maps();
1647} 1647}
1648 1648
1649struct device_node *of_console_device;
1650EXPORT_SYMBOL(of_console_device);
1651
1652char *of_console_path;
1653EXPORT_SYMBOL(of_console_path);
1654
1655char *of_console_options;
1656EXPORT_SYMBOL(of_console_options);
1657
1658static void __init of_console_init(void)
1659{
1660 char *msg = "OF stdout device is: %s\n";
1661 struct device_node *dp;
1662 const char *type;
1663 phandle node;
1664
1665 of_console_path = prom_early_alloc(256);
1666 if (prom_ihandle2path(prom_stdout, of_console_path, 256) < 0) {
1667 prom_printf("Cannot obtain path of stdout.\n");
1668 prom_halt();
1669 }
1670 of_console_options = strrchr(of_console_path, ':');
1671 if (of_console_options) {
1672 of_console_options++;
1673 if (*of_console_options == '\0')
1674 of_console_options = NULL;
1675 }
1676
1677 node = prom_inst2pkg(prom_stdout);
1678 if (!node) {
1679 prom_printf("Cannot resolve stdout node from "
1680 "instance %08x.\n", prom_stdout);
1681 prom_halt();
1682 }
1683
1684 dp = of_find_node_by_phandle(node);
1685 type = of_get_property(dp, "device_type", NULL);
1686 if (!type) {
1687 prom_printf("Console stdout lacks device_type property.\n");
1688 prom_halt();
1689 }
1690
1691 if (strcmp(type, "display") && strcmp(type, "serial")) {
1692 prom_printf("Console device_type is neither display "
1693 "nor serial.\n");
1694 prom_halt();
1695 }
1696
1697 of_console_device = dp;
1698
1699 prom_printf(msg, of_console_path);
1700 printk(msg, of_console_path);
1701}
1702
1649void __init prom_build_devicetree(void) 1703void __init prom_build_devicetree(void)
1650{ 1704{
1651 struct device_node **nextp; 1705 struct device_node **nextp;
@@ -1658,6 +1712,8 @@ void __init prom_build_devicetree(void)
1658 allnodes->child = build_tree(allnodes, 1712 allnodes->child = build_tree(allnodes,
1659 prom_getchild(allnodes->node), 1713 prom_getchild(allnodes->node),
1660 &nextp); 1714 &nextp);
1715 of_console_init();
1716
1661 printk("PROM: Built device tree with %u bytes of memory.\n", 1717 printk("PROM: Built device tree with %u bytes of memory.\n",
1662 prom_early_allocated); 1718 prom_early_allocated);
1663 1719
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index aafde3dd9fd4..0f5be828ee92 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -133,33 +133,6 @@ static void __init process_switch(char c)
133 } 133 }
134} 134}
135 135
136static void __init process_console(char *commands)
137{
138 serial_console = 0;
139 commands += 8;
140 /* Linux-style serial */
141 if (!strncmp(commands, "ttyS", 4))
142 serial_console = simple_strtoul(commands + 4, NULL, 10) + 1;
143 else if (!strncmp(commands, "tty", 3)) {
144 char c = *(commands + 3);
145 /* Solaris-style serial */
146 if (c == 'a' || c == 'b') {
147 serial_console = c - 'a' + 1;
148 prom_printf ("Using /dev/tty%c as console.\n", c);
149 }
150 /* else Linux-style fbcon, not serial */
151 }
152#if defined(CONFIG_PROM_CONSOLE)
153 if (!strncmp(commands, "prom", 4)) {
154 char *p;
155
156 for (p = commands - 8; *p && *p != ' '; p++)
157 *p = ' ';
158 conswitchp = &prom_con;
159 }
160#endif
161}
162
163static void __init boot_flags_init(char *commands) 136static void __init boot_flags_init(char *commands)
164{ 137{
165 while (*commands) { 138 while (*commands) {
@@ -176,9 +149,7 @@ static void __init boot_flags_init(char *commands)
176 process_switch(*commands++); 149 process_switch(*commands++);
177 continue; 150 continue;
178 } 151 }
179 if (!strncmp(commands, "console=", 8)) { 152 if (!strncmp(commands, "mem=", 4)) {
180 process_console(commands);
181 } else if (!strncmp(commands, "mem=", 4)) {
182 /* 153 /*
183 * "mem=XXX[kKmM]" overrides the PROM-reported 154 * "mem=XXX[kKmM]" overrides the PROM-reported
184 * memory size. 155 * memory size.
@@ -378,44 +349,6 @@ void __init setup_arch(char **cmdline_p)
378 paging_init(); 349 paging_init();
379} 350}
380 351
381static int __init set_preferred_console(void)
382{
383 int idev, odev;
384
385 /* The user has requested a console so this is already set up. */
386 if (serial_console >= 0)
387 return -EBUSY;
388
389 idev = prom_query_input_device();
390 odev = prom_query_output_device();
391 if (idev == PROMDEV_IKBD && odev == PROMDEV_OSCREEN) {
392 serial_console = 0;
393 } else if (idev == PROMDEV_ITTYA && odev == PROMDEV_OTTYA) {
394 serial_console = 1;
395 } else if (idev == PROMDEV_ITTYB && odev == PROMDEV_OTTYB) {
396 serial_console = 2;
397 } else if (idev == PROMDEV_IRSC && odev == PROMDEV_ORSC) {
398 serial_console = 3;
399 } else if (idev == PROMDEV_IVCONS && odev == PROMDEV_OVCONS) {
400 /* sunhv_console_init() doesn't check the serial_console
401 * value anyways...
402 */
403 serial_console = 4;
404 return add_preferred_console("ttyHV", 0, NULL);
405 } else {
406 prom_printf("Inconsistent console: "
407 "input %d, output %d\n",
408 idev, odev);
409 prom_halt();
410 }
411
412 if (serial_console)
413 return add_preferred_console("ttyS", serial_console - 1, NULL);
414
415 return -ENODEV;
416}
417console_initcall(set_preferred_console);
418
419/* BUFFER is PAGE_SIZE bytes long. */ 352/* BUFFER is PAGE_SIZE bytes long. */
420 353
421extern char *sparc_cpu_type; 354extern char *sparc_cpu_type;
@@ -508,5 +441,4 @@ void sun_do_break(void)
508 prom_cmdline(); 441 prom_cmdline();
509} 442}
510 443
511int serial_console = -1;
512int stop_a_enabled = 1; 444int stop_a_enabled = 1;
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index 719d676c2ddc..7d36531aa5b9 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -330,7 +330,6 @@ EXPORT_SYMBOL(VISenter);
330 330
331/* for input/keybdev */ 331/* for input/keybdev */
332EXPORT_SYMBOL(sun_do_break); 332EXPORT_SYMBOL(sun_do_break);
333EXPORT_SYMBOL(serial_console);
334EXPORT_SYMBOL(stop_a_enabled); 333EXPORT_SYMBOL(stop_a_enabled);
335 334
336#ifdef CONFIG_DEBUG_BUGVERBOSE 335#ifdef CONFIG_DEBUG_BUGVERBOSE
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index 592ffcd57605..e340eb401fb9 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -1434,6 +1434,78 @@ static int bq4802_set_rtc_time(struct rtc_time *time)
1434 1434
1435 return 0; 1435 return 0;
1436} 1436}
1437
1438static void cmos_get_rtc_time(struct rtc_time *rtc_tm)
1439{
1440 unsigned char ctrl;
1441
1442 rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS);
1443 rtc_tm->tm_min = CMOS_READ(RTC_MINUTES);
1444 rtc_tm->tm_hour = CMOS_READ(RTC_HOURS);
1445 rtc_tm->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH);
1446 rtc_tm->tm_mon = CMOS_READ(RTC_MONTH);
1447 rtc_tm->tm_year = CMOS_READ(RTC_YEAR);
1448 rtc_tm->tm_wday = CMOS_READ(RTC_DAY_OF_WEEK);
1449
1450 ctrl = CMOS_READ(RTC_CONTROL);
1451 if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
1452 BCD_TO_BIN(rtc_tm->tm_sec);
1453 BCD_TO_BIN(rtc_tm->tm_min);
1454 BCD_TO_BIN(rtc_tm->tm_hour);
1455 BCD_TO_BIN(rtc_tm->tm_mday);
1456 BCD_TO_BIN(rtc_tm->tm_mon);
1457 BCD_TO_BIN(rtc_tm->tm_year);
1458 BCD_TO_BIN(rtc_tm->tm_wday);
1459 }
1460
1461 if (rtc_tm->tm_year <= 69)
1462 rtc_tm->tm_year += 100;
1463
1464 rtc_tm->tm_mon--;
1465}
1466
1467static int cmos_set_rtc_time(struct rtc_time *rtc_tm)
1468{
1469 unsigned char mon, day, hrs, min, sec;
1470 unsigned char save_control, save_freq_select;
1471 unsigned int yrs;
1472
1473 yrs = rtc_tm->tm_year;
1474 mon = rtc_tm->tm_mon + 1;
1475 day = rtc_tm->tm_mday;
1476 hrs = rtc_tm->tm_hour;
1477 min = rtc_tm->tm_min;
1478 sec = rtc_tm->tm_sec;
1479
1480 if (yrs >= 100)
1481 yrs -= 100;
1482
1483 if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
1484 BIN_TO_BCD(sec);
1485 BIN_TO_BCD(min);
1486 BIN_TO_BCD(hrs);
1487 BIN_TO_BCD(day);
1488 BIN_TO_BCD(mon);
1489 BIN_TO_BCD(yrs);
1490 }
1491
1492 save_control = CMOS_READ(RTC_CONTROL);
1493 CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
1494 save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
1495 CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
1496
1497 CMOS_WRITE(yrs, RTC_YEAR);
1498 CMOS_WRITE(mon, RTC_MONTH);
1499 CMOS_WRITE(day, RTC_DAY_OF_MONTH);
1500 CMOS_WRITE(hrs, RTC_HOURS);
1501 CMOS_WRITE(min, RTC_MINUTES);
1502 CMOS_WRITE(sec, RTC_SECONDS);
1503
1504 CMOS_WRITE(save_control, RTC_CONTROL);
1505 CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
1506
1507 return 0;
1508}
1437#endif /* CONFIG_PCI */ 1509#endif /* CONFIG_PCI */
1438 1510
1439struct mini_rtc_ops { 1511struct mini_rtc_ops {
@@ -1456,6 +1528,11 @@ static struct mini_rtc_ops bq4802_rtc_ops = {
1456 .get_rtc_time = bq4802_get_rtc_time, 1528 .get_rtc_time = bq4802_get_rtc_time,
1457 .set_rtc_time = bq4802_set_rtc_time, 1529 .set_rtc_time = bq4802_set_rtc_time,
1458}; 1530};
1531
1532static struct mini_rtc_ops cmos_rtc_ops = {
1533 .get_rtc_time = cmos_get_rtc_time,
1534 .set_rtc_time = cmos_set_rtc_time,
1535};
1459#endif /* CONFIG_PCI */ 1536#endif /* CONFIG_PCI */
1460 1537
1461static struct mini_rtc_ops *mini_rtc_ops; 1538static struct mini_rtc_ops *mini_rtc_ops;
@@ -1583,6 +1660,8 @@ static int __init rtc_mini_init(void)
1583#ifdef CONFIG_PCI 1660#ifdef CONFIG_PCI
1584 else if (bq4802_regs) 1661 else if (bq4802_regs)
1585 mini_rtc_ops = &bq4802_rtc_ops; 1662 mini_rtc_ops = &bq4802_rtc_ops;
1663 else if (ds1287_regs)
1664 mini_rtc_ops = &cmos_rtc_ops;
1586#endif /* CONFIG_PCI */ 1665#endif /* CONFIG_PCI */
1587 else 1666 else
1588 return -ENODEV; 1667 return -ENODEV;
diff --git a/arch/sparc64/kernel/vio.c b/arch/sparc64/kernel/vio.c
index 491223a6628f..3685daf5157f 100644
--- a/arch/sparc64/kernel/vio.c
+++ b/arch/sparc64/kernel/vio.c
@@ -205,7 +205,8 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
205 struct device_node *dp; 205 struct device_node *dp;
206 struct vio_dev *vdev; 206 struct vio_dev *vdev;
207 int err, tlen, clen; 207 int err, tlen, clen;
208 const u64 *id; 208 const u64 *id, *cfg_handle;
209 u64 a;
209 210
210 type = mdesc_get_property(hp, mp, "device-type", &tlen); 211 type = mdesc_get_property(hp, mp, "device-type", &tlen);
211 if (!type) { 212 if (!type) {
@@ -221,26 +222,18 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
221 return NULL; 222 return NULL;
222 } 223 }
223 224
224 if (!strcmp(type, "vdc-port")) { 225 id = mdesc_get_property(hp, mp, "id", NULL);
225 u64 a;
226 226
227 id = NULL; 227 cfg_handle = NULL;
228 mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) { 228 mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) {
229 u64 target; 229 u64 target;
230 230
231 target = mdesc_arc_target(hp, a); 231 target = mdesc_arc_target(hp, a);
232 id = mdesc_get_property(hp, target, 232 cfg_handle = mdesc_get_property(hp, target,
233 "cfg-handle", NULL); 233 "cfg-handle", NULL);
234 if (id) 234 if (cfg_handle)
235 break; 235 break;
236 } 236 }
237 if (!id) {
238 printk(KERN_ERR "VIO: vdc-port lacks parent "
239 "cfg-handle.\n");
240 return NULL;
241 }
242 } else
243 id = mdesc_get_property(hp, mp, "id", NULL);
244 237
245 bus_id_name = type; 238 bus_id_name = type;
246 if (!strcmp(type, "domain-services-port")) 239 if (!strcmp(type, "domain-services-port"))
@@ -285,10 +278,14 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
285 snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s", 278 snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s",
286 bus_id_name); 279 bus_id_name);
287 vdev->dev_no = ~(u64)0; 280 vdev->dev_no = ~(u64)0;
288 } else { 281 } else if (!cfg_handle) {
289 snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s-%lu", 282 snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s-%lu",
290 bus_id_name, *id); 283 bus_id_name, *id);
291 vdev->dev_no = *id; 284 vdev->dev_no = *id;
285 } else {
286 snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s-%lu-%lu",
287 bus_id_name, *cfg_handle, *id);
288 vdev->dev_no = *cfg_handle;
292 } 289 }
293 290
294 vdev->dev.parent = parent; 291 vdev->dev.parent = parent;
diff --git a/arch/sparc64/prom/console.c b/arch/sparc64/prom/console.c
index 7c25c54cefdc..3fafa9a8b50b 100644
--- a/arch/sparc64/prom/console.c
+++ b/arch/sparc64/prom/console.c
@@ -73,88 +73,3 @@ prom_puts(const char *s, int len)
73 P1275_INOUT(3,1), 73 P1275_INOUT(3,1),
74 prom_stdout, s, P1275_SIZE(len)); 74 prom_stdout, s, P1275_SIZE(len));
75} 75}
76
77/* Query for input device type */
78enum prom_input_device
79prom_query_input_device(void)
80{
81 int st_p;
82 char propb[64];
83
84 st_p = prom_inst2pkg(prom_stdin);
85 if(prom_node_has_property(st_p, "keyboard"))
86 return PROMDEV_IKBD;
87 prom_getproperty(st_p, "device_type", propb, sizeof(propb));
88 if(strncmp(propb, "serial", 6))
89 return PROMDEV_I_UNK;
90 /* FIXME: Is there any better way how to find out? */
91 memset(propb, 0, sizeof(propb));
92 st_p = prom_finddevice ("/options");
93 prom_getproperty(st_p, "input-device", propb, sizeof(propb));
94
95 /*
96 * If we get here with propb == 'keyboard', we are on ttya, as
97 * the PROM defaulted to this due to 'no input device'.
98 */
99 if (!strncmp(propb, "keyboard", 8))
100 return PROMDEV_ITTYA;
101
102 if (!strncmp (propb, "rsc", 3))
103 return PROMDEV_IRSC;
104
105 if (!strncmp (propb, "virtual-console", 3))
106 return PROMDEV_IVCONS;
107
108 if (strncmp (propb, "tty", 3) || !propb[3])
109 return PROMDEV_I_UNK;
110
111 switch (propb[3]) {
112 case 'a': return PROMDEV_ITTYA;
113 case 'b': return PROMDEV_ITTYB;
114 default: return PROMDEV_I_UNK;
115 }
116}
117
118/* Query for output device type */
119
120enum prom_output_device
121prom_query_output_device(void)
122{
123 int st_p;
124 char propb[64];
125 int propl;
126
127 st_p = prom_inst2pkg(prom_stdout);
128 propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb));
129 if (propl >= 0 && propl == sizeof("display") &&
130 strncmp("display", propb, sizeof("display")) == 0)
131 return PROMDEV_OSCREEN;
132 if(strncmp("serial", propb, 6))
133 return PROMDEV_O_UNK;
134 /* FIXME: Is there any better way how to find out? */
135 memset(propb, 0, sizeof(propb));
136 st_p = prom_finddevice ("/options");
137 prom_getproperty(st_p, "output-device", propb, sizeof(propb));
138
139 /*
140 * If we get here with propb == 'screen', we are on ttya, as
141 * the PROM defaulted to this due to 'no input device'.
142 */
143 if (!strncmp(propb, "screen", 6))
144 return PROMDEV_OTTYA;
145
146 if (!strncmp (propb, "rsc", 3))
147 return PROMDEV_ORSC;
148
149 if (!strncmp (propb, "virtual-console", 3))
150 return PROMDEV_OVCONS;
151
152 if (strncmp (propb, "tty", 3) || !propb[3])
153 return PROMDEV_O_UNK;
154
155 switch (propb[3]) {
156 case 'a': return PROMDEV_OTTYA;
157 case 'b': return PROMDEV_OTTYB;
158 default: return PROMDEV_O_UNK;
159 }
160}
diff --git a/arch/sparc64/prom/misc.c b/arch/sparc64/prom/misc.c
index 33c5b7da31e5..68c83ad04ad9 100644
--- a/arch/sparc64/prom/misc.c
+++ b/arch/sparc64/prom/misc.c
@@ -72,7 +72,7 @@ void prom_cmdline(void)
72 72
73 local_irq_save(flags); 73 local_irq_save(flags);
74 74
75 if (!serial_console && prom_palette) 75 if (prom_palette)
76 prom_palette(1); 76 prom_palette(1);
77 77
78#ifdef CONFIG_SMP 78#ifdef CONFIG_SMP
@@ -85,7 +85,7 @@ void prom_cmdline(void)
85 smp_release(); 85 smp_release();
86#endif 86#endif
87 87
88 if (!serial_console && prom_palette) 88 if (prom_palette)
89 prom_palette(0); 89 prom_palette(0);
90 90
91 local_irq_restore(flags); 91 local_irq_restore(flags);
diff --git a/arch/sparc64/prom/tree.c b/arch/sparc64/prom/tree.c
index 17b7ecfe7ca9..b2c5b12c9818 100644
--- a/arch/sparc64/prom/tree.c
+++ b/arch/sparc64/prom/tree.c
@@ -304,3 +304,11 @@ prom_pathtoinode(const char *path)
304 if (node == -1) return 0; 304 if (node == -1) return 0;
305 return node; 305 return node;
306} 306}
307
308int prom_ihandle2path(int handle, char *buffer, int bufsize)
309{
310 return p1275_cmd("instance-to-path",
311 P1275_ARG(1,P1275_ARG_OUT_BUF)|
312 P1275_INOUT(3, 1),
313 handle, buffer, P1275_SIZE(bufsize));
314}
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 4373d7cdc5d2..c8dfd18bea44 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -726,7 +726,7 @@ config NVRAM
726 726
727config RTC 727config RTC
728 tristate "Enhanced Real Time Clock Support" 728 tristate "Enhanced Real Time Clock Support"
729 depends on !PPC && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV && !ARM && !SUPERH && !S390 729 depends on !PPC && !PARISC && !IA64 && !M68K && !SPARC64 && (!SPARC32 || PCI) && !FRV && !ARM && !SUPERH && !S390
730 ---help--- 730 ---help---
731 If you say Y here and create a character special file /dev/rtc with 731 If you say Y here and create a character special file /dev/rtc with
732 major number 10 and minor number 135 using mknod ("man mknod"), you 732 major number 10 and minor number 135 using mknod ("man mknod"), you
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index 22cf7aa56cc4..30c3f54c7666 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -86,12 +86,9 @@
86#include <asm/hpet.h> 86#include <asm/hpet.h>
87#endif 87#endif
88 88
89#ifdef __sparc__ 89#ifdef CONFIG_SPARC32
90#include <linux/pci.h> 90#include <linux/pci.h>
91#include <asm/ebus.h> 91#include <asm/ebus.h>
92#ifdef __sparc_v9__
93#include <asm/isa.h>
94#endif
95 92
96static unsigned long rtc_port; 93static unsigned long rtc_port;
97static int rtc_irq = PCI_IRQ_NONE; 94static int rtc_irq = PCI_IRQ_NONE;
@@ -930,13 +927,9 @@ static int __init rtc_init(void)
930 unsigned int year, ctrl; 927 unsigned int year, ctrl;
931 char *guess = NULL; 928 char *guess = NULL;
932#endif 929#endif
933#ifdef __sparc__ 930#ifdef CONFIG_SPARC32
934 struct linux_ebus *ebus; 931 struct linux_ebus *ebus;
935 struct linux_ebus_device *edev; 932 struct linux_ebus_device *edev;
936#ifdef __sparc_v9__
937 struct sparc_isa_bridge *isa_br;
938 struct sparc_isa_device *isa_dev;
939#endif
940#else 933#else
941 void *r; 934 void *r;
942#ifdef RTC_IRQ 935#ifdef RTC_IRQ
@@ -944,7 +937,7 @@ static int __init rtc_init(void)
944#endif 937#endif
945#endif 938#endif
946 939
947#ifdef __sparc__ 940#ifdef CONFIG_SPARC32
948 for_each_ebus(ebus) { 941 for_each_ebus(ebus) {
949 for_each_ebusdev(edev, ebus) { 942 for_each_ebusdev(edev, ebus) {
950 if(strcmp(edev->prom_node->name, "rtc") == 0) { 943 if(strcmp(edev->prom_node->name, "rtc") == 0) {
@@ -954,17 +947,6 @@ static int __init rtc_init(void)
954 } 947 }
955 } 948 }
956 } 949 }
957#ifdef __sparc_v9__
958 for_each_isa(isa_br) {
959 for_each_isadev(isa_dev, isa_br) {
960 if (strcmp(isa_dev->prom_node->name, "rtc") == 0) {
961 rtc_port = isa_dev->resource.start;
962 rtc_irq = isa_dev->irq;
963 goto found;
964 }
965 }
966 }
967#endif
968 rtc_has_irq = 0; 950 rtc_has_irq = 0;
969 printk(KERN_ERR "rtc_init: no PC rtc found\n"); 951 printk(KERN_ERR "rtc_init: no PC rtc found\n");
970 return -EIO; 952 return -EIO;
@@ -1020,7 +1002,7 @@ no_irq:
1020 1002
1021#endif 1003#endif
1022 1004
1023#endif /* __sparc__ vs. others */ 1005#endif /* CONFIG_SPARC32 vs. others */
1024 1006
1025 if (misc_register(&rtc_dev)) { 1007 if (misc_register(&rtc_dev)) {
1026#ifdef RTC_IRQ 1008#ifdef RTC_IRQ
@@ -1105,7 +1087,7 @@ static void __exit rtc_exit (void)
1105 remove_proc_entry ("driver/rtc", NULL); 1087 remove_proc_entry ("driver/rtc", NULL);
1106 misc_deregister(&rtc_dev); 1088 misc_deregister(&rtc_dev);
1107 1089
1108#ifdef __sparc__ 1090#ifdef CONFIG_SPARC32
1109 if (rtc_has_irq) 1091 if (rtc_has_irq)
1110 free_irq (rtc_irq, &rtc_port); 1092 free_irq (rtc_irq, &rtc_port);
1111#else 1093#else
@@ -1117,7 +1099,7 @@ static void __exit rtc_exit (void)
1117 if (rtc_has_irq) 1099 if (rtc_has_irq)
1118 free_irq (RTC_IRQ, NULL); 1100 free_irq (RTC_IRQ, NULL);
1119#endif 1101#endif
1120#endif /* __sparc__ */ 1102#endif /* CONFIG_SPARC32 */
1121} 1103}
1122 1104
1123module_init(rtc_init); 1105module_init(rtc_init);
diff --git a/drivers/net/sunvnet.c b/drivers/net/sunvnet.c
index ef0066bab2cf..61f98251feab 100644
--- a/drivers/net/sunvnet.c
+++ b/drivers/net/sunvnet.c
@@ -459,6 +459,22 @@ static int vnet_nack(struct vnet_port *port, void *msgbuf)
459 return 0; 459 return 0;
460} 460}
461 461
462static int handle_mcast(struct vnet_port *port, void *msgbuf)
463{
464 struct vio_net_mcast_info *pkt = msgbuf;
465
466 if (pkt->tag.stype != VIO_SUBTYPE_ACK)
467 printk(KERN_ERR PFX "%s: Got unexpected MCAST reply "
468 "[%02x:%02x:%04x:%08x]\n",
469 port->vp->dev->name,
470 pkt->tag.type,
471 pkt->tag.stype,
472 pkt->tag.stype_env,
473 pkt->tag.sid);
474
475 return 0;
476}
477
462static void maybe_tx_wakeup(struct vnet *vp) 478static void maybe_tx_wakeup(struct vnet *vp)
463{ 479{
464 struct net_device *dev = vp->dev; 480 struct net_device *dev = vp->dev;
@@ -544,7 +560,10 @@ static void vnet_event(void *arg, int event)
544 err = vnet_nack(port, &msgbuf); 560 err = vnet_nack(port, &msgbuf);
545 } 561 }
546 } else if (msgbuf.tag.type == VIO_TYPE_CTRL) { 562 } else if (msgbuf.tag.type == VIO_TYPE_CTRL) {
547 err = vio_control_pkt_engine(vio, &msgbuf); 563 if (msgbuf.tag.stype_env == VNET_MCAST_INFO)
564 err = handle_mcast(port, &msgbuf);
565 else
566 err = vio_control_pkt_engine(vio, &msgbuf);
548 if (err) 567 if (err)
549 break; 568 break;
550 } else { 569 } else {
@@ -731,9 +750,122 @@ static int vnet_close(struct net_device *dev)
731 return 0; 750 return 0;
732} 751}
733 752
753static struct vnet_mcast_entry *__vnet_mc_find(struct vnet *vp, u8 *addr)
754{
755 struct vnet_mcast_entry *m;
756
757 for (m = vp->mcast_list; m; m = m->next) {
758 if (!memcmp(m->addr, addr, ETH_ALEN))
759 return m;
760 }
761 return NULL;
762}
763
764static void __update_mc_list(struct vnet *vp, struct net_device *dev)
765{
766 struct dev_addr_list *p;
767
768 for (p = dev->mc_list; p; p = p->next) {
769 struct vnet_mcast_entry *m;
770
771 m = __vnet_mc_find(vp, p->dmi_addr);
772 if (m) {
773 m->hit = 1;
774 continue;
775 }
776
777 if (!m) {
778 m = kzalloc(sizeof(*m), GFP_ATOMIC);
779 if (!m)
780 continue;
781 memcpy(m->addr, p->dmi_addr, ETH_ALEN);
782 m->hit = 1;
783
784 m->next = vp->mcast_list;
785 vp->mcast_list = m;
786 }
787 }
788}
789
790static void __send_mc_list(struct vnet *vp, struct vnet_port *port)
791{
792 struct vio_net_mcast_info info;
793 struct vnet_mcast_entry *m, **pp;
794 int n_addrs;
795
796 memset(&info, 0, sizeof(info));
797
798 info.tag.type = VIO_TYPE_CTRL;
799 info.tag.stype = VIO_SUBTYPE_INFO;
800 info.tag.stype_env = VNET_MCAST_INFO;
801 info.tag.sid = vio_send_sid(&port->vio);
802 info.set = 1;
803
804 n_addrs = 0;
805 for (m = vp->mcast_list; m; m = m->next) {
806 if (m->sent)
807 continue;
808 m->sent = 1;
809 memcpy(&info.mcast_addr[n_addrs * ETH_ALEN],
810 m->addr, ETH_ALEN);
811 if (++n_addrs == VNET_NUM_MCAST) {
812 info.count = n_addrs;
813
814 (void) vio_ldc_send(&port->vio, &info,
815 sizeof(info));
816 n_addrs = 0;
817 }
818 }
819 if (n_addrs) {
820 info.count = n_addrs;
821 (void) vio_ldc_send(&port->vio, &info, sizeof(info));
822 }
823
824 info.set = 0;
825
826 n_addrs = 0;
827 pp = &vp->mcast_list;
828 while ((m = *pp) != NULL) {
829 if (m->hit) {
830 m->hit = 0;
831 pp = &m->next;
832 continue;
833 }
834
835 memcpy(&info.mcast_addr[n_addrs * ETH_ALEN],
836 m->addr, ETH_ALEN);
837 if (++n_addrs == VNET_NUM_MCAST) {
838 info.count = n_addrs;
839 (void) vio_ldc_send(&port->vio, &info,
840 sizeof(info));
841 n_addrs = 0;
842 }
843
844 *pp = m->next;
845 kfree(m);
846 }
847 if (n_addrs) {
848 info.count = n_addrs;
849 (void) vio_ldc_send(&port->vio, &info, sizeof(info));
850 }
851}
852
734static void vnet_set_rx_mode(struct net_device *dev) 853static void vnet_set_rx_mode(struct net_device *dev)
735{ 854{
736 /* XXX Implement multicast support XXX */ 855 struct vnet *vp = netdev_priv(dev);
856 struct vnet_port *port;
857 unsigned long flags;
858
859 spin_lock_irqsave(&vp->lock, flags);
860 if (!list_empty(&vp->port_list)) {
861 port = list_entry(vp->port_list.next, struct vnet_port, list);
862
863 if (port->switch_port) {
864 __update_mc_list(vp, dev);
865 __send_mc_list(vp, port);
866 }
867 }
868 spin_unlock_irqrestore(&vp->lock, flags);
737} 869}
738 870
739static int vnet_change_mtu(struct net_device *dev, int new_mtu) 871static int vnet_change_mtu(struct net_device *dev, int new_mtu)
@@ -1070,6 +1202,7 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev,
1070 switch_port = 0; 1202 switch_port = 0;
1071 if (mdesc_get_property(hp, vdev->mp, "switch-port", NULL) != NULL) 1203 if (mdesc_get_property(hp, vdev->mp, "switch-port", NULL) != NULL)
1072 switch_port = 1; 1204 switch_port = 1;
1205 port->switch_port = switch_port;
1073 1206
1074 spin_lock_irqsave(&vp->lock, flags); 1207 spin_lock_irqsave(&vp->lock, flags);
1075 if (switch_port) 1208 if (switch_port)
diff --git a/drivers/net/sunvnet.h b/drivers/net/sunvnet.h
index 7d3a0cac727b..d347a5bf24b0 100644
--- a/drivers/net/sunvnet.h
+++ b/drivers/net/sunvnet.h
@@ -30,6 +30,8 @@ struct vnet_port {
30 30
31 struct hlist_node hash; 31 struct hlist_node hash;
32 u8 raddr[ETH_ALEN]; 32 u8 raddr[ETH_ALEN];
33 u8 switch_port;
34 u8 __pad;
33 35
34 struct vnet *vp; 36 struct vnet *vp;
35 37
@@ -53,6 +55,13 @@ static inline unsigned int vnet_hashfn(u8 *mac)
53 return val & (VNET_PORT_HASH_MASK); 55 return val & (VNET_PORT_HASH_MASK);
54} 56}
55 57
58struct vnet_mcast_entry {
59 u8 addr[ETH_ALEN];
60 u8 sent;
61 u8 hit;
62 struct vnet_mcast_entry *next;
63};
64
56struct vnet { 65struct vnet {
57 /* Protects port_list and port_hash. */ 66 /* Protects port_list and port_hash. */
58 spinlock_t lock; 67 spinlock_t lock;
@@ -65,6 +74,8 @@ struct vnet {
65 74
66 struct hlist_head port_hash[VNET_PORT_HASH_SIZE]; 75 struct hlist_head port_hash[VNET_PORT_HASH_SIZE];
67 76
77 struct vnet_mcast_entry *mcast_list;
78
68 struct list_head list; 79 struct list_head list;
69 u64 local_mac; 80 u64 local_mac;
70}; 81};
diff --git a/drivers/sbus/sbus.c b/drivers/sbus/sbus.c
index 002643392d42..2553629ec15d 100644
--- a/drivers/sbus/sbus.c
+++ b/drivers/sbus/sbus.c
@@ -33,6 +33,7 @@ struct sbus_bus *sbus_root;
33 33
34static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sdev) 34static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sdev)
35{ 35{
36 struct dev_archdata *sd;
36 unsigned long base; 37 unsigned long base;
37 const void *pval; 38 const void *pval;
38 int len, err; 39 int len, err;
@@ -67,6 +68,10 @@ static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sde
67 68
68 sbus_fill_device_irq(sdev); 69 sbus_fill_device_irq(sdev);
69 70
71 sd = &sdev->ofdev.dev.archdata;
72 sd->prom_node = dp;
73 sd->op = &sdev->ofdev;
74
70 sdev->ofdev.node = dp; 75 sdev->ofdev.node = dp;
71 if (sdev->parent) 76 if (sdev->parent)
72 sdev->ofdev.dev.parent = &sdev->parent->ofdev.dev; 77 sdev->ofdev.dev.parent = &sdev->parent->ofdev.dev;
diff --git a/drivers/serial/suncore.c b/drivers/serial/suncore.c
index b45ba5392dd3..70a09a3d5af0 100644
--- a/drivers/serial/suncore.c
+++ b/drivers/serial/suncore.c
@@ -16,9 +16,10 @@
16#include <linux/tty.h> 16#include <linux/tty.h>
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <linux/string.h> 18#include <linux/string.h>
19#include <linux/serial_core.h>
19#include <linux/init.h> 20#include <linux/init.h>
20 21
21#include <asm/oplib.h> 22#include <asm/prom.h>
22 23
23#include "suncore.h" 24#include "suncore.h"
24 25
@@ -26,92 +27,60 @@ int sunserial_current_minor = 64;
26 27
27EXPORT_SYMBOL(sunserial_current_minor); 28EXPORT_SYMBOL(sunserial_current_minor);
28 29
29void 30int sunserial_console_match(struct console *con, struct device_node *dp,
30sunserial_console_termios(struct console *con) 31 struct uart_driver *drv, int line)
31{ 32{
32 char mode[16], buf[16], *s; 33 int off;
33 char mode_prop[] = "ttyX-mode";
34 char cd_prop[] = "ttyX-ignore-cd";
35 char dtr_prop[] = "ttyX-rts-dtr-off";
36 char *ssp_console_modes_prop = "ssp-console-modes";
37 int baud, bits, stop, cflag;
38 char parity;
39 int carrier = 0;
40 int rtsdtr = 1;
41 int topnd, nd;
42
43 if (!serial_console)
44 return;
45
46 switch (serial_console) {
47 case PROMDEV_OTTYA:
48 mode_prop[3] = 'a';
49 cd_prop[3] = 'a';
50 dtr_prop[3] = 'a';
51 break;
52
53 case PROMDEV_OTTYB:
54 mode_prop[3] = 'b';
55 cd_prop[3] = 'b';
56 dtr_prop[3] = 'b';
57 break;
58
59 case PROMDEV_ORSC:
60
61 nd = prom_pathtoinode("rsc");
62 if (!nd) {
63 strcpy(mode, "115200,8,n,1,-");
64 goto no_options;
65 }
66 34
67 if (!prom_node_has_property(nd, ssp_console_modes_prop)) { 35 if (!con || of_console_device != dp)
68 strcpy(mode, "115200,8,n,1,-"); 36 return 0;
69 goto no_options;
70 }
71 37
72 memset(mode, 0, sizeof(mode)); 38 off = 0;
73 prom_getstring(nd, ssp_console_modes_prop, mode, sizeof(mode)); 39 if (of_console_options &&
74 goto no_options; 40 *of_console_options == 'b')
41 off = 1;
75 42
76 default: 43 if ((line & 1) != off)
77 strcpy(mode, "9600,8,n,1,-"); 44 return 0;
78 goto no_options;
79 }
80 45
81 topnd = prom_getchild(prom_root_node); 46 con->index = line;
82 nd = prom_searchsiblings(topnd, "options"); 47 drv->cons = con;
83 if (!nd) { 48 add_preferred_console(con->name, line, NULL);
84 strcpy(mode, "9600,8,n,1,-");
85 goto no_options;
86 }
87
88 if (!prom_node_has_property(nd, mode_prop)) {
89 strcpy(mode, "9600,8,n,1,-");
90 goto no_options;
91 }
92 49
93 memset(mode, 0, sizeof(mode)); 50 return 1;
94 prom_getstring(nd, mode_prop, mode, sizeof(mode)); 51}
95 52EXPORT_SYMBOL(sunserial_console_match);
96 if (prom_node_has_property(nd, cd_prop)) {
97 memset(buf, 0, sizeof(buf));
98 prom_getstring(nd, cd_prop, buf, sizeof(buf));
99 if (!strcmp(buf, "false"))
100 carrier = 1;
101
102 /* XXX: this is unused below. */
103 }
104 53
105 if (prom_node_has_property(nd, dtr_prop)) { 54void
106 memset(buf, 0, sizeof(buf)); 55sunserial_console_termios(struct console *con)
107 prom_getstring(nd, dtr_prop, buf, sizeof(buf)); 56{
108 if (!strcmp(buf, "false")) 57 struct device_node *dp;
109 rtsdtr = 0; 58 const char *od, *mode, *s;
59 char mode_prop[] = "ttyX-mode";
60 int baud, bits, stop, cflag;
61 char parity;
110 62
111 /* XXX: this is unused below. */ 63 dp = of_find_node_by_path("/options");
64 od = of_get_property(dp, "output-device", NULL);
65 if (!strcmp(od, "rsc")) {
66 mode = of_get_property(of_console_device,
67 "ssp-console-modes", NULL);
68 if (!mode)
69 mode = "115200,8,n,1,-";
70 } else {
71 char c;
72
73 c = 'a';
74 if (of_console_options)
75 c = *of_console_options;
76
77 mode_prop[3] = c;
78
79 mode = of_get_property(dp, mode_prop, NULL);
80 if (!mode)
81 mode = "9600,8,n,1,-";
112 } 82 }
113 83
114no_options:
115 cflag = CREAD | HUPCL | CLOCAL; 84 cflag = CREAD | HUPCL | CLOCAL;
116 85
117 s = mode; 86 s = mode;
diff --git a/drivers/serial/suncore.h b/drivers/serial/suncore.h
index 513916a8ce37..829d7d65d6db 100644
--- a/drivers/serial/suncore.h
+++ b/drivers/serial/suncore.h
@@ -24,6 +24,8 @@ extern int suncore_mouse_baud_detection(unsigned char, int);
24 24
25extern int sunserial_current_minor; 25extern int sunserial_current_minor;
26 26
27extern int sunserial_console_match(struct console *, struct device_node *,
28 struct uart_driver *, int);
27extern void sunserial_console_termios(struct console *); 29extern void sunserial_console_termios(struct console *);
28 30
29#endif /* !(_SERIAL_SUN_H) */ 31#endif /* !(_SERIAL_SUN_H) */
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c
index d82be42ff29a..8ff900b09811 100644
--- a/drivers/serial/sunhv.c
+++ b/drivers/serial/sunhv.c
@@ -520,16 +520,6 @@ static struct console sunhv_console = {
520 .data = &sunhv_reg, 520 .data = &sunhv_reg,
521}; 521};
522 522
523static inline struct console *SUNHV_CONSOLE(void)
524{
525 if (con_is_present())
526 return NULL;
527
528 sunhv_console.index = 0;
529
530 return &sunhv_console;
531}
532
533static int __devinit hv_probe(struct of_device *op, const struct of_device_id *match) 523static int __devinit hv_probe(struct of_device *op, const struct of_device_id *match)
534{ 524{
535 struct uart_port *port; 525 struct uart_port *port;
@@ -582,7 +572,8 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m
582 sunhv_reg.tty_driver->name_base = sunhv_reg.minor - 64; 572 sunhv_reg.tty_driver->name_base = sunhv_reg.minor - 64;
583 sunserial_current_minor += 1; 573 sunserial_current_minor += 1;
584 574
585 sunhv_reg.cons = SUNHV_CONSOLE(); 575 sunserial_console_match(&sunhv_console, op->node,
576 &sunhv_reg, port->line);
586 577
587 err = uart_add_one_port(&sunhv_reg, port); 578 err = uart_add_one_port(&sunhv_reg, port);
588 if (err) 579 if (err)
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index 8a0f9e4408d4..bca57bb94939 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -968,22 +968,6 @@ static struct console sunsab_console = {
968 968
969static inline struct console *SUNSAB_CONSOLE(void) 969static inline struct console *SUNSAB_CONSOLE(void)
970{ 970{
971 int i;
972
973 if (con_is_present())
974 return NULL;
975
976 for (i = 0; i < num_channels; i++) {
977 int this_minor = sunsab_reg.minor + i;
978
979 if ((this_minor - 64) == (serial_console - 1))
980 break;
981 }
982 if (i == num_channels)
983 return NULL;
984
985 sunsab_console.index = i;
986
987 return &sunsab_console; 971 return &sunsab_console;
988} 972}
989#else 973#else
@@ -1080,7 +1064,12 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id *
1080 return err; 1064 return err;
1081 } 1065 }
1082 1066
1067 sunserial_console_match(SUNSAB_CONSOLE(), op->node,
1068 &sunsab_reg, up[0].port.line);
1083 uart_add_one_port(&sunsab_reg, &up[0].port); 1069 uart_add_one_port(&sunsab_reg, &up[0].port);
1070
1071 sunserial_console_match(SUNSAB_CONSOLE(), op->node,
1072 &sunsab_reg, up[1].port.line);
1084 uart_add_one_port(&sunsab_reg, &up[1].port); 1073 uart_add_one_port(&sunsab_reg, &up[1].port);
1085 1074
1086 dev_set_drvdata(&op->dev, &up[0]); 1075 dev_set_drvdata(&op->dev, &up[0]);
@@ -1164,7 +1153,6 @@ static int __init sunsab_init(void)
1164 } 1153 }
1165 1154
1166 sunsab_reg.tty_driver->name_base = sunsab_reg.minor - 64; 1155 sunsab_reg.tty_driver->name_base = sunsab_reg.minor - 64;
1167 sunsab_reg.cons = SUNSAB_CONSOLE();
1168 sunserial_current_minor += num_channels; 1156 sunserial_current_minor += num_channels;
1169 } 1157 }
1170 1158
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 26d720baf88c..79b13685bdfa 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1371,28 +1371,12 @@ static struct console sunsu_console = {
1371 * Register console. 1371 * Register console.
1372 */ 1372 */
1373 1373
1374static inline struct console *SUNSU_CONSOLE(int num_uart) 1374static inline struct console *SUNSU_CONSOLE(void)
1375{ 1375{
1376 int i;
1377
1378 if (con_is_present())
1379 return NULL;
1380
1381 for (i = 0; i < num_uart; i++) {
1382 int this_minor = sunsu_reg.minor + i;
1383
1384 if ((this_minor - 64) == (serial_console - 1))
1385 break;
1386 }
1387 if (i == num_uart)
1388 return NULL;
1389
1390 sunsu_console.index = i;
1391
1392 return &sunsu_console; 1376 return &sunsu_console;
1393} 1377}
1394#else 1378#else
1395#define SUNSU_CONSOLE(num_uart) (NULL) 1379#define SUNSU_CONSOLE() (NULL)
1396#define sunsu_serial_console_init() do { } while (0) 1380#define sunsu_serial_console_init() do { } while (0)
1397#endif 1381#endif
1398 1382
@@ -1482,6 +1466,8 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
1482 1466
1483 up->port.ops = &sunsu_pops; 1467 up->port.ops = &sunsu_pops;
1484 1468
1469 sunserial_console_match(SUNSU_CONSOLE(), dp,
1470 &sunsu_reg, up->port.line);
1485 err = uart_add_one_port(&sunsu_reg, &up->port); 1471 err = uart_add_one_port(&sunsu_reg, &up->port);
1486 if (err) 1472 if (err)
1487 goto out_unmap; 1473 goto out_unmap;
@@ -1572,7 +1558,6 @@ static int __init sunsu_init(void)
1572 return err; 1558 return err;
1573 sunsu_reg.tty_driver->name_base = sunsu_reg.minor - 64; 1559 sunsu_reg.tty_driver->name_base = sunsu_reg.minor - 64;
1574 sunserial_current_minor += num_uart; 1560 sunserial_current_minor += num_uart;
1575 sunsu_reg.cons = SUNSU_CONSOLE(num_uart);
1576 } 1561 }
1577 1562
1578 err = of_register_driver(&su_driver, &of_bus_type); 1563 err = of_register_driver(&su_driver, &of_bus_type);
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 0a3e10a4a35d..1d262c0c613f 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -1226,23 +1226,6 @@ static struct console sunzilog_console_ops = {
1226 1226
1227static inline struct console *SUNZILOG_CONSOLE(void) 1227static inline struct console *SUNZILOG_CONSOLE(void)
1228{ 1228{
1229 int i;
1230
1231 if (con_is_present())
1232 return NULL;
1233
1234 for (i = 0; i < NUM_CHANNELS; i++) {
1235 int this_minor = sunzilog_reg.minor + i;
1236
1237 if ((this_minor - 64) == (serial_console - 1))
1238 break;
1239 }
1240 if (i == NUM_CHANNELS)
1241 return NULL;
1242
1243 sunzilog_console_ops.index = i;
1244 sunzilog_port_table[i].flags |= SUNZILOG_FLAG_IS_CONS;
1245
1246 return &sunzilog_console_ops; 1229 return &sunzilog_console_ops;
1247} 1230}
1248 1231
@@ -1428,12 +1411,18 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
1428 sunzilog_init_hw(&up[1]); 1411 sunzilog_init_hw(&up[1]);
1429 1412
1430 if (!keyboard_mouse) { 1413 if (!keyboard_mouse) {
1414 if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node,
1415 &sunzilog_reg, up[0].port.line))
1416 up->flags |= SUNZILOG_FLAG_IS_CONS;
1431 err = uart_add_one_port(&sunzilog_reg, &up[0].port); 1417 err = uart_add_one_port(&sunzilog_reg, &up[0].port);
1432 if (err) { 1418 if (err) {
1433 of_iounmap(&op->resource[0], 1419 of_iounmap(&op->resource[0],
1434 rp, sizeof(struct zilog_layout)); 1420 rp, sizeof(struct zilog_layout));
1435 return err; 1421 return err;
1436 } 1422 }
1423 if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node,
1424 &sunzilog_reg, up[1].port.line))
1425 up->flags |= SUNZILOG_FLAG_IS_CONS;
1437 err = uart_add_one_port(&sunzilog_reg, &up[1].port); 1426 err = uart_add_one_port(&sunzilog_reg, &up[1].port);
1438 if (err) { 1427 if (err) {
1439 uart_remove_one_port(&sunzilog_reg, &up[0].port); 1428 uart_remove_one_port(&sunzilog_reg, &up[0].port);
@@ -1531,7 +1520,6 @@ static int __init sunzilog_init(void)
1531 goto out_free_tables; 1520 goto out_free_tables;
1532 1521
1533 sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64; 1522 sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64;
1534 sunzilog_reg.cons = SUNZILOG_CONSOLE();
1535 1523
1536 sunserial_current_minor += uart_count; 1524 sunserial_current_minor += uart_count;
1537 } 1525 }
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 0c7bf75732ea..13990697b5c1 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2913,10 +2913,6 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
2913 int node, len, i, j, ret; 2913 int node, len, i, j, ret;
2914 u32 mem, chip_id; 2914 u32 mem, chip_id;
2915 2915
2916 /* Do not attach when we have a serial console. */
2917 if (!con_is_present())
2918 return -ENXIO;
2919
2920 /* 2916 /*
2921 * Map memory-mapped registers. 2917 * Map memory-mapped registers.
2922 */ 2918 */
diff --git a/drivers/video/igafb.c b/drivers/video/igafb.c
index eb1a4812ad1d..b87ea21d3d78 100644
--- a/drivers/video/igafb.c
+++ b/drivers/video/igafb.c
@@ -379,10 +379,6 @@ int __init igafb_init(void)
379 if (fb_get_options("igafb", NULL)) 379 if (fb_get_options("igafb", NULL))
380 return -ENODEV; 380 return -ENODEV;
381 381
382 /* Do not attach when we have a serial console. */
383 if (!con_is_present())
384 return -ENXIO;
385
386 pdev = pci_get_device(PCI_VENDOR_ID_INTERG, 382 pdev = pci_get_device(PCI_VENDOR_ID_INTERG,
387 PCI_DEVICE_ID_INTERG_1682, 0); 383 PCI_DEVICE_ID_INTERG_1682, 0);
388 if (pdev == NULL) { 384 if (pdev == NULL) {
diff --git a/include/asm-sparc/device.h b/include/asm-sparc/device.h
index d8f9872b0e2d..4a56d84d69c4 100644
--- a/include/asm-sparc/device.h
+++ b/include/asm-sparc/device.h
@@ -3,5 +3,17 @@
3 * 3 *
4 * This file is released under the GPLv2 4 * This file is released under the GPLv2
5 */ 5 */
6#include <asm-generic/device.h> 6#ifndef _ASM_SPARC_DEVICE_H
7#define _ASM_SPARC_DEVICE_H
8
9struct device_node;
10struct of_device;
11
12struct dev_archdata {
13 struct device_node *prom_node;
14 struct of_device *op;
15};
16
17#endif /* _ASM_SPARC_DEVICE_H */
18
7 19
diff --git a/include/asm-sparc/fb.h b/include/asm-sparc/fb.h
index c7df38030992..c73ca081e1f5 100644
--- a/include/asm-sparc/fb.h
+++ b/include/asm-sparc/fb.h
@@ -1,11 +1,20 @@
1#ifndef _ASM_FB_H_ 1#ifndef _ASM_FB_H_
2#define _ASM_FB_H_ 2#define _ASM_FB_H_
3#include <linux/fb.h> 3#include <linux/fb.h>
4#include <asm/prom.h>
4 5
5#define fb_pgprotect(...) do {} while (0) 6#define fb_pgprotect(...) do {} while (0)
6 7
7static inline int fb_is_primary_device(struct fb_info *info) 8static inline int fb_is_primary_device(struct fb_info *info)
8{ 9{
10 struct device *dev = info->device;
11 struct device_node *node;
12
13 node = dev->archdata.prom_node;
14 if (node &&
15 node == of_console_device)
16 return 1;
17
9 return 0; 18 return 0;
10} 19}
11 20
diff --git a/include/asm-sparc/oplib.h b/include/asm-sparc/oplib.h
index 91691e52c058..17ba82ee220a 100644
--- a/include/asm-sparc/oplib.h
+++ b/include/asm-sparc/oplib.h
@@ -158,32 +158,6 @@ extern void prom_putchar(char character);
158extern void prom_printf(char *fmt, ...); 158extern void prom_printf(char *fmt, ...);
159extern void prom_write(const char *buf, unsigned int len); 159extern void prom_write(const char *buf, unsigned int len);
160 160
161/* Query for input device type */
162
163enum prom_input_device {
164 PROMDEV_IKBD, /* input from keyboard */
165 PROMDEV_ITTYA, /* input from ttya */
166 PROMDEV_ITTYB, /* input from ttyb */
167 PROMDEV_IRSC, /* input from rsc */
168 PROMDEV_IVCONS, /* input from virtual-console */
169 PROMDEV_I_UNK,
170};
171
172extern enum prom_input_device prom_query_input_device(void);
173
174/* Query for output device type */
175
176enum prom_output_device {
177 PROMDEV_OSCREEN, /* to screen */
178 PROMDEV_OTTYA, /* to ttya */
179 PROMDEV_OTTYB, /* to ttyb */
180 PROMDEV_ORSC, /* to rsc */
181 PROMDEV_OVCONS, /* to virtual-console */
182 PROMDEV_O_UNK,
183};
184
185extern enum prom_output_device prom_query_output_device(void);
186
187/* Multiprocessor operations... */ 161/* Multiprocessor operations... */
188 162
189/* Start the CPU with the given device tree node, context table, and context 163/* Start the CPU with the given device tree node, context table, and context
diff --git a/include/asm-sparc/prom.h b/include/asm-sparc/prom.h
index db9feb75bd86..350676c589f9 100644
--- a/include/asm-sparc/prom.h
+++ b/include/asm-sparc/prom.h
@@ -85,5 +85,9 @@ static inline void of_node_put(struct device_node *node)
85 */ 85 */
86#include <linux/of.h> 86#include <linux/of.h>
87 87
88extern struct device_node *of_console_device;
89extern char *of_console_path;
90extern char *of_console_options;
91
88#endif /* __KERNEL__ */ 92#endif /* __KERNEL__ */
89#endif /* _SPARC_PROM_H */ 93#endif /* _SPARC_PROM_H */
diff --git a/include/asm-sparc64/fb.h b/include/asm-sparc64/fb.h
index d6cd3a175fc3..389012e5fbad 100644
--- a/include/asm-sparc64/fb.h
+++ b/include/asm-sparc64/fb.h
@@ -3,6 +3,7 @@
3#include <linux/fb.h> 3#include <linux/fb.h>
4#include <linux/fs.h> 4#include <linux/fs.h>
5#include <asm/page.h> 5#include <asm/page.h>
6#include <asm/prom.h>
6 7
7static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma, 8static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
8 unsigned long off) 9 unsigned long off)
@@ -12,6 +13,14 @@ static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
12 13
13static inline int fb_is_primary_device(struct fb_info *info) 14static inline int fb_is_primary_device(struct fb_info *info)
14{ 15{
16 struct device *dev = info->device;
17 struct device_node *node;
18
19 node = dev->archdata.prom_node;
20 if (node &&
21 node == of_console_device)
22 return 1;
23
15 return 0; 24 return 0;
16} 25}
17 26
diff --git a/include/asm-sparc64/oplib.h b/include/asm-sparc64/oplib.h
index 992f9f7a476c..3f23c5dc5f21 100644
--- a/include/asm-sparc64/oplib.h
+++ b/include/asm-sparc64/oplib.h
@@ -140,32 +140,6 @@ extern void prom_putchar(char character);
140extern void prom_printf(const char *fmt, ...); 140extern void prom_printf(const char *fmt, ...);
141extern void prom_write(const char *buf, unsigned int len); 141extern void prom_write(const char *buf, unsigned int len);
142 142
143/* Query for input device type */
144
145enum prom_input_device {
146 PROMDEV_IKBD, /* input from keyboard */
147 PROMDEV_ITTYA, /* input from ttya */
148 PROMDEV_ITTYB, /* input from ttyb */
149 PROMDEV_IRSC, /* input from rsc */
150 PROMDEV_IVCONS, /* input from virtual-console */
151 PROMDEV_I_UNK,
152};
153
154extern enum prom_input_device prom_query_input_device(void);
155
156/* Query for output device type */
157
158enum prom_output_device {
159 PROMDEV_OSCREEN, /* to screen */
160 PROMDEV_OTTYA, /* to ttya */
161 PROMDEV_OTTYB, /* to ttyb */
162 PROMDEV_ORSC, /* to rsc */
163 PROMDEV_OVCONS, /* to virtual-console */
164 PROMDEV_O_UNK,
165};
166
167extern enum prom_output_device prom_query_output_device(void);
168
169/* Multiprocessor operations... */ 143/* Multiprocessor operations... */
170#ifdef CONFIG_SMP 144#ifdef CONFIG_SMP
171/* Start the CPU with the given device tree node at the passed program 145/* Start the CPU with the given device tree node at the passed program
@@ -319,6 +293,8 @@ extern int prom_inst2pkg(int);
319extern int prom_service_exists(const char *service_name); 293extern int prom_service_exists(const char *service_name);
320extern void prom_sun4v_guest_soft_state(void); 294extern void prom_sun4v_guest_soft_state(void);
321 295
296extern int prom_ihandle2path(int handle, char *buffer, int bufsize);
297
322/* Client interface level routines. */ 298/* Client interface level routines. */
323extern void prom_set_trap_table(unsigned long tba); 299extern void prom_set_trap_table(unsigned long tba);
324extern void prom_set_trap_table_sun4v(unsigned long tba, unsigned long mmfsa); 300extern void prom_set_trap_table_sun4v(unsigned long tba, unsigned long mmfsa);
diff --git a/include/asm-sparc64/parport.h b/include/asm-sparc64/parport.h
index 23cc63f049a8..600afe5ae2e3 100644
--- a/include/asm-sparc64/parport.h
+++ b/include/asm-sparc64/parport.h
@@ -8,8 +8,9 @@
8#define _ASM_SPARC64_PARPORT_H 1 8#define _ASM_SPARC64_PARPORT_H 1
9 9
10#include <asm/ebus.h> 10#include <asm/ebus.h>
11#include <asm/isa.h>
12#include <asm/ns87303.h> 11#include <asm/ns87303.h>
12#include <asm/of_device.h>
13#include <asm/prom.h>
13 14
14#define PARPORT_PC_MAX_PORTS PARPORT_MAX 15#define PARPORT_PC_MAX_PORTS PARPORT_MAX
15 16
@@ -35,8 +36,12 @@ static struct sparc_ebus_info {
35 unsigned int addr; 36 unsigned int addr;
36 unsigned int count; 37 unsigned int count;
37 int lock; 38 int lock;
39
40 struct parport *port;
38} sparc_ebus_dmas[PARPORT_PC_MAX_PORTS]; 41} sparc_ebus_dmas[PARPORT_PC_MAX_PORTS];
39 42
43static DECLARE_BITMAP(dma_slot_map, PARPORT_PC_MAX_PORTS);
44
40static __inline__ int request_dma(unsigned int dmanr, const char *device_id) 45static __inline__ int request_dma(unsigned int dmanr, const char *device_id)
41{ 46{
42 if (dmanr >= PARPORT_PC_MAX_PORTS) 47 if (dmanr >= PARPORT_PC_MAX_PORTS)
@@ -98,117 +103,145 @@ static __inline__ unsigned int get_dma_residue(unsigned int dmanr)
98 return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info); 103 return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info);
99} 104}
100 105
101static int ebus_ecpp_p(struct linux_ebus_device *edev) 106static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id *match)
102{ 107{
103 if (!strcmp(edev->prom_node->name, "ecpp")) 108 unsigned long base = op->resource[0].start;
104 return 1; 109 unsigned long config = op->resource[1].start;
105 if (!strcmp(edev->prom_node->name, "parallel")) { 110 unsigned long d_base = op->resource[2].start;
106 const char *compat; 111 unsigned long d_len;
107 112 struct device_node *parent;
108 compat = of_get_property(edev->prom_node, 113 struct parport *p;
109 "compatible", NULL); 114 int slot, err;
110 if (compat && 115
111 (!strcmp(compat, "ecpp") || 116 parent = op->node->parent;
112 !strcmp(compat, "ns87317-ecpp") || 117 if (!strcmp(parent->name, "dma")) {
113 !strcmp(compat + 13, "ecpp"))) 118 p = parport_pc_probe_port(base, base + 0x400,
114 return 1; 119 op->irqs[0], PARPORT_DMA_NOFIFO,
120 op->dev.parent);
121 if (!p)
122 return -ENOMEM;
123 dev_set_drvdata(&op->dev, p);
124 return 0;
115 } 125 }
126
127 for (slot = 0; slot < PARPORT_PC_MAX_PORTS; slot++) {
128 if (!test_and_set_bit(slot, dma_slot_map))
129 break;
130 }
131 err = -ENODEV;
132 if (slot >= PARPORT_PC_MAX_PORTS)
133 goto out_err;
134
135 spin_lock_init(&sparc_ebus_dmas[slot].info.lock);
136
137 d_len = (op->resource[2].end - d_base) + 1UL;
138 sparc_ebus_dmas[slot].info.regs =
139 of_ioremap(&op->resource[2], 0, d_len, "ECPP DMA");
140
141 if (!sparc_ebus_dmas[slot].info.regs)
142 goto out_clear_map;
143
144 sparc_ebus_dmas[slot].info.flags = 0;
145 sparc_ebus_dmas[slot].info.callback = NULL;
146 sparc_ebus_dmas[slot].info.client_cookie = NULL;
147 sparc_ebus_dmas[slot].info.irq = 0xdeadbeef;
148 strcpy(sparc_ebus_dmas[slot].info.name, "parport");
149 if (ebus_dma_register(&sparc_ebus_dmas[slot].info))
150 goto out_unmap_regs;
151
152 ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 1);
153
154 /* Configure IRQ to Push Pull, Level Low */
155 /* Enable ECP, set bit 2 of the CTR first */
156 outb(0x04, base + 0x02);
157 ns87303_modify(config, PCR,
158 PCR_EPP_ENABLE |
159 PCR_IRQ_ODRAIN,
160 PCR_ECP_ENABLE |
161 PCR_ECP_CLK_ENA |
162 PCR_IRQ_POLAR);
163
164 /* CTR bit 5 controls direction of port */
165 ns87303_modify(config, PTR,
166 0, PTR_LPT_REG_DIR);
167
168 p = parport_pc_probe_port(base, base + 0x400,
169 op->irqs[0],
170 slot,
171 op->dev.parent);
172 err = -ENOMEM;
173 if (!p)
174 goto out_disable_irq;
175
176 dev_set_drvdata(&op->dev, p);
177
116 return 0; 178 return 0;
179
180out_disable_irq:
181 ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0);
182 ebus_dma_unregister(&sparc_ebus_dmas[slot].info);
183
184out_unmap_regs:
185 of_iounmap(&op->resource[2], sparc_ebus_dmas[slot].info.regs, d_len);
186
187out_clear_map:
188 clear_bit(slot, dma_slot_map);
189
190out_err:
191 return err;
117} 192}
118 193
119static int parport_isa_probe(int count) 194static int __devexit ecpp_remove(struct of_device *op)
120{ 195{
121 struct sparc_isa_bridge *isa_br; 196 struct parport *p = dev_get_drvdata(&op->dev);
122 struct sparc_isa_device *isa_dev; 197 int slot = p->dma;
123 198
124 for_each_isa(isa_br) { 199 parport_pc_unregister_port(p);
125 for_each_isadev(isa_dev, isa_br) { 200
126 struct sparc_isa_device *child; 201 if (slot != PARPORT_DMA_NOFIFO) {
127 unsigned long base; 202 unsigned long d_base = op->resource[2].start;
128 203 unsigned long d_len;
129 if (strcmp(isa_dev->prom_node->name, "dma")) 204
130 continue; 205 d_len = (op->resource[2].end - d_base) + 1UL;
131 206
132 child = isa_dev->child; 207 ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0);
133 while (child) { 208 ebus_dma_unregister(&sparc_ebus_dmas[slot].info);
134 if (!strcmp(child->prom_node->name, "parallel")) 209 of_iounmap(&op->resource[2],
135 break; 210 sparc_ebus_dmas[slot].info.regs,
136 child = child->next; 211 d_len);
137 } 212 clear_bit(slot, dma_slot_map);
138 if (!child)
139 continue;
140
141 base = child->resource.start;
142
143 /* No DMA, see commentary in
144 * asm-sparc64/floppy.h:isa_floppy_init()
145 */
146 if (parport_pc_probe_port(base, base + 0x400,
147 child->irq, PARPORT_DMA_NOFIFO,
148 &child->bus->self->dev))
149 count++;
150 }
151 } 213 }
152 214
153 return count; 215 return 0;
154} 216}
155 217
156static int parport_pc_find_nonpci_ports (int autoirq, int autodma) 218static struct of_device_id ecpp_match[] = {
219 {
220 .name = "ecpp",
221 },
222 {
223 .name = "parallel",
224 .compatible = "ecpp",
225 },
226 {
227 .name = "parallel",
228 .compatible = "ns87317-ecpp",
229 },
230 {},
231};
232
233static struct of_platform_driver ecpp_driver = {
234 .name = "ecpp",
235 .match_table = ecpp_match,
236 .probe = ecpp_probe,
237 .remove = __devexit_p(ecpp_remove),
238};
239
240static int parport_pc_find_nonpci_ports(int autoirq, int autodma)
157{ 241{
158 struct linux_ebus *ebus; 242 of_register_driver(&ecpp_driver, &of_bus_type);
159 struct linux_ebus_device *edev;
160 int count = 0;
161
162 for_each_ebus(ebus) {
163 for_each_ebusdev(edev, ebus) {
164 if (ebus_ecpp_p(edev)) {
165 unsigned long base = edev->resource[0].start;
166 unsigned long config = edev->resource[1].start;
167 unsigned long d_base = edev->resource[2].start;
168 unsigned long d_len;
169
170 spin_lock_init(&sparc_ebus_dmas[count].info.lock);
171 d_len = (edev->resource[2].end -
172 d_base) + 1;
173 sparc_ebus_dmas[count].info.regs =
174 ioremap(d_base, d_len);
175 if (!sparc_ebus_dmas[count].info.regs)
176 continue;
177 sparc_ebus_dmas[count].info.flags = 0;
178 sparc_ebus_dmas[count].info.callback = NULL;
179 sparc_ebus_dmas[count].info.client_cookie = NULL;
180 sparc_ebus_dmas[count].info.irq = 0xdeadbeef;
181 strcpy(sparc_ebus_dmas[count].info.name, "parport");
182 if (ebus_dma_register(&sparc_ebus_dmas[count].info))
183 continue;
184 ebus_dma_irq_enable(&sparc_ebus_dmas[count].info, 1);
185
186 /* Configure IRQ to Push Pull, Level Low */
187 /* Enable ECP, set bit 2 of the CTR first */
188 outb(0x04, base + 0x02);
189 ns87303_modify(config, PCR,
190 PCR_EPP_ENABLE |
191 PCR_IRQ_ODRAIN,
192 PCR_ECP_ENABLE |
193 PCR_ECP_CLK_ENA |
194 PCR_IRQ_POLAR);
195
196 /* CTR bit 5 controls direction of port */
197 ns87303_modify(config, PTR,
198 0, PTR_LPT_REG_DIR);
199
200 if (parport_pc_probe_port(base, base + 0x400,
201 edev->irqs[0],
202 count,
203 &ebus->self->dev))
204 count++;
205 }
206 }
207 }
208 243
209 count = parport_isa_probe(count); 244 return 0;
210
211 return count;
212} 245}
213 246
214#endif /* !(_ASM_SPARC64_PARPORT_H */ 247#endif /* !(_ASM_SPARC64_PARPORT_H */
diff --git a/include/asm-sparc64/prom.h b/include/asm-sparc64/prom.h
index 2b9e0d795faf..31dcb92fbae0 100644
--- a/include/asm-sparc64/prom.h
+++ b/include/asm-sparc64/prom.h
@@ -94,5 +94,9 @@ static inline void of_node_put(struct device_node *node)
94 */ 94 */
95#include <linux/of.h> 95#include <linux/of.h>
96 96
97extern struct device_node *of_console_device;
98extern char *of_console_path;
99extern char *of_console_options;
100
97#endif /* __KERNEL__ */ 101#endif /* __KERNEL__ */
98#endif /* _SPARC64_PROM_H */ 102#endif /* _SPARC64_PROM_H */
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
index 409067408eec..64891cb10f05 100644
--- a/include/asm-sparc64/system.h
+++ b/include/asm-sparc64/system.h
@@ -115,14 +115,8 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \
115#ifndef __ASSEMBLY__ 115#ifndef __ASSEMBLY__
116 116
117extern void sun_do_break(void); 117extern void sun_do_break(void);
118extern int serial_console;
119extern int stop_a_enabled; 118extern int stop_a_enabled;
120 119
121static __inline__ int con_is_present(void)
122{
123 return serial_console ? 0 : 1;
124}
125
126extern void synchronize_user_stack(void); 120extern void synchronize_user_stack(void);
127 121
128extern void __flushw_user(void); 122extern void __flushw_user(void);