aboutsummaryrefslogtreecommitdiff
path: root/arch/sparc64/kernel
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-09-02 00:49:38 -0700
committerDavid S. Miller <davem@davemloft.net>2008-09-02 00:49:38 -0700
commit446139a8f7078d96159a936fd6059660db425405 (patch)
tree01b122d257de51c365c1bef32285efa0fbe1c189 /arch/sparc64/kernel
parentcdb3592a20b41377a28a0737dc9af95e53024470 (diff)
sparc64: Implement SSTATE purely using notifiers and initcalls.
Don't clutter up the tree with sstate_blah() scattered all over the place. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r--arch/sparc64/kernel/hvapi.c3
-rw-r--r--arch/sparc64/kernel/reboot.c4
-rw-r--r--arch/sparc64/kernel/sstate.c67
3 files changed, 45 insertions, 29 deletions
diff --git a/arch/sparc64/kernel/hvapi.c b/arch/sparc64/kernel/hvapi.c
index 691760b5b01..1d272c3b574 100644
--- a/arch/sparc64/kernel/hvapi.c
+++ b/arch/sparc64/kernel/hvapi.c
@@ -9,7 +9,6 @@
#include <asm/hypervisor.h>
#include <asm/oplib.h>
-#include <asm/sstate.h>
/* If the hypervisor indicates that the API setting
* calls are unsupported, by returning HV_EBADTRAP or
@@ -184,8 +183,6 @@ void __init sun4v_hvapi_init(void)
if (sun4v_hvapi_register(group, major, &minor))
goto bad;
- sun4v_sstate_init();
-
return;
bad:
diff --git a/arch/sparc64/kernel/reboot.c b/arch/sparc64/kernel/reboot.c
index 04dd34cbb87..11f24966063 100644
--- a/arch/sparc64/kernel/reboot.c
+++ b/arch/sparc64/kernel/reboot.c
@@ -7,7 +7,6 @@
#include <linux/module.h>
#include <linux/pm.h>
-#include <asm/sstate.h>
#include <asm/oplib.h>
#include <asm/prom.h>
@@ -24,7 +23,6 @@ EXPORT_SYMBOL(pm_power_off);
void machine_power_off(void)
{
- sstate_poweroff();
if (strcmp(of_console_device->type, "serial") || scons_pwroff)
prom_halt_power_off();
@@ -33,7 +31,6 @@ void machine_power_off(void)
void machine_halt(void)
{
- sstate_halt();
prom_halt();
panic("Halt failed!");
}
@@ -42,7 +39,6 @@ void machine_restart(char *cmd)
{
char *p;
- sstate_reboot();
p = strchr(reboot_command, '\n');
if (p)
*p = 0;
diff --git a/arch/sparc64/kernel/sstate.c b/arch/sparc64/kernel/sstate.c
index 5b6e75b7f05..8cdbe5946b4 100644
--- a/arch/sparc64/kernel/sstate.c
+++ b/arch/sparc64/kernel/sstate.c
@@ -1,14 +1,15 @@
/* sstate.c: System soft state support.
*
- * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
+ * Copyright (C) 2007, 2008 David S. Miller <davem@davemloft.net>
*/
#include <linux/kernel.h>
#include <linux/notifier.h>
+#include <linux/reboot.h>
#include <linux/init.h>
#include <asm/hypervisor.h>
-#include <asm/sstate.h>
+#include <asm/spitfire.h>
#include <asm/oplib.h>
#include <asm/head.h>
#include <asm/io.h>
@@ -50,31 +51,34 @@ static const char rebooting_msg[32] __attribute__((aligned(32))) =
static const char panicing_msg[32] __attribute__((aligned(32))) =
"Linux panicing";
-void sstate_booting(void)
+static int sstate_reboot_call(struct notifier_block *np, unsigned long type, void *_unused)
{
- do_set_sstate(HV_SOFT_STATE_TRANSITION, booting_msg);
-}
+ const char *msg;
-void sstate_running(void)
-{
- do_set_sstate(HV_SOFT_STATE_NORMAL, running_msg);
-}
+ switch (type) {
+ case SYS_DOWN:
+ default:
+ msg = rebooting_msg;
+ break;
-void sstate_halt(void)
-{
- do_set_sstate(HV_SOFT_STATE_TRANSITION, halting_msg);
-}
+ case SYS_HALT:
+ msg = halting_msg;
+ break;
-void sstate_poweroff(void)
-{
- do_set_sstate(HV_SOFT_STATE_TRANSITION, poweroff_msg);
-}
+ case SYS_POWER_OFF:
+ msg = poweroff_msg;
+ break;
+ }
-void sstate_reboot(void)
-{
- do_set_sstate(HV_SOFT_STATE_TRANSITION, rebooting_msg);
+ do_set_sstate(HV_SOFT_STATE_TRANSITION, msg);
+
+ return NOTIFY_OK;
}
+static struct notifier_block sstate_reboot_notifier = {
+ .notifier_call = sstate_reboot_call,
+};
+
static int sstate_panic_event(struct notifier_block *n, unsigned long event, void *ptr)
{
do_set_sstate(HV_SOFT_STATE_TRANSITION, panicing_msg);
@@ -87,18 +91,37 @@ static struct notifier_block sstate_panic_block = {
.priority = INT_MAX,
};
-void __init sun4v_sstate_init(void)
+static int __init sstate_init(void)
{
unsigned long major, minor;
+ if (tlb_type != hypervisor)
+ return 0;
+
major = 1;
minor = 0;
if (sun4v_hvapi_register(HV_GRP_SOFT_STATE, major, &minor))
- return;
+ return 0;
hv_supports_soft_state = 1;
prom_sun4v_guest_soft_state();
+
+ do_set_sstate(HV_SOFT_STATE_TRANSITION, booting_msg);
+
atomic_notifier_chain_register(&panic_notifier_list,
&sstate_panic_block);
+ register_reboot_notifier(&sstate_reboot_notifier);
+
+ return 0;
}
+
+core_initcall(sstate_init);
+
+static int __init sstate_running(void)
+{
+ do_set_sstate(HV_SOFT_STATE_NORMAL, running_msg);
+ return 0;
+}
+
+late_initcall(sstate_running);