summaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2013-04-08 18:00:45 +0200
committerArnd Bergmann <arnd@arndb.de>2013-04-08 18:00:45 +0200
commit8bd2bcf320cfd0e7118da61d186c8466a247ef62 (patch)
treed95f86afbfa833e46403b021d1ce71f6815e1978 /kernel/sys.c
parent21b3ac76b1bd31ec22bd00fff7d0259c86b8b957 (diff)
parent105612489bf59386b46b3f9f034e03f70e57aee6 (diff)
Merge tag 'omap-for-v3.10/fixes-non-critical-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/fixes-non-critical
From Tony Lindgren <tony@atomide.com>: Non critical omap fixes for v3.10 merge window. A big chunk of these fixes are needed to support omap5 es2 version that includes PM features while the earlier version es1 did not. * tag 'omap-for-v3.10/fixes-non-critical-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: ARM: OMAP2+: fix typo "CONFIG_BRIDGE_DVFS" ARM: OMAP1: remove "config MACH_OMAP_HTCWIZARD" ARM: OMAP: dpll: enable bypass clock only when attempting dpll bypass ARM: OMAP2+: powerdomain: avoid testing whether an unsigned char is less than 0 ARM: OMAP2+: hwmod: Remove unused _HWMOD_WAKEUP_ENABLED flag ARM: OMAP2+: am335x: Change the wdt1 func clk src to per_32k clk ARM: OMAP2+: AM33xx: hwmod: Add missing sysc definition to wdt1 entry Contains an update to 3.9-rc5 Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c57
1 files changed, 32 insertions, 25 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index 81f56445fba..39c9c4a2949 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -2185,9 +2185,8 @@ SYSCALL_DEFINE3(getcpu, unsigned __user *, cpup, unsigned __user *, nodep,
char poweroff_cmd[POWEROFF_CMD_PATH_LEN] = "/sbin/poweroff";
-static int __orderly_poweroff(void)
+static int __orderly_poweroff(bool force)
{
- int argc;
char **argv;
static char *envp[] = {
"HOME=/",
@@ -2196,20 +2195,40 @@ static int __orderly_poweroff(void)
};
int ret;
- argv = argv_split(GFP_ATOMIC, poweroff_cmd, &argc);
- if (argv == NULL) {
+ argv = argv_split(GFP_KERNEL, poweroff_cmd, NULL);
+ if (argv) {
+ ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
+ argv_free(argv);
+ } else {
printk(KERN_WARNING "%s failed to allocate memory for \"%s\"\n",
- __func__, poweroff_cmd);
- return -ENOMEM;
+ __func__, poweroff_cmd);
+ ret = -ENOMEM;
}
- ret = call_usermodehelper_fns(argv[0], argv, envp, UMH_WAIT_EXEC,
- NULL, NULL, NULL);
- argv_free(argv);
+ if (ret && force) {
+ printk(KERN_WARNING "Failed to start orderly shutdown: "
+ "forcing the issue\n");
+ /*
+ * I guess this should try to kick off some daemon to sync and
+ * poweroff asap. Or not even bother syncing if we're doing an
+ * emergency shutdown?
+ */
+ emergency_sync();
+ kernel_power_off();
+ }
return ret;
}
+static bool poweroff_force;
+
+static void poweroff_work_func(struct work_struct *work)
+{
+ __orderly_poweroff(poweroff_force);
+}
+
+static DECLARE_WORK(poweroff_work, poweroff_work_func);
+
/**
* orderly_poweroff - Trigger an orderly system poweroff
* @force: force poweroff if command execution fails
@@ -2219,21 +2238,9 @@ static int __orderly_poweroff(void)
*/
int orderly_poweroff(bool force)
{
- int ret = __orderly_poweroff();
-
- if (ret && force) {
- printk(KERN_WARNING "Failed to start orderly shutdown: "
- "forcing the issue\n");
-
- /*
- * I guess this should try to kick off some daemon to sync and
- * poweroff asap. Or not even bother syncing if we're doing an
- * emergency shutdown?
- */
- emergency_sync();
- kernel_power_off();
- }
-
- return ret;
+ if (force) /* do not override the pending "true" */
+ poweroff_force = true;
+ schedule_work(&poweroff_work);
+ return 0;
}
EXPORT_SYMBOL_GPL(orderly_poweroff);