diff options
Diffstat (limited to 'arch/s390/kernel/ipl.c')
-rw-r--r-- | arch/s390/kernel/ipl.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index a689070be287..04361d5a4279 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
@@ -45,11 +45,13 @@ | |||
45 | * - halt | 45 | * - halt |
46 | * - power off | 46 | * - power off |
47 | * - reipl | 47 | * - reipl |
48 | * - restart | ||
48 | */ | 49 | */ |
49 | #define ON_PANIC_STR "on_panic" | 50 | #define ON_PANIC_STR "on_panic" |
50 | #define ON_HALT_STR "on_halt" | 51 | #define ON_HALT_STR "on_halt" |
51 | #define ON_POFF_STR "on_poff" | 52 | #define ON_POFF_STR "on_poff" |
52 | #define ON_REIPL_STR "on_reboot" | 53 | #define ON_REIPL_STR "on_reboot" |
54 | #define ON_RESTART_STR "on_restart" | ||
53 | 55 | ||
54 | struct shutdown_action; | 56 | struct shutdown_action; |
55 | struct shutdown_trigger { | 57 | struct shutdown_trigger { |
@@ -1544,17 +1546,20 @@ static char vmcmd_on_reboot[128]; | |||
1544 | static char vmcmd_on_panic[128]; | 1546 | static char vmcmd_on_panic[128]; |
1545 | static char vmcmd_on_halt[128]; | 1547 | static char vmcmd_on_halt[128]; |
1546 | static char vmcmd_on_poff[128]; | 1548 | static char vmcmd_on_poff[128]; |
1549 | static char vmcmd_on_restart[128]; | ||
1547 | 1550 | ||
1548 | DEFINE_IPL_ATTR_STR_RW(vmcmd, on_reboot, "%s\n", "%s\n", vmcmd_on_reboot); | 1551 | DEFINE_IPL_ATTR_STR_RW(vmcmd, on_reboot, "%s\n", "%s\n", vmcmd_on_reboot); |
1549 | DEFINE_IPL_ATTR_STR_RW(vmcmd, on_panic, "%s\n", "%s\n", vmcmd_on_panic); | 1552 | DEFINE_IPL_ATTR_STR_RW(vmcmd, on_panic, "%s\n", "%s\n", vmcmd_on_panic); |
1550 | DEFINE_IPL_ATTR_STR_RW(vmcmd, on_halt, "%s\n", "%s\n", vmcmd_on_halt); | 1553 | DEFINE_IPL_ATTR_STR_RW(vmcmd, on_halt, "%s\n", "%s\n", vmcmd_on_halt); |
1551 | DEFINE_IPL_ATTR_STR_RW(vmcmd, on_poff, "%s\n", "%s\n", vmcmd_on_poff); | 1554 | DEFINE_IPL_ATTR_STR_RW(vmcmd, on_poff, "%s\n", "%s\n", vmcmd_on_poff); |
1555 | DEFINE_IPL_ATTR_STR_RW(vmcmd, on_restart, "%s\n", "%s\n", vmcmd_on_restart); | ||
1552 | 1556 | ||
1553 | static struct attribute *vmcmd_attrs[] = { | 1557 | static struct attribute *vmcmd_attrs[] = { |
1554 | &sys_vmcmd_on_reboot_attr.attr, | 1558 | &sys_vmcmd_on_reboot_attr.attr, |
1555 | &sys_vmcmd_on_panic_attr.attr, | 1559 | &sys_vmcmd_on_panic_attr.attr, |
1556 | &sys_vmcmd_on_halt_attr.attr, | 1560 | &sys_vmcmd_on_halt_attr.attr, |
1557 | &sys_vmcmd_on_poff_attr.attr, | 1561 | &sys_vmcmd_on_poff_attr.attr, |
1562 | &sys_vmcmd_on_restart_attr.attr, | ||
1558 | NULL, | 1563 | NULL, |
1559 | }; | 1564 | }; |
1560 | 1565 | ||
@@ -1576,6 +1581,8 @@ static void vmcmd_run(struct shutdown_trigger *trigger) | |||
1576 | cmd = vmcmd_on_halt; | 1581 | cmd = vmcmd_on_halt; |
1577 | else if (strcmp(trigger->name, ON_POFF_STR) == 0) | 1582 | else if (strcmp(trigger->name, ON_POFF_STR) == 0) |
1578 | cmd = vmcmd_on_poff; | 1583 | cmd = vmcmd_on_poff; |
1584 | else if (strcmp(trigger->name, ON_RESTART_STR) == 0) | ||
1585 | cmd = vmcmd_on_restart; | ||
1579 | else | 1586 | else |
1580 | return; | 1587 | return; |
1581 | 1588 | ||
@@ -1707,6 +1714,34 @@ static void do_panic(void) | |||
1707 | stop_run(&on_panic_trigger); | 1714 | stop_run(&on_panic_trigger); |
1708 | } | 1715 | } |
1709 | 1716 | ||
1717 | /* on restart */ | ||
1718 | |||
1719 | static struct shutdown_trigger on_restart_trigger = {ON_RESTART_STR, | ||
1720 | &reipl_action}; | ||
1721 | |||
1722 | static ssize_t on_restart_show(struct kobject *kobj, | ||
1723 | struct kobj_attribute *attr, char *page) | ||
1724 | { | ||
1725 | return sprintf(page, "%s\n", on_restart_trigger.action->name); | ||
1726 | } | ||
1727 | |||
1728 | static ssize_t on_restart_store(struct kobject *kobj, | ||
1729 | struct kobj_attribute *attr, | ||
1730 | const char *buf, size_t len) | ||
1731 | { | ||
1732 | return set_trigger(buf, &on_restart_trigger, len); | ||
1733 | } | ||
1734 | |||
1735 | static struct kobj_attribute on_restart_attr = | ||
1736 | __ATTR(on_restart, 0644, on_restart_show, on_restart_store); | ||
1737 | |||
1738 | void do_restart(void) | ||
1739 | { | ||
1740 | smp_send_stop(); | ||
1741 | on_restart_trigger.action->fn(&on_restart_trigger); | ||
1742 | stop_run(&on_restart_trigger); | ||
1743 | } | ||
1744 | |||
1710 | /* on halt */ | 1745 | /* on halt */ |
1711 | 1746 | ||
1712 | static struct shutdown_trigger on_halt_trigger = {ON_HALT_STR, &stop_action}; | 1747 | static struct shutdown_trigger on_halt_trigger = {ON_HALT_STR, &stop_action}; |
@@ -1783,7 +1818,9 @@ static void __init shutdown_triggers_init(void) | |||
1783 | if (sysfs_create_file(&shutdown_actions_kset->kobj, | 1818 | if (sysfs_create_file(&shutdown_actions_kset->kobj, |
1784 | &on_poff_attr.attr)) | 1819 | &on_poff_attr.attr)) |
1785 | goto fail; | 1820 | goto fail; |
1786 | 1821 | if (sysfs_create_file(&shutdown_actions_kset->kobj, | |
1822 | &on_restart_attr.attr)) | ||
1823 | goto fail; | ||
1787 | return; | 1824 | return; |
1788 | fail: | 1825 | fail: |
1789 | panic("shutdown_triggers_init failed\n"); | 1826 | panic("shutdown_triggers_init failed\n"); |
@@ -1959,6 +1996,12 @@ static void do_reset_calls(void) | |||
1959 | { | 1996 | { |
1960 | struct reset_call *reset; | 1997 | struct reset_call *reset; |
1961 | 1998 | ||
1999 | #ifdef CONFIG_64BIT | ||
2000 | if (diag308_set_works) { | ||
2001 | diag308_reset(); | ||
2002 | return; | ||
2003 | } | ||
2004 | #endif | ||
1962 | list_for_each_entry(reset, &rcall, list) | 2005 | list_for_each_entry(reset, &rcall, list) |
1963 | reset->fn(); | 2006 | reset->fn(); |
1964 | } | 2007 | } |