aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-20 11:26:54 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-20 11:26:54 -0400
commit5ac12c6fe1b5fbda0d0caedb8214cde545a5737c (patch)
tree26c7ad8f48ee82d4253a4a8c0637180aa0fb8b0d /arch/sparc64/kernel
parent52a23685f37c06d0cd00eeb8f517a90de3f2c338 (diff)
parent78d00125398f18f7354e759ba7cd544a6b07f504 (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 two year old bug in early bootup asm. [SPARC64]: Update defconfig. [SPARC64]: Fix log message type in vio_create_one(). [SPARC64]: Tweak assertions in sun4v_build_virq(). [SPARC64]: Tweak kernel log messages in power_probe(). [SPARC64]: Fix handling of multiple vdc-port nodes. [SPARC64]: Fix device type matching in VIO's devspec_show(). [SPARC64]: Fix MODULE_DEVICE_TABLE() specification in VDC and VNET. [SPARC]: Add sys_fallocate() entries. [SPARC64]: Use orderly_poweroff().
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r--arch/sparc64/kernel/ds.c6
-rw-r--r--arch/sparc64/kernel/head.S1
-rw-r--r--arch/sparc64/kernel/irq.c4
-rw-r--r--arch/sparc64/kernel/mdesc.c56
-rw-r--r--arch/sparc64/kernel/power.c64
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c12
-rw-r--r--arch/sparc64/kernel/systbls.S11
-rw-r--r--arch/sparc64/kernel/vio.c33
8 files changed, 101 insertions, 86 deletions
diff --git a/arch/sparc64/kernel/ds.c b/arch/sparc64/kernel/ds.c
index fa1f04d756a2..1a2062ecb0bc 100644
--- a/arch/sparc64/kernel/ds.c
+++ b/arch/sparc64/kernel/ds.c
@@ -13,11 +13,11 @@
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/mutex.h> 14#include <linux/mutex.h>
15#include <linux/kthread.h> 15#include <linux/kthread.h>
16#include <linux/reboot.h>
16#include <linux/cpu.h> 17#include <linux/cpu.h>
17 18
18#include <asm/ldc.h> 19#include <asm/ldc.h>
19#include <asm/vio.h> 20#include <asm/vio.h>
20#include <asm/power.h>
21#include <asm/mdesc.h> 21#include <asm/mdesc.h>
22#include <asm/head.h> 22#include <asm/head.h>
23#include <asm/irq.h> 23#include <asm/irq.h>
@@ -328,7 +328,7 @@ static void domain_shutdown_data(struct ldc_channel *lp,
328 328
329 ds_send(lp, &pkt, sizeof(pkt)); 329 ds_send(lp, &pkt, sizeof(pkt));
330 330
331 wake_up_powerd(); 331 orderly_poweroff(true);
332} 332}
333 333
334struct ds_panic_req { 334struct ds_panic_req {
@@ -1133,8 +1133,6 @@ static int __devinit ds_probe(struct vio_dev *vdev,
1133 1133
1134 ds_info = dp; 1134 ds_info = dp;
1135 1135
1136 start_powerd();
1137
1138 return err; 1136 return err;
1139 1137
1140out_free_ldc: 1138out_free_ldc:
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
index 77259526cb15..35feacb6b8ec 100644
--- a/arch/sparc64/kernel/head.S
+++ b/arch/sparc64/kernel/head.S
@@ -458,7 +458,6 @@ tlb_fixup_done:
458 or %g6, %lo(init_thread_union), %g6 458 or %g6, %lo(init_thread_union), %g6
459 ldx [%g6 + TI_TASK], %g4 459 ldx [%g6 + TI_TASK], %g4
460 mov %sp, %l6 460 mov %sp, %l6
461 mov %o4, %l7
462 461
463 wr %g0, ASI_P, %asi 462 wr %g0, ASI_P, %asi
464 mov 1, %g1 463 mov 1, %g1
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index 8cb3358674f5..c72795666a62 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -701,10 +701,10 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
701{ 701{
702 unsigned long sysino, hv_err; 702 unsigned long sysino, hv_err;
703 703
704 BUG_ON(devhandle & ~IMAP_IGN); 704 BUG_ON(devhandle & devino);
705 BUG_ON(devino & ~IMAP_INO);
706 705
707 sysino = devhandle | devino; 706 sysino = devhandle | devino;
707 BUG_ON(sysino & ~(IMAP_IGN | IMAP_INO));
708 708
709 hv_err = sun4v_vintr_set_cookie(devhandle, devino, sysino); 709 hv_err = sun4v_vintr_set_cookie(devhandle, devino, sysino);
710 if (hv_err) { 710 if (hv_err) {
diff --git a/arch/sparc64/kernel/mdesc.c b/arch/sparc64/kernel/mdesc.c
index 302ba5e5a0bb..13a79fe5115b 100644
--- a/arch/sparc64/kernel/mdesc.c
+++ b/arch/sparc64/kernel/mdesc.c
@@ -231,6 +231,25 @@ void mdesc_register_notifier(struct mdesc_notifier_client *client)
231 mutex_unlock(&mdesc_mutex); 231 mutex_unlock(&mdesc_mutex);
232} 232}
233 233
234static const u64 *parent_cfg_handle(struct mdesc_handle *hp, u64 node)
235{
236 const u64 *id;
237 u64 a;
238
239 id = NULL;
240 mdesc_for_each_arc(a, hp, node, MDESC_ARC_TYPE_BACK) {
241 u64 target;
242
243 target = mdesc_arc_target(hp, a);
244 id = mdesc_get_property(hp, target,
245 "cfg-handle", NULL);
246 if (id)
247 break;
248 }
249
250 return id;
251}
252
234/* Run 'func' on nodes which are in A but not in B. */ 253/* Run 'func' on nodes which are in A but not in B. */
235static void invoke_on_missing(const char *name, 254static void invoke_on_missing(const char *name,
236 struct mdesc_handle *a, 255 struct mdesc_handle *a,
@@ -240,13 +259,42 @@ static void invoke_on_missing(const char *name,
240 u64 node; 259 u64 node;
241 260
242 mdesc_for_each_node_by_name(a, node, name) { 261 mdesc_for_each_node_by_name(a, node, name) {
243 const u64 *id = mdesc_get_property(a, node, "id", NULL); 262 int found = 0, is_vdc_port = 0;
244 int found = 0; 263 const char *name_prop;
264 const u64 *id;
245 u64 fnode; 265 u64 fnode;
246 266
267 name_prop = mdesc_get_property(a, node, "name", NULL);
268 if (name_prop && !strcmp(name_prop, "vdc-port")) {
269 is_vdc_port = 1;
270 id = parent_cfg_handle(a, node);
271 } else
272 id = mdesc_get_property(a, node, "id", NULL);
273
274 if (!id) {
275 printk(KERN_ERR "MD: Cannot find ID for %s node.\n",
276 (name_prop ? name_prop : name));
277 continue;
278 }
279
247 mdesc_for_each_node_by_name(b, fnode, name) { 280 mdesc_for_each_node_by_name(b, fnode, name) {
248 const u64 *fid = mdesc_get_property(b, fnode, 281 const u64 *fid;
249 "id", NULL); 282
283 if (is_vdc_port) {
284 name_prop = mdesc_get_property(b, fnode,
285 "name", NULL);
286 if (!name_prop ||
287 strcmp(name_prop, "vdc-port"))
288 continue;
289 fid = parent_cfg_handle(b, fnode);
290 if (!fid) {
291 printk(KERN_ERR "MD: Cannot find ID "
292 "for vdc-port node.\n");
293 continue;
294 }
295 } else
296 fid = mdesc_get_property(b, fnode,
297 "id", NULL);
250 298
251 if (*id == *fid) { 299 if (*id == *fid) {
252 found = 1; 300 found = 1;
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c
index 8dd4294ad21e..39f9f6494d4c 100644
--- a/arch/sparc64/kernel/power.c
+++ b/arch/sparc64/kernel/power.c
@@ -12,13 +12,13 @@
12#include <linux/interrupt.h> 12#include <linux/interrupt.h>
13#include <linux/pm.h> 13#include <linux/pm.h>
14#include <linux/syscalls.h> 14#include <linux/syscalls.h>
15#include <linux/reboot.h>
15 16
16#include <asm/system.h> 17#include <asm/system.h>
17#include <asm/auxio.h> 18#include <asm/auxio.h>
18#include <asm/prom.h> 19#include <asm/prom.h>
19#include <asm/of_device.h> 20#include <asm/of_device.h>
20#include <asm/io.h> 21#include <asm/io.h>
21#include <asm/power.h>
22#include <asm/sstate.h> 22#include <asm/sstate.h>
23 23
24#include <linux/unistd.h> 24#include <linux/unistd.h>
@@ -31,20 +31,9 @@ int scons_pwroff = 1;
31 31
32static void __iomem *power_reg; 32static void __iomem *power_reg;
33 33
34static DECLARE_WAIT_QUEUE_HEAD(powerd_wait);
35static int button_pressed;
36
37void wake_up_powerd(void)
38{
39 if (button_pressed == 0) {
40 button_pressed = 1;
41 wake_up(&powerd_wait);
42 }
43}
44
45static irqreturn_t power_handler(int irq, void *dev_id) 34static irqreturn_t power_handler(int irq, void *dev_id)
46{ 35{
47 wake_up_powerd(); 36 orderly_poweroff(true);
48 37
49 /* FIXME: Check registers for status... */ 38 /* FIXME: Check registers for status... */
50 return IRQ_HANDLED; 39 return IRQ_HANDLED;
@@ -77,48 +66,6 @@ void machine_power_off(void)
77void (*pm_power_off)(void) = machine_power_off; 66void (*pm_power_off)(void) = machine_power_off;
78EXPORT_SYMBOL(pm_power_off); 67EXPORT_SYMBOL(pm_power_off);
79 68
80static int powerd(void *__unused)
81{
82 static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
83 char *argv[] = { "/sbin/shutdown", "-h", "now", NULL };
84 DECLARE_WAITQUEUE(wait, current);
85
86 daemonize("powerd");
87
88 add_wait_queue(&powerd_wait, &wait);
89
90 for (;;) {
91 set_task_state(current, TASK_INTERRUPTIBLE);
92 if (button_pressed)
93 break;
94 flush_signals(current);
95 schedule();
96 }
97 __set_current_state(TASK_RUNNING);
98 remove_wait_queue(&powerd_wait, &wait);
99
100 /* Ok, down we go... */
101 button_pressed = 0;
102 if (kernel_execve("/sbin/shutdown", argv, envp) < 0) {
103 printk(KERN_ERR "powerd: shutdown execution failed\n");
104 machine_power_off();
105 }
106 return 0;
107}
108
109int start_powerd(void)
110{
111 int err;
112
113 err = kernel_thread(powerd, NULL, CLONE_FS);
114 if (err < 0)
115 printk(KERN_ERR "power: Failed to start power daemon.\n");
116 else
117 printk(KERN_INFO "power: powerd running.\n");
118
119 return err;
120}
121
122static int __init has_button_interrupt(unsigned int irq, struct device_node *dp) 69static int __init has_button_interrupt(unsigned int irq, struct device_node *dp)
123{ 70{
124 if (irq == 0xffffffff) 71 if (irq == 0xffffffff)
@@ -136,20 +83,15 @@ static int __devinit power_probe(struct of_device *op, const struct of_device_id
136 83
137 power_reg = of_ioremap(res, 0, 0x4, "power"); 84 power_reg = of_ioremap(res, 0, 0x4, "power");
138 85
139 printk("%s: Control reg at %lx ... ", 86 printk(KERN_INFO "%s: Control reg at %lx\n",
140 op->node->name, res->start); 87 op->node->name, res->start);
141 88
142 poweroff_method = machine_halt; /* able to use the standard halt */ 89 poweroff_method = machine_halt; /* able to use the standard halt */
143 90
144 if (has_button_interrupt(irq, op->node)) { 91 if (has_button_interrupt(irq, op->node)) {
145 if (start_powerd() < 0)
146 return 0;
147
148 if (request_irq(irq, 92 if (request_irq(irq,
149 power_handler, 0, "power", NULL) < 0) 93 power_handler, 0, "power", NULL) < 0)
150 printk(KERN_ERR "power: Cannot setup IRQ handler.\n"); 94 printk(KERN_ERR "power: Cannot setup IRQ handler.\n");
151 } else {
152 printk(KERN_INFO "power: Not using powerd.\n");
153 } 95 }
154 96
155 return 0; 97 return 0;
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index abd83129b2e7..e8dce90d05d4 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -1,8 +1,7 @@
1/* $Id: sys_sparc32.c,v 1.184 2002/02/09 19:49:31 davem Exp $ 1/* sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
2 * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
3 * 2 *
4 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) 3 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) 4 * Copyright (C) 1997, 2007 David S. Miller (davem@davemloft.net)
6 * 5 *
7 * These routines maintain argument size conversion between 32bit and 64bit 6 * These routines maintain argument size conversion between 32bit and 64bit
8 * environment. 7 * environment.
@@ -1028,3 +1027,10 @@ long compat_sync_file_range(int fd, unsigned long off_high, unsigned long off_lo
1028 (nb_high << 32) | nb_low, 1027 (nb_high << 32) | nb_low,
1029 flags); 1028 flags);
1030} 1029}
1030
1031asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offhi, u32 offlo,
1032 u32 lenhi, u32 lenlo)
1033{
1034 return sys_fallocate(fd, mode, ((loff_t)offhi << 32) | offlo,
1035 ((loff_t)lenhi << 32) | lenlo);
1036}
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index 8765e32155a0..06d10907d8ce 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -1,8 +1,7 @@
1/* $Id: systbls.S,v 1.81 2002/02/08 03:57:14 davem Exp $ 1/* systbls.S: System call entry point tables for OS compatibility.
2 * systbls.S: System call entry point tables for OS compatibility.
3 * The native Linux system call table lives here also. 2 * The native Linux system call table lives here also.
4 * 3 *
5 * Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu) 4 * Copyright (C) 1995, 1996, 2007 David S. Miller (davem@davemloft.net)
6 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) 5 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
7 * 6 *
8 * Based upon preliminary work which is: 7 * Based upon preliminary work which is:
@@ -81,7 +80,7 @@ sys_call_table32:
81 .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare 80 .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare
82/*300*/ .word compat_sys_set_robust_list, compat_sys_get_robust_list, compat_sys_migrate_pages, compat_sys_mbind, compat_sys_get_mempolicy 81/*300*/ .word compat_sys_set_robust_list, compat_sys_get_robust_list, compat_sys_migrate_pages, compat_sys_mbind, compat_sys_get_mempolicy
83 .word compat_sys_set_mempolicy, compat_sys_kexec_load, compat_sys_move_pages, sys_getcpu, compat_sys_epoll_pwait 82 .word compat_sys_set_mempolicy, compat_sys_kexec_load, compat_sys_move_pages, sys_getcpu, compat_sys_epoll_pwait
84/*310*/ .word compat_sys_utimensat, compat_sys_signalfd, compat_sys_timerfd, sys_eventfd 83/*310*/ .word compat_sys_utimensat, compat_sys_signalfd, compat_sys_timerfd, sys_eventfd, compat_sys_fallocate
85 84
86#endif /* CONFIG_COMPAT */ 85#endif /* CONFIG_COMPAT */
87 86
@@ -153,7 +152,7 @@ sys_call_table:
153 .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare 152 .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare
154/*300*/ .word sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy 153/*300*/ .word sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy
155 .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait 154 .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait
156/*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd, sys_eventfd 155/*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd, sys_eventfd, sys_fallocate
157 156
158#if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ 157#if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
159 defined(CONFIG_SOLARIS_EMUL_MODULE) 158 defined(CONFIG_SOLARIS_EMUL_MODULE)
@@ -272,6 +271,6 @@ sunos_sys_table:
272 .word sunos_nosys, sunos_nosys, sunos_nosys 271 .word sunos_nosys, sunos_nosys, sunos_nosys
273 .word sunos_nosys 272 .word sunos_nosys
274/*310*/ .word sunos_nosys, sunos_nosys, sunos_nosys 273/*310*/ .word sunos_nosys, sunos_nosys, sunos_nosys
275 .word sunos_nosys 274 .word sunos_nosys, sunos_nosys
276 275
277#endif 276#endif
diff --git a/arch/sparc64/kernel/vio.c b/arch/sparc64/kernel/vio.c
index 8d3cc4fdb557..491223a6628f 100644
--- a/arch/sparc64/kernel/vio.c
+++ b/arch/sparc64/kernel/vio.c
@@ -103,9 +103,9 @@ static ssize_t devspec_show(struct device *dev,
103 struct vio_dev *vdev = to_vio_dev(dev); 103 struct vio_dev *vdev = to_vio_dev(dev);
104 const char *str = "none"; 104 const char *str = "none";
105 105
106 if (!strcmp(vdev->type, "network")) 106 if (!strcmp(vdev->type, "vnet-port"))
107 str = "vnet"; 107 str = "vnet";
108 else if (!strcmp(vdev->type, "block")) 108 else if (!strcmp(vdev->type, "vdc-port"))
109 str = "vdisk"; 109 str = "vdisk";
110 110
111 return sprintf(buf, "%s\n", str); 111 return sprintf(buf, "%s\n", str);
@@ -221,6 +221,27 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
221 return NULL; 221 return NULL;
222 } 222 }
223 223
224 if (!strcmp(type, "vdc-port")) {
225 u64 a;
226
227 id = NULL;
228 mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) {
229 u64 target;
230
231 target = mdesc_arc_target(hp, a);
232 id = mdesc_get_property(hp, target,
233 "cfg-handle", NULL);
234 if (id)
235 break;
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
224 bus_id_name = type; 245 bus_id_name = type;
225 if (!strcmp(type, "domain-services-port")) 246 if (!strcmp(type, "domain-services-port"))
226 bus_id_name = "ds"; 247 bus_id_name = "ds";
@@ -260,13 +281,15 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
260 281
261 vio_fill_channel_info(hp, mp, vdev); 282 vio_fill_channel_info(hp, mp, vdev);
262 283
263 id = mdesc_get_property(hp, mp, "id", NULL); 284 if (!id) {
264 if (!id)
265 snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s", 285 snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s",
266 bus_id_name); 286 bus_id_name);
267 else 287 vdev->dev_no = ~(u64)0;
288 } else {
268 snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s-%lu", 289 snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s-%lu",
269 bus_id_name, *id); 290 bus_id_name, *id);
291 vdev->dev_no = *id;
292 }
270 293
271 vdev->dev.parent = parent; 294 vdev->dev.parent = parent;
272 vdev->dev.bus = &vio_bus_type; 295 vdev->dev.bus = &vio_bus_type;