Merge branches 'acpi-bus', 'acpi-pci', 'acpica' and 'acpi-doc'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 25 Jul 2016 11:41:25 +0000 (13:41 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 25 Jul 2016 11:41:25 +0000 (13:41 +0200)
* acpi-bus:
  ACPI / bus: Support for platform initiated graceful shutdown
  ACPI / bus: Correct the comments about acpi_subsystem_init()
  ACPI / bus: Use acpi_handle_debug() in acpi_print_osc_error()

* acpi-pci:
  ACPI / PCI: make pci_slot explicitly non-modular
  ACPI / PCI: pci_slot: Use generic pr_debug utility
  ACPI / PCI: pci_slot: Use more common logging style

* acpica:
  ACPICA: Linux: Enable ACPI_MUTEX_DEBUG for Linux kernel

* acpi-doc:
  ACPI / debugger: Add AML debugger documentation
  ACPI: Add documentation describing ACPICA release automation

Documentation/acpi/aml-debugger.txt [new file with mode: 0644]
Documentation/acpi/linuxized-acpica.txt [new file with mode: 0644]
drivers/acpi/bus.c
drivers/acpi/pci_slot.c
include/acpi/platform/aclinux.h

diff --git a/Documentation/acpi/aml-debugger.txt b/Documentation/acpi/aml-debugger.txt
new file mode 100644 (file)
index 0000000..5f62aa4
--- /dev/null
@@ -0,0 +1,66 @@
+The AML Debugger
+
+Copyright (C) 2016, Intel Corporation
+Author: Lv Zheng <lv.zheng@intel.com>
+
+
+This document describes the usage of the AML debugger embedded in the Linux
+kernel.
+
+1. Build the debugger
+
+   The following kernel configuration items are required to enable the AML
+   debugger interface from the Linux kernel:
+
+   CONFIG_ACPI_DEBUGGER=y
+   CONFIG_ACPI_DEBUGGER_USER=m
+
+   The userspace utlities can be built from the kernel source tree using
+   the following commands:
+
+   $ cd tools
+   $ make acpi
+
+   The resultant userspace tool binary is then located at:
+
+     tools/acpi/power/acpi/acpidbg/acpidbg
+
+   It can be installed to system directories by running "make install" (as a
+   sufficiently privileged user).
+
+2. Start the userspace debugger interface
+
+   After booting the kernel with the debugger built-in, the debugger can be
+   started by using the following commands:
+
+   # mount -t debugfs none /sys/kernel/debug
+   # modprobe acpi_dbg
+   # tools/acpi/power/acpi/acpidbg/acpidbg
+
+   That spawns the interactive AML debugger environment where you can execute
+   debugger commands.
+
+   The commands are documented in the "ACPICA Overview and Programmer Reference"
+   that can be downloaded from
+
+   https://acpica.org/documentation
+
+   The detailed debugger commands reference is located in Chapter 12 "ACPICA
+   Debugger Reference".  The "help" command can be used for a quick reference.
+
+3. Stop the userspace debugger interface
+
+   The interactive debugger interface can be closed by pressing Ctrl+C or using
+   the "quit" or "exit" commands.  When finished, unload the module with:
+
+   # rmmod acpi_dbg
+
+   The module unloading may fail if there is an acpidbg instance running.
+
+4. Run the debugger in a script
+
+   It may be useful to run the AML debugger in a test script. "acpidbg" supports
+   this in a special "batch" mode.  For example, the following command outputs
+   the entire ACPI namespace:
+
+   # acpidbg -b "namespace"
diff --git a/Documentation/acpi/linuxized-acpica.txt b/Documentation/acpi/linuxized-acpica.txt
new file mode 100644 (file)
index 0000000..defe2ee
--- /dev/null
@@ -0,0 +1,262 @@
+Linuxized ACPICA - Introduction to ACPICA Release Automation
+
+Copyright (C) 2013-2016, Intel Corporation
+Author: Lv Zheng <lv.zheng@intel.com>
+
+
+Abstract:
+
+This document describes the ACPICA project and the relationship between
+ACPICA and Linux.  It also describes how ACPICA code in drivers/acpi/acpica,
+include/acpi and tools/power/acpi is automatically updated to follow the
+upstream.
+
+
+1. ACPICA Project
+
+   The ACPI Component Architecture (ACPICA) project provides an operating
+   system (OS)-independent reference implementation of the Advanced
+   Configuration and Power Interface Specification (ACPI).  It has been
+   adapted by various host OSes.  By directly integrating ACPICA, Linux can
+   also benefit from the application experiences of ACPICA from other host
+   OSes.
+
+   The homepage of ACPICA project is: www.acpica.org, it is maintained and
+   supported by Intel Corporation.
+
+   The following figure depicts the Linux ACPI subystem where the ACPICA
+   adaptation is included:
+
+      +---------------------------------------------------------+
+      |                                                         |
+      |   +---------------------------------------------------+ |
+      |   | +------------------+                              | |
+      |   | | Table Management |                              | |
+      |   | +------------------+                              | |
+      |   | +----------------------+                          | |
+      |   | | Namespace Management |                          | |
+      |   | +----------------------+                          | |
+      |   | +------------------+       ACPICA Components      | |
+      |   | | Event Management |                              | |
+      |   | +------------------+                              | |
+      |   | +---------------------+                           | |
+      |   | | Resource Management |                           | |
+      |   | +---------------------+                           | |
+      |   | +---------------------+                           | |
+      |   | | Hardware Management |                           | |
+      |   | +---------------------+                           | |
+      | +---------------------------------------------------+ | |
+      | | |                            +------------------+ | | |
+      | | |                            | OS Service Layer | | | |
+      | | |                            +------------------+ | | |
+      | | +-------------------------------------------------|-+ |
+      | |   +--------------------+                          |   |
+      | |   | Device Enumeration |                          |   |
+      | |   +--------------------+                          |   |
+      | |   +------------------+                            |   |
+      | |   | Power Management |                            |   |
+      | |   +------------------+     Linux/ACPI Components  |   |
+      | |   +--------------------+                          |   |
+      | |   | Thermal Management |                          |   |
+      | |   +--------------------+                          |   |
+      | |   +--------------------------+                    |   |
+      | |   | Drivers for ACPI Devices |                    |   |
+      | |   +--------------------------+                    |   |
+      | |   +--------+                                      |   |
+      | |   | ...... |                                      |   |
+      | |   +--------+                                      |   |
+      | +---------------------------------------------------+   |
+      |                                                         |
+      +---------------------------------------------------------+
+
+                 Figure 1. Linux ACPI Software Components
+
+   NOTE:
+    A. OS Service Layer - Provided by Linux to offer OS dependent
+       implementation of the predefined ACPICA interfaces (acpi_os_*).
+         include/acpi/acpiosxf.h
+         drivers/acpi/osl.c
+         include/acpi/platform
+         include/asm/acenv.h
+    B. ACPICA Functionality - Released from ACPICA code base to offer
+       OS independent implementation of the ACPICA interfaces (acpi_*).
+         drivers/acpi/acpica
+         include/acpi/ac*.h
+         tools/power/acpi
+    C. Linux/ACPI Functionality - Providing Linux specific ACPI
+       functionality to the other Linux kernel subsystems and user space
+       programs.
+         drivers/acpi
+         include/linux/acpi.h
+         include/linux/acpi*.h
+         include/acpi
+         tools/power/acpi
+    D. Architecture Specific ACPICA/ACPI Functionalities - Provided by the
+       ACPI subsystem to offer architecture specific implementation of the
+       ACPI interfaces.  They are Linux specific components and are out of
+       the scope of this document.
+         include/asm/acpi.h
+         include/asm/acpi*.h
+         arch/*/acpi
+
+2. ACPICA Release
+
+   The ACPICA project maintains its code base at the following repository URL:
+   https://github.com/acpica/acpica.git. As a rule, a release is made every
+   month.
+
+   As the coding style adopted by the ACPICA project is not acceptable by
+   Linux, there is a release process to convert the ACPICA git commits into
+   Linux patches.  The patches generated by this process are referred to as
+   "linuxized ACPICA patches".  The release process is carried out on a local
+   copy the ACPICA git repository.  Each commit in the monthly release is
+   converted into a linuxized ACPICA patch.  Together, they form the montly
+   ACPICA release patchset for the Linux ACPI community.  This process is
+   illustrated in the following figure:
+
+    +-----------------------------+
+    | acpica / master (-) commits |
+    +-----------------------------+
+       /|\         |
+        |         \|/
+        |  /---------------------\    +----------------------+
+        | < Linuxize repo Utility >-->| old linuxized acpica |--+
+        |  \---------------------/    +----------------------+  |
+        |                                                       |
+     /---------\                                                |
+    < git reset >                                                \
+     \---------/                                                  \
+       /|\                                                        /+-+
+        |                                                        /   |
+    +-----------------------------+                             |    |
+    | acpica / master (+) commits |                             |    |
+    +-----------------------------+                             |    |
+                   |                                            |    |
+                  \|/                                           |    |
+         /-----------------------\    +----------------------+  |    |
+        < Linuxize repo Utilities >-->| new linuxized acpica |--+    |
+         \-----------------------/    +----------------------+       |
+                                                                    \|/
+    +--------------------------+                  /----------------------\
+    | Linuxized ACPICA Patches |<----------------< Linuxize patch Utility >
+    +--------------------------+                  \----------------------/
+                   |
+                  \|/
+     /---------------------------\
+    < Linux ACPI Community Review >
+     \---------------------------/
+                   |
+                  \|/
+    +-----------------------+    /------------------\    +----------------+
+    | linux-pm / linux-next |-->< Linux Merge Window >-->| linux / master |
+    +-----------------------+    \------------------/    +----------------+
+
+                Figure 2. ACPICA -> Linux Upstream Process
+
+   NOTE:
+    A. Linuxize Utilities - Provided by the ACPICA repository, including a
+       utility located in source/tools/acpisrc folder and a number of
+       scripts located in generate/linux folder.
+    B. acpica / master - "master" branch of the git repository at
+       <https://github.com/acpica/acpica.git>.
+    C. linux-pm / linux-next - "linux-next" branch of the git repository at
+       <http://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git>.
+    D. linux / master - "master" branch of the git repository at
+       <http://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git>.
+
+   Before the linuxized ACPICA patches are sent to the Linux ACPI community
+   for review, there is a quality ensurance build test process to reduce
+   porting issues.  Currently this build process only takes care of the
+   following kernel configuration options:
+   CONFIG_ACPI/CONFIG_ACPI_DEBUG/CONFIG_ACPI_DEBUGGER
+
+3. ACPICA Divergences
+
+   Ideally, all of the ACPICA commits should be converted into Linux patches
+   automatically without manual modifications, the "linux / master" tree should
+   contain the ACPICA code that exactly corresponds to the ACPICA code
+   contained in "new linuxized acpica" tree and it should be possible to run
+   the release process fully automatically.
+
+   As a matter of fact, however, there are source code differences between
+   the ACPICA code in Linux and the upstream ACPICA code, referred to as
+   "ACPICA Divergences".
+
+   The various sources of ACPICA divergences include:
+   1. Legacy divergences - Before the current ACPICA release process was
+      established, there already had been divergences between Linux and
+      ACPICA. Over the past several years those divergences have been greatly
+      reduced, but there still are several ones and it takes time to figure
+      out the underlying reasons for their existence.
+   2. Manual modifications - Any manual modification (eg. coding style fixes)
+      made directly in the Linux sources obviously hurts the ACPICA release
+      automation.  Thus it is recommended to fix such issues in the ACPICA
+      upstream source code and generate the linuxized fix using the ACPICA
+      release utilities (please refer to Section 4 below for the details).
+   3. Linux specific features - Sometimes it's impossible to use the
+      current ACPICA APIs to implement features required by the Linux kernel,
+      so Linux developers occasionaly have to change ACPICA code directly.
+      Those changes may not be acceptable by ACPICA upstream and in such cases
+      they are left as committed ACPICA divergences unless the ACPICA side can
+      implement new mechanisms as replacements for them.
+   4. ACPICA release fixups - ACPICA only tests commits using a set of the
+      user space simulation utilies, thus the linuxized ACPICA patches may
+      break the Linux kernel, leaving us build/boot failures.  In order to
+      avoid breaking Linux bisection, fixes are applied directly to the
+      linuxized ACPICA patches during the release process.  When the release
+      fixups are backported to the upstream ACPICA sources, they must follow
+      the upstream ACPICA rules and so further modifications may appear.
+      That may result in the appearance of new divergences.
+   5. Fast tracking of ACPICA commits - Some ACPICA commits are regression
+      fixes or stable-candidate material, so they are applied in advance with
+      respect to the ACPICA release process.  If such commits are reverted or
+      rebased on the ACPICA side in order to offer better solutions, new ACPICA
+      divergences are generated.
+
+4. ACPICA Development
+
+   This paragraph guides Linux developers to use the ACPICA upstream release
+   utilities to obtain Linux patches corresponding to upstream ACPICA commits
+   before they become available from the ACPICA release process.
+
+   1. Cherry-pick an ACPICA commit
+
+   First you need to git clone the ACPICA repository and the ACPICA change
+   you want to cherry pick must be committed into the local repository.
+
+   Then the gen-patch.sh command can help to cherry-pick an ACPICA commit
+   from the ACPICA local repository:
+
+   $ git clone https://github.com/acpica/acpica
+   $ cd acpica
+   $ generate/linux/gen-patch.sh -u [commit ID]
+
+   Here the commit ID is the ACPICA local repository commit ID you want to
+   cherry pick.  It can be omitted if the commit is "HEAD".
+
+   2. Cherry-pick recent ACPICA commits
+
+   Sometimes you need to rebase your code on top of the most recent ACPICA
+   changes that haven't been applied to Linux yet.
+
+   You can generate the ACPICA release series yourself and rebase your code on
+   top of the generated ACPICA release patches:
+
+   $ git clone https://github.com/acpica/acpica
+   $ cd acpica
+   $ generate/linux/make-patches.sh -u [commit ID]
+
+   The commit ID should be the last ACPICA commit accepted by Linux.  Usually,
+   it is the commit modifying ACPI_CA_VERSION.  It can be found by executing
+   "git blame source/include/acpixf.h" and referencing the line that contains
+   "ACPI_CA_VERSION".
+
+   3. Inspect the current divergences
+
+   If you have local copies of both Linux and upstream ACPICA, you can generate
+   a diff file indicating the state of the current divergences:
+
+   # git clone https://github.com/acpica/acpica
+   # git clone http://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
+   # cd acpica
+   # generate/linux/divergences.sh -s ../linux
index 97e270e..cb9558e 100644 (file)
@@ -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
@@ -174,22 +177,17 @@ void acpi_bus_detach_private_data(acpi_handle handle)
 EXPORT_SYMBOL_GPL(acpi_bus_detach_private_data);
 
 static void acpi_print_osc_error(acpi_handle handle,
-       struct acpi_osc_context *context, char *error)
+                                struct acpi_osc_context *context, char *error)
 {
-       struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER};
        int i;
 
-       if (ACPI_FAILURE(acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer)))
-               printk(KERN_DEBUG "%s: %s\n", context->uuid_str, error);
-       else {
-               printk(KERN_DEBUG "%s (%s): %s\n",
-                      (char *)buffer.pointer, context->uuid_str, error);
-               kfree(buffer.pointer);
-       }
-       printk(KERN_DEBUG "_OSC request data:");
+       acpi_handle_debug(handle, "(%s): %s\n", context->uuid_str, error);
+
+       pr_debug("_OSC request data:");
        for (i = 0; i < context->cap.length; i += sizeof(u32))
-               printk(" %x", *((u32 *)(context->cap.pointer + i)));
-       printk("\n");
+               pr_debug(" %x", *((u32 *)(context->cap.pointer + i)));
+
+       pr_debug("\n");
 }
 
 acpi_status acpi_str_to_uuid(char *str, u8 *uuid)
@@ -475,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
    -------------------------------------------------------------------------- */
@@ -961,8 +1009,7 @@ void __init acpi_early_init(void)
 /**
  * acpi_subsystem_init - Finalize the early initialization of ACPI.
  *
- * Switch over the platform to the ACPI mode (if possible), initialize the
- * handling of ACPI events, install the interrupt and global lock handlers.
+ * Switch over the platform to the ACPI mode (if possible).
  *
  * Doing this too early is generally unsafe, but at the same time it needs to be
  * done before all things that really depend on ACPI.  The right spot appears to
@@ -1133,6 +1180,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;
 }
 
index 7188e53..f62c68e 100644 (file)
@@ -22,8 +22,9 @@
  *  General Public License for more details.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/dmi.h>
 #include <linux/pci-acpi.h>
 
-static bool debug;
 static int check_sta_before_sun;
 
-#define DRIVER_VERSION         "0.1"
-#define DRIVER_AUTHOR  "Alex Chiang <achiang@hp.com>"
-#define DRIVER_DESC    "ACPI PCI Slot Detection Driver"
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
-module_param(debug, bool, 0644);
-
 #define _COMPONENT             ACPI_PCI_COMPONENT
 ACPI_MODULE_NAME("pci_slot");
 
-#define MY_NAME "pci_slot"
-#define err(format, arg...) pr_err("%s: " format , MY_NAME , ## arg)
-#define info(format, arg...) pr_info("%s: " format , MY_NAME , ## arg)
-#define dbg(format, arg...)                                    \
-       do {                                                    \
-               if (debug)                                      \
-                       pr_debug("%s: " format, MY_NAME , ## arg); \
-       } while (0)
-
 #define SLOT_NAME_SIZE 21              /* Inspired by #define in acpiphp.h */
 
 struct acpi_pci_slot {
@@ -76,7 +58,7 @@ check_slot(acpi_handle handle, unsigned long long *sun)
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 
        acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
-       dbg("Checking slot on path: %s\n", (char *)buffer.pointer);
+       pr_debug("Checking slot on path: %s\n", (char *)buffer.pointer);
 
        if (check_sta_before_sun) {
                /* If SxFy doesn't have _STA, we just assume it's there */
@@ -87,14 +69,16 @@ check_slot(acpi_handle handle, unsigned long long *sun)
 
        status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
        if (ACPI_FAILURE(status)) {
-               dbg("_ADR returned %d on %s\n", status, (char *)buffer.pointer);
+               pr_debug("_ADR returned %d on %s\n",
+                        status, (char *)buffer.pointer);
                goto out;
        }
 
        /* No _SUN == not a slot == bail */
        status = acpi_evaluate_integer(handle, "_SUN", NULL, sun);
        if (ACPI_FAILURE(status)) {
-               dbg("_SUN returned %d on %s\n", status, (char *)buffer.pointer);
+               pr_debug("_SUN returned %d on %s\n",
+                        status, (char *)buffer.pointer);
                goto out;
        }
 
@@ -132,15 +116,13 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
        }
 
        slot = kmalloc(sizeof(*slot), GFP_KERNEL);
-       if (!slot) {
-               err("%s: cannot allocate memory\n", __func__);
+       if (!slot)
                return AE_OK;
-       }
 
        snprintf(name, sizeof(name), "%llu", sun);
        pci_slot = pci_create_slot(pci_bus, device, name, NULL);
        if (IS_ERR(pci_slot)) {
-               err("pci_create_slot returned %ld\n", PTR_ERR(pci_slot));
+               pr_err("pci_create_slot returned %ld\n", PTR_ERR(pci_slot));
                kfree(slot);
                return AE_OK;
        }
@@ -150,8 +132,8 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 
        get_device(&pci_bus->dev);
 
-       dbg("pci_slot: %p, pci_bus: %x, device: %d, name: %s\n",
-               pci_slot, pci_bus->number, device, name);
+       pr_debug("%p, pci_bus: %x, device: %d, name: %s\n",
+                pci_slot, pci_bus->number, device, name);
 
        return AE_OK;
 }
@@ -186,7 +168,8 @@ void acpi_pci_slot_remove(struct pci_bus *bus)
 
 static int do_sta_before_sun(const struct dmi_system_id *d)
 {
-       info("%s detected: will evaluate _STA before calling _SUN\n", d->ident);
+       pr_info("%s detected: will evaluate _STA before calling _SUN\n",
+               d->ident);
        check_sta_before_sun = 1;
        return 0;
 }
index 45c2d65..93b61b1 100644 (file)
 #define ACPI_DEBUGGER
 #endif
 
+#ifdef CONFIG_ACPI_DEBUG
+#define ACPI_MUTEX_DEBUG
+#endif
+
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/ctype.h>