diff options
Diffstat (limited to 'arch/sparc/kernel/ds.c')
-rw-r--r-- | arch/sparc/kernel/ds.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c index dd1342c0a3be..7429b47c3aca 100644 --- a/arch/sparc/kernel/ds.c +++ b/arch/sparc/kernel/ds.c | |||
@@ -15,12 +15,15 @@ | |||
15 | #include <linux/reboot.h> | 15 | #include <linux/reboot.h> |
16 | #include <linux/cpu.h> | 16 | #include <linux/cpu.h> |
17 | 17 | ||
18 | #include <asm/hypervisor.h> | ||
18 | #include <asm/ldc.h> | 19 | #include <asm/ldc.h> |
19 | #include <asm/vio.h> | 20 | #include <asm/vio.h> |
20 | #include <asm/mdesc.h> | 21 | #include <asm/mdesc.h> |
21 | #include <asm/head.h> | 22 | #include <asm/head.h> |
22 | #include <asm/irq.h> | 23 | #include <asm/irq.h> |
23 | 24 | ||
25 | #include "kernel.h" | ||
26 | |||
24 | #define DRV_MODULE_NAME "ds" | 27 | #define DRV_MODULE_NAME "ds" |
25 | #define PFX DRV_MODULE_NAME ": " | 28 | #define PFX DRV_MODULE_NAME ": " |
26 | #define DRV_MODULE_VERSION "1.0" | 29 | #define DRV_MODULE_VERSION "1.0" |
@@ -828,18 +831,32 @@ void ldom_set_var(const char *var, const char *value) | |||
828 | } | 831 | } |
829 | } | 832 | } |
830 | 833 | ||
834 | static char full_boot_str[256] __attribute__((aligned(32))); | ||
835 | static int reboot_data_supported; | ||
836 | |||
831 | void ldom_reboot(const char *boot_command) | 837 | void ldom_reboot(const char *boot_command) |
832 | { | 838 | { |
833 | /* Don't bother with any of this if the boot_command | 839 | /* Don't bother with any of this if the boot_command |
834 | * is empty. | 840 | * is empty. |
835 | */ | 841 | */ |
836 | if (boot_command && strlen(boot_command)) { | 842 | if (boot_command && strlen(boot_command)) { |
837 | char full_boot_str[256]; | 843 | unsigned long len; |
838 | 844 | ||
839 | strcpy(full_boot_str, "boot "); | 845 | strcpy(full_boot_str, "boot "); |
840 | strcpy(full_boot_str + strlen("boot "), boot_command); | 846 | strcpy(full_boot_str + strlen("boot "), boot_command); |
847 | len = strlen(full_boot_str); | ||
841 | 848 | ||
842 | ldom_set_var("reboot-command", full_boot_str); | 849 | if (reboot_data_supported) { |
850 | unsigned long ra = kimage_addr_to_ra(full_boot_str); | ||
851 | unsigned long hv_ret; | ||
852 | |||
853 | hv_ret = sun4v_reboot_data_set(ra, len); | ||
854 | if (hv_ret != HV_EOK) | ||
855 | pr_err("SUN4V: Unable to set reboot data " | ||
856 | "hv_ret=%lu\n", hv_ret); | ||
857 | } else { | ||
858 | ldom_set_var("reboot-command", full_boot_str); | ||
859 | } | ||
843 | } | 860 | } |
844 | sun4v_mach_sir(); | 861 | sun4v_mach_sir(); |
845 | } | 862 | } |
@@ -1237,6 +1254,16 @@ static struct vio_driver ds_driver = { | |||
1237 | 1254 | ||
1238 | static int __init ds_init(void) | 1255 | static int __init ds_init(void) |
1239 | { | 1256 | { |
1257 | unsigned long hv_ret, major, minor; | ||
1258 | |||
1259 | if (tlb_type == hypervisor) { | ||
1260 | hv_ret = sun4v_get_version(HV_GRP_REBOOT_DATA, &major, &minor); | ||
1261 | if (hv_ret == HV_EOK) { | ||
1262 | pr_info("SUN4V: Reboot data supported (maj=%lu,min=%lu).\n", | ||
1263 | major, minor); | ||
1264 | reboot_data_supported = 1; | ||
1265 | } | ||
1266 | } | ||
1240 | kthread_run(ds_thread, NULL, "kldomd"); | 1267 | kthread_run(ds_thread, NULL, "kldomd"); |
1241 | 1268 | ||
1242 | return vio_register_driver(&ds_driver); | 1269 | return vio_register_driver(&ds_driver); |