Skip to content

Commit

Permalink
ACPI / bus: Support for platform initiated graceful shutdown
Browse files Browse the repository at this point in the history
This patch adds support for platform initited graceful shutdown as
described in sections 5.6.6(Table-143) and 6.3.5.1 of ACPI 6.1 spec

The OSPM will get a graceful shutdown request via a Notify operator
on \_SB device with a value of 0x81 per section 5.6.6. Following the
shutdown request from platform the OSPM needs to follow the
processing sequence as described in section 6.2.5.1.

v3
* Switched to regular work with delays from delayed work
* Dropped changes to actypes.h
* Small style changes

v2
* Switched from standalone driver to a simple notify handler

v1
* Initial

Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Signed-off-by: Prashanth Prakash <pprakash@codeaurora.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
Prakash, Prashanth authored and Rafael J. Wysocki committed Jul 6, 2016
1 parent 3af03f7 commit baa0c01
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions drivers/acpi/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
#include <linux/acpi.h>
#include <linux/slab.h>
#include <linux/regulator/machine.h>
#include <linux/workqueue.h>
#include <linux/reboot.h>
#include <linux/delay.h>
#ifdef CONFIG_X86
#include <asm/mpspec.h>
#endif
Expand Down Expand Up @@ -470,6 +473,56 @@ static void acpi_device_remove_notify_handler(struct acpi_device *device)
acpi_device_notify);
}

/* Handle events targeting \_SB device (at present only graceful shutdown) */

#define ACPI_SB_NOTIFY_SHUTDOWN_REQUEST 0x81
#define ACPI_SB_INDICATE_INTERVAL 10000

static void sb_notify_work(struct work_struct *dummy)
{
acpi_handle sb_handle;

orderly_poweroff(true);

/*
* After initiating graceful shutdown, the ACPI spec requires OSPM
* to evaluate _OST method once every 10seconds to indicate that
* the shutdown is in progress
*/
acpi_get_handle(NULL, "\\_SB", &sb_handle);
while (1) {
pr_info("Graceful shutdown in progress.\n");
acpi_evaluate_ost(sb_handle, ACPI_OST_EC_OSPM_SHUTDOWN,
ACPI_OST_SC_OS_SHUTDOWN_IN_PROGRESS, NULL);
msleep(ACPI_SB_INDICATE_INTERVAL);
}
}

static void acpi_sb_notify(acpi_handle handle, u32 event, void *data)
{
static DECLARE_WORK(acpi_sb_work, sb_notify_work);

if (event == ACPI_SB_NOTIFY_SHUTDOWN_REQUEST) {
if (!work_busy(&acpi_sb_work))
schedule_work(&acpi_sb_work);
} else
pr_warn("event %x is not supported by \\_SB device\n", event);
}

static int __init acpi_setup_sb_notify_handler(void)
{
acpi_handle sb_handle;

if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &sb_handle)))
return -ENXIO;

if (ACPI_FAILURE(acpi_install_notify_handler(sb_handle, ACPI_DEVICE_NOTIFY,
acpi_sb_notify, NULL)))
return -EINVAL;

return 0;
}

/* --------------------------------------------------------------------------
Device Matching
-------------------------------------------------------------------------- */
Expand Down Expand Up @@ -1118,6 +1171,7 @@ static int __init acpi_init(void)
acpi_sleep_proc_init();
acpi_wakeup_device_init();
acpi_debugger_init();
acpi_setup_sb_notify_handler();
return 0;
}

Expand Down

0 comments on commit baa0c01

Please sign in to comment.