[PATCH v5 1/2] ACPI: Add early console framework for DBGP/DBG2.

2012-10-08 Thread Lv Zheng
+
   | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +---+++
   +-+++
   | ACPI DBGP PROBE | -> | EARLY_RPINTK START |
   +-+++
   Early consoles started in this style will lose part of the testability
   in the kernel boot up sequence.  If the system does not crash very
   early, developers still can see the bufferred kernel outputs when the
   register_console() is called.
   Comparing to the solution 2, we can notice that the user configuration
   can not be applied to the registered early consoles in this way as the
   acpi_table_init() is still called after the parse_early_param().
   Instead, the early consoles should derive the hardware settings used in
   the BIOS/bootloaders.
   This is what the patch set has done to enable this new usage model.
   It is known as "ACPI early console launcher mode".
   As a launcher, ACPI DBGP will not actually output kernel messages
   without the real early console drivers, that's why the
   CONFIG_EARLY_PRINTK_INTEL_MID_SPI still need to be enabled along with
   the CONFIG_EARLY_PRINTK_ACPI.
   In order to disable this facility by default and enable it at runtime,
   an kernel parameter "earlyprintk=acpi" is introduced.  This makes the
   actual sequence look like:
   +---+++
   | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +---+++
| ACPI DBGP LAUNCH   | ->
++
  +-+++
   -> | ACPI DBGP PROBE | -> | EARLY_PRINTK START |
  +-+++

Version 1:
 1. Enables single DBG2 debug port support.
Version 2:
 1. Applies Rui's comments.
Version 3:
 1. Applies Len's comments (earlycon should be disabled by default).
 2. Enables single DBG2 debug ports support.
Version 4:
 1. Fixes the CodingStyle issues reported by checkpatch.pl.
 2. Enables single DBGP debug port support.
Version 5:
 1. Enables multiple DBG2 debug ports support.
 2. Applies Konrad's comments (pr_debug should be used in earlycon).
 3. Changes kstrtoul back to simple_strtoul.

Known Issues:
1. The simple_strtoul function cannot be replaced by the kstrtoul in
   the x86 specific booting codes.  The kstrtoul will return error on
   strings like "acpi0,keep".  This will leave one CodingStyle issue
   reported by the checkpatch.pl.

Signed-off-by: Lv Zheng 
Reviewed-by: Len Brown 
Reviewed-by: Rui Zhang 
Reviewed-by: Ying Huang 
Reviewed-by: Konrad Rzeszutek Wilk 
---
 Documentation/kernel-parameters.txt |1 +
 arch/x86/Kconfig.debug  |   15 +++
 arch/x86/kernel/acpi/boot.c |1 +
 arch/x86/kernel/early_printk.c  |   13 +++
 drivers/acpi/Makefile   |2 +
 drivers/acpi/early_printk.c |  173 +++
 include/linux/acpi.h|   22 +
 7 files changed, 227 insertions(+)
 create mode 100644 drivers/acpi/early_printk.c

diff --git a/Documentation/kernel-parameters.txt 
b/Documentation/kernel-parameters.txt
index ad7e2e5..f656765 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -763,6 +763,7 @@ bytes respectively. Such letter suffixes can also be 
entirely omitted.
earlyprintk=serial[,ttySn[,baudrate]]
earlyprintk=ttySn[,baudrate]
earlyprintk=dbgp[debugController#]
+   earlyprintk=acpi[debugController#]
 
Append ",keep" to not disable it when the real console
takes over.
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index b322f12..5778082 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -59,6 +59,21 @@ config EARLY_PRINTK_DBGP
  with klogd/syslogd or the X server. You should normally N here,
  unless you want to debug such a crash. You need usb debug device.
 
+config EARLY_PRINTK_ACPI
+   bool "Early printk launcher via ACPI debug port tables"
+   depends on EARLY_PRINTK && ACPI
+   ---help---
+ Write kernel log output directly into the debug ports described
+ in the ACPI tables known as DBGP and DBG2.
+
+ To enable such debugging facilities, you need to enable this
+ configuration option and append the "earlyprintk=acpi" kernel
+ parameter through the boot loaders.  Please refer the
+ "Documentation/kernel-parameters.txt" for details.  Since this
+ is an early console launcher, you still need to enable actual
+ early console drivers that are suitable for your platform.
+ If in doubt, say "N".
+
 config DEBUG_STACKOVERFLOW
   

[PATCH v5 2/2] ACPI: Add Intel MID SPI early console support.

2012-10-08 Thread Lv Zheng
DesignWare SPI UART is used as one of the debug ports on Low Power Intel
Architecture (LPIA) platforms.  This patch is introduced to support this
debugging console reported by ACPI DBGP/DBG2.  The original MID SPI
early console stuff is also refined to co-exist with the new ACPI usage
model.

To use this facility on LPIA platforms, you need to enable the following
kernel configurations:
  CONFIG_EARLY_PRINTK_ACPI=y
  CONFIG_EARLY_PRINTK_INTEL_MID_SPI=y
Then you need to append the following kernel parameter to the kernel
command line in the boot loader configuration file:
  earlyprintk=acpi

Signed-off-by: Lv Zheng 
Reviewed-by: Feng Tang 
---
 Documentation/kernel-parameters.txt|1 +
 arch/x86/Kconfig.debug |   23 +++
 arch/x86/include/asm/mrst.h|2 +-
 arch/x86/kernel/early_printk.c |   12 +-
 arch/x86/platform/mrst/early_printk_mrst.c |  186 +--
 drivers/platform/x86/Makefile  |2 +
 drivers/platform/x86/early/Makefile|5 +
 drivers/platform/x86/early/intel_mid_spi.c |  220 
 include/acpi/actbl2.h  |1 +
 include/linux/intel_mid_early.h|   12 ++
 10 files changed, 283 insertions(+), 181 deletions(-)
 create mode 100644 drivers/platform/x86/early/Makefile
 create mode 100644 drivers/platform/x86/early/intel_mid_spi.c
 create mode 100644 include/linux/intel_mid_early.h

diff --git a/Documentation/kernel-parameters.txt 
b/Documentation/kernel-parameters.txt
index f656765..003ffd9 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -762,6 +762,7 @@ bytes respectively. Such letter suffixes can also be 
entirely omitted.
earlyprintk=vga
earlyprintk=serial[,ttySn[,baudrate]]
earlyprintk=ttySn[,baudrate]
+   earlyprintk=mrst
earlyprintk=dbgp[debugController#]
earlyprintk=acpi[debugController#]
 
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index 5778082..4a26e2d 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -43,9 +43,32 @@ config EARLY_PRINTK
  with klogd/syslogd or the X server. You should normally N here,
  unless you want to debug such a crash.
 
+config EARLY_PRINTK_INTEL_MID_SPI
+   bool "Early printk for Intel MID SPI UART port"
+   depends on EARLY_PRINTK
+   ---help---
+ Write kernel log output directly into the MID SPI UART debug port.
+
+ Intel MID platforms are using DesignWare SPI UART as its debug
+ console.  This option does not introduce actual early console into
+ the kernel binary, but is required by a real early console
+ implementation (EARLY_PRINTK_INTEL_MID or EARLY_PRINTK_ACPI).
+ You should normally N here unless you need to do kernel booting
+ development.
+
 config EARLY_PRINTK_INTEL_MID
bool "Early printk for Intel MID platform support"
depends on EARLY_PRINTK && X86_INTEL_MID
+   select EARLY_PRINTK_INTEL_MID_SPI
+   ---help---
+ Write kernel log output directly into the MID SPI UART debug port.
+
+ Intel MID platforms are always equipped with SPI debug ports and
+ USB OTG debug ports. To enable these debugging facilities, you
+ need to pass "earlyprintk=mrst" parameter to the kernel through
+ boot loaders.  Please see "Documentation/kernel-parameter.txt" for
+ details.  You should normally N here unless you need to do kernel
+ booting development.
 
 config EARLY_PRINTK_DBGP
bool "Early printk via EHCI debug port"
diff --git a/arch/x86/include/asm/mrst.h b/arch/x86/include/asm/mrst.h
index fc18bf3..8ab0655 100644
--- a/arch/x86/include/asm/mrst.h
+++ b/arch/x86/include/asm/mrst.h
@@ -12,6 +12,7 @@
 #define _ASM_X86_MRST_H
 
 #include 
+#include 
 
 extern int pci_mrst_init(void);
 extern int __init sfi_parse_mrtc(struct sfi_table_header *table);
@@ -63,7 +64,6 @@ extern enum mrst_timer_options mrst_timer_options;
 #define SFI_MTMR_MAX_NUM 8
 #define SFI_MRTC_MAX   8
 
-extern struct console early_mrst_console;
 extern void mrst_early_console_init(void);
 
 extern struct console early_hsu_console;
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c
index bf5b596..9b5ee96 100644
--- a/arch/x86/kernel/early_printk.c
+++ b/arch/x86/kernel/early_printk.c
@@ -205,6 +205,16 @@ static inline void early_console_register(struct console 
*con, int keep_early)
 
 int __init __acpi_early_console_start(struct acpi_debug_port *info)
 {
+#ifdef CONFIG_EARLY_PRINTK_INTEL_MID_SPI
+   if (info->port_type == ACPI_DBG2_SERIAL_PORT
+   && info->port_subtype == ACPI_DBG2_INTEL_MID_SPI
+   && info->register_count

[PATCH v6 1/2] ACPI: Add early console framework for DBGP/DBG2.

2012-10-09 Thread Lv Zheng
+
   | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +---+++
   +-+++
   | ACPI DBGP PROBE | -> | EARLY_RPINTK START |
   +-+++
   Early consoles started in this style will lose part of the testability
   in the kernel boot up sequence.  If the system does not crash very
   early, developers still can see the bufferred kernel outputs when the
   register_console() is called.
   Comparing to the solution 2, we can notice that the user configuration
   can not be applied to the registered early consoles in this way as the
   acpi_table_init() is still called after the parse_early_param().
   Instead, the early consoles should derive the hardware settings used in
   the BIOS/bootloaders.
   This is what the patch set has done to enable this new usage model.
   It is known as "ACPI early console launcher mode".
   As a launcher, ACPI DBGP will not actually output kernel messages
   without the real early console drivers, that's why the
   CONFIG_EARLY_PRINTK_INTEL_MID_SPI still need to be enabled along with
   the CONFIG_EARLY_PRINTK_ACPI.
   In order to disable this facility by default and enable it at runtime,
   an kernel parameter "earlyprintk=acpi" is introduced.  This makes the
   actual sequence look like:
   +---+++
   | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +---+++
| ACPI DBGP LAUNCH   | ->
++
  +-+++
   -> | ACPI DBGP PROBE | -> | EARLY_PRINTK START |
  +-+++

Version 1:
 1. Enables single DBG2 debug port support.
Version 2:
 1. Applies Rui's comments.
Version 3:
 1. Applies Len's comments (earlycon should be disabled by default).
 2. Enables single DBG2 debug ports support.
Version 4:
 1. Fixes the CodingStyle issues reported by checkpatch.pl.
 2. Enables single DBGP debug port support.
Version 5:
 1. Enables multiple DBG2 debug ports support.
 2. Applies Konrad's comments (pr_debug should be used in earlycon).
 3. Changes kstrtoul back to simple_strtoul.
Version 6:
 1. Applies Konrad's comments (MAX_ACPI_DBG_PORTS bug and count improvement)
 2. Adds "__init" and "__initdata" to the symbols introduced in this patch.

Known Issues:
1. The simple_strtoul function cannot be replaced by the kstrtoul in
   the x86 specific booting codes.  The kstrtoul will return error on
   strings like "acpi0,keep".  This will leave one CodingStyle issue
   reported by the checkpatch.pl.

Signed-off-by: Lv Zheng 
---
 Documentation/kernel-parameters.txt |1 +
 arch/x86/Kconfig.debug  |   15 +++
 arch/x86/kernel/acpi/boot.c |1 +
 arch/x86/kernel/early_printk.c  |   13 +++
 drivers/acpi/Makefile   |2 +
 drivers/acpi/early_printk.c |  172 +++
 include/linux/acpi.h|   22 +
 7 files changed, 226 insertions(+)
 create mode 100644 drivers/acpi/early_printk.c

diff --git a/Documentation/kernel-parameters.txt 
b/Documentation/kernel-parameters.txt
index ad7e2e5..f656765 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -763,6 +763,7 @@ bytes respectively. Such letter suffixes can also be 
entirely omitted.
earlyprintk=serial[,ttySn[,baudrate]]
earlyprintk=ttySn[,baudrate]
earlyprintk=dbgp[debugController#]
+   earlyprintk=acpi[debugController#]
 
Append ",keep" to not disable it when the real console
takes over.
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index b322f12..5778082 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -59,6 +59,21 @@ config EARLY_PRINTK_DBGP
  with klogd/syslogd or the X server. You should normally N here,
  unless you want to debug such a crash. You need usb debug device.
 
+config EARLY_PRINTK_ACPI
+   bool "Early printk launcher via ACPI debug port tables"
+   depends on EARLY_PRINTK && ACPI
+   ---help---
+ Write kernel log output directly into the debug ports described
+ in the ACPI tables known as DBGP and DBG2.
+
+ To enable such debugging facilities, you need to enable this
+ configuration option and append the "earlyprintk=acpi" kernel
+ parameter through the boot loaders.  Please refer the
+ "Documentation/kernel-parameters.txt" for details.  Since this
+ is an early console launcher, you still need to enable actual
+ early console drivers that are suitable for your platform.

[PATCH v6 2/2] ACPI: Add Intel MID SPI early console support.

2012-10-09 Thread Lv Zheng
DesignWare SPI UART is used as one of the debug ports on Low Power Intel
Architecture (LPIA) platforms.  This patch is introduced to support this
debugging console reported by ACPI DBGP/DBG2.  The original MID SPI
early console stuff is also refined to co-exist with the new ACPI usage
model.

There are two alternatives to use this facility on LPIA platforms:
1. Launch by normal earlycon (on MEDFIELD platforms):
   Enable the following kernel configurations:
 CONFIG_EARLY_PRINTK_INTEL_MID=y
   Pass the following kernel parameter to the kernel:
 earlyprintk=mrst
2. Launch by ACPI DBG2 earlycon (on CLOVERVIEW platforms):
   Enable the following kernel configurations:
 CONFIG_EARLY_PRINTK_ACPI=y
 CONFIG_EARLY_PRINTK_INTEL_MID_SPI=y
   Pass the following kernel parameter to the kernel:
 earlyprintk=acpi

Signed-off-by: Lv Zheng 
---
 Documentation/kernel-parameters.txt|1 +
 arch/x86/Kconfig.debug |   23 +++
 arch/x86/include/asm/mrst.h|2 +-
 arch/x86/kernel/early_printk.c |   12 +-
 arch/x86/platform/mrst/early_printk_mrst.c |  186 +--
 drivers/platform/x86/Makefile  |2 +
 drivers/platform/x86/early/Makefile|5 +
 drivers/platform/x86/early/intel_mid_spi.c |  220 
 include/acpi/actbl2.h  |1 +
 include/linux/intel_mid_early.h|   12 ++
 10 files changed, 283 insertions(+), 181 deletions(-)
 create mode 100644 drivers/platform/x86/early/Makefile
 create mode 100644 drivers/platform/x86/early/intel_mid_spi.c
 create mode 100644 include/linux/intel_mid_early.h

diff --git a/Documentation/kernel-parameters.txt 
b/Documentation/kernel-parameters.txt
index f656765..003ffd9 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -762,6 +762,7 @@ bytes respectively. Such letter suffixes can also be 
entirely omitted.
earlyprintk=vga
earlyprintk=serial[,ttySn[,baudrate]]
earlyprintk=ttySn[,baudrate]
+   earlyprintk=mrst
earlyprintk=dbgp[debugController#]
earlyprintk=acpi[debugController#]
 
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index 5778082..4a26e2d 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -43,9 +43,32 @@ config EARLY_PRINTK
  with klogd/syslogd or the X server. You should normally N here,
  unless you want to debug such a crash.
 
+config EARLY_PRINTK_INTEL_MID_SPI
+   bool "Early printk for Intel MID SPI UART port"
+   depends on EARLY_PRINTK
+   ---help---
+ Write kernel log output directly into the MID SPI UART debug port.
+
+ Intel MID platforms are using DesignWare SPI UART as its debug
+ console.  This option does not introduce actual early console into
+ the kernel binary, but is required by a real early console
+ implementation (EARLY_PRINTK_INTEL_MID or EARLY_PRINTK_ACPI).
+ You should normally N here unless you need to do kernel booting
+ development.
+
 config EARLY_PRINTK_INTEL_MID
bool "Early printk for Intel MID platform support"
depends on EARLY_PRINTK && X86_INTEL_MID
+   select EARLY_PRINTK_INTEL_MID_SPI
+   ---help---
+ Write kernel log output directly into the MID SPI UART debug port.
+
+ Intel MID platforms are always equipped with SPI debug ports and
+ USB OTG debug ports. To enable these debugging facilities, you
+ need to pass "earlyprintk=mrst" parameter to the kernel through
+ boot loaders.  Please see "Documentation/kernel-parameter.txt" for
+ details.  You should normally N here unless you need to do kernel
+ booting development.
 
 config EARLY_PRINTK_DBGP
bool "Early printk via EHCI debug port"
diff --git a/arch/x86/include/asm/mrst.h b/arch/x86/include/asm/mrst.h
index fc18bf3..8ab0655 100644
--- a/arch/x86/include/asm/mrst.h
+++ b/arch/x86/include/asm/mrst.h
@@ -12,6 +12,7 @@
 #define _ASM_X86_MRST_H
 
 #include 
+#include 
 
 extern int pci_mrst_init(void);
 extern int __init sfi_parse_mrtc(struct sfi_table_header *table);
@@ -63,7 +64,6 @@ extern enum mrst_timer_options mrst_timer_options;
 #define SFI_MTMR_MAX_NUM 8
 #define SFI_MRTC_MAX   8
 
-extern struct console early_mrst_console;
 extern void mrst_early_console_init(void);
 
 extern struct console early_hsu_console;
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c
index bf5b596..9b5ee96 100644
--- a/arch/x86/kernel/early_printk.c
+++ b/arch/x86/kernel/early_printk.c
@@ -205,6 +205,16 @@ static inline void early_console_register(struct console 
*con, int keep_early)
 
 int __init __acpi_early_console_start(struct acpi_debug_port *info)
 {
+#ifdef CON

[RFC PATCH] Scripts: Add binary diff utility.

2012-12-18 Thread Lv Zheng
This utility is used as part of Linux ACPICA release process. It may be a
good idea to add it to kernel scripts, since it may be generally usefull for
verifying small kernel changes, like coding style cleanups etc.

Signed-off-by: Lv Zheng 
---
 scripts/diffvmlinux.sh |  227 
 1 file changed, 227 insertions(+)
 create mode 100755 scripts/diffvmlinux.sh

Index: linux-pm/scripts/diffvmlinux.sh
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-pm/scripts/diffvmlinux.sh 2012-12-19 13:40:21.0 +0800
@@ -0,0 +1,226 @@
+#!/bin/sh
+#
+# Copyright (c) 2012, Intel Corporation
+# Author: Lv Zheng 
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; version 2 of the License.
+#
+# NAME
+#   diffvmlinux.sh - Generating vmlinux assembly differences before/after
+#applying a quilt patch
+# SYNOPSIS
+#   diffvmlinux.sh [-f assembly-diff] [-p patch-file] [-o object-file]
+#  
+
+
+# FIXME: More Useless Sections
+#
+# Please add other sections that would appear as executable but should get
+# removed for the comparision.
+USELESS_SECTIONS=".notes"
+
+fulldir() {
+   lpath=$1
+   (
+   cd $lpath; pwd
+   )
+}
+
+getdir() {
+   lpath=`dirname $1`
+   fulldir $lpath
+}
+
+fatal() {
+   echo $1
+   exit -1
+}
+
+usage() {
+   echo "Usage: `basename $0` [-p patch] "
+   echo "Where:"
+   echo " linux: Specify the linux source tree."
+   echo " patch: Specify the patch file name."
+}
+
+fatal_usage() {
+   usage
+   exit -1
+}
+
+quilt_applied() {
+   c=$1
+   applied_patches=`quilt applied 2>/dev/null`
+
+   for a in $applied_patches; do
+   if [ "x$a" = "x$c" ]; then
+   return 0
+   fi
+   done
+   return -1
+}
+
+remove_sections() {
+   binary2=$1
+   binary3=$2
+
+   for section in $USELESS_SECTIONS; do
+   echo "Removing $section section..."
+   objcopy -R $section $binary2 $binary3
+   mv $binary3 $binary2
+   done
+}
+
+quilt_push() {
+   quilt push > /dev/null || fatal "failed to push quilt stack"
+}
+
+quilt_pop() {
+   quilt pop > /dev/null || fatal "failed to pop quilt stack"
+}
+
+detect_patch() {
+   quilt_push
+   detected_patches=`quilt applied 2>/dev/null`
+   quilt_pop
+   for d in $detected_patches; do
+   quilt_applied $d || echo $d
+   done
+}
+
+quilt_forward() {
+   l=$1
+   patches=`quilt unapplied 2>/dev/null`
+   for i in $patches; do
+   quilt_push
+   quilt_applied $l
+   if [ $? -eq 0 ]; then
+   quilt_pop
+   return 0;
+   fi
+   done
+   fatal "Cannot find $locate in the unapplied patches."
+}
+
+quilt_backward() {
+   l=$1
+   patches=`quilt applied 2>/dev/null`
+   for i in $patches; do
+   quilt_pop
+   quilt_applied $l || return 0
+   done
+   fatal "Cannot find $locate in the applied patches."
+}
+
+locate_patch() {
+   t=$1
+   quilt_applied $t
+   if [ $? -eq 0 ]; then
+   echo "Locating $t in the applied patches..."
+   quilt_backward $t
+   else
+   echo "Locating $t in the unapplied patches..."
+   quilt_forward $t
+   fi
+}
+
+while getopts "f:p:o:" opt
+do
+   case $opt in
+   f) ASMDIFF=$OPTARG;;
+   o) BINARY=$OPTARG;;
+   p) PATCH=$OPTARG;;
+   ?) echo "Invalid argument $opt"
+  fatal_usage;;
+   esac
+done
+shift $(($OPTIND - 1))
+
+if [ "x$1" = "x" ]; then
+   echo "Missing  paraemter."
+   fatal_usage
+fi
+
+CURDIR=`pwd`
+LINUX=`getdir $1`
+LINUX_BASE=`basename $LINUX`/vmlinux
+AFTER=$CURDIR/after.dump
+BEFORE=$CURDIR/before.dump
+
+if [ "x$BINARY" = "x" ]; then
+   BINARY=vmlinux
+fi
+echo "Diffing $BINARY..."
+BINARY0=$LINUX/$BINARY
+BINARY1=$LINUX/diffvmlinux
+BINARY2=$LINUX/diffvmlinux-nosections
+BINARY3=$LINUX/diffvmlinux-nosection
+
+# Prepare quilt stack
+if [ "x$PATCH" != "x" ]; then
+   echo "Locating patch $PATCH..."
+   locate_patch $PATCH
+else
+   PATCH=`detect_patch`
+   echo "Detected patch $PATCH."
+fi
+if [ "x$PATCH" = "x" ]; then
+   echo "Missing patch file"
+   fatal_usage
+fi
+
+# Allow overloading of ASMDIFF
+if [ "x$ASMDIFF" = "x&qu

[PATCH 06/13] ACPI/IPMI: Add reference counting for ACPI operation region handlers

2013-07-23 Thread Lv Zheng
This patch adds reference couting for ACPI operation region handlers to fix
races caused by the ACPICA address space callback invocations.

ACPICA address space callback invocation is not suitable for Linux
CONFIG_MODULE=y execution environment.  This patch tries to protect the
address space callbacks by invoking them under a module safe environment.
The IPMI address space handler is also upgraded in this patch.
The acpi_unregister_region() is designed to meet the following
requirements:
1. It acts as a barrier for operation region callbacks - no callback will
   happen after acpi_unregister_region().
2. acpi_unregister_region() is safe to be called in moudle->exit()
   functions.
Using reference counting rather than module referencing allows
such benefits to be achieved even when acpi_unregister_region() is called
in the environments other than module->exit().
The header file of include/acpi/acpi_bus.h should contain the declarations
that have references to some ACPICA defined types.

Signed-off-by: Lv Zheng 
Reviewed-by: Huang Ying 
---
 drivers/acpi/acpi_ipmi.c |   16 ++--
 drivers/acpi/osl.c   |  224 ++
 include/acpi/acpi_bus.h  |5 ++
 3 files changed, 235 insertions(+), 10 deletions(-)

diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c
index 5f8f495..2a09156 100644
--- a/drivers/acpi/acpi_ipmi.c
+++ b/drivers/acpi/acpi_ipmi.c
@@ -539,20 +539,18 @@ out_ref:
 static int __init acpi_ipmi_init(void)
 {
int result = 0;
-   acpi_status status;
 
if (acpi_disabled)
return result;
 
mutex_init(&driver_data.ipmi_lock);
 
-   status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
-   ACPI_ADR_SPACE_IPMI,
-   &acpi_ipmi_space_handler,
-   NULL, NULL);
-   if (ACPI_FAILURE(status)) {
+   result = acpi_register_region(ACPI_ADR_SPACE_IPMI,
+ &acpi_ipmi_space_handler,
+ NULL, NULL);
+   if (result) {
pr_warn("Can't register IPMI opregion space handle\n");
-   return -EINVAL;
+   return result;
}
 
result = ipmi_smi_watcher_register(&driver_data.bmc_events);
@@ -596,9 +594,7 @@ static void __exit acpi_ipmi_exit(void)
}
mutex_unlock(&driver_data.ipmi_lock);
 
-   acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
- ACPI_ADR_SPACE_IPMI,
- &acpi_ipmi_space_handler);
+   acpi_unregister_region(ACPI_ADR_SPACE_IPMI);
 }
 
 module_init(acpi_ipmi_init);
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 6ab2c35..8398e51 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -86,6 +86,42 @@ static struct workqueue_struct *kacpid_wq;
 static struct workqueue_struct *kacpi_notify_wq;
 static struct workqueue_struct *kacpi_hotplug_wq;
 
+struct acpi_region {
+   unsigned long flags;
+#define ACPI_REGION_DEFAULT0x01
+#define ACPI_REGION_INSTALLED  0x02
+#define ACPI_REGION_REGISTERED 0x04
+#define ACPI_REGION_UNREGISTERING  0x08
+#define ACPI_REGION_INSTALLING 0x10
+   /*
+* NOTE: Upgrading All Region Handlers
+* This flag is only used during the period where not all of the
+* region handers are upgraded to the new interfaces.
+*/
+#define ACPI_REGION_MANAGED0x80
+   acpi_adr_space_handler handler;
+   acpi_adr_space_setup setup;
+   void *context;
+   /* Invoking references */
+   atomic_t refcnt;
+};
+
+static struct acpi_region acpi_regions[ACPI_NUM_PREDEFINED_REGIONS] = {
+   [ACPI_ADR_SPACE_SYSTEM_MEMORY] = {
+   .flags = ACPI_REGION_DEFAULT,
+   },
+   [ACPI_ADR_SPACE_SYSTEM_IO] = {
+   .flags = ACPI_REGION_DEFAULT,
+   },
+   [ACPI_ADR_SPACE_PCI_CONFIG] = {
+   .flags = ACPI_REGION_DEFAULT,
+   },
+   [ACPI_ADR_SPACE_IPMI] = {
+   .flags = ACPI_REGION_MANAGED,
+   },
+};
+static DEFINE_MUTEX(acpi_mutex_region);
+
 /*
  * This list of permanent mappings is for memory that may be accessed from
  * interrupt context, where we can't do the ioremap().
@@ -1799,3 +1835,191 @@ void alloc_acpi_hp_work(acpi_handle handle, u32 type, 
void *context,
kfree(hp_work);
 }
 EXPORT_SYMBOL_GPL(alloc_acpi_hp_work);
+
+static bool acpi_region_managed(struct acpi_region *rgn)
+{
+   /*
+* NOTE: Default and Managed
+* We only need to avoid region management on the regions managed
+* by ACPICA (ACPI_REGION_DEFAULT).  Currently, we need additional
+* check as many operation region handlers are not upgraded, so
+* only those

[PATCH 01/13] ACPI/IPMI: Fix potential response buffer overflow

2013-07-23 Thread Lv Zheng
This patch enhances sanity checks on message size to avoid potential buffer
overflow.

The kernel IPMI message size is IPMI_MAX_MSG_LENGTH(272 bytes) while the
ACPI specification defined IPMI message size is 64 bytes.  The difference
is not handled by the original codes.  This may cause crash in the response
handling codes.
This patch fixes this gap and also combines rx_data/tx_data to use single
data/len pair since they need not be seperated.

Signed-off-by: Lv Zheng 
Reviewed-by: Huang Ying 
---
 drivers/acpi/acpi_ipmi.c |  100 --
 1 file changed, 61 insertions(+), 39 deletions(-)

diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c
index f40acef..28e2b4c 100644
--- a/drivers/acpi/acpi_ipmi.c
+++ b/drivers/acpi/acpi_ipmi.c
@@ -51,6 +51,7 @@ MODULE_LICENSE("GPL");
 #define ACPI_IPMI_UNKNOWN  0x07
 /* the IPMI timeout is 5s */
 #define IPMI_TIMEOUT   (5 * HZ)
+#define ACPI_IPMI_MAX_MSG_LENGTH   64
 
 struct acpi_ipmi_device {
/* the device list attached to driver_data.ipmi_devices */
@@ -89,11 +90,9 @@ struct acpi_ipmi_msg {
struct completion tx_complete;
struct kernel_ipmi_msg tx_message;
int msg_done;
-   /* tx data . And copy it from ACPI object buffer */
-   u8  tx_data[64];
-   int tx_len;
-   u8  rx_data[64];
-   int rx_len;
+   /* tx/rx data . And copy it from/to ACPI object buffer */
+   u8  data[ACPI_IPMI_MAX_MSG_LENGTH];
+   u8  rx_len;
struct acpi_ipmi_device *device;
 };
 
@@ -101,7 +100,7 @@ struct acpi_ipmi_msg {
 struct acpi_ipmi_buffer {
u8 status;
u8 length;
-   u8 data[64];
+   u8 data[ACPI_IPMI_MAX_MSG_LENGTH];
 };
 
 static void ipmi_register_bmc(int iface, struct device *dev);
@@ -140,9 +139,9 @@ static struct acpi_ipmi_msg *acpi_alloc_ipmi_msg(struct 
acpi_ipmi_device *ipmi)
 
 #defineIPMI_OP_RGN_NETFN(offset)   ((offset >> 8) & 0xff)
 #defineIPMI_OP_RGN_CMD(offset) (offset & 0xff)
-static void acpi_format_ipmi_msg(struct acpi_ipmi_msg *tx_msg,
-   acpi_physical_address address,
-   acpi_integer *value)
+static int acpi_format_ipmi_request(struct acpi_ipmi_msg *tx_msg,
+   acpi_physical_address address,
+   acpi_integer *value)
 {
struct kernel_ipmi_msg *msg;
struct acpi_ipmi_buffer *buffer;
@@ -155,15 +154,21 @@ static void acpi_format_ipmi_msg(struct acpi_ipmi_msg 
*tx_msg,
 */
msg->netfn = IPMI_OP_RGN_NETFN(address);
msg->cmd = IPMI_OP_RGN_CMD(address);
-   msg->data = tx_msg->tx_data;
+   msg->data = tx_msg->data;
/*
 * value is the parameter passed by the IPMI opregion space handler.
 * It points to the IPMI request message buffer
 */
buffer = (struct acpi_ipmi_buffer *)value;
/* copy the tx message data */
+   if (buffer->length > ACPI_IPMI_MAX_MSG_LENGTH) {
+   dev_WARN_ONCE(&tx_msg->device->pnp_dev->dev, true,
+ "Unexpected request (msg len %d).\n",
+ buffer->length);
+   return -EINVAL;
+   }
msg->data_len = buffer->length;
-   memcpy(tx_msg->tx_data, buffer->data, msg->data_len);
+   memcpy(tx_msg->data, buffer->data, msg->data_len);
/*
 * now the default type is SYSTEM_INTERFACE and channel type is BMC.
 * If the netfn is APP_REQUEST and the cmd is SEND_MESSAGE,
@@ -181,10 +186,12 @@ static void acpi_format_ipmi_msg(struct acpi_ipmi_msg 
*tx_msg,
device->curr_msgid++;
tx_msg->tx_msgid = device->curr_msgid;
mutex_unlock(&device->tx_msg_lock);
+
+   return 0;
 }
 
 static void acpi_format_ipmi_response(struct acpi_ipmi_msg *msg,
-   acpi_integer *value, int rem_time)
+ acpi_integer *value, int rem_time)
 {
struct acpi_ipmi_buffer *buffer;
 
@@ -206,13 +213,14 @@ static void acpi_format_ipmi_response(struct 
acpi_ipmi_msg *msg,
buffer->status = ACPI_IPMI_UNKNOWN;
return;
}
+
/*
 * If the IPMI response message is obtained correctly, the status code
 * will be ACPI_IPMI_OK
 */
buffer->status = ACPI_IPMI_OK;
buffer->length = msg->rx_len;
-   memcpy(buffer->data, msg->rx_data, msg->rx_len);
+   memcpy(buffer->data, msg->data, msg->rx_len);
 }
 
 static void ipmi_flush_tx_msg(struct acpi_ipmi_device *ipmi)
@@ -244,12 +252,12 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, 
void *user_msg_data)
struct pnp_dev *pnp_dev = ipmi_dev

[PATCH 13/13] ACPI/IPMI: Add IPMI operation region test device driver

2013-07-23 Thread Lv Zheng
This patch is only used for test purpose and should not be merged by any
public Linux kernel repositories.

This patch contains one driver that can drive a fake test device accessing
IPMI operation region fields.

Signed-off-by: Lv Zheng 
---
 drivers/acpi/Kconfig |   68 +
 drivers/acpi/Makefile|1 +
 drivers/acpi/ipmi_test.c |  254 ++
 3 files changed, 323 insertions(+)
 create mode 100644 drivers/acpi/ipmi_test.c

diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index d129869..e3dd3fd 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -377,6 +377,74 @@ config ACPI_BGRT
  data from the firmware boot splash. It will appear under
  /sys/firmware/acpi/bgrt/ .
 
+config ACPI_IPMI_TEST
+   tristate "IPMI operation region tester"
+   help
+ This is a test device written for such fake ACPI namespace device.
+   Device (PMIT)
+   {
+   Name (_HID, "ZETA")  // _HID: Hardware ID
+   Name (_STA, 0x0F)  // _STA: Status
+   OperationRegion (SYSI, IPMI, 0x0600, 0x0100)
+   Field (SYSI, BufferAcc, Lock, Preserve)
+   {
+   AccessAs (BufferAcc, 0x01),
+   Offset (0x01),
+   GDIC,   8,  // Get Device ID Command
+   }
+   Method (GDIM, 0, NotSerialized)  // GDIM: Get Device ID Method
+   {
+   Name (GDIR, Package (0x08)
+   {
+   0x00,
+   0x00,
+   0x,
+   0x00,
+   0x00,
+   Buffer (0x03) {0x00, 0x00, 0x00},
+   Buffer (0x02) {0x00, 0x00},
+   0x
+   })
+   Name (BUFF, Buffer (0x42) {})
+   CreateByteField (BUFF, 0x00, STAT)
+   CreateByteField (BUFF, 0x01, LENG)
+   CreateByteField (BUFF, 0x02, CMPC)
+   CreateByteField (BUFF, 0x03, DID)
+   CreateByteField (BUFF, 0x04, DREV)
+   CreateWordField (BUFF, 0x05, FREV)
+   CreateByteField (BUFF, 0x07, SREV)
+   CreateByteField (BUFF, 0x08, ADS)
+   CreateByteField (BUFF, 0x09, VID0)
+   CreateByteField (BUFF, 0x0A, VID1)
+   CreateByteField (BUFF, 0x0B, VID2)
+   CreateByteField (BUFF, 0x0C, PID0)
+   CreateByteField (BUFF, 0x0D, PID1)
+   CreateDWordField (BUFF, 0x0E, AFRI)
+   Store (0x00, LENG)
+   Store (Store (BUFF, GDIC), BUFF)
+   If (LAnd (LEqual (STAT, 0x00), LEqual (CMPC, 0x00)))
+   {
+   Name (VBUF, Buffer (0x03) { 0x00, 0x00, 0x00 })
+   Name (PBUF, Buffer (0x02) { 0x00, 0x00 })
+   Store (DID, Index (GDIR, 0x00))
+   Store (DREV, Index (GDIR, 0x01))
+   Store (FREV, Index (GDIR, 0x02))
+   Store (SREV, Index (GDIR, 0x03))
+   Store (ADS, Index (GDIR, 0x04))
+   Store (VID0, Index (VBUF, 0x00))
+   Store (VID1, Index (VBUF, 0x01))
+   Store (VID2, Index (VBUF, 0x02))
+   Store (VBUF, Index (GDIR, 0x05))
+   Store (PID0, Index (PBUF, 0x00))
+   Store (PID1, Index (PBUF, 0x01))
+   Store (PBUF, Index (GDIR, 0x06))
+   Store (AFRI, Index (GDIR, 0x07))
+   }
+   Return (GDIR)
+   }
+   }
+ It is for validation purpose, only calls "Get Device ID" command.
+
 source "drivers/acpi/apei/Kconfig"
 
 endif  # ACPI
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 81dbeb8..1476623 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -74,6 +74,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)+= bgrt.o
 obj-$(CONFIG_ACPI_I2C) += acpi_i2c.o
+obj-$(CONFIG_ACPI_IPMI_TEST)   += ipmi_test.o
 
 # processor has its own "processor." module_param namespace
 processor-y:= processor_driver.o processor_throttling.o
diff --git a/drivers/acpi/ipmi_test.c b/drivers/acpi/ipmi_test.c
new file mode 100644
index 000..5d144e4
--- /dev/null
+++ b/drivers/acpi/ipmi_test.c
@@ -0,0 +1,254 @@
+/*
+ * An IPMI operation region tester driver
+ *
+ * Copyright (C) 2013 Intel Corporation
+ *   Author: Lv Zheng 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the

[PATCH 12/13] Testing: Add module load/unload test suite

2013-07-23 Thread Lv Zheng
This patch contains two test scripts for module load/unload race testing.

Follow the following steps to use this test suite:
1. Run several instances invoking endless_cat.sh to access the sysfs files
   that exported by the module.
2. Run endless_mod.sh to load/unload the module frequently to see if races
   will happen.

Signed-off-by: Lv Zheng 
---
 tools/testing/module-unloading/endless_cat.sh |   32 ++
 tools/testing/module-unloading/endless_mod.sh |   81 +
 2 files changed, 113 insertions(+)
 create mode 100755 tools/testing/module-unloading/endless_cat.sh
 create mode 100755 tools/testing/module-unloading/endless_mod.sh

diff --git a/tools/testing/module-unloading/endless_cat.sh 
b/tools/testing/module-unloading/endless_cat.sh
new file mode 100755
index 000..72e035c
--- /dev/null
+++ b/tools/testing/module-unloading/endless_cat.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+fatal() {
+   echo $1
+   exit 1
+}
+
+usage() {
+   echo "Usage: `basename $0` "
+   echo "Where:"
+   echo " file: file to cat"
+}
+
+fatal_usage() {
+   usage
+   exit 1
+}
+
+if [ "x$1" = "x" ]; then
+   echo "Missing  paraemter."
+   fatal_usage
+fi
+if [ ! -f $1 ]; then
+   echo "$1 is not an accessible file."
+   fatal_usage
+fi
+
+while :
+do
+   cat $1
+   echo "---"
+done
diff --git a/tools/testing/module-unloading/endless_mod.sh 
b/tools/testing/module-unloading/endless_mod.sh
new file mode 100755
index 000..359b0c0
--- /dev/null
+++ b/tools/testing/module-unloading/endless_mod.sh
@@ -0,0 +1,81 @@
+#!/bin/sh
+
+fatal() {
+   echo $1
+   exit 1
+}
+
+usage() {
+   echo "Usage: `basename $0` [-t second] "
+   echo "Where:"
+   echo " second: seconds to sleep between module actions"
+   echo " module: name of module to test"
+}
+
+fatal_usage() {
+   usage
+   exit 1
+}
+
+SLEEPSEC=10
+
+while getopts "t:" opt
+do
+   case $opt in
+   t) SLEEPSEC=$OPTARG;;
+   ?) echo "Invalid argument $opt"
+  fatal_usage;;
+   esac
+done
+shift $(($OPTIND - 1))
+
+if [ "x$1" = "x" ]; then
+   echo "Missing  paraemter."
+   fatal_usage
+fi
+
+find_module() {
+   curr_modules=`lsmod | cut -d " " -f1`
+
+   for m in $curr_modules; do
+   if [ "x$m" = "x$1" ]; then
+   return 0
+   fi
+   done
+   return 1
+}
+
+remove_module() {
+   while :
+   do
+   find_module $1
+   if [ $? -eq 0 ]; then
+   rmmod $1
+   echo "Removing $1 ..."
+   else
+   break
+   fi
+   done
+}
+
+insert_module() {
+   while :
+   do
+   find_module $1
+   if [ ! $? -eq 0 ]; then
+   modprobe $1
+   echo "Inserting $1 ..."
+   else
+   break
+   fi
+   done
+}
+
+while :
+do
+   echo "---"
+   insert_module $1
+   sleep $SLEEPSEC
+   remove_module $1
+   sleep $SLEEPSEC
+done
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 10/13] ACPI/IPMI: Cleanup some inclusion codes

2013-07-23 Thread Lv Zheng
This is a trivial patch:
1. Deletes several useless header inclusions.
2. Kernel codes should always include  instead of
or  where many conditional
   declarations are handled.

Signed-off-by: Lv Zheng 
Reviewed-by: Huang Ying 
---
 drivers/acpi/acpi_ipmi.c |   15 +--
 1 file changed, 1 insertion(+), 14 deletions(-)

diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c
index 2d31003..e56b1f8 100644
--- a/drivers/acpi/acpi_ipmi.c
+++ b/drivers/acpi/acpi_ipmi.c
@@ -24,22 +24,9 @@
  * ~~
  */
 
-#include 
 #include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
+#include 
 #include 
-#include 
-#include 
 #include 
 
 MODULE_AUTHOR("Zhao Yakui");
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 11/13] ACPI/IPMI: Cleanup some Kconfig codes

2013-07-23 Thread Lv Zheng
This is a trivial patch:
1. Deletes duplicate Kconfig dependency as there is "if IPMI_HANDLER"
   around "IPMI_SI".

Signed-off-by: Lv Zheng 
Reviewed-by: Huang Ying 
---
 drivers/acpi/Kconfig |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 3278a21..d129869 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -181,9 +181,10 @@ config ACPI_PROCESSOR
 
  To compile this driver as a module, choose M here:
  the module will be called processor.
+
 config ACPI_IPMI
tristate "IPMI"
-   depends on IPMI_SI && IPMI_HANDLER
+   depends on IPMI_SI
default n
help
  This driver enables the ACPI to access the BMC controller. And it
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 04/13] ACPI/IPMI: Fix race caused by the unprotected ACPI IPMI user

2013-07-23 Thread Lv Zheng
This patch uses reference counting to fix the race caused by the
unprotected ACPI IPMI user.

As the acpi_ipmi_device->user_interface check in acpi_ipmi_space_handler()
can happen before setting user_interface to NULL and codes after the check
in acpi_ipmi_space_handler() can happen after user_interface becoming NULL,
then the on-going acpi_ipmi_space_handler() still can pass an invalid
acpi_ipmi_device->user_interface to ipmi_request_settime().  Such race
condition is not allowed by the IPMI layer's API design as crash will
happen in ipmi_request_settime().
In IPMI layer, smi_gone()/new_smi() callbacks are protected by
smi_watchers_mutex, thus their invocations are serialized.  But as a new
smi can re-use the freed intf_num, it requires that the callback
implementation must not use intf_num as an identification mean or it must
ensure all references to the previous smi are all dropped before exiting
smi_gone() callback.  In case of acpi_ipmi module, this means
ipmi_flush_tx_msg() must ensure all on-going IPMI transfers are completed
before exiting ipmi_flush_tx_msg().

This patch follows ipmi_devintf.c design:
1. Invoking ipmi_destroy_user() after the reference count of
   acpi_ipmi_device dropping to 0, this matches IPMI layer's API calling
   rule on ipmi_destroy_user() and ipmi_request_settime().
2. References of acpi_ipmi_device dropping to 1 means tx_msg related to
   this acpi_ipmi_device are all freed, this can be used to implement the
   new flushing mechanism.  Note complete() must be retried so that the
   on-going tx_msg won't block flushing at the point to add tx_msg into
   tx_msg_list where reference of acpi_ipmi_device is held.  This matches
   the IPMI layer's callback rule on smi_gone()/new_smi() serialization.
3. ipmi_flush_tx_msg() is performed after deleting acpi_ipmi_device from
   the list so that no new tx_msg can be created after entering flushing
   process.
4. The flushing of tx_msg is also moved out of ipmi_lock in this patch.

The forthcoming IPMI operation region handler installation changes also
requires acpi_ipmi_device be handled in the reference counting style.

Authorship is also updated due to this design change.

Signed-off-by: Lv Zheng 
Cc: Zhao Yakui 
Reviewed-by: Huang Ying 
---
 drivers/acpi/acpi_ipmi.c |  249 +++---
 1 file changed, 149 insertions(+), 100 deletions(-)

diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c
index 527ee43..cbf25e0 100644
--- a/drivers/acpi/acpi_ipmi.c
+++ b/drivers/acpi/acpi_ipmi.c
@@ -1,8 +1,9 @@
 /*
  *  acpi_ipmi.c - ACPI IPMI opregion
  *
- *  Copyright (C) 2010 Intel Corporation
- *  Copyright (C) 2010 Zhao Yakui 
+ *  Copyright (C) 2010, 2013 Intel Corporation
+ *Author: Zhao Yakui 
+ *Lv Zheng 
  *
  * ~~
  *
@@ -67,6 +68,7 @@ struct acpi_ipmi_device {
long curr_msgid;
unsigned long flags;
struct ipmi_smi_info smi_data;
+   atomic_t refcnt;
 };
 
 struct ipmi_driver_data {
@@ -107,8 +109,8 @@ struct acpi_ipmi_buffer {
 static void ipmi_register_bmc(int iface, struct device *dev);
 static void ipmi_bmc_gone(int iface);
 static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data);
-static void acpi_add_ipmi_device(struct acpi_ipmi_device *ipmi_device);
-static void acpi_remove_ipmi_device(struct acpi_ipmi_device *ipmi_device);
+static int ipmi_install_space_handler(struct acpi_ipmi_device *ipmi);
+static void ipmi_remove_space_handler(struct acpi_ipmi_device *ipmi);
 
 static struct ipmi_driver_data driver_data = {
.ipmi_devices = LIST_HEAD_INIT(driver_data.ipmi_devices),
@@ -122,6 +124,80 @@ static struct ipmi_driver_data driver_data = {
},
 };
 
+static struct acpi_ipmi_device *
+ipmi_dev_alloc(int iface, struct ipmi_smi_info *smi_data, acpi_handle handle)
+{
+   struct acpi_ipmi_device *ipmi_device;
+   int err;
+   ipmi_user_t user;
+
+   ipmi_device = kzalloc(sizeof(*ipmi_device), GFP_KERNEL);
+   if (!ipmi_device)
+   return NULL;
+
+   atomic_set(&ipmi_device->refcnt, 1);
+   INIT_LIST_HEAD(&ipmi_device->head);
+   INIT_LIST_HEAD(&ipmi_device->tx_msg_list);
+   spin_lock_init(&ipmi_device->tx_msg_lock);
+
+   ipmi_device->handle = handle;
+   ipmi_device->pnp_dev = to_pnp_dev(get_device(smi_data->dev));
+   memcpy(&ipmi_device->smi_data, smi_data, sizeof(struct ipmi_smi_info));
+   ipmi_device->ipmi_ifnum = iface;
+
+   err = ipmi_create_user(iface, &driver_data.ipmi_hndlrs,
+  ipmi_device, &user);
+   if (err) {
+   put_device(smi_data->dev);
+   kfree(ipmi_device);
+   return NULL;
+   }
+   ipmi_device->user_interface = user;
+   ipmi_install_space_handler(ipmi_device);
+
+

[PATCH 05/13] ACPI/IPMI: Fix issue caused by the per-device registration of the IPMI operation region handler

2013-07-23 Thread Lv Zheng
It is found on a real machine, in its ACPI namespace, the IPMI
OperationRegions (in the ACPI000D - ACPI power meter) are not defined under
the IPMI system interface device (the IPI0001 with KCS type returned from
_IFT control method):
  Device (PMI0)
  {
  Name (_HID, "ACPI000D")  // _HID: Hardware ID
  OperationRegion (SYSI, IPMI, 0x0600, 0x0100)
  Field (SYSI, BufferAcc, Lock, Preserve)
  {
  AccessAs (BufferAcc, 0x01),
  Offset (0x58),
  SCMD,   8,
  GCMD,   8
  }

  OperationRegion (POWR, IPMI, 0x3000, 0x0100)
  Field (POWR, BufferAcc, Lock, Preserve)
  {
  AccessAs (BufferAcc, 0x01),
  Offset (0xB3),
  GPMM,   8
  }
  }

  Device (PCI0)
  {
  Device (ISA)
  {
  Device (NIPM)
  {
  Name (_HID, EisaId ("IPI0001"))  // _HID: Hardware ID
  Method (_IFT, 0, NotSerialized)  // _IFT: IPMI Interface Type
  {
  Return (0x01)
  }
  }
  }
  }
Current ACPI_IPMI code registers IPMI operation region handler on a
per-device basis, so that for above namespace, the IPMI operation region
handler is registered only under the scope of \_SB.PCI0.ISA.NIPM.  Thus
when an IPMI operation region field of \PMI0 is accessed, there are errors
reported on such platform:
  ACPI Error: No handlers for Region [IPMI]
  ACPI Error: Region IPMI(7) has no handler
The solution is to install IPMI operation region handler from root node so
that every object that defines IPMI OperationRegion can get an address
space handler registered.

When an IPMI operation region field is accessed, the Network Function
(0x06 for SYSI and 0x30 for POWR) and the Command (SCMD, GCMD, GPMM) are
passed to the operation region handler, there is no system interface
specified by the BIOS.  The patch tries to select one system interface by
monitoring the system interface notification.  IPMI messages passed from
the ACPI codes are sent to this selected global IPMI system interface.

Known issues:
- How to select the IPMI system interface:
  Currently, the ACPI_IPMI always selects the first registered one with the
  ACPI handle set (i.e., defined in the ACPI namespace).  It's hard to
  determine the selection when there are multiple IPMI system interfaces
  defined in the ACPI namespace.
  According to the IPMI specification:
  A BMC device may make available multiple system interfaces, but only one
  management controller is allowed to be 'active' BMC that provides BMC
  functionality for the system (in case of a 'partitioned' system, there
  can be only one active BMC per partition).  Only the system interface(s)
  for the active BMC allowed to respond to the 'Get Device Id' command.
  According to the ipmi_si desigin:
  The ipmi_si registeration notifications can only happen after a
  successful "Get Device ID" command.
  Thus it should be OK for non-partitioned systems to do such selection.
  But we do not have too much knowledges on 'partitioned' systems.
- Lack of smi_gone()/new_smi() testability:
  It is not possible to do module(ipmi_si) load/unload test, and I can't
  find any multiple IPMI system interfaces platforms available for testing.
  There might be issues in the untested code path.

Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=46741
Signed-off-by: Lv Zheng 
Cc: Zhao Yakui 
Reviewed-by: Huang Ying 
---
 drivers/acpi/acpi_ipmi.c |  111 +++---
 1 file changed, 55 insertions(+), 56 deletions(-)

diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c
index cbf25e0..5f8f495 100644
--- a/drivers/acpi/acpi_ipmi.c
+++ b/drivers/acpi/acpi_ipmi.c
@@ -46,7 +46,8 @@ MODULE_AUTHOR("Zhao Yakui");
 MODULE_DESCRIPTION("ACPI IPMI Opregion driver");
 MODULE_LICENSE("GPL");
 
-#define IPMI_FLAGS_HANDLER_INSTALL 0
+#undef PREFIX
+#define PREFIX "ACPI: IPMI: "
 
 #define ACPI_IPMI_OK   0
 #define ACPI_IPMI_TIMEOUT  0x10
@@ -66,7 +67,6 @@ struct acpi_ipmi_device {
ipmi_user_t user_interface;
int ipmi_ifnum; /* IPMI interface number */
long curr_msgid;
-   unsigned long flags;
struct ipmi_smi_info smi_data;
atomic_t refcnt;
 };
@@ -76,6 +76,14 @@ struct ipmi_driver_data {
struct ipmi_smi_watcher bmc_events;
struct ipmi_user_hndl   ipmi_hndlrs;
struct mutexipmi_lock;
+   /*
+* NOTE: IPMI System Interface Selection
+* There is no system interface specified by the IPMI operation
+* region access.  We try to select one system interface with ACPI
+* handle set.  IPMI messages passed from the ACPI codes are sent
+* to this selected global IPMI system interface.
+*/
+   struct acpi_ipmi_device *selected_smi;
 };
 
 stru

[PATCH 09/13] ACPI/IPMI: Cleanup some initialization codes

2013-07-23 Thread Lv Zheng
This is a trivial patch.
1. Changes dynamic mutex initialization to static initialization.
2. Removes one acpi_ipmi_init() variable initialization as it is not
   needed.

Signed-off-by: Lv Zheng 
Reviewed-by: Huang Ying 
---
 drivers/acpi/acpi_ipmi.c |7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c
index 7f93ffd..2d31003 100644
--- a/drivers/acpi/acpi_ipmi.c
+++ b/drivers/acpi/acpi_ipmi.c
@@ -128,6 +128,7 @@ static struct ipmi_driver_data driver_data = {
.ipmi_hndlrs = {
.ipmi_recv_hndl = ipmi_msg_handler,
},
+   .ipmi_lock = __MUTEX_INITIALIZER(driver_data.ipmi_lock)
 };
 
 static struct acpi_ipmi_device *
@@ -583,12 +584,10 @@ out_msg:
 
 static int __init acpi_ipmi_init(void)
 {
-   int result = 0;
+   int result;
 
if (acpi_disabled)
-   return result;
-
-   mutex_init(&driver_data.ipmi_lock);
+   return 0;
 
result = acpi_register_region(ACPI_ADR_SPACE_IPMI,
  &acpi_ipmi_space_handler,
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 00/13] ACPI/IPMI: Fix several issues in the current codes

2013-07-23 Thread Lv Zheng
This patchset tries to fix the following kernel bug:
Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=46741
This is fixed by [PATCH 05].

The bug shows IPMI operation region may appear in a device not under the
IPMI system interface device's scope, thus it's required to install the
ACPI IPMI operation region handler from the root of the ACPI namespace.

The original acpi_ipmi implementation includes several issues that break
the test process.  This patchset also includes a re-design of acpi_ipmi
module to make the test possible.
 
[PATCH 01-05] are bug-fix patches that can be applied to the kernels whose
  version is > 2.6.38.  This can be confirmed with:
  # git tag --contains e92b297c
[PATCH 06] is also a bug-fix patch.
   The drivers/acpi/osl.c part can be back ported to the kernels
   whose version > 2.6.14.  This can be confirmed with:
   # git tag --contains 4be44fcd
   The drivers/acpi/acpi_ipmi.c part can be applied on top of
   [PATCH 01-05].
[PATCH 07] is a tuning patch for acpi_ipmi.c.
[PATCH 08-10] are cleanup patches for acpi_ipmi.c.
[PATCH 11] is a cleanup patch not for acpi_ipmi.c.
[PATCH 12-13] are test patches.
  [PATCH 12] may be accepted by upstream kernel as a useful
 facility to test the loading/unloading of the
 modules.
  [PATCH 13] should not be merged by any published kernel as it
 is a driver for a pseudo device with a PnP ID that
 does not exist in the real machines.

This patchset has passed the test around a fake device accessing IPMI
operation region fields on an IPMI capable platform.  A stress test of
module(acpi_ipmi) load/unload has been performed on such platform.  No
races can be found and the IPMI operation region handler is functioning
now.  It is not possible to test module(ipmi_si) load/unload as it can't be
unloaded due to its' transfer flushing implementation.

Lv Zheng (13):
  ACPI/IPMI: Fix potential response buffer overflow
  ACPI/IPMI: Fix atomic context requirement of ipmi_msg_handler()
  ACPI/IPMI: Fix race caused by the unprotected ACPI IPMI transfers
  ACPI/IPMI: Fix race caused by the unprotected ACPI IPMI user
  ACPI/IPMI: Fix issue caused by the per-device registration of the
IPMI operation region handler
  ACPI/IPMI: Add reference counting for ACPI operation region handlers
  ACPI/IPMI: Add reference counting for ACPI IPMI transfers
  ACPI/IPMI: Cleanup several acpi_ipmi_device members
  ACPI/IPMI: Cleanup some initialization codes
  ACPI/IPMI: Cleanup some inclusion codes
  ACPI/IPMI: Cleanup some Kconfig codes
  Testing: Add module load/unload test suite
  ACPI/IPMI: Add IPMI operation region test device driver

 drivers/acpi/Kconfig  |   71 +++-
 drivers/acpi/Makefile |1 +
 drivers/acpi/acpi_ipmi.c  |  513 +++--
 drivers/acpi/ipmi_test.c  |  254 
 drivers/acpi/osl.c|  224 +++
 include/acpi/acpi_bus.h   |5 +
 tools/testing/module-unloading/endless_cat.sh |   32 ++
 tools/testing/module-unloading/endless_mod.sh |   81 
 8 files changed, 977 insertions(+), 204 deletions(-)
 create mode 100644 drivers/acpi/ipmi_test.c
 create mode 100755 tools/testing/module-unloading/endless_cat.sh
 create mode 100755 tools/testing/module-unloading/endless_mod.sh

-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 03/13] ACPI/IPMI: Fix race caused by the unprotected ACPI IPMI transfers

2013-07-23 Thread Lv Zheng
This patch fixes races caused by unprotected ACPI IPMI transfers.

We can see the following crashes may occur:
1. There is no tx_msg_lock held for iterating tx_msg_list in
   ipmi_flush_tx_msg() while it is parellel unlinked on failure in
   acpi_ipmi_space_handler() under protection of tx_msg_lock.
2. There is no lock held for freeing tx_msg in acpi_ipmi_space_handler()
   while it is parellel accessed in ipmi_flush_tx_msg() and
   ipmi_msg_handler().

This patch enhances tx_msg_lock to protect all tx_msg accesses to solve
this issue.  Then tx_msg_lock is always held around complete() and tx_msg
accesses.
Calling smp_wmb() before setting msg_done flag so that messages completed
due to flushing will not be handled as 'done' messages while their contents
are not vaild.

Signed-off-by: Lv Zheng 
Cc: Zhao Yakui 
Reviewed-by: Huang Ying 
---
 drivers/acpi/acpi_ipmi.c |   10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c
index b37c189..527ee43 100644
--- a/drivers/acpi/acpi_ipmi.c
+++ b/drivers/acpi/acpi_ipmi.c
@@ -230,11 +230,14 @@ static void ipmi_flush_tx_msg(struct acpi_ipmi_device 
*ipmi)
struct acpi_ipmi_msg *tx_msg, *temp;
int count = HZ / 10;
struct pnp_dev *pnp_dev = ipmi->pnp_dev;
+   unsigned long flags;
 
+   spin_lock_irqsave(&ipmi->tx_msg_lock, flags);
list_for_each_entry_safe(tx_msg, temp, &ipmi->tx_msg_list, head) {
/* wake up the sleep thread on the Tx msg */
complete(&tx_msg->tx_complete);
}
+   spin_unlock_irqrestore(&ipmi->tx_msg_lock, flags);
 
/* wait for about 100ms to flush the tx message list */
while (count--) {
@@ -268,13 +271,12 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, 
void *user_msg_data)
break;
}
}
-   spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags);
 
if (!msg_found) {
dev_warn(&pnp_dev->dev,
 "Unexpected response (msg id %ld) is returned.\n",
 msg->msgid);
-   goto out_msg;
+   goto out_lock;
}
 
/* copy the response data to Rx_data buffer */
@@ -286,10 +288,14 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, 
void *user_msg_data)
}
tx_msg->rx_len = msg->msg.data_len;
memcpy(tx_msg->data, msg->msg.data, tx_msg->rx_len);
+   /* tx_msg content must be valid before setting msg_done flag */
+   smp_wmb();
tx_msg->msg_done = 1;
 
 out_comp:
complete(&tx_msg->tx_complete);
+out_lock:
+   spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags);
 out_msg:
ipmi_free_recv_msg(msg);
 }
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 08/13] ACPI/IPMI: Cleanup several acpi_ipmi_device members

2013-07-23 Thread Lv Zheng
This is a trivial patch:
1. Deletes a member of the acpi_ipmi_device - smi_data which is not
   actually used.
2. Updates a member of the acpi_ipmi_device - pnp_dev which is only used
   by dev_warn() invocations, so changes it to struct device.

Signed-off-by: Lv Zheng 
Reviewed-by: Huang Ying 
---
 drivers/acpi/acpi_ipmi.c |   30 ++
 1 file changed, 14 insertions(+), 16 deletions(-)

diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c
index 0ee1ea6..7f93ffd 100644
--- a/drivers/acpi/acpi_ipmi.c
+++ b/drivers/acpi/acpi_ipmi.c
@@ -63,11 +63,10 @@ struct acpi_ipmi_device {
struct list_head tx_msg_list;
spinlock_t  tx_msg_lock;
acpi_handle handle;
-   struct pnp_dev *pnp_dev;
+   struct device *dev;
ipmi_user_t user_interface;
int ipmi_ifnum; /* IPMI interface number */
long curr_msgid;
-   struct ipmi_smi_info smi_data;
atomic_t refcnt;
 };
 
@@ -132,7 +131,7 @@ static struct ipmi_driver_data driver_data = {
 };
 
 static struct acpi_ipmi_device *
-ipmi_dev_alloc(int iface, struct ipmi_smi_info *smi_data, acpi_handle handle)
+ipmi_dev_alloc(int iface, struct device *pdev, acpi_handle handle)
 {
struct acpi_ipmi_device *ipmi_device;
int err;
@@ -148,14 +147,13 @@ ipmi_dev_alloc(int iface, struct ipmi_smi_info *smi_data, 
acpi_handle handle)
spin_lock_init(&ipmi_device->tx_msg_lock);
 
ipmi_device->handle = handle;
-   ipmi_device->pnp_dev = to_pnp_dev(get_device(smi_data->dev));
-   memcpy(&ipmi_device->smi_data, smi_data, sizeof(struct ipmi_smi_info));
+   ipmi_device->dev = get_device(pdev);
ipmi_device->ipmi_ifnum = iface;
 
err = ipmi_create_user(iface, &driver_data.ipmi_hndlrs,
   ipmi_device, &user);
if (err) {
-   put_device(smi_data->dev);
+   put_device(pdev);
kfree(ipmi_device);
return NULL;
}
@@ -175,7 +173,7 @@ acpi_ipmi_dev_get(struct acpi_ipmi_device *ipmi_device)
 static void ipmi_dev_release(struct acpi_ipmi_device *ipmi_device)
 {
ipmi_destroy_user(ipmi_device->user_interface);
-   put_device(ipmi_device->smi_data.dev);
+   put_device(ipmi_device->dev);
kfree(ipmi_device);
 }
 
@@ -263,7 +261,7 @@ static int acpi_format_ipmi_request(struct acpi_ipmi_msg 
*tx_msg,
buffer = (struct acpi_ipmi_buffer *)value;
/* copy the tx message data */
if (buffer->length > ACPI_IPMI_MAX_MSG_LENGTH) {
-   dev_WARN_ONCE(&tx_msg->device->pnp_dev->dev, true,
+   dev_WARN_ONCE(tx_msg->device->dev, true,
  "Unexpected request (msg len %d).\n",
  buffer->length);
return -EINVAL;
@@ -382,11 +380,11 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, 
void *user_msg_data)
struct acpi_ipmi_device *ipmi_device = user_msg_data;
int msg_found = 0;
struct acpi_ipmi_msg *tx_msg;
-   struct pnp_dev *pnp_dev = ipmi_device->pnp_dev;
+   struct device *dev = ipmi_device->dev;
unsigned long flags;
 
if (msg->user != ipmi_device->user_interface) {
-   dev_warn(&pnp_dev->dev,
+   dev_warn(dev,
 "Unexpected response is returned. returned user %p, 
expected user %p\n",
 msg->user, ipmi_device->user_interface);
goto out_msg;
@@ -404,7 +402,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, 
void *user_msg_data)
spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags);
 
if (!msg_found) {
-   dev_warn(&pnp_dev->dev,
+   dev_warn(dev,
 "Unexpected response (msg id %ld) is returned.\n",
 msg->msgid);
goto out_msg;
@@ -412,7 +410,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, 
void *user_msg_data)
 
/* copy the response data to Rx_data buffer */
if (msg->msg.data_len > ACPI_IPMI_MAX_MSG_LENGTH) {
-   dev_WARN_ONCE(&pnp_dev->dev, true,
+   dev_WARN_ONCE(dev, true,
  "Unexpected response (msg len %d).\n",
  msg->msg.data_len);
goto out_comp;
@@ -431,7 +429,7 @@ out_msg:
 static void ipmi_register_bmc(int iface, struct device *dev)
 {
struct acpi_ipmi_device *ipmi_device, *temp;
-   struct pnp_dev *pnp_dev;
+   struct device *pdev;
int err;
struct ipmi_smi_info smi_data;
acpi_handle handle;
@@ -445,11 +443,11 @@ static void ipmi_register_bmc(int iface, struct device 
*dev)
handle = smi_data.addr_info.acpi_info.acpi_handle;

[PATCH 07/13] ACPI/IPMI: Add reference counting for ACPI IPMI transfers

2013-07-23 Thread Lv Zheng
This patch adds reference counting for ACPI IPMI transfers to tune the
locking granularity of tx_msg_lock.

The acpi_ipmi_msg handling is re-designed using referece counting.
1. tx_msg is always unlinked before complete(), so that:
   1.1. it is safe to put complete() out side of tx_msg_lock;
   1.2. complete() can only happen once, thus smp_wmb() is not required.
2. Increasing the reference of tx_msg before calling
   ipmi_request_settime() and introducing tx_msg_lock protected
   ipmi_cancel_tx_msg() so that a complete() can happen in parellel with
   tx_msg unlinking in the failure cases.
3. tx_msg holds the reference of acpi_ipmi_device so that it can be flushed
   and freed in the contexts other than acpi_ipmi_space_handler().

The lockdep_chains shows all acpi_ipmi locks are leaf locks after the
tuning:
1. ipmi_lock is always leaf:
   irq_context: 0
   [81a943f8] smi_watchers_mutex
   [a06eca60] driver_data.ipmi_lock
   irq_context: 0
   [82767b40] &buffer->mutex
   [a00a6678] s_active#103
   [a06eca60] driver_data.ipmi_lock
2. without this patch applied, lock used by complete() is held after
   holding tx_msg_lock:
   irq_context: 0
   [82767b40] &buffer->mutex
   [a00a6678] s_active#103
   [a06ecce8] &(&ipmi_device->tx_msg_lock)->rlock
   irq_context: 1
   [a06ecce8] &(&ipmi_device->tx_msg_lock)->rlock
   irq_context: 1
   [a06ecce8] &(&ipmi_device->tx_msg_lock)->rlock
   [a06eccf0] &x->wait#25
   irq_context: 1
   [a06ecce8] &(&ipmi_device->tx_msg_lock)->rlock
   [a06eccf0] &x->wait#25
   [81e36620] &p->pi_lock
   irq_context: 1
   [a06ecce8] &(&ipmi_device->tx_msg_lock)->rlock
   [a06eccf0] &x->wait#25
   [81e36620] &p->pi_lock
   [81e5d0a8] &rq->lock
3. with this patch applied, tx_msg_lock is always leaf:
   irq_context: 0
   [82767b40] &buffer->mutex
   [a00a66d8] s_active#107
   [a07ecdc8] &(&ipmi_device->tx_msg_lock)->rlock
   irq_context: 1
   [a07ecdc8] &(&ipmi_device->tx_msg_lock)->rlock

Signed-off-by: Lv Zheng 
Cc: Zhao Yakui 
Reviewed-by: Huang Ying 
---
 drivers/acpi/acpi_ipmi.c |  107 +-
 1 file changed, 77 insertions(+), 30 deletions(-)

diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c
index 2a09156..0ee1ea6 100644
--- a/drivers/acpi/acpi_ipmi.c
+++ b/drivers/acpi/acpi_ipmi.c
@@ -105,6 +105,7 @@ struct acpi_ipmi_msg {
u8  data[ACPI_IPMI_MAX_MSG_LENGTH];
u8  rx_len;
struct acpi_ipmi_device *device;
+   atomic_trefcnt;
 };
 
 /* IPMI request/response buffer per ACPI 4.0, sec 5.5.2.4.3.2 */
@@ -195,22 +196,47 @@ static struct acpi_ipmi_device 
*acpi_ipmi_get_selected_smi(void)
return ipmi_device;
 }
 
-static struct acpi_ipmi_msg *acpi_alloc_ipmi_msg(struct acpi_ipmi_device *ipmi)
+static struct acpi_ipmi_msg *ipmi_msg_alloc(void)
 {
+   struct acpi_ipmi_device *ipmi;
struct acpi_ipmi_msg *ipmi_msg;
-   struct pnp_dev *pnp_dev = ipmi->pnp_dev;
 
+   ipmi = acpi_ipmi_get_selected_smi();
+   if (!ipmi)
+   return NULL;
ipmi_msg = kzalloc(sizeof(struct acpi_ipmi_msg), GFP_KERNEL);
-   if (!ipmi_msg)  {
-   dev_warn(&pnp_dev->dev, "Can't allocate memory for ipmi_msg\n");
+   if (!ipmi_msg) {
+   acpi_ipmi_dev_put(ipmi);
return NULL;
}
+   atomic_set(&ipmi_msg->refcnt, 1);
init_completion(&ipmi_msg->tx_complete);
INIT_LIST_HEAD(&ipmi_msg->head);
ipmi_msg->device = ipmi;
+
return ipmi_msg;
 }
 
+static struct acpi_ipmi_msg *
+acpi_ipmi_msg_get(struct acpi_ipmi_msg *tx_msg)
+{
+   if (tx_msg)
+   atomic_inc(&tx_msg->refcnt);
+   return tx_msg;
+}
+
+static void ipmi_msg_release(struct acpi_ipmi_msg *tx_msg)
+{
+   acpi_ipmi_dev_put(tx_msg->device);
+   kfree(tx_msg);
+}
+
+static void acpi_ipmi_msg_put(struct acpi_ipmi_msg *tx_msg)
+{
+   if (tx_msg && atomic_dec_and_test(&tx_msg->refcnt))
+   ipmi_msg_release(tx_msg);
+}
+
 #defineIPMI_OP_RGN_NETFN(offset)   ((offset >> 8) & 0xff)
 #defineIPMI_OP_RGN_CMD(offset) (offset & 0xff)
 static int acpi_format_ipmi_request(struct acpi_ipmi_msg *tx_msg,
@@ -300,7 +326,7 @@ static void acpi_format_ipmi_response(struct acpi_ipmi_msg 
*msg,
 
 static void ipmi_flush_tx_msg(struct acpi_ipmi_device *ipmi)
 {
-   struct acpi_ipmi_msg *tx_msg, *temp;
+   struct acpi_ipmi_msg *tx_msg;
unsigned long flags;
 
/*
@@ -311,16 +337,46 @@ static void ipmi_flush_tx_msg(struct acpi_ipmi_device 
*

[PATCH 02/13] ACPI/IPMI: Fix atomic context requirement of ipmi_msg_handler()

2013-07-23 Thread Lv Zheng
This patch quick fixes the issues indicated by the test results that
ipmi_msg_handler() is invoked in atomic context.

BUG: scheduling while atomic: kipmi0/18933/0x1100
Modules linked in: ipmi_si acpi_ipmi ...
CPU: 3 PID: 18933 Comm: kipmi0 Tainted: G   AW3.10.0-rc7+ #2
Hardware name: QCI QSSC-S4R/QSSC-S4R, BIOS QSSC-S4R.QCI.01.00.0027.070120100606 
07/01/2010
 8838245eea00 88103fc63c98 814c4a1e 88103fc63ca8
 814bfbab 88103fc63d28 814c73e0 88103933cbd4
 0096 88103fc63ce8 88102f618000 881035c01fd8
Call Trace:
   [] dump_stack+0x19/0x1b
 [] __schedule_bug+0x46/0x54
 [] __schedule+0x83/0x59c
 [] __cond_resched+0x22/0x2d
 [] _cond_resched+0x14/0x1d
 [] mutex_lock+0x11/0x32
 [] ? __default_send_IPI_dest_field.constprop.0+0x53/0x58
 [] ipmi_msg_handler+0x23/0x166 [ipmi_si]
 [] deliver_response+0x55/0x5a
 [] handle_new_recv_msgs+0xb67/0xc65
 [] ? read_tsc+0x9/0x19
 [] ? _raw_spin_lock_irq+0xa/0xc
 [] ipmi_thread+0x5c/0x146 [ipmi_si]
 ...

Known issues:
- Replacing tx_msg_lock with spinlock is not performance friendly
  Current solution works but does not have the best performance because it
  is better to make atomic context run as fast as possible.  Given there
  are no many IPMI messages created by ACPI, performance of current
  solution may be OK.  It can be better via linking ipmi_recv_msg into an
  RX message queue and process it in other contexts.

Signed-off-by: Lv Zheng 
Reviewed-by: Huang Ying 
---
 drivers/acpi/acpi_ipmi.c |   24 ++--
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c
index 28e2b4c..b37c189 100644
--- a/drivers/acpi/acpi_ipmi.c
+++ b/drivers/acpi/acpi_ipmi.c
@@ -39,6 +39,7 @@
 #include 
 #include 
 #include 
+#include 
 
 MODULE_AUTHOR("Zhao Yakui");
 MODULE_DESCRIPTION("ACPI IPMI Opregion driver");
@@ -58,7 +59,7 @@ struct acpi_ipmi_device {
struct list_head head;
/* the IPMI request message list */
struct list_head tx_msg_list;
-   struct mutextx_msg_lock;
+   spinlock_t  tx_msg_lock;
acpi_handle handle;
struct pnp_dev *pnp_dev;
ipmi_user_t user_interface;
@@ -146,6 +147,7 @@ static int acpi_format_ipmi_request(struct acpi_ipmi_msg 
*tx_msg,
struct kernel_ipmi_msg *msg;
struct acpi_ipmi_buffer *buffer;
struct acpi_ipmi_device *device;
+   unsigned long flags;
 
msg = &tx_msg->tx_message;
/*
@@ -182,10 +184,10 @@ static int acpi_format_ipmi_request(struct acpi_ipmi_msg 
*tx_msg,
 
/* Get the msgid */
device = tx_msg->device;
-   mutex_lock(&device->tx_msg_lock);
+   spin_lock_irqsave(&device->tx_msg_lock, flags);
device->curr_msgid++;
tx_msg->tx_msgid = device->curr_msgid;
-   mutex_unlock(&device->tx_msg_lock);
+   spin_unlock_irqrestore(&device->tx_msg_lock, flags);
 
return 0;
 }
@@ -250,6 +252,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, 
void *user_msg_data)
int msg_found = 0;
struct acpi_ipmi_msg *tx_msg;
struct pnp_dev *pnp_dev = ipmi_device->pnp_dev;
+   unsigned long flags;
 
if (msg->user != ipmi_device->user_interface) {
dev_warn(&pnp_dev->dev,
@@ -258,14 +261,14 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, 
void *user_msg_data)
goto out_msg;
}
 
-   mutex_lock(&ipmi_device->tx_msg_lock);
+   spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags);
list_for_each_entry(tx_msg, &ipmi_device->tx_msg_list, head) {
if (msg->msgid == tx_msg->tx_msgid) {
msg_found = 1;
break;
}
}
-   mutex_unlock(&ipmi_device->tx_msg_lock);
+   spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags);
 
if (!msg_found) {
dev_warn(&pnp_dev->dev,
@@ -394,6 +397,7 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address 
address,
struct acpi_ipmi_device *ipmi_device = handler_context;
int err, rem_time;
acpi_status status;
+   unsigned long flags;
 
/*
 * IPMI opregion message.
@@ -416,9 +420,9 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address 
address,
goto out_msg;
}
 
-   mutex_lock(&ipmi_device->tx_msg_lock);
+   spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags);
list_add_tail(&tx_msg->head, &ipmi_device->tx_msg_list);
-   mutex_unlock(&ipmi_device->tx_msg_lock);
+   spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags);
err = ipmi_request_settime(ipmi_device->user_interface,
   &tx_msg->a

[PATCH v4 0/2] ACPI: DBGP/DBG2 early console support for LPIA.

2012-09-27 Thread Lv Zheng
PROBE | -> | EARLY_RPINTK START |
   +-+++
   This is what the patch set has done to enable this new usage model.
   It is known as "ACPI early console launcher mode".
   Early consoles started in this style will lose some debuggabilities in
   the kernel boot up.  If the system does not crash very early,
   developers still can see the bufferred kernel outputs when the
   register_console() is called.
   Note that the user configuration can not be applied to the registered
   early consoles in this way as the acpi_table_init() is still called
   after the parse_early_param().  Instead, the early consoles should
   derive the hardware settings used in the BIOS/bootloaders.
   As a launcher, ACPI DBGP will not actually output kernel messages
   without the real early console drivers, that's why the
   CONFIG_EARLY_PRINTK_INTEL_MID_SPI is still need to be enabled along
   along with the CONFIG_EARLY_PRINTK_ACPI.
   In order to disable this facility by default and enable it at runtime,
   an kernel parameter "earlyprintk=acpi" is introduced.  This makes the
   actual sequence looks like:
   +---+++
   | EARLY_PARAM SETUP | -> | EARLY_RPINTK START |
   +---++++-+
| ACPI DBGP LAUNCH   | -> | ACPI DBGP PROBE | ->
+++-+
  ++
   -> | EARLY_RPINTK START |
  ++

Version 3 of this patch set is the first version that will be published
in the Linux community.  Earlier versions are reviewed internally in
Intel.  This patch set keeps the version number to track the history
that is known to Intel internal developers.
Version 4 of this patch set fixed bunch of CodingStyle issues.

Lv Zheng (2):
  ACPI: Add early console framework for DBGP/DBG2.
  ACPI: Add Intel MID SPI early console support.

 Documentation/kernel-parameters.txt|2 +
 arch/x86/Kconfig.debug |   38 +
 arch/x86/include/asm/mrst.h|2 +-
 arch/x86/kernel/acpi/boot.c|1 +
 arch/x86/kernel/early_printk.c |   25 +++-
 arch/x86/platform/mrst/early_printk_mrst.c |  186 +--
 drivers/acpi/Makefile  |2 +
 drivers/acpi/early_printk.c|  201 +
 drivers/platform/x86/Makefile  |2 +
 drivers/platform/x86/early/Makefile|5 +
 drivers/platform/x86/early/intel_mid_spi.c |  220 
 include/acpi/actbl2.h  |1 +
 include/linux/acpi.h   |   24 +++
 include/linux/intel_mid_early.h|   12 ++
 14 files changed, 540 insertions(+), 181 deletions(-)
 create mode 100644 drivers/acpi/early_printk.c
 create mode 100644 drivers/platform/x86/early/Makefile
 create mode 100644 drivers/platform/x86/early/intel_mid_spi.c
 create mode 100644 include/linux/intel_mid_early.h

-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 2/2] ACPI: Add Intel MID SPI early console support.

2012-09-27 Thread Lv Zheng
DesignWare SPI UART is used as one of the debug ports on Low Power Intel
Architecture (LPIA) platforms.  This patch is introduced to support this
debugging console reported by ACPI DBGP/DBG2.  The original MID SPI
early console stuff is also refined to co-exist with the new ACPI usage
model.

Signed-off-by: Lv Zheng 
---
 Documentation/kernel-parameters.txt|1 +
 arch/x86/Kconfig.debug |   23 +++
 arch/x86/include/asm/mrst.h|2 +-
 arch/x86/kernel/early_printk.c |   12 +-
 arch/x86/platform/mrst/early_printk_mrst.c |  186 +--
 drivers/platform/x86/Makefile  |2 +
 drivers/platform/x86/early/Makefile|5 +
 drivers/platform/x86/early/intel_mid_spi.c |  220 
 include/acpi/actbl2.h  |1 +
 include/linux/intel_mid_early.h|   12 ++
 10 files changed, 283 insertions(+), 181 deletions(-)
 create mode 100644 drivers/platform/x86/early/Makefile
 create mode 100644 drivers/platform/x86/early/intel_mid_spi.c
 create mode 100644 include/linux/intel_mid_early.h

Index: linux-acpi/arch/x86/Kconfig.debug
===
--- linux-acpi.orig/arch/x86/Kconfig.debug  2012-09-27 22:35:13.0 
+0800
+++ linux-acpi/arch/x86/Kconfig.debug   2012-09-27 22:35:14.0 +0800
@@ -43,9 +43,32 @@
  with klogd/syslogd or the X server. You should normally N here,
  unless you want to debug such a crash.
 
+config EARLY_PRINTK_INTEL_MID_SPI
+   bool "Early printk for Intel MID SPI UART port"
+   depends on EARLY_PRINTK
+   ---help---
+ Write kernel log output directly into the MID SPI UART debug port.
+
+ Intel MID platforms are using DesignWare SPI UART as its debug
+ console.  This option does not introduce actual early console into
+ the kernel binary, but is required by a real early console
+ implementation (EARLY_PRINTK_INTEL_MID or EARLY_PRINTK_ACPI).
+ You should normally N here unless you need to do kernel booting
+ development.
+
 config EARLY_PRINTK_INTEL_MID
bool "Early printk for Intel MID platform support"
depends on EARLY_PRINTK && X86_INTEL_MID
+   select EARLY_PRINTK_INTEL_MID_SPI
+   ---help---
+ Write kernel log output directly into the MID SPI UART debug port.
+
+ Intel MID platforms are always equipped with SPI debug ports and
+ USB OTG debug ports. To enable these debugging facilities, you
+ need to pass "earlyprintk=mrst" parameter to the kernel through
+ boot loaders.  Please see "Documentation/kernel-parameter.txt" for
+ details.  You should normally N here unless you need to do kernel
+ booting development.
 
 config EARLY_PRINTK_DBGP
bool "Early printk via EHCI debug port"
Index: linux-acpi/arch/x86/include/asm/mrst.h
===
--- linux-acpi.orig/arch/x86/include/asm/mrst.h 2012-09-27 22:35:05.0 
+0800
+++ linux-acpi/arch/x86/include/asm/mrst.h  2012-09-27 22:35:41.0 
+0800
@@ -12,6 +12,7 @@
 #define _ASM_X86_MRST_H
 
 #include 
+#include 
 
 extern int pci_mrst_init(void);
 extern int __init sfi_parse_mrtc(struct sfi_table_header *table);
@@ -63,7 +64,6 @@
 #define SFI_MTMR_MAX_NUM 8
 #define SFI_MRTC_MAX   8
 
-extern struct console early_mrst_console;
 extern void mrst_early_console_init(void);
 
 extern struct console early_hsu_console;
Index: linux-acpi/arch/x86/kernel/early_printk.c
===
--- linux-acpi.orig/arch/x86/kernel/early_printk.c  2012-09-27 
22:35:13.0 +0800
+++ linux-acpi/arch/x86/kernel/early_printk.c   2012-09-27 22:35:42.0 
+0800
@@ -205,6 +205,16 @@
 
 int __init acpi_early_console_setup(struct acpi_debug_port *info)
 {
+#ifdef CONFIG_EARLY_PRINTK_INTEL_MID_SPI
+   if (info->port_type == ACPI_DBG2_SERIAL_PORT
+   && info->port_subtype == ACPI_DBG2_INTEL_MID_SPI
+   && info->register_count > 0) {
+   mid_spi_early_console_init((u32)(info->registers[0].address));
+   early_console_register(&mid_spi_early_console,
+  acpi_early_console_keep());
+   }
+#endif
+
return 0;
 }
 #endif
@@ -256,7 +266,7 @@
 #ifdef CONFIG_EARLY_PRINTK_INTEL_MID
if (!strncmp(buf, "mrst", 4)) {
mrst_early_console_init();
-   early_console_register(&early_mrst_console, keep);
+   early_console_register(&mid_spi_early_console, keep);
}
 
if (!strncmp(buf, "hsu", 3)) {
Index: linux-acpi/arch/x86/platform/mrst/early_printk_mrst.c
===

[PATCH v4 1/2] ACPI: Add early console framework for DBGP/DBG2.

2012-09-27 Thread Lv Zheng
Microsoft Debug Port Table (DBGP or DBG2) is required for Windows SoC
platforms.  This patch is introduced to fix the gap between Windows
and Linux.

Signed-off-by: Lv Zheng 
---
 Documentation/kernel-parameters.txt |1 +
 arch/x86/Kconfig.debug  |   15 +++
 arch/x86/kernel/acpi/boot.c |1 +
 arch/x86/kernel/early_printk.c  |   13 +++
 drivers/acpi/Makefile   |2 +
 drivers/acpi/early_printk.c |  201 +++
 include/linux/acpi.h|   24 +
 7 files changed, 257 insertions(+)
 create mode 100644 drivers/acpi/early_printk.c

Index: linux-acpi/Documentation/kernel-parameters.txt
===
--- linux-acpi.orig/Documentation/kernel-parameters.txt 2012-09-27 
22:35:07.0 +0800
+++ linux-acpi/Documentation/kernel-parameters.txt  2012-09-27 
22:35:44.0 +0800
@@ -763,6 +763,7 @@
earlyprintk=serial[,ttySn[,baudrate]]
earlyprintk=ttySn[,baudrate]
earlyprintk=dbgp[debugController#]
+   earlyprintk=acpi[debugController#]
 
Append ",keep" to not disable it when the real console
takes over.
Index: linux-acpi/arch/x86/Kconfig.debug
===
--- linux-acpi.orig/arch/x86/Kconfig.debug  2012-09-27 22:35:07.0 
+0800
+++ linux-acpi/arch/x86/Kconfig.debug   2012-09-27 22:35:44.0 +0800
@@ -59,6 +59,21 @@
  with klogd/syslogd or the X server. You should normally N here,
  unless you want to debug such a crash. You need usb debug device.
 
+config EARLY_PRINTK_ACPI
+   bool "Early printk launcher via ACPI debug port tables"
+   depends on EARLY_PRINTK && ACPI
+   ---help---
+ Write kernel log output directly into the debug ports described
+ in the ACPI tables known as DBGP and DBG2.
+
+ To enable such debugging facilities, you need to enable this
+ configuration option and append the "earlyprintk=acpi" kernel
+ parameter through the boot loaders.  Please refer the
+ "Documentation/kernel-parameters.txt" for details.  Since this
+ is an early console launcher, you still need to enable actual
+ early console drivers that are suitable for your platform.
+ If in doubt, say "N".
+
 config DEBUG_STACKOVERFLOW
bool "Check for stack overflows"
depends on DEBUG_KERNEL
Index: linux-acpi/arch/x86/kernel/acpi/boot.c
===
--- linux-acpi.orig/arch/x86/kernel/acpi/boot.c 2012-09-27 22:35:07.0 
+0800
+++ linux-acpi/arch/x86/kernel/acpi/boot.c  2012-09-27 22:35:13.0 
+0800
@@ -1518,6 +1518,7 @@
return;
}
 
+   acpi_early_console_parse();
acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf);
 
/*
Index: linux-acpi/arch/x86/kernel/early_printk.c
===
--- linux-acpi.orig/arch/x86/kernel/early_printk.c  2012-09-27 
22:35:07.0 +0800
+++ linux-acpi/arch/x86/kernel/early_printk.c   2012-09-27 22:35:44.0 
+0800
@@ -200,6 +200,15 @@
register_console(early_console);
 }
 
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+#include 
+
+int __init acpi_early_console_setup(struct acpi_debug_port *info)
+{
+   return 0;
+}
+#endif
+
 static int __init setup_early_printk(char *buf)
 {
int keep;
@@ -236,6 +245,10 @@
if (!strncmp(buf, "dbgp", 4) && !early_dbgp_init(buf + 4))
early_console_register(&early_dbgp_console, keep);
 #endif
+#ifdef CONFIG_EARLY_PRINTK_ACPI
+   if (!strncmp(buf, "acpi", 4))
+   acpi_early_console_init(buf + 4, keep);
+#endif
 #ifdef CONFIG_HVC_XEN
if (!strncmp(buf, "xen", 3))
early_console_register(&xenboot_console, keep);
Index: linux-acpi/drivers/acpi/Makefile
===
--- linux-acpi.orig/drivers/acpi/Makefile   2012-09-27 22:35:07.0 
+0800
+++ linux-acpi/drivers/acpi/Makefile2012-09-27 22:35:36.0 +0800
@@ -46,6 +46,8 @@
 acpi-y += video_detect.o
 endif
 
+obj-$(CONFIG_EARLY_PRINTK_ACPI)+= early_printk.o
+
 # These are (potentially) separate modules
 obj-$(CONFIG_ACPI_AC)  += ac.o
 obj-$(CONFIG_ACPI_BUTTON)  += button.o
Index: linux-acpi/drivers/acpi/early_printk.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ linux-acpi/drivers/acpi/early_printk.c  2012-09-27 22:35:13.00000 
+080

[PATCH] tools/power/acpi/tools/acpidbg: Add multi-commands support in batch mode

2016-07-20 Thread Lv Zheng
This patch adds multi-commands support for the batch mode. The same mode
can be seen in acpiexec.

However people may think this is not useful for an in-kernel debugger,
because the in-kernel debugger is always running, never exits. So we can
run another command by running another acpidbg batch mode instance.

But this mode should still be useful for acpidbg. The reason is: when the
in-kernel debugger has entered the single-stepping mode, ending acpidbg
(which closes the debugger IO interface) will lead to the end of the
single-stepping mode.

So we need the acpidbg multi-commands batch mode in order to execute
multiple single-stepping mode commands in the batch mode.

Signed-off-by: Lv Zheng 
---
 tools/power/acpi/tools/acpidbg/acpidbg.c |   77 +-
 1 file changed, 64 insertions(+), 13 deletions(-)

diff --git a/tools/power/acpi/tools/acpidbg/acpidbg.c 
b/tools/power/acpi/tools/acpidbg/acpidbg.c
index 0aba129..330e5fe 100644
--- a/tools/power/acpi/tools/acpidbg/acpidbg.c
+++ b/tools/power/acpi/tools/acpidbg/acpidbg.c
@@ -90,6 +90,7 @@ static char acpi_aml_batch_prompt;
 static char acpi_aml_batch_roll;
 static unsigned long acpi_aml_log_state;
 static char *acpi_aml_batch_cmd = NULL;
+static char *acpi_aml_batch_cmds = NULL;
 static char *acpi_aml_batch_pos = NULL;
 
 static int acpi_aml_set_fl(int fd, int flags)
@@ -326,12 +327,65 @@ static void acpi_aml_loop(int fd)
}
 }
 
+static void acpi_aml_delete_batch(void)
+{
+   if (acpi_aml_batch_cmd) {
+   free(acpi_aml_batch_cmd);
+   acpi_aml_batch_cmd = NULL;
+   }
+}
+
+static bool acpi_aml_create_batch(char *cmd)
+{
+   int len;
+
+   acpi_aml_delete_batch();
+   len = strlen(cmd);
+   acpi_aml_batch_cmd = calloc(len + 2, 1);
+   if (!acpi_aml_batch_cmd) {
+   perror("calloc");
+   return false;
+   }
+   memcpy(acpi_aml_batch_cmd, cmd, len);
+   acpi_aml_batch_cmd[len] = '\n';
+   return true;
+}
+
+static void acpi_aml_batch(int fd)
+{
+   char *ptr, *cmd;
+   bool run = false;
+
+   cmd = ptr = acpi_aml_batch_cmds;
+   while (*ptr) {
+   if (*ptr == ',') {
+   /* Convert commas to spaces */
+   *ptr = ' ';
+   } else if (*ptr == ';') {
+   *ptr = '\0';
+   run = true;
+   }
+   ptr++;
+   if (run || (*ptr == '\0')) {
+   if (!acpi_aml_create_batch(cmd))
+   return;
+   ioctl(fd, ACPI_IOCTL_DEBUGGER_FLUSH);
+   acpi_aml_loop(fd);
+   run = 0;
+   cmd = ptr;
+   acpi_aml_delete_batch();
+   }
+   }
+}
+
 void usage(FILE *file, char *progname)
 {
fprintf(file, "usage: %s [-b cmd] [-f file] [-h]\n", progname);
fprintf(file, "\nOptions:\n");
-   fprintf(file, "  -b Specify command to be executed in batch 
mode\n");
-   fprintf(file, "  -f Specify interface file other than");
+   fprintf(file, "  -b Specify commands to be executed in batch 
mode\n");
+   fprintf(file, " Use ';' as command delimiters\n");
+   fprintf(file, " Use ',' as spaces\n");
+   fprintf(file, "  -f Specify interface file other than\n");
fprintf(file, " /sys/kernel/debug/acpi/acpidbg\n");
fprintf(file, "  -h Print this help message\n");
 }
@@ -340,27 +394,23 @@ int main(int argc, char **argv)
 {
int fd = -1;
int ch;
-   int len;
int ret = EXIT_SUCCESS;
 
while ((ch = getopt(argc, argv, "b:f:h")) != -1) {
switch (ch) {
case 'b':
-   if (acpi_aml_batch_cmd) {
+   if (acpi_aml_batch_cmds) {
fprintf(stderr, "Already specify %s\n",
-   acpi_aml_batch_cmd);
+   acpi_aml_batch_cmds);
ret = EXIT_FAILURE;
goto exit;
}
-   len = strlen(optarg);
-   acpi_aml_batch_cmd = calloc(len + 2, 1);
-   if (!acpi_aml_batch_cmd) {
-   perror("calloc");
+   acpi_aml_batch_cmds = strdup(optarg);
+   if (!acpi_aml_batch_cmds) {
+   perror("strdup");
ret = EXIT_FAILURE;
goto exit;
}
- 

[PATCH 1/2] ACPI / EC: Add PM operations to tune polling mode efficiency

2016-07-21 Thread Lv Zheng
When the PM code disables all IRQs, EC will be in polling mode, it is
efficient to use busy polling with zero timeout in such cases.

Signed-off-by: Lv Zheng 
---
 drivers/acpi/ec.c   |   53 +++
 drivers/acpi/internal.h |2 ++
 2 files changed, 55 insertions(+)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 999a109..c2d135d 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -1613,6 +1613,58 @@ error:
return ret;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static void acpi_ec_enter_noirq(struct acpi_ec *ec)
+{
+   unsigned long flags;
+
+   if (ec == first_ec) {
+   spin_lock_irqsave(&ec->lock, flags);
+   ec->saved_busy_polling = ec_busy_polling;
+   ec->saved_polling_guard = ec_polling_guard;
+   ec_busy_polling = true;
+   ec_polling_guard = 0;
+   ec_log_drv("interrupt blocked");
+   spin_unlock_irqrestore(&ec->lock, flags);
+   }
+}
+
+static void acpi_ec_leave_noirq(struct acpi_ec *ec)
+{
+   unsigned long flags;
+
+   if (ec == first_ec) {
+   spin_lock_irqsave(&ec->lock, flags);
+   ec_busy_polling = ec->saved_busy_polling;
+   ec_polling_guard = ec->saved_polling_guard;
+   ec_log_drv("interrupt unblocked");
+   spin_unlock_irqrestore(&ec->lock, flags);
+   }
+}
+
+static int acpi_ec_suspend_noirq(struct device *dev)
+{
+   struct acpi_ec *ec =
+   acpi_driver_data(to_acpi_device(dev));
+
+   acpi_ec_enter_noirq(ec);
+   return 0;
+}
+
+static int acpi_ec_resume_noirq(struct device *dev)
+{
+   struct acpi_ec *ec =
+   acpi_driver_data(to_acpi_device(dev));
+
+   acpi_ec_leave_noirq(ec);
+   return 0;
+}
+#endif
+
+static const struct dev_pm_ops acpi_ec_pm = {
+   SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(acpi_ec_suspend_noirq, 
acpi_ec_resume_noirq)
+};
+
 static int param_set_event_clearing(const char *val, struct kernel_param *kp)
 {
int result = 0;
@@ -1658,6 +1710,7 @@ static struct acpi_driver acpi_ec_driver = {
.add = acpi_ec_add,
.remove = acpi_ec_remove,
},
+   .drv.pm = &acpi_ec_pm,
 };
 
 int __init acpi_ec_init(void)
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 940218f..6996121 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -174,6 +174,8 @@ struct acpi_ec {
struct work_struct work;
unsigned long timestamp;
unsigned long nr_pending_queries;
+   bool saved_busy_polling;
+   unsigned int saved_polling_guard;
 };
 
 extern struct acpi_ec *first_ec;
-- 
1.7.10



[PATCH 2/2] ACPI / EC: Add PM operations to block event handling

2016-07-21 Thread Lv Zheng
During the early stage for boot/resume, EC shouldn't handle _Qxx as EC
shouldn't expect the AML interpreter to be fully running and other drivers
are ready to handle the notifications issued from _Qxx.

Originally, EC driver stops handling both events and transactions in
acpi_ec_block_transactions(), and restarts to handle transactions in
acpi_ec_unblock_transactions_early(), restarts to handle both events and
transactions in acpi_ec_unblock_transactions().

However "stop handling events" mean the EC driver notices that the system
is about to suspend, "start handling events" means the EC driver notices
that the system is about to resume. This can be implemented via PM ops.
With "event handling switch" implemented via suspend/resume ops, the
following 2 APIs serve for the same purpose and can be combined:
acpi_ec_unblock_transactions_early()/acpi_ec_unblock_transactions().

Signed-off-by: Lv Zheng 
---
 drivers/acpi/ec.c   |   63 ++-
 drivers/acpi/internal.h |1 -
 drivers/acpi/sleep.c|4 +--
 3 files changed, 48 insertions(+), 20 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index c2d135d..6493df8 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -103,6 +103,7 @@ enum ec_command {
 * when trying to clear the EC */
 
 enum {
+   EC_FLAGS_QUERY_ENABLED, /* Query is enabled */
EC_FLAGS_QUERY_PENDING, /* Query is pending */
EC_FLAGS_QUERY_GUARDING,/* Guard for SCI_EVT check */
EC_FLAGS_GPE_HANDLER_INSTALLED, /* GPE handler installed */
@@ -423,7 +424,8 @@ static bool acpi_ec_submit_flushable_request(struct acpi_ec 
*ec)
 
 static void acpi_ec_submit_query(struct acpi_ec *ec)
 {
-   if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) {
+   if (test_bit(EC_FLAGS_QUERY_ENABLED, &ec->flags) &&
+   !test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) {
ec_dbg_evt("Command(%s) submitted/blocked",
   acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY));
ec->nr_pending_queries++;
@@ -440,6 +442,26 @@ static void acpi_ec_complete_query(struct acpi_ec *ec)
}
 }
 
+static void acpi_ec_disable_event(struct acpi_ec *ec)
+{
+   unsigned long flags;
+
+   spin_lock_irqsave(&ec->lock, flags);
+   clear_bit(EC_FLAGS_QUERY_ENABLED, &ec->flags);
+   ec_log_drv("event blocked");
+   spin_unlock_irqrestore(&ec->lock, flags);
+}
+
+static void acpi_ec_enable_event(struct acpi_ec *ec)
+{
+   unsigned long flags;
+
+   spin_lock_irqsave(&ec->lock, flags);
+   set_bit(EC_FLAGS_QUERY_ENABLED, &ec->flags);
+   ec_log_drv("event unblocked");
+   spin_unlock_irqrestore(&ec->lock, flags);
+}
+
 static bool acpi_ec_guard_event(struct acpi_ec *ec)
 {
bool guarded = true;
@@ -913,20 +935,6 @@ void acpi_ec_block_transactions(void)
 
 void acpi_ec_unblock_transactions(void)
 {
-   struct acpi_ec *ec = first_ec;
-
-   if (!ec)
-   return;
-
-   /* Allow transactions to be carried out again */
-   acpi_ec_start(ec, true);
-
-   if (EC_FLAGS_CLEAR_ON_RESUME)
-   acpi_ec_clear(ec);
-}
-
-void acpi_ec_unblock_transactions_early(void)
-{
/*
 * Allow transactions to happen again (this function is called from
 * atomic context during wakeup, so we don't need to acquire the mutex).
@@ -1228,13 +1236,13 @@ static struct acpi_ec *make_acpi_ec(void)
 
if (!ec)
return NULL;
-   ec->flags = 1 << EC_FLAGS_QUERY_PENDING;
mutex_init(&ec->mutex);
init_waitqueue_head(&ec->wait);
INIT_LIST_HEAD(&ec->list);
spin_lock_init(&ec->lock);
INIT_WORK(&ec->work, acpi_ec_event_handler);
ec->timestamp = jiffies;
+   acpi_ec_disable_event(ec);
return ec;
 }
 
@@ -1415,7 +1423,7 @@ static int acpi_ec_add(struct acpi_device *device)
acpi_walk_dep_device_list(ec->handle);
 
/* EC is fully operational, allow queries */
-   clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
+   acpi_ec_enable_event(ec);
 
/* Clear stale _Q events if hardware might require that */
if (EC_FLAGS_CLEAR_ON_RESUME)
@@ -1659,10 +1667,31 @@ static int acpi_ec_resume_noirq(struct device *dev)
acpi_ec_leave_noirq(ec);
return 0;
 }
+
+static int acpi_ec_suspend(struct device *dev)
+{
+   struct acpi_ec *ec =
+   acpi_driver_data(to_acpi_device(dev));
+
+   acpi_ec_disable_event(ec);
+   return 0;
+}
+
+static int acpi_ec_resume(struct device *dev)
+{
+   struct acpi_ec *ec =
+   acpi_driver_data(to_acpi_device(dev));
+
+   acpi_ec_enable_event(ec);
+   

[PATCH v3 0/3] ACPI / debugger: Add kernel flushing support

2016-07-21 Thread Lv Zheng
AML debugger is implemented in the kernel as a character device located in
the debugfs. Currently, when its batch mode is used, the userspace tool
needs to flush the logs/prompts remained in the kernel output buffer, this
is implemented in an inefficient way in the userspace by polling the IO and
reading everything out.

This patch introduces a kernel space flushing support, so that userspace
can invoke ioctl() to put the driver into a state waiting for new commands,
all kernel space logs/prompts will be automatically discarded by ioctl().

Lv Zheng (3):
  ACPI / debugger: Add kernel flushing support
  tools/power/acpi/acpidbg: Use new flushing mechanism
  tools/power/acpi/acpidbg: Add multi-commands support in batch mode

 drivers/acpi/acpi_dbg.c  |   85 +--
 include/linux/acpi.h |1 +
 include/uapi/linux/acpi-ioctls.h |   21 ++
 tools/power/acpi/tools/acpidbg/acpidbg.c |  110 +-
 4 files changed, 165 insertions(+), 52 deletions(-)
 create mode 100644 include/uapi/linux/acpi-ioctls.h

-- 
1.7.10



[PATCH v3 2/3] tools/power/acpi/acpidbg: Use new flushing mechanism

2016-07-21 Thread Lv Zheng
This patch converts tools/power/acpi/tools/acpidbg/acpidbg to use the new
flushing mechanism.

Signed-off-by: Lv Zheng 
---
 tools/power/acpi/tools/acpidbg/acpidbg.c |   51 --
 1 file changed, 7 insertions(+), 44 deletions(-)

diff --git a/tools/power/acpi/tools/acpidbg/acpidbg.c 
b/tools/power/acpi/tools/acpidbg/acpidbg.c
index a88ac45..f5542b9 100644
--- a/tools/power/acpi/tools/acpidbg/acpidbg.c
+++ b/tools/power/acpi/tools/acpidbg/acpidbg.c
@@ -15,7 +15,9 @@
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 
 #define ACPI_AML_FILE  "/sys/kernel/debug/acpi/acpidbg"
 #define ACPI_AML_SEC_TICK  1
@@ -83,7 +85,6 @@ static const char *acpi_aml_file_path = ACPI_AML_FILE;
 static unsigned long acpi_aml_mode = ACPI_AML_INTERACTIVE;
 static bool acpi_aml_exit;
 
-static bool acpi_aml_batch_drain;
 static unsigned long acpi_aml_batch_state;
 static char acpi_aml_batch_prompt;
 static char acpi_aml_batch_roll;
@@ -239,11 +240,9 @@ static int acpi_aml_write_batch_log(int fd, struct 
circ_buf *crc)
 
p = &crc->buf[crc->tail];
len = circ_count_to_end(crc);
-   if (!acpi_aml_batch_drain) {
-   len = write(fd, p, len);
-   if (len < 0)
-   perror("write");
-   }
+   len = write(fd, p, len);
+   if (len < 0)
+   perror("write");
if (len > 0)
crc->tail = (crc->tail + len) & (ACPI_AML_BUF_SIZE - 1);
return len;
@@ -270,10 +269,7 @@ static void acpi_aml_loop(int fd)
if (acpi_aml_mode == ACPI_AML_BATCH) {
acpi_aml_log_state = ACPI_AML_LOG_START;
acpi_aml_batch_pos = acpi_aml_batch_cmd;
-   if (acpi_aml_batch_drain)
-   acpi_aml_batch_state = ACPI_AML_BATCH_READ_LOG;
-   else
-   acpi_aml_batch_state = ACPI_AML_BATCH_WRITE_CMD;
+   acpi_aml_batch_state = ACPI_AML_BATCH_WRITE_CMD;
}
acpi_aml_exit = false;
while (!acpi_aml_exit) {
@@ -330,39 +326,6 @@ static void acpi_aml_loop(int fd)
}
 }
 
-static bool acpi_aml_readable(int fd)
-{
-   fd_set rfds;
-   struct timeval tv;
-   int ret;
-   int maxfd = 0;
-
-   tv.tv_sec = 0;
-   tv.tv_usec = ACPI_AML_USEC_PEEK;
-   FD_ZERO(&rfds);
-   maxfd = acpi_aml_set_fd(fd, maxfd, &rfds);
-   ret = select(maxfd+1, &rfds, NULL, NULL, &tv);
-   if (ret < 0)
-   perror("select");
-   if (ret > 0 && FD_ISSET(fd, &rfds))
-   return true;
-   return false;
-}
-
-/*
- * This is a userspace IO flush implementation, replying on the prompt
- * characters and can be turned into a flush() call after kernel implements
- * .flush() filesystem operation.
- */
-static void acpi_aml_flush(int fd)
-{
-   while (acpi_aml_readable(fd)) {
-   acpi_aml_batch_drain = true;
-   acpi_aml_loop(fd);
-   acpi_aml_batch_drain = false;
-   }
-}
-
 void usage(FILE *file, char *progname)
 {
fprintf(file, "usage: %s [-b cmd] [-f file] [-h]\n", progname);
@@ -426,7 +389,7 @@ int main(int argc, char **argv)
acpi_aml_set_fl(STDOUT_FILENO, O_NONBLOCK);
 
if (acpi_aml_mode == ACPI_AML_BATCH)
-   acpi_aml_flush(fd);
+   ioctl(fd, ACPI_IOCTL_DEBUGGER_FLUSH);
acpi_aml_loop(fd);
 
 exit:
-- 
1.7.10



[PATCH v3 1/3] ACPI / debugger: Add kernel flushing support

2016-07-21 Thread Lv Zheng
This patch adds debugger log flushing support in kernel via .ioctl()
callback. The in-kernel flushing is more efficient, because it reduces
useless log IOs by bypassing log user_read/kern_write during the flush
period.

Signed-off-by: Lv Zheng 
Cc: linux-...@vger.kernel.org
---
 drivers/acpi/acpi_dbg.c  |   85 --
 include/linux/acpi.h |1 +
 include/uapi/linux/acpi-ioctls.h |   21 ++
 3 files changed, 103 insertions(+), 4 deletions(-)
 create mode 100644 include/uapi/linux/acpi-ioctls.h

diff --git a/drivers/acpi/acpi_dbg.c b/drivers/acpi/acpi_dbg.c
index dee8692..a5f4457 100644
--- a/drivers/acpi/acpi_dbg.c
+++ b/drivers/acpi/acpi_dbg.c
@@ -46,6 +46,8 @@
 #define ACPI_AML_KERN  (ACPI_AML_IN_KERN | ACPI_AML_OUT_KERN)
 #define ACPI_AML_BUSY  (ACPI_AML_USER | ACPI_AML_KERN)
 #define ACPI_AML_OPEN  (ACPI_AML_OPENED | ACPI_AML_CLOSED)
+#define ACPI_AML_FLUSHING_LOG  0x0040 /* flushing log output */
+#define ACPI_AML_WAITING_CMD   0x0080 /* waiting for cmd input */
 
 struct acpi_aml_io {
wait_queue_head_t wait;
@@ -120,6 +122,16 @@ static inline bool __acpi_aml_busy(void)
return false;
 }
 
+static inline bool __acpi_aml_waiting_cmd(void)
+{
+   return !!(acpi_aml_io.flags & ACPI_AML_WAITING_CMD);
+}
+
+static inline bool __acpi_aml_flushing_log(void)
+{
+   return !!(acpi_aml_io.flags & ACPI_AML_FLUSHING_LOG);
+}
+
 static inline bool __acpi_aml_opened(void)
 {
if (acpi_aml_io.flags & ACPI_AML_OPEN)
@@ -152,6 +164,26 @@ static bool acpi_aml_busy(void)
return ret;
 }
 
+static inline bool acpi_aml_waiting_cmd(void)
+{
+   bool ret;
+
+   mutex_lock(&acpi_aml_io.lock);
+   ret = __acpi_aml_waiting_cmd();
+   mutex_unlock(&acpi_aml_io.lock);
+   return ret;
+}
+
+static inline bool acpi_aml_flushing_log(void)
+{
+   bool ret;
+
+   mutex_lock(&acpi_aml_io.lock);
+   ret = __acpi_aml_flushing_log();
+   mutex_unlock(&acpi_aml_io.lock);
+   return ret;
+}
+
 static bool acpi_aml_used(void)
 {
bool ret;
@@ -183,7 +215,8 @@ static bool acpi_aml_kern_writable(void)
 
mutex_lock(&acpi_aml_io.lock);
ret = !__acpi_aml_access_ok(ACPI_AML_OUT_KERN) ||
- __acpi_aml_writable(&acpi_aml_io.out_crc, ACPI_AML_OUT_KERN);
+ __acpi_aml_writable(&acpi_aml_io.out_crc, ACPI_AML_OUT_KERN) ||
+ __acpi_aml_flushing_log();
mutex_unlock(&acpi_aml_io.lock);
return ret;
 }
@@ -264,6 +297,9 @@ static int acpi_aml_write_kern(const char *buf, int len)
int n;
char *p;
 
+   if (acpi_aml_flushing_log())
+   return len;
+
ret = acpi_aml_lock_write(crc, ACPI_AML_OUT_KERN);
if (ret < 0)
return ret;
@@ -458,9 +494,18 @@ static int acpi_aml_wait_command_ready(bool single_step,
else
acpi_os_printf("\n%1c ", ACPI_DEBUGGER_COMMAND_PROMPT);
 
+   mutex_lock(&acpi_aml_io.lock);
+   acpi_aml_io.flags |= ACPI_AML_WAITING_CMD;
+   wake_up_interruptible(&acpi_aml_io.wait);
+   mutex_unlock(&acpi_aml_io.lock);
+
status = acpi_os_get_line(buffer, length, NULL);
if (ACPI_FAILURE(status))
return -EINVAL;
+
+   mutex_lock(&acpi_aml_io.lock);
+   acpi_aml_io.flags &= ~ACPI_AML_WAITING_CMD;
+   mutex_unlock(&acpi_aml_io.lock);
return 0;
 }
 
@@ -593,9 +638,11 @@ static int acpi_aml_read_user(char __user *buf, int len)
smp_rmb();
p = &crc->buf[crc->tail];
n = min(len, circ_count_to_end(crc));
-   if (copy_to_user(buf, p, n)) {
-   ret = -EFAULT;
-   goto out;
+   if (!acpi_aml_flushing_log()) {
+   if (copy_to_user(buf, p, n)) {
+   ret = -EFAULT;
+   goto out;
+   }
}
/* sync tail after removing logs */
smp_mb();
@@ -731,10 +778,40 @@ static unsigned int acpi_aml_poll(struct file *file, 
poll_table *wait)
return masks;
 }
 
+static int acpi_aml_flush(void)
+{
+   int ret;
+
+   /*
+* Discard output buffer and put the driver into a state waiting
+* for the new user input.
+*/
+   mutex_lock(&acpi_aml_io.lock);
+   acpi_aml_io.flags |= ACPI_AML_FLUSHING_LOG;
+   mutex_unlock(&acpi_aml_io.lock);
+
+   ret = wait_event_interruptible(acpi_aml_io.wait,
+   acpi_aml_waiting_cmd());
+   (void)acpi_aml_read_user(NULL, ACPI_AML_BUF_SIZE);
+
+   mutex_lock(&acpi_aml_io.lock);
+   acpi_aml_io.flags &= ~ACPI_AML_FLUSHING_LOG;
+   mutex_unlock(&acpi_aml_io.lock);
+   return ret;
+}
+
+static long acpi_aml_ioctl(struct file *file,
+  unsigned int cmd, unsigned long arg)
+{
+   return cmd == ACPI_IOCTL_DEBUGGER_F

[PATCH v3 3/3] tools/power/acpi/acpidbg: Add multi-commands support in batch mode

2016-07-21 Thread Lv Zheng
This patch adds multi-commands support for the batch mode. The same mode
can be seen in acpiexec.

However people may think this is not useful for an in-kernel debugger,
because the in-kernel debugger is always running, never exits. So we can
run another command by running another acpidbg batch mode instance.

But this mode should still be useful for acpidbg. The reason is: when the
in-kernel debugger has entered the single-stepping mode, ending acpidbg
(which closes the debugger IO interface) will lead to the end of the
single-stepping mode.

So we need the acpidbg multi-commands batch mode in order to execute
multiple single-stepping mode commands in the batch mode.

Signed-off-by: Lv Zheng 
---
 tools/power/acpi/tools/acpidbg/acpidbg.c |   77 +-
 1 file changed, 64 insertions(+), 13 deletions(-)

diff --git a/tools/power/acpi/tools/acpidbg/acpidbg.c 
b/tools/power/acpi/tools/acpidbg/acpidbg.c
index f5542b9..99a8f766 100644
--- a/tools/power/acpi/tools/acpidbg/acpidbg.c
+++ b/tools/power/acpi/tools/acpidbg/acpidbg.c
@@ -90,6 +90,7 @@ static char acpi_aml_batch_prompt;
 static char acpi_aml_batch_roll;
 static unsigned long acpi_aml_log_state;
 static char *acpi_aml_batch_cmd = NULL;
+static char *acpi_aml_batch_cmds = NULL;
 static char *acpi_aml_batch_pos = NULL;
 
 static int acpi_aml_set_fl(int fd, int flags)
@@ -326,12 +327,65 @@ static void acpi_aml_loop(int fd)
}
 }
 
+static void acpi_aml_delete_batch(void)
+{
+   if (acpi_aml_batch_cmd) {
+   free(acpi_aml_batch_cmd);
+   acpi_aml_batch_cmd = NULL;
+   }
+}
+
+static bool acpi_aml_create_batch(char *cmd)
+{
+   int len;
+
+   acpi_aml_delete_batch();
+   len = strlen(cmd);
+   acpi_aml_batch_cmd = calloc(len + 2, 1);
+   if (!acpi_aml_batch_cmd) {
+   perror("calloc");
+   return false;
+   }
+   memcpy(acpi_aml_batch_cmd, cmd, len);
+   acpi_aml_batch_cmd[len] = '\n';
+   return true;
+}
+
+static void acpi_aml_batch(int fd)
+{
+   char *ptr, *cmd;
+   bool run = false;
+
+   cmd = ptr = acpi_aml_batch_cmds;
+   while (*ptr) {
+   if (*ptr == ',') {
+   /* Convert commas to spaces */
+   *ptr = ' ';
+   } else if (*ptr == ';') {
+   *ptr = '\0';
+   run = true;
+   }
+   ptr++;
+   if (run || (*ptr == '\0')) {
+   if (!acpi_aml_create_batch(cmd))
+   return;
+   ioctl(fd, ACPI_IOCTL_DEBUGGER_FLUSH);
+   acpi_aml_loop(fd);
+   run = 0;
+   cmd = ptr;
+   acpi_aml_delete_batch();
+   }
+   }
+}
+
 void usage(FILE *file, char *progname)
 {
fprintf(file, "usage: %s [-b cmd] [-f file] [-h]\n", progname);
fprintf(file, "\nOptions:\n");
-   fprintf(file, "  -b Specify command to be executed in batch 
mode\n");
-   fprintf(file, "  -f Specify interface file other than");
+   fprintf(file, "  -b Specify commands to be executed in batch 
mode\n");
+   fprintf(file, " Use ';' as command delimiters\n");
+   fprintf(file, " Use ',' as spaces\n");
+   fprintf(file, "  -f Specify interface file other than\n");
fprintf(file, " /sys/kernel/debug/acpi/acpidbg\n");
fprintf(file, "  -h Print this help message\n");
 }
@@ -340,27 +394,23 @@ int main(int argc, char **argv)
 {
int fd = -1;
int ch;
-   int len;
int ret = EXIT_SUCCESS;
 
while ((ch = getopt(argc, argv, "b:f:h")) != -1) {
switch (ch) {
case 'b':
-   if (acpi_aml_batch_cmd) {
+   if (acpi_aml_batch_cmds) {
fprintf(stderr, "Already specify %s\n",
-   acpi_aml_batch_cmd);
+   acpi_aml_batch_cmds);
ret = EXIT_FAILURE;
goto exit;
}
-   len = strlen(optarg);
-   acpi_aml_batch_cmd = calloc(len + 2, 1);
-   if (!acpi_aml_batch_cmd) {
-   perror("calloc");
+   acpi_aml_batch_cmds = strdup(optarg);
+   if (!acpi_aml_batch_cmds) {
+   perror("strdup");
ret = EXIT_FAILURE;
goto exit;
}
- 

[PATCH v5 1/3] ACPI / button: Add missing event to keep SW_LID running without additional event loss

2016-07-21 Thread Lv Zheng
There are several possibilities that a lid event can be lost. For example,
EC event queue full, or the resume order of the underlying drivers.

When the event loss happens, new event may also be lost due to the type of
the SW_LID (switch event). The 2nd loss is what we want to avoid.

This patch adds a mechanism to insert lid events as a compensation for the
switch event nature of the lid events in order to avoid the 2nd loss.

Signed-off-by: Lv Zheng 
Cc: Dmitry Torokhov 
Cc: Benjamin Tissoires 
Cc: Bastien Nocera: 
Cc: linux-in...@vger.kernel.org
---
 drivers/acpi/button.c |   21 -
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 148f4e5..41fd21d 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -104,6 +104,8 @@ struct acpi_button {
struct input_dev *input;
char phys[32];  /* for input device */
unsigned long pushed;
+   int sw_last_state;
+   unsigned long sw_last_time;
bool suspended;
 };
 
@@ -111,6 +113,10 @@ static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
 static struct acpi_device *lid_device;
 static u8 lid_init_state = ACPI_BUTTON_LID_INIT_METHOD;
 
+static unsigned long lid_report_interval __read_mostly = 500;
+module_param(lid_report_interval, ulong, 0644);
+MODULE_PARM_DESC(lid_report_interval, "Interval (ms) between lid key events");
+
 /* --
   FS Interface (/proc)
-- 
*/
@@ -133,11 +139,22 @@ static int acpi_lid_evaluate_state(struct acpi_device 
*device)
 static int acpi_lid_notify_state(struct acpi_device *device, int state)
 {
struct acpi_button *button = acpi_driver_data(device);
+   unsigned long sw_tout;
int ret;
 
-   /* input layer checks if event is redundant */
+   /* Send the switch event */
+   sw_tout = button->sw_last_time +
+ msecs_to_jiffies(lid_report_interval);
+   if (time_after(jiffies, sw_tout) &&
+   (button->sw_last_state == !!state)) {
+   /* Send the complement switch event */
+   input_report_switch(button->input, SW_LID, state);
+   input_sync(button->input);
+   }
input_report_switch(button->input, SW_LID, !state);
input_sync(button->input);
+   button->sw_last_state = !!state;
+   button->sw_last_time = jiffies;
 
if (state)
pm_wakeup_event(&device->dev, 0);
@@ -407,6 +424,8 @@ static int acpi_button_add(struct acpi_device *device)
strcpy(name, ACPI_BUTTON_DEVICE_NAME_LID);
sprintf(class, "%s/%s",
ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID);
+   button->sw_last_state = !!acpi_lid_evaluate_state(device);
+   button->sw_last_time = jiffies;
} else {
printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid);
error = -ENODEV;
-- 
1.7.10



[PATCH v5 2/3] ACPI / button: Add KEY_LID_OPEN/KEY_LID_CLOSE for new usage model

2016-07-21 Thread Lv Zheng
There are many AML tables reporting wrong initial lid state (Link 1), and
some of them never report lid open state (Link 2). For example, lid
notifications on Surface 3 are as follows (no open event):
Method (_E4C, 0, Serialized)
{
If (LEqual(HELD, One))
{
Store(One, ^^LID.LIDB)
}
Else
{
Store(Zero, ^^LID.LIDB)
Notify (LID, 0x80)
}
}
For the first issue, we can work it around via reporting forced initial
"open" state (however, it is apparently still not reliable) and sending
complement switch events.
For the second issue, it is totally a different usage model than the switch
event type because the switch event type requires the driver to send paired
events while the events is naturally not paired on this platform. There is
only one case that the lid driver can help to make a paired events on such
platforms: if the "lid close" is used to trigger system pending, then the
driver can report a forced "lid open" via resume callback. But if "lid
close" is not used to trigger system suspending, then the lid driver can
never have a chance to make the events paired. And an even worse thing is
the forced value breaks some use cases (e.x., dark resume).

As a proxy layer acting between, ACPI button driver is not able to handle
all such platform designed cases via Linux input switch events, but need to
re-define the usage model of the ACPI lid. That is:
1. It's initial state is not reliable;
2. There may not be an open event;
3. Userspace should only take action against the close event which is
   reliable, always sent after a real lid close.

So we need to introduce a new ABI, which is input key events based, not
input switch events based. And this usage model could help to ensure a
reliable lid state during runtime. Adopting with this usage model, the
platform firmware has been facilitated to have the maximum possibilities to
force the hosting OS to behave as what they want.

This patch adds a set of new input key events so that the new userspace
programs can use them to handle this usage model correctly. And in the
meanwhile, the old input switch event is kept so that no old programs will
be broken by the ABI change.

Link 1: https://bugzilla.kernel.org/show_bug.cgi?id=89211
https://bugzilla.kernel.org/show_bug.cgi?id=106151
Link 2: https://bugzilla.kernel.org/show_bug.cgi?id=106941
Signed-off-by: Lv Zheng 
Reviewed-by: Benjamin Tissoires 
Cc: Dmitry Torokhov 
Cc: Bastien Nocera: 
Cc: linux-in...@vger.kernel.org
---
 drivers/acpi/button.c  |   26 +++---
 include/uapi/linux/input-event-codes.h |7 +++
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 41fd21d..c5fd793 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -106,6 +106,8 @@ struct acpi_button {
unsigned long pushed;
int sw_last_state;
unsigned long sw_last_time;
+   int key_last_state;
+   unsigned long key_last_time;
bool suspended;
 };
 
@@ -139,7 +141,8 @@ static int acpi_lid_evaluate_state(struct acpi_device 
*device)
 static int acpi_lid_notify_state(struct acpi_device *device, int state)
 {
struct acpi_button *button = acpi_driver_data(device);
-   unsigned long sw_tout;
+   int keycode;
+   unsigned long sw_tout, key_tout;
int ret;
 
/* Send the switch event */
@@ -156,6 +159,20 @@ static int acpi_lid_notify_state(struct acpi_device 
*device, int state)
button->sw_last_state = !!state;
button->sw_last_time = jiffies;
 
+   /* Send the key event */
+   key_tout = button->key_last_time +
+  msecs_to_jiffies(lid_report_interval);
+   if (time_after(jiffies, key_tout) ||
+   (button->key_last_state != !!state)) {
+   keycode = state ? KEY_LID_OPEN : KEY_LID_CLOSE;
+   input_report_key(button->input, keycode, 1);
+   input_sync(button->input);
+   input_report_key(button->input, keycode, 0);
+   input_sync(button->input);
+   button->key_last_state = !!state;
+   button->key_last_time = jiffies;
+   }
+
if (state)
pm_wakeup_event(&device->dev, 0);
 
@@ -424,8 +441,9 @@ static int acpi_button_add(struct acpi_device *device)
strcpy(name, ACPI_BUTTON_DEVICE_NAME_LID);
sprintf(class, "%s/%s",
ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID);
-   button->sw_last_state = !!acpi_lid_evaluate_state(device);
-   button->sw_last_time = jiffies;
+   button->sw_last_state = button->key_last_state =
+   !!acpi_lid_evaluate_state(device);
+   button->sw_last_time = button->

[PATCH v5 3/3] ACPI / button: Add document for ACPI control method lid device restrictions

2016-07-21 Thread Lv Zheng
This patch adds documentation for the usage model of the control method lid
device.

Signed-off-by: Lv Zheng 
Acked-by: Benjamin Tissoires 
Cc: Dmitry Torokhov 
Cc: Bastien Nocera: 
Cc: linux-in...@vger.kernel.org
---
 Documentation/acpi/acpi-lid.txt |   89 +++
 1 file changed, 89 insertions(+)
 create mode 100644 Documentation/acpi/acpi-lid.txt

diff --git a/Documentation/acpi/acpi-lid.txt b/Documentation/acpi/acpi-lid.txt
new file mode 100644
index 000..2addedc
--- /dev/null
+++ b/Documentation/acpi/acpi-lid.txt
@@ -0,0 +1,89 @@
+Usage Model of the ACPI Control Method Lid Device
+
+Copyright (C) 2016, Intel Corporation
+Author: Lv Zheng 
+
+
+Abstract:
+
+Platforms containing lids convey lid state (open/close) to OSPMs using a
+control method lid device. To implement this, the AML tables issue
+Notify(lid_device, 0x80) to notify the OSPMs whenever the lid state has
+changed. The _LID control method for the lid device must be implemented to
+report the "current" state of the lid as either "opened" or "closed".
+
+This document describes the restrictions and the expections of the Linux
+ACPI lid device driver.
+
+
+1. Restrictions of the returning value of the _LID control method
+
+The _LID control method is described to return the "current" lid state.
+However the word of "current" has ambiguity, many AML tables return the lid
+state upon the last lid notification instead of returning the lid state
+upon the last _LID evaluation. There won't be difference when the _LID
+control method is evaluated during the runtime, the problem is its initial
+returning value. When the AML tables implement this control method with
+cached value, the initial returning value is likely not reliable. There are
+simply so many examples always retuning "closed" as initial lid state.
+
+2. Restrictions of the lid state change notifications
+
+There are many AML tables never notifying when the lid device state is
+changed to "opened". Thus the "opened" notification is not guaranteed.
+
+But it is guaranteed that the AML tables always notify "closed" when the
+lid state is changed to "closed". The "closed" notification is normally
+used to trigger some system power saving operations on Windows. Since it is
+fully tested, the "closed" notification is reliable for all AML tables.
+
+3. Expections for the userspace users of the ACPI lid device driver
+
+The ACPI button driver exports the lid state to the userspace via the
+following file:
+  /proc/acpi/button/lid/LID0/state
+This file actually calls the _LID control method described above. And given
+the previous explanation, it is not reliable enough on some platforms. So
+it is advised for the userspace program to not to solely rely on this file
+to determine the actual lid state.
+
+The ACPI button driver emits 2 kinds of events to the user space:
+  SW_LID
+   When the lid state/event is reliable, the userspace can behave
+   according to this input switch event.
+   This is a mode prepared for backward compatiblity.
+  KEY_EVENT_OPEN/KEY_EVENT_CLOSE
+   When the lid state/event is not reliable, the userspace should behave
+   according to these 2 input key events.
+   New userspace programs may only be prepared for the input key events.
+
+If the userspace hasn't been prepared to handle the new input lid key
+events, Linux users can use the following kernel parameters to handle the
+possible issues triggered because of the unreliable lid state/event:
+A. button.lid_init_state=method:
+   When this option is specified, the ACPI button driver reports the
+   initial lid state using the returning value of the _LID control method.
+   This option can be used to fix some platforms where the _LID control
+   method's returning value is reliable but the initial lid state
+   notification is missing.
+   This option is the default behavior during the period the userspace
+   isn't ready to handle the new usage model.
+B. button.lid_init_state=open:
+   When this option is specified, the ACPI button driver always reports the
+   initial lid state as "opened".
+   This may fix some platforms where the returning value of the _LID
+   control method is not reliable and the initial lid state notification is
+   missing.
+
+If the userspace has been prepared to handle the new input lid key events,
+Linux users should always use the following kernel parameter:
+C. button.lid_init_state=ignore:
+   When this option is specified, the ACPI button driver never reports the
+   initial lid state. However, the platform may automatically report a
+   correct initial lid state and there is no "open" event missing. When
+   this is the case (everything is correctly implemented by the platform
+   firmware), the old input switch event based userspace can still work.
+   Otherwise, the userspace progr

[PATCH v3 2/5] ACPICA: Dispatcher: Fix an issue that the opregions created by the linked MLC were not tracked

2016-06-20 Thread Lv Zheng
Operation regions created by MLC were not tracked by
acpi_check_address_range(), this patch fixes this issue. ACPICA BZ 1279. Fixed
by Lv Zheng.

Link: https://bugs.acpica.org/show_bug.cgi?id=1279
Signed-off-by: Lv Zheng 
---
 drivers/acpi/acpica/dsopcode.c |6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c
index 4cc9d98..96f2eef 100644
--- a/drivers/acpi/acpica/dsopcode.c
+++ b/drivers/acpi/acpica/dsopcode.c
@@ -455,6 +455,12 @@ acpi_ds_eval_region_operands(struct acpi_walk_state 
*walk_state,
/* Now the address and length are valid for this opregion */
 
obj_desc->region.flags |= AOPOBJ_DATA_VALID;
+   if (walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL) {
+   status = acpi_ut_add_address_range(obj_desc->region.space_id,
+  obj_desc->region.address,
+  obj_desc->region.length,
+  node);
+   }
return_ACPI_STATUS(status);
 }
 
-- 
1.7.10



[PATCH v3 3/5] ACPICA: ACPI 2.0, Interpreter: Fix MLC issues by switching to new TermList grammar for table loading

2016-06-20 Thread Lv Zheng
The MLC (Module Level Code) is an ACPICA terminology describing the AML
code out of any control method, its support is the main contention of the
interpreter behavior during the table loading.

The original implementation of MLC in ACPICA had several issues:
1. Out of any control method, besides of the object creating opcodes, only
   the code blocks wrapped by "If/Else/While" opcodes were supported.
2. The supported MLC code blocks were executed after loading the table
   rather than being executed right in place.
   
   The demo of this order issue is as follows:
 Name (OBJ1, 1)
 If (CND1 == 1)
 {
   Name (OBJ2, 2)
 }
 Name (OBJ3, 3)
   The original MLC support created OBJ2 after OBJ3's creation.
   
Other than these limitations, MLC support in ACPICA looks correct. And
supporting this should be easy/natural for ACPICA, but enabling of this was
blocked by some ACPICA internal and OSPM specific initialization order
issues we've fixed recently. The wrong support started from the following
false bug fixing commit:
  Commit: 80d7951177315f70b5ffd8663985fbf725d07799
  Subject: Add support for module-level executable AML code.

We can confirm Windows interpreter behavior via reverse engineering means.
It can be proven that not only If/Else/While wrapped code blocks, all
opcodes can be executed at the module level, including operation region
accesses. And it can be proven that the MLC should be executed right in
place, not in such a deferred way executed after loading the table.

And the above facts indeed reflect the spec words around ACPI definition
block tables (DSDT/SSDT/...), the entire table and the Scope object is
defined by the AML specification in BNF style as:
  AMLCode := DefBlockHeader TermList
  DefScope := ScopeOp PkgLength NameString TermList
The bodies of the scope opening terms (AMLCode/Scope) are all TermList,
thus the table loading should be no difference than the control method
evaluations as the body of the Method is also defined by the AML
specification as TermList:
  DefMethod := MethodOp PkgLength NameString MethodFlags TermList
The only difference is: after evaluating control method, created named
objects may be freed due to no reference, while named objects created by
the table loading should only be freed after unloading the table.

So this patch follows the spec and the de-facto standard behavior, enables
the new grammar (TermList) for the table loading.

By doing so, beyond the fixes to the above issues, we can see additional
differences comparing to the old grammar based table loading:
1. Originally, beyond the scope opening terms (AMLCode/Scope),
   If/Else/While wrapped code blocks under the scope creating terms
   (Device/PowerResource/Processor/ThermalZone) are also supported as
   deferred MLC, which violates the spec defined grammar where ObjectList
   is enforced. With MLC support improved as non-deferred, the interpreter
   parses such scope creating terms as TermList rather ObjectList like the
   scope opening terms.
   After probing the Windows behavior and proving that it also parses these
   terms as TermList, we submitted an ECR (Engineering Change Request) to
   the ASWG (ACPI Specification Working Group) to clarify this. The ECR is
   titled as "ASL Grammar Clarification for Executable AML Opcodes" and has
   been accepted by the ASWG. The new grammar will appear in ACPI
   specification 6.2.
2. Originally, Buffer/Package/OperationRegion/CreateXXXField/BankField
   arguments are evaluated in a deferred way after loading the table. With
   MLC support improved, they are also parsed right in place during the
   table loading.
   This is also Windows compliant and the only difference is the removal
   of the debugging messages implemented before acpi_ds_execute_arguments(),
   see Link 1 for the details. A previous commit should have ensured that
   acpi_check_address_range() won't regress.

Note that enabling this feature may cause regressions due to long term
Linux ACPI support on top of the wrong grammar. So this patch also prepares
a global option to be used to roll back to the old grammar during the
period between a regression is reported and the regression is
root-cause-fixed. ACPICA BZ 963, fixed by Lv Zheng.

Link 1: https://bugzilla.kernel.org/show_bug.cgi?id=112911
Link 2: https://bugs.acpica.org/show_bug.cgi?id=963
Tested-by: Chris Bainbridge 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/acpica/acnamesp.h |3 +
 drivers/acpi/acpica/acparser.h |2 +
 drivers/acpi/acpica/evrgnini.c |3 +-
 drivers/acpi/acpica/exconfig.c |3 +-
 drivers/acpi/acpica/nsload.c   |3 +-
 drivers/acpi/acpica/nsparse.c  |  167 
 drivers/acpi/acpica/psparse.c  |4 +-
 drivers/acpi/acpica/psxface.c  |   71 +
 drivers/acpi/acpica/tbxflo

[PATCH v3 1/5] ACPICA: Namespace: Fix a regression that MLC support triggers dead lock in dynamic table loading

2016-06-20 Thread Lv Zheng
The new MLC approach invokes MLC per-table basis. But the dynamic loading
support of this is incorrect because of the lock order:
 acpi_ns_evaluate
   acpi_ex_enter_intperter
 acpi_ns_load_table (triggered by Load opcode)
   acpi_ns_exec_module_code_list
 acpi_ex_enter_intperter
The regression is introduced by the following commit:
  Commit: 2785ce8d0da1cac9d8f78615e116cf929e9a9123
  ACPICA Commit: 071eff738c59eda1792ac24b3b688b61691d7e7c
  Subject: ACPICA: Add per-table execution of module-level code
This patch fixes this regression by unlocking the interpreter lock before
invoking MLC. However the unlocking is done to the acpi_ns_load_table(), in
which, the interpreter lock should be locked by acpi_ns_parse_table() but
wasn't. Reported by Mika Westerberg. Fixed by Lv Zheng.

Fixes: 2785ce8d0da1 ("ACPICA: Add per-table execution of module-level code")
Reported-by: Mika Westerberg 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/acpica/exconfig.c |2 ++
 drivers/acpi/acpica/nsparse.c  |8 ++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c
index a1d177d..21932d6 100644
--- a/drivers/acpi/acpica/exconfig.c
+++ b/drivers/acpi/acpica/exconfig.c
@@ -108,7 +108,9 @@ acpi_ex_add_table(u32 table_index,
 
/* Add the table to the namespace */
 
+   acpi_ex_exit_interpreter();
status = acpi_ns_load_table(table_index, parent_node);
+   acpi_ex_enter_interpreter();
if (ACPI_FAILURE(status)) {
acpi_ut_remove_reference(obj_desc);
*ddb_handle = NULL;
diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c
index f631a47..0d29383 100644
--- a/drivers/acpi/acpica/nsparse.c
+++ b/drivers/acpi/acpica/nsparse.c
@@ -170,6 +170,8 @@ acpi_ns_parse_table(u32 table_index, struct 
acpi_namespace_node *start_node)
 
ACPI_FUNCTION_TRACE(ns_parse_table);
 
+   acpi_ex_enter_interpreter();
+
/*
 * AML Parse, pass 1
 *
@@ -185,7 +187,7 @@ acpi_ns_parse_table(u32 table_index, struct 
acpi_namespace_node *start_node)
status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1,
table_index, start_node);
if (ACPI_FAILURE(status)) {
-   return_ACPI_STATUS(status);
+   goto error_exit;
}
 
/*
@@ -201,8 +203,10 @@ acpi_ns_parse_table(u32 table_index, struct 
acpi_namespace_node *start_node)
status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2,
table_index, start_node);
if (ACPI_FAILURE(status)) {
-   return_ACPI_STATUS(status);
+   goto error_exit;
}
 
+error_exit:
+   acpi_ex_exit_interpreter();
return_ACPI_STATUS(status);
 }
-- 
1.7.10



[PATCH v3 0/5] ACPI 2.0: Enable TermList interpretion for table loading

2016-06-20 Thread Lv Zheng
tion (acpi_gbl_parse_table_as_term_list) in
the fixes. The earlier the fix is tested by more real users, the better
quality can be achieved by knowing the unknown cases (if any).

Lv Zheng (5):
  ACPICA: Namespace: Fix a regression that MLC support triggers dead
lock in dynamic table loading
  ACPICA: Dispatcher: Fix an issue that the opregions created by the
linked MLC were not tracked
  ACPICA: ACPI 2.0, Interpreter: Fix MLC issues by switching to new
TermList grammar for table loading
  ACPI 2.0 / AML: Enable correct ACPI subsystem initialization order
for new table loading mode
  ACPI 2.0 / AML: Fix module level execution by correctly parsing table
as TermList

 drivers/acpi/acpica/acnamesp.h |3 +
 drivers/acpi/acpica/acparser.h |2 +
 drivers/acpi/acpica/dsopcode.c |6 ++
 drivers/acpi/acpica/evrgnini.c |3 +-
 drivers/acpi/acpica/exconfig.c |5 +-
 drivers/acpi/acpica/nsload.c   |3 +-
 drivers/acpi/acpica/nsparse.c  |  169 
 drivers/acpi/acpica/psparse.c  |4 +-
 drivers/acpi/acpica/psxface.c  |   71 +
 drivers/acpi/acpica/tbxfload.c |3 +-
 drivers/acpi/acpica/utxfinit.c |3 +-
 drivers/acpi/bus.c |6 +-
 include/acpi/acpixf.h  |6 ++
 13 files changed, 245 insertions(+), 39 deletions(-)

-- 
1.7.10



[PATCH v3 4/5] ACPI 2.0 / AML: Enable correct ACPI subsystem initialization order for new table loading mode

2016-06-20 Thread Lv Zheng
This patch enables the following initialization order for the new table
loading mode (which is enabled by setting
acpi_gbl_parse_table_as_term_list to TRUE):
  1. Install default region handlers (SystemMemory, SystemIo, PciConfig,
 EmbeddedControl via ECDT) without evaluating _REG;
  2. Load the table and execute the module level AML opcodes instantly.

Signed-off-by: Lv Zheng 
---
 drivers/acpi/bus.c |6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 262ca31..4582db3 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -925,7 +925,8 @@ void __init acpi_early_init(void)
goto error0;
}
 
-   if (acpi_gbl_group_module_level_code) {
+   if (!acpi_gbl_parse_table_as_term_list &&
+   acpi_gbl_group_module_level_code) {
status = acpi_load_tables();
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX
@@ -1008,7 +1009,8 @@ static int __init acpi_bus_init(void)
status = acpi_ec_ecdt_probe();
/* Ignore result. Not having an ECDT is not fatal. */
 
-   if (!acpi_gbl_group_module_level_code) {
+   if (acpi_gbl_parse_table_as_term_list ||
+   !acpi_gbl_group_module_level_code) {
status = acpi_load_tables();
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX
-- 
1.7.10



[PATCH v3 5/5] ACPI 2.0 / AML: Fix module level execution by correctly parsing table as TermList

2016-06-20 Thread Lv Zheng
This experiment follows de-facto standard behavior, parsing entire
table as a single TermList, so that all module level executions are
possible during the table loading.

If regressions are found against the enabling of this experimental fix,
this patch is the only one that should get bisected out. Please report
the regressions to the kernel bugzilla for further root causing.

Signed-off-by: Lv Zheng 
---
 include/acpi/acpixf.h |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 22b0397..e21bdd1 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -196,9 +196,9 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_group_module_level_code, 
FALSE);
 
 /*
  * Optionally support module level code by parsing the entire table as
- * a term_list. Default is FALSE, do not execute entire table.
+ * a term_list. Default is TRUE, do execute entire table.
  */
-ACPI_INIT_GLOBAL(u8, acpi_gbl_parse_table_as_term_list, FALSE);
+ACPI_INIT_GLOBAL(u8, acpi_gbl_parse_table_as_term_list, TRUE);
 
 /*
  * Optionally use 32-bit FADT addresses if and when there is a conflict
-- 
1.7.10



[PATCH v4 0/5] ACPI 2.0: Enable TermList interpretion for table loading

2016-06-20 Thread Lv Zheng
tion (acpi_gbl_parse_table_as_term_list) in
the fixes. The earlier the fix is tested by more real users, the better
quality can be achieved by knowing the unknown cases (if any).

Lv Zheng (5):
  ACPICA: Namespace: Fix a regression that MLC support triggers dead
lock in dynamic table loading
  ACPICA: Dispatcher: Fix an issue that the opregions created by the
linked MLC were not tracked
  ACPICA: ACPI 2.0, Interpreter: Fix MLC issues by switching to new
TermList grammar for table loading
  ACPI 2.0 / AML: Enable correct ACPI subsystem initialization order
for new table loading mode
  ACPI 2.0 / AML: Fix module level execution by correctly parsing table
as TermList

 drivers/acpi/acpica/acnamesp.h |3 +
 drivers/acpi/acpica/acparser.h |2 +
 drivers/acpi/acpica/dsopcode.c |6 ++
 drivers/acpi/acpica/evrgnini.c |3 +-
 drivers/acpi/acpica/exconfig.c |5 +-
 drivers/acpi/acpica/nsload.c   |3 +-
 drivers/acpi/acpica/nsparse.c  |  169 
 drivers/acpi/acpica/psparse.c  |4 +-
 drivers/acpi/acpica/psxface.c  |   71 +
 drivers/acpi/acpica/tbxfload.c |3 +-
 drivers/acpi/acpica/utxfinit.c |3 +-
 drivers/acpi/bus.c |6 +-
 include/acpi/acpixf.h  |6 ++
 13 files changed, 245 insertions(+), 39 deletions(-)

-- 
1.7.10



[PATCH v4 2/5] ACPICA: Dispatcher: Fix an issue that the opregions created by the linked MLC were not tracked

2016-06-20 Thread Lv Zheng
Operation regions created by MLC were not tracked by
acpi_check_address_range(), this patch fixes this issue. ACPICA BZ 1279. Fixed
by Lv Zheng.

Link: https://bugs.acpica.org/show_bug.cgi?id=1279
Signed-off-by: Lv Zheng 
---
 drivers/acpi/acpica/dsopcode.c |6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c
index 4cc9d98..96f2eef 100644
--- a/drivers/acpi/acpica/dsopcode.c
+++ b/drivers/acpi/acpica/dsopcode.c
@@ -455,6 +455,12 @@ acpi_ds_eval_region_operands(struct acpi_walk_state 
*walk_state,
/* Now the address and length are valid for this opregion */
 
obj_desc->region.flags |= AOPOBJ_DATA_VALID;
+   if (walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL) {
+   status = acpi_ut_add_address_range(obj_desc->region.space_id,
+  obj_desc->region.address,
+  obj_desc->region.length,
+  node);
+   }
return_ACPI_STATUS(status);
 }
 
-- 
1.7.10



[PATCH v4 5/5] ACPI 2.0 / AML: Fix module level execution by correctly parsing table as TermList

2016-06-20 Thread Lv Zheng
This experiment follows de-facto standard behavior, parsing entire
table as a single TermList, so that all module level executions are
possible during the table loading.

If regressions are found against the enabling of this experimental fix,
this patch is the only one that should get bisected out. Please report
the regressions to the kernel bugzilla for further root causing.

Signed-off-by: Lv Zheng 
---
 include/acpi/acpixf.h |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 22b0397..e21bdd1 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -196,9 +196,9 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_group_module_level_code, 
FALSE);
 
 /*
  * Optionally support module level code by parsing the entire table as
- * a term_list. Default is FALSE, do not execute entire table.
+ * a term_list. Default is TRUE, do execute entire table.
  */
-ACPI_INIT_GLOBAL(u8, acpi_gbl_parse_table_as_term_list, FALSE);
+ACPI_INIT_GLOBAL(u8, acpi_gbl_parse_table_as_term_list, TRUE);
 
 /*
  * Optionally use 32-bit FADT addresses if and when there is a conflict
-- 
1.7.10



[PATCH v4 4/5] ACPI 2.0 / AML: Enable correct ACPI subsystem initialization order for new table loading mode

2016-06-20 Thread Lv Zheng
This patch enables the following initialization order for the new table
loading mode (which is enabled by setting
acpi_gbl_parse_table_as_term_list to TRUE):
  1. Install default region handlers (SystemMemory, SystemIo, PciConfig,
 EmbeddedControl via ECDT) without evaluating _REG;
  2. Load the table and execute the module level AML opcodes instantly.

Signed-off-by: Lv Zheng 
---
 drivers/acpi/bus.c |6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 262ca31..4582db3 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -925,7 +925,8 @@ void __init acpi_early_init(void)
goto error0;
}
 
-   if (acpi_gbl_group_module_level_code) {
+   if (!acpi_gbl_parse_table_as_term_list &&
+   acpi_gbl_group_module_level_code) {
status = acpi_load_tables();
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX
@@ -1008,7 +1009,8 @@ static int __init acpi_bus_init(void)
status = acpi_ec_ecdt_probe();
/* Ignore result. Not having an ECDT is not fatal. */
 
-   if (!acpi_gbl_group_module_level_code) {
+   if (acpi_gbl_parse_table_as_term_list ||
+   !acpi_gbl_group_module_level_code) {
status = acpi_load_tables();
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX
-- 
1.7.10



[PATCH v4 1/5] ACPICA: Namespace: Fix a regression that MLC support triggers dead lock in dynamic table loading

2016-06-20 Thread Lv Zheng
The new MLC approach invokes MLC per-table basis. But the dynamic loading
support of this is incorrect because of the lock order:
 acpi_ns_evaluate
   acpi_ex_enter_intperter
 acpi_ns_load_table (triggered by Load opcode)
   acpi_ns_exec_module_code_list
 acpi_ex_enter_intperter
The regression is introduced by the following commit:
  Commit: 2785ce8d0da1cac9d8f78615e116cf929e9a9123
  ACPICA Commit: 071eff738c59eda1792ac24b3b688b61691d7e7c
  Subject: ACPICA: Add per-table execution of module-level code
This patch fixes this regression by unlocking the interpreter lock before
invoking MLC. However the unlocking is done to the acpi_ns_load_table(), in
which, the interpreter lock should be locked by acpi_ns_parse_table() but
wasn't. Reported by Mika Westerberg. Fixed by Lv Zheng.

Fixes: 2785ce8d0da1 ("ACPICA: Add per-table execution of module-level code")
Cc: Mika Westerberg 
Reported-by: Mika Westerberg 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/acpica/exconfig.c |2 ++
 drivers/acpi/acpica/nsparse.c  |9 +++--
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c
index a1d177d..21932d6 100644
--- a/drivers/acpi/acpica/exconfig.c
+++ b/drivers/acpi/acpica/exconfig.c
@@ -108,7 +108,9 @@ acpi_ex_add_table(u32 table_index,
 
/* Add the table to the namespace */
 
+   acpi_ex_exit_interpreter();
status = acpi_ns_load_table(table_index, parent_node);
+   acpi_ex_enter_interpreter();
if (ACPI_FAILURE(status)) {
acpi_ut_remove_reference(obj_desc);
*ddb_handle = NULL;
diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c
index f631a47..1783cd7 100644
--- a/drivers/acpi/acpica/nsparse.c
+++ b/drivers/acpi/acpica/nsparse.c
@@ -47,6 +47,7 @@
 #include "acparser.h"
 #include "acdispat.h"
 #include "actables.h"
+#include "acinterp.h"
 
 #define _COMPONENT  ACPI_NAMESPACE
 ACPI_MODULE_NAME("nsparse")
@@ -170,6 +171,8 @@ acpi_ns_parse_table(u32 table_index, struct 
acpi_namespace_node *start_node)
 
ACPI_FUNCTION_TRACE(ns_parse_table);
 
+   acpi_ex_enter_interpreter();
+
/*
 * AML Parse, pass 1
 *
@@ -185,7 +188,7 @@ acpi_ns_parse_table(u32 table_index, struct 
acpi_namespace_node *start_node)
status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1,
table_index, start_node);
if (ACPI_FAILURE(status)) {
-   return_ACPI_STATUS(status);
+   goto error_exit;
}
 
/*
@@ -201,8 +204,10 @@ acpi_ns_parse_table(u32 table_index, struct 
acpi_namespace_node *start_node)
status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2,
table_index, start_node);
if (ACPI_FAILURE(status)) {
-   return_ACPI_STATUS(status);
+   goto error_exit;
}
 
+error_exit:
+   acpi_ex_exit_interpreter();
return_ACPI_STATUS(status);
 }
-- 
1.7.10



[PATCH v4 3/5] ACPICA: ACPI 2.0, Interpreter: Fix MLC issues by switching to new TermList grammar for table loading

2016-06-20 Thread Lv Zheng
The MLC (Module Level Code) is an ACPICA terminology describing the AML
code out of any control method, its support is the main contention of the
interpreter behavior during the table loading.

The original implementation of MLC in ACPICA had several issues:
1. Out of any control method, besides of the object creating opcodes, only
   the code blocks wrapped by "If/Else/While" opcodes were supported.
2. The supported MLC code blocks were executed after loading the table
   rather than being executed right in place.
   
   The demo of this order issue is as follows:
 Name (OBJ1, 1)
 If (CND1 == 1)
 {
   Name (OBJ2, 2)
 }
 Name (OBJ3, 3)
   The original MLC support created OBJ2 after OBJ3's creation.
   
Other than these limitations, MLC support in ACPICA looks correct. And
supporting this should be easy/natural for ACPICA, but enabling of this was
blocked by some ACPICA internal and OSPM specific initialization order
issues we've fixed recently. The wrong support started from the following
false bug fixing commit:
  Commit: 80d7951177315f70b5ffd8663985fbf725d07799
  Subject: Add support for module-level executable AML code.

We can confirm Windows interpreter behavior via reverse engineering means.
It can be proven that not only If/Else/While wrapped code blocks, all
opcodes can be executed at the module level, including operation region
accesses. And it can be proven that the MLC should be executed right in
place, not in such a deferred way executed after loading the table.

And the above facts indeed reflect the spec words around ACPI definition
block tables (DSDT/SSDT/...), the entire table and the Scope object is
defined by the AML specification in BNF style as:
  AMLCode := DefBlockHeader TermList
  DefScope := ScopeOp PkgLength NameString TermList
The bodies of the scope opening terms (AMLCode/Scope) are all TermList,
thus the table loading should be no difference than the control method
evaluations as the body of the Method is also defined by the AML
specification as TermList:
  DefMethod := MethodOp PkgLength NameString MethodFlags TermList
The only difference is: after evaluating control method, created named
objects may be freed due to no reference, while named objects created by
the table loading should only be freed after unloading the table.

So this patch follows the spec and the de-facto standard behavior, enables
the new grammar (TermList) for the table loading.

By doing so, beyond the fixes to the above issues, we can see additional
differences comparing to the old grammar based table loading:
1. Originally, beyond the scope opening terms (AMLCode/Scope),
   If/Else/While wrapped code blocks under the scope creating terms
   (Device/PowerResource/Processor/ThermalZone) are also supported as
   deferred MLC, which violates the spec defined grammar where ObjectList
   is enforced. With MLC support improved as non-deferred, the interpreter
   parses such scope creating terms as TermList rather ObjectList like the
   scope opening terms.
   After probing the Windows behavior and proving that it also parses these
   terms as TermList, we submitted an ECR (Engineering Change Request) to
   the ASWG (ACPI Specification Working Group) to clarify this. The ECR is
   titled as "ASL Grammar Clarification for Executable AML Opcodes" and has
   been accepted by the ASWG. The new grammar will appear in ACPI
   specification 6.2.
2. Originally, Buffer/Package/OperationRegion/CreateXXXField/BankField
   arguments are evaluated in a deferred way after loading the table. With
   MLC support improved, they are also parsed right in place during the
   table loading.
   This is also Windows compliant and the only difference is the removal
   of the debugging messages implemented before acpi_ds_execute_arguments(),
   see Link 1 for the details. A previous commit should have ensured that
   acpi_check_address_range() won't regress.

Note that enabling this feature may cause regressions due to long term
Linux ACPI support on top of the wrong grammar. So this patch also prepares
a global option to be used to roll back to the old grammar during the
period between a regression is reported and the regression is
root-cause-fixed. ACPICA BZ 963, fixed by Lv Zheng.

Link 1: https://bugzilla.kernel.org/show_bug.cgi?id=112911
Link 2: https://bugs.acpica.org/show_bug.cgi?id=963
Tested-by: Chris Bainbridge 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/acpica/acnamesp.h |3 +
 drivers/acpi/acpica/acparser.h |2 +
 drivers/acpi/acpica/evrgnini.c |3 +-
 drivers/acpi/acpica/exconfig.c |3 +-
 drivers/acpi/acpica/nsload.c   |3 +-
 drivers/acpi/acpica/nsparse.c  |  166 
 drivers/acpi/acpica/psparse.c  |4 +-
 drivers/acpi/acpica/psxface.c  |   71 +
 drivers/acpi/acpica/tbxflo

[PATCH 1/2] ACPI / EC: Cleanup boot EC code using acpi_ec_alloc()

2016-06-21 Thread Lv Zheng
Failure handling of the boot EC code is not tidy. This patch cleans
them up with acpi_ec_alloc().
This patch also changes acpi_ec_dsdt_probe(), always switches the boot EC
from the ECDT one to the DSDT one in this function.

Signed-off-by: Lv Zheng 
---
 drivers/acpi/ec.c |   85 ++---
 1 file changed, 48 insertions(+), 37 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 73c76d6..f63a43a 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -1348,13 +1348,9 @@ static void ec_remove_handlers(struct acpi_ec *ec)
}
 }
 
-static int acpi_ec_add(struct acpi_device *device)
+static struct acpi_ec *acpi_ec_alloc(void)
 {
-   struct acpi_ec *ec = NULL;
-   int ret;
-
-   strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
-   strcpy(acpi_device_class(device), ACPI_EC_CLASS);
+   struct acpi_ec *ec;
 
/* Check for boot EC */
if (boot_ec) {
@@ -1365,9 +1361,21 @@ static int acpi_ec_add(struct acpi_device *device)
first_ec = NULL;
} else {
ec = make_acpi_ec();
-   if (!ec)
-   return -ENOMEM;
}
+   return ec;
+}
+
+static int acpi_ec_add(struct acpi_device *device)
+{
+   struct acpi_ec *ec = NULL;
+   int ret;
+
+   strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
+   strcpy(acpi_device_class(device), ACPI_EC_CLASS);
+
+   ec = acpi_ec_alloc();
+   if (!ec)
+   return -ENOMEM;
if (ec_parse_device(device->handle, 0, ec, NULL) !=
AE_CTRL_TERMINATE) {
kfree(ec);
@@ -1454,27 +1462,31 @@ static const struct acpi_device_id ec_device_ids[] = {
 int __init acpi_ec_dsdt_probe(void)
 {
acpi_status status;
+   struct acpi_ec *ec;
+   int ret;
 
-   if (boot_ec)
-   return 0;
-
+   ec = acpi_ec_alloc();
+   if (!ec)
+   return -ENOMEM;
/*
 * Finding EC from DSDT if there is no ECDT EC available. When this
 * function is invoked, ACPI tables have been fully loaded, we can
 * walk namespace now.
 */
-   boot_ec = make_acpi_ec();
-   if (!boot_ec)
-   return -ENOMEM;
status = acpi_get_devices(ec_device_ids[0].id,
- ec_parse_device, boot_ec, NULL);
-   if (ACPI_FAILURE(status) || !boot_ec->handle)
-   return -ENODEV;
-   if (!ec_install_handlers(boot_ec)) {
-   first_ec = boot_ec;
-   return 0;
+ ec_parse_device, ec, NULL);
+   if (ACPI_FAILURE(status) || !ec->handle) {
+   ret = -ENODEV;
+   goto error;
}
-   return -EFAULT;
+   ret = ec_install_handlers(ec);
+
+error:
+   if (ret)
+   kfree(ec);
+   else
+   first_ec = boot_ec = ec;
+   return ret;
 }
 
 #if 0
@@ -1548,12 +1560,13 @@ static struct dmi_system_id ec_dmi_table[] __initdata = 
{
 
 int __init acpi_ec_ecdt_probe(void)
 {
-   int ret = 0;
+   int ret;
acpi_status status;
struct acpi_table_ecdt *ecdt_ptr;
+   struct acpi_ec *ec;
 
-   boot_ec = make_acpi_ec();
-   if (!boot_ec)
+   ec = acpi_ec_alloc();
+   if (!ec)
return -ENOMEM;
/*
 * Generate a boot ec context
@@ -1583,22 +1596,20 @@ int __init acpi_ec_ecdt_probe(void)
 * MSI MS-171F
 * https://bugzilla.kernel.org/show_bug.cgi?id=12461
 */
-   boot_ec->command_addr = ecdt_ptr->data.address;
-   boot_ec->data_addr = ecdt_ptr->control.address;
+   ec->command_addr = ecdt_ptr->data.address;
+   ec->data_addr = ecdt_ptr->control.address;
} else {
-   boot_ec->command_addr = ecdt_ptr->control.address;
-   boot_ec->data_addr = ecdt_ptr->data.address;
+   ec->command_addr = ecdt_ptr->control.address;
+   ec->data_addr = ecdt_ptr->data.address;
}
-   boot_ec->gpe = ecdt_ptr->gpe;
-   boot_ec->handle = ACPI_ROOT_OBJECT;
-   ret = ec_install_handlers(boot_ec);
-   if (!ret)
-   first_ec = boot_ec;
+   ec->gpe = ecdt_ptr->gpe;
+   ec->handle = ACPI_ROOT_OBJECT;
+   ret = ec_install_handlers(ec);
 error:
-   if (ret) {
-   kfree(boot_ec);
-   boot_ec = NULL;
-   }
+   if (ret)
+   kfree(ec);
+   else
+   first_ec = boot_ec = ec;
return ret;
 }
 
-- 
1.7.10



[PATCH 2/2] ACPI / EC: Remove wrong ECDT correction quirks

2016-06-21 Thread Lv Zheng
Our Windows probe result shows that EC._REG is evaluated after evaluating
all _INI/_STA control methods.

With boot EC always switched in acpi_ec_dsdt_probe(), we can see that as
long as there is no EC opregion accesses in the MLC (module level code, AML
code out of any control methods) and in _INI/_STA, there is no need to make
sure that ECDT must be correct.

Bugs of 9399/12461 were reported against an order issue that BAT0/1._STA
evaluations contain EC accesses while the ECDT setting is wrong.

>From the acpidump output posted on bug 9399, we can see that it is actually
a different issue. In this table, if EC._REG is not executed, EC accesses
will be done in a platform specific manner. As we've already ensured not to
execute EC._REG during the eary stage, we can remove the quirks for bug
9399.

>From the acpidump output posted on bug 12461, we can see that it still
needs the quirk. In this table, EC._REG flags a named object whose default
value is One, thus BAT1._STA surely should invoke EC accesses whatever we
invoke EC._REG or not. We have to keep the quirk for it before we can root
cause the issue.

Signed-off-by: Lv Zheng 
---
 drivers/acpi/ec.c |   21 +
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index f63a43a..b1050a0 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -1530,6 +1530,11 @@ static int ec_clear_on_resume(const struct dmi_system_id 
*id)
return 0;
 }
 
+/*
+ * Some ECDTs contain wrong register addresses.
+ * MSI MS-171F
+ * https://bugzilla.kernel.org/show_bug.cgi?id=12461
+ */
 static int ec_correct_ecdt(const struct dmi_system_id *id)
 {
pr_debug("Detected system needing ECDT address correction.\n");
@@ -1539,16 +1544,6 @@ static int ec_correct_ecdt(const struct dmi_system_id 
*id)
 
 static struct dmi_system_id ec_dmi_table[] __initdata = {
{
-   ec_correct_ecdt, "Asus L4R", {
-   DMI_MATCH(DMI_BIOS_VERSION, "1008.006"),
-   DMI_MATCH(DMI_PRODUCT_NAME, "L4R"),
-   DMI_MATCH(DMI_BOARD_NAME, "L4R") }, NULL},
-   {
-   ec_correct_ecdt, "Asus M6R", {
-   DMI_MATCH(DMI_BIOS_VERSION, "0207"),
-   DMI_MATCH(DMI_PRODUCT_NAME, "M6R"),
-   DMI_MATCH(DMI_BOARD_NAME, "M6R") }, NULL},
-   {
ec_correct_ecdt, "MSI MS-171F", {
DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star"),
DMI_MATCH(DMI_PRODUCT_NAME, "MS-171F"),}, NULL},
@@ -1590,12 +1585,6 @@ int __init acpi_ec_ecdt_probe(void)
 
pr_info("EC description table is found, configuring boot EC\n");
if (EC_FLAGS_CORRECT_ECDT) {
-   /*
-* Asus L4R, Asus M6R
-* https://bugzilla.kernel.org/show_bug.cgi?id=9399
-* MSI MS-171F
-* https://bugzilla.kernel.org/show_bug.cgi?id=12461
-*/
ec->command_addr = ecdt_ptr->data.address;
ec->data_addr = ecdt_ptr->control.address;
} else {
-- 
1.7.10



[PATCH v5 1/5] ACPICA: Tables: Fix "UNLOAD" code path lock issues

2016-09-22 Thread Lv Zheng
ACPICA commit 39227380f5b99c51b897a3ffedd88508aa26789b

The previous lock fixes didn't cover "Unload" opcode and table unload APIs,
this patch fixes lock issues in the "Unload" code path. BZ 1325, Lv Zheng.

Link: https://github.com/acpica/acpica/commit/39227380
Link: https://bugs.acpica.org/show_bug.cgi?id=1325
Signed-off-by: Lv Zheng 
Signed-off-by: Bob Moore 
---
 drivers/acpi/acpica/exconfig.c |   23 +++
 drivers/acpi/acpica/tbdata.c   |7 +--
 drivers/acpi/acpica/tbxfload.c |9 ++---
 3 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c
index 421836a..718428b 100644
--- a/drivers/acpi/acpica/exconfig.c
+++ b/drivers/acpi/acpica/exconfig.c
@@ -532,10 +532,17 @@ acpi_status acpi_ex_unload_table(union 
acpi_operand_object *ddb_handle)
 
table_index = table_desc->reference.value;
 
+   /*
+* Release the interpreter lock so that the table lock won't have
+* strict order requirement against it.
+*/
+   acpi_ex_exit_interpreter();
+
/* Ensure the table is still loaded */
 
if (!acpi_tb_is_table_loaded(table_index)) {
-   return_ACPI_STATUS(AE_NOT_EXIST);
+   status = AE_NOT_EXIST;
+   goto lock_and_exit;
}
 
/* Invoke table handler if present */
@@ -553,16 +560,24 @@ acpi_status acpi_ex_unload_table(union 
acpi_operand_object *ddb_handle)
 
status = acpi_tb_delete_namespace_by_owner(table_index);
if (ACPI_FAILURE(status)) {
-   return_ACPI_STATUS(status);
+   goto lock_and_exit;
}
 
(void)acpi_tb_release_owner_id(table_index);
acpi_tb_set_table_loaded_flag(table_index, FALSE);
 
+lock_and_exit:
+
+   /* Re-acquire the interpreter lock */
+
+   acpi_ex_enter_interpreter();
+
/*
 * Invalidate the handle. We do this because the handle may be stored
 * in a named object and may not be actually deleted until much later.
 */
-   ddb_handle->common.flags &= ~AOPOBJ_DATA_VALID;
-   return_ACPI_STATUS(AE_OK);
+   if (ACPI_SUCCESS(status)) {
+   ddb_handle->common.flags &= ~AOPOBJ_DATA_VALID;
+   }
+   return_ACPI_STATUS(status);
 }
diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c
index 7e93fd6..d9ca8c2 100644
--- a/drivers/acpi/acpica/tbdata.c
+++ b/drivers/acpi/acpica/tbdata.c
@@ -614,17 +614,12 @@ acpi_status acpi_tb_delete_namespace_by_owner(u32 
table_index)
 * lock may block, and also since the execution of a namespace walk
 * must be allowed to use the interpreter.
 */
-   (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
-
-   acpi_ns_delete_namespace_by_owner(owner_id);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
-
+   acpi_ns_delete_namespace_by_owner(owner_id);
acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock);
-
-   status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
return_ACPI_STATUS(status);
 }
 
diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
index 870ad64..5569f63 100644
--- a/drivers/acpi/acpica/tbxfload.c
+++ b/drivers/acpi/acpica/tbxfload.c
@@ -378,9 +378,9 @@ acpi_status acpi_unload_parent_table(acpi_handle object)
return_ACPI_STATUS(AE_TYPE);
}
 
-   /* Must acquire the interpreter lock during this operation */
+   /* Must acquire the table lock during this operation */
 
-   status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
+   status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -407,8 +407,10 @@ acpi_status acpi_unload_parent_table(acpi_handle object)
 
/* Ensure the table is actually loaded */
 
+   (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
if (!acpi_tb_is_table_loaded(i)) {
status = AE_NOT_EXIST;
+   (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
break;
}
 
@@ -434,10 +436,11 @@ acpi_status acpi_unload_parent_table(acpi_handle object)
 
status = acpi_tb_release_owner_id(i);
acpi_tb_set_table_loaded_flag(i, FALSE);
+   (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
break;
}
 
-   (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
+   (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
return_ACPI_STATUS(status);
 }
 
-- 
1.7.10



[PATCH v5 0/5] ACPI 2.0: Stop defer-executing module level code

2016-09-22 Thread Lv Zheng
After fixing ACPICA internal locking issues, we can enable the correct
grammar support for the table loading. The new grammar treats the entire
table as TermList rather than ObjectList, thus the module level code should
be executed right in place.

MLC (module level code) is an ACPICA terminology describing the AML code
out of any control method, currently only Type1Opcode (If/Else/While)
wrapped MLC code blocks are executed by the AML interpreter after the table
loading. But the issue which is fixed by this patchset is:
   Not only Type1Opcode, but also Type2Opcode will be executed as MLC and
   MLC is not defer-executed after loading the table, but is executed right
   in place.

The following AML code is assembled into a static loading SSDT, and used
as an instrumentation to pry into the de-facto standard AML interpreter
behaviors:
  Name (ECOK, Zero)
  Scope (\)
  {
  DBUG ("TermList 1")
  If (LEqual (ECOK, Zero))
  {
  DBUG ("TermList 2")
  Device (MDEV)
  {
  DEBUG (TermList 3")
  If (CondRefOf (MDEV))
  {
  DBUG ("MDEV exists")
  }
  If (CondRefOf (MDEV._STA))
  {
  DBUG ("MDEV._STA exists")
  }
  If (CondRefOf (\_SB.PCI0.EC))
  {
  DBUG ("\\_SB.PCI0.EC exists")
  }
  Name (_HID, EisaId ("PNP"))
  Method (_STA, 0, Serialized)
  {
  DEBUG ("\\_SB.MDEV._STA")
  Return (0x0F)
  }
  }
  DBUG ("TermList 4")
  }
  Method (_INI, 0, Serialized)
  {
  DBUG ("\\_SB._INI")
  }
  }
  Scope (_SB.PCI0)
  {
  Device (EC)
  {
  ...
  }
  }
The DBUG function is a function to write the debugging messages into a
SystemIo debug port.
Running Windows with the BIOS providing this SSDT via RSDT, the following
messages are obtained from the debug port:
  TermList 1
  TermList 2
  TermList 3
  \_SB.MDEV exists
  TermList 4
  \_SB._INI
  ...

This test reveals the de-facto grammar for the AMLCode to us:
1. During the table loading, MLC will be executed by the interpreter, this
   is partially supported by the current ACPICA;
2. For SystemIo, not only after the _REG(1, 1) is evaluated (current ACPICA
   interpreter limitation), but when the table is being loaded, the
   SystemIo (the debugging port) is accessible, this is recently fixed in
   the upstream, now all early operation regions are accessible during the
   table loading;
3. Not only Type1Opcode, but also Type2Opcode will be executed as MLC and
   MLC is not executed after loading the table, but is executed right in
   place, the Linux upstream is not compliant to this behavior.

The last compliance issue has already been clarified in ACPI 2.0
specification, so the compliance issue is not that Linux is not compliant
to the de-facto standard OS, but that Linux is not compliant to ACPI 2.0.
Definition block tables in fact is defined by the spec as TermList, which
has no difference than the control methods, thus the interpretion of the
table should be no difference that the control method evaluation:
 AMLCode := DefBlockHeader TermList
 DefMethod := MethodOp PkgLength NameString MethodFlags TermList
Now the new upcoming ACPI specification has been clarified around the above
grammar primitives, so we need to implement them for Linux.

This patchset also contains 2 required fixes generated to fix the
regressions detected by the ACPICA ASLTS tool. The ASLTS 'table' test suite
has detected such regressions. The fixes have been accepted by the ACPICA
upstream (please refer to the ACPICA upstream URL in the description of the
2 patches). And they are sent to Linux community as urgent materials along
with the module level code enabling series. With the additional regression
fixes, new grammar changes have passed all ASLTS 'table' cases:
  https://bugs.acpica.org/show_bug.cgi?id=1327
  https://github.com/acpica/acpica/pull/177

Lv Zheng (5):
  ACPICA: Tables: Fix "UNLOAD" code path lock issues
  ACPICA: Parser: Fix a regression in LoadTable support
  ACPI 2.0 / AML: Enable correct ACPI subsystem initialization order
for new table loading mode
  ACPI 2.0 / AML: Improve module level execution by moving the
If/Else/While execution to per-table basis
  ACPI 2.0 / AML: Fix module level execution by correctly parsing table
as TermList

 drivers/acpi/acpica/exconfig.c |   23 +++
 drivers/acpi/acpica/psxface.c  |   11 +++
 drivers/acpi/acpica/tbdata.c   |7 +--
 drivers/acpi/acpica/tbxfload.c |9 ++---
 drivers/acpi/bus.c |6 --
 include/acpi/acpixf.h  |7 +++
 6 files changed, 44 insertions(+), 19 deletions(-)

-- 
1.7.10



[PATCH v5 3/5] ACPI 2.0 / AML: Enable correct ACPI subsystem initialization order for new table loading mode

2016-09-22 Thread Lv Zheng
This patch enables the following initialization order for the new table
loading mode (which is enabled by setting
acpi_gbl_parse_table_as_term_list to TRUE):
  1. Install default region handlers (SystemMemory, SystemIo, PciConfig,
 EmbeddedControl via ECDT) without evaluating _REG;
  2. Load the table and execute the module level AML opcodes instantly.

Signed-off-by: Lv Zheng 
---
 drivers/acpi/bus.c |6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 85b7d07..658b4c4 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -985,7 +985,8 @@ void __init acpi_early_init(void)
goto error0;
}
 
-   if (acpi_gbl_group_module_level_code) {
+   if (!acpi_gbl_parse_table_as_term_list &&
+   acpi_gbl_group_module_level_code) {
status = acpi_load_tables();
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX
@@ -1074,7 +1075,8 @@ static int __init acpi_bus_init(void)
status = acpi_ec_ecdt_probe();
/* Ignore result. Not having an ECDT is not fatal. */
 
-   if (!acpi_gbl_group_module_level_code) {
+   if (acpi_gbl_parse_table_as_term_list ||
+   !acpi_gbl_group_module_level_code) {
status = acpi_load_tables();
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX
-- 
1.7.10



[PATCH v5 4/5] ACPI 2.0 / AML: Improve module level execution by moving the If/Else/While execution to per-table basis

2016-09-22 Thread Lv Zheng
This reverts commit 00c611def8748a0a1cf1d31842e49b42dfdb3de1.

Signed-off-by: Lv Zheng 
---
 include/acpi/acpixf.h |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index c7b3a13..169ec81 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -192,7 +192,7 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_do_not_use_xsdt, FALSE);
 /*
  * Optionally support group module level code.
  */
-ACPI_INIT_GLOBAL(u8, acpi_gbl_group_module_level_code, TRUE);
+ACPI_INIT_GLOBAL(u8, acpi_gbl_group_module_level_code, FALSE);
 
 /*
  * Optionally support module level code by parsing the entire table as
-- 
1.7.10



[PATCH v5 5/5] ACPI 2.0 / AML: Fix module level execution by correctly parsing table as TermList

2016-09-22 Thread Lv Zheng
This experiment follows de-facto standard behavior, parsing entire
table as a single TermList, so that all module level executions are
possible during the table loading.

If regressions are found against the enabling of this experimental fix,
this patch is the only one that should get bisected out. Please report
the regressions to the kernel bugzilla for further root causing.

Signed-off-by: Lv Zheng 
---
 include/acpi/acpixf.h |5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 169ec81..2e22eae 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -196,10 +196,9 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_group_module_level_code, 
FALSE);
 
 /*
  * Optionally support module level code by parsing the entire table as
- * a term_list. Default is FALSE, do not execute entire table until some
- * lock order issues are fixed.
+ * a term_list. Default is TRUE, do execute entire table.
  */
-ACPI_INIT_GLOBAL(u8, acpi_gbl_parse_table_as_term_list, FALSE);
+ACPI_INIT_GLOBAL(u8, acpi_gbl_parse_table_as_term_list, TRUE);
 
 /*
  * Optionally use 32-bit FADT addresses if and when there is a conflict
-- 
1.7.10



[PATCH v5 2/5] ACPICA: Parser: Fix a regression in LoadTable support

2016-09-22 Thread Lv Zheng
ACPICA commit a78506e0ce8ab1d20db2a055d99cf9143e89eb29

LoadTable allows an alternative RootPathString than the default "\", while
the new table execution support fails to keep this logic.

This regression can be detected by ASLTS - TLT0.tst4, this patch fixes this
regression.

Linux upstream is not affected by this regression as we haven't enabled the
new table execution support there. BZ 1326, Lv Zheng.

Link: https://github.com/acpica/acpica/commit/a78506e0
Link: https://bugs.acpica.org/show_bug.cgi?id=1326
Signed-off-by: Lv Zheng 
Signed-off-by: Bob Moore 
---
 drivers/acpi/acpica/psxface.c |   11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/acpi/acpica/psxface.c b/drivers/acpi/acpica/psxface.c
index 8d7e5b5..f3c8726 100644
--- a/drivers/acpi/acpica/psxface.c
+++ b/drivers/acpi/acpica/psxface.c
@@ -305,6 +305,17 @@ acpi_status acpi_ps_execute_table(struct 
acpi_evaluate_info *info)
walk_state->parse_flags |= ACPI_PARSE_MODULE_LEVEL;
}
 
+   /* Info->Node is the default location to load the table  */
+
+   if (info->node && info->node != acpi_gbl_root_node) {
+   status =
+   acpi_ds_scope_stack_push(info->node, ACPI_TYPE_METHOD,
+walk_state);
+   if (ACPI_FAILURE(status)) {
+   goto cleanup;
+   }
+   }
+
/*
 * Parse the AML, walk_state will be deleted by parse_aml
 */
-- 
1.7.10



[PATCH] acpiexec: Move an acpiexec specific purposed new line to acpiexec specific file

2016-09-22 Thread Lv Zheng
> No need, Robert did it already:
> 
> 1d435008fd9e ("Update an info message during table load phase.")

Not exactly what I meant. I meant the following on top of the above
mentioned commit. As the newline is an acpiexec specific logic, it should
be kept in acpiexec, shouldn't be left polluting a common file. Lv Zheng.

Signed-off-by: Lv Zheng 
To: Borislav Petkov 
Cc: Rafael J. Wysocki 
Cc: Rafael J. Wysocki 
Cc: Len Brown 
Cc: 
--
Index: acpica/source/components/tables/tbxfload.c
===
--- acpica.orig/source/components/tables/tbxfload.c
+++ acpica/source/components/tables/tbxfload.c
@@ -348,11 +348,6 @@ AcpiTbLoadNamespace (
 Status = AE_CTRL_TERMINATE;
 }
 
-#ifdef ACPI_APPLICATION
-ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "\n"));
-#endif
-
-
 UnlockAndExit:
 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
 return_ACPI_STATUS (Status);
Index: acpica/source/tools/acpiexec/aetables.c
===
--- acpica.orig/source/tools/acpiexec/aetables.c
+++ acpica/source/tools/acpiexec/aetables.c
@@ -625,6 +625,7 @@ AeLoadTables (
 
 Status = AcpiLoadTables ();
 ACPI_CHECK_OK (AcpiLoadTables, Status);
+ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "\n"));
 
 /*
  * Test run-time control method installation. Do it twice to test code


[PATCH] acpiexec: Move an acpiexec specific purposed new line to acpiexec specific file

2016-09-22 Thread Lv Zheng
> No need, Robert did it already:
> 
> 1d435008fd9e ("Update an info message during table load phase.")

Not exactly what I meant. I meant the following on top of the above
mentioned commit. As the newline is an acpiexec specific logic, it should
be kept in acpiexec, shouldn't be left polluting a common file. Lv Zheng.

Signed-off-by: Lv Zheng 
--
Index: acpica/source/components/tables/tbxfload.c
===
--- acpica.orig/source/components/tables/tbxfload.c
+++ acpica/source/components/tables/tbxfload.c
@@ -348,11 +348,6 @@ AcpiTbLoadNamespace (
 Status = AE_CTRL_TERMINATE;
 }
 
-#ifdef ACPI_APPLICATION
-ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "\n"));
-#endif
-
-
 UnlockAndExit:
 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
 return_ACPI_STATUS (Status);
Index: acpica/source/tools/acpiexec/aetables.c
===
--- acpica.orig/source/tools/acpiexec/aetables.c
+++ acpica/source/tools/acpiexec/aetables.c
@@ -625,6 +625,7 @@ AeLoadTables (
 
 Status = AcpiLoadTables ();
 ACPI_CHECK_OK (AcpiLoadTables, Status);
+ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "\n"));
 
 /*
  * Test run-time control method installation. Do it twice to test code


[PATCH v2 0/2] ACPI / EC: Tune suspend/resume speed using PM operations

2016-07-29 Thread Lv Zheng
There are 2 improvements can be done to the EC driver to make system
suspend/resume faster:
1. Automatically use busy polling mode when noirq is entered
2. Disallow event handling (SCI_EVT/_Qxx) during suspend/resume period

This patchset achieves such performance tuning on top of a recent
workaround that creates ec_query_wq.

Lv Zheng (2):
  ACPI / EC: Add PM operations to tune polling mode efficiency
  ACPI / EC: Add PM operations to block event handling

 drivers/acpi/ec.c   |  199 ---
 drivers/acpi/internal.h |3 +-
 drivers/acpi/sleep.c|4 +-
 3 files changed, 158 insertions(+), 48 deletions(-)

-- 
1.7.10



[PATCH v2 1/2] ACPI / EC: Add PM operations to tune polling mode efficiency

2016-07-29 Thread Lv Zheng
It is reported that on some platforms, resume speed is not fast. The cause
is: in noirq stage, EC driver is working in polling mode, and each state
machine advancement requires a context switch.

The context switch is not necessary to the EC driver's polling mode. This
patch implements PM hooks to automatically switch the driver to/from the
busy polling mode to eliminate the overhead caused by the context switch.

This finally contributes to the tuning result: acpi_pm_finish() execution
time is improved from 192ms to 6ms.

Signed-off-by: Lv Zheng 
Reported-and-tested-by: Todd E Brandt 
---
 drivers/acpi/ec.c   |   53 +++
 drivers/acpi/internal.h |2 ++
 2 files changed, 55 insertions(+)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 907b450..7cdcdf6 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -1619,6 +1619,58 @@ error:
return ret;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static void acpi_ec_enter_noirq(struct acpi_ec *ec)
+{
+   unsigned long flags;
+
+   if (ec == first_ec) {
+   spin_lock_irqsave(&ec->lock, flags);
+   ec->saved_busy_polling = ec_busy_polling;
+   ec->saved_polling_guard = ec_polling_guard;
+   ec_busy_polling = true;
+   ec_polling_guard = 0;
+   ec_log_drv("interrupt blocked");
+   spin_unlock_irqrestore(&ec->lock, flags);
+   }
+}
+
+static void acpi_ec_leave_noirq(struct acpi_ec *ec)
+{
+   unsigned long flags;
+
+   if (ec == first_ec) {
+   spin_lock_irqsave(&ec->lock, flags);
+   ec_busy_polling = ec->saved_busy_polling;
+   ec_polling_guard = ec->saved_polling_guard;
+   ec_log_drv("interrupt unblocked");
+   spin_unlock_irqrestore(&ec->lock, flags);
+   }
+}
+
+static int acpi_ec_suspend_noirq(struct device *dev)
+{
+   struct acpi_ec *ec =
+   acpi_driver_data(to_acpi_device(dev));
+
+   acpi_ec_enter_noirq(ec);
+   return 0;
+}
+
+static int acpi_ec_resume_noirq(struct device *dev)
+{
+   struct acpi_ec *ec =
+   acpi_driver_data(to_acpi_device(dev));
+
+   acpi_ec_leave_noirq(ec);
+   return 0;
+}
+#endif
+
+static const struct dev_pm_ops acpi_ec_pm = {
+   SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(acpi_ec_suspend_noirq, 
acpi_ec_resume_noirq)
+};
+
 static int param_set_event_clearing(const char *val, struct kernel_param *kp)
 {
int result = 0;
@@ -1664,6 +1716,7 @@ static struct acpi_driver acpi_ec_driver = {
.add = acpi_ec_add,
.remove = acpi_ec_remove,
},
+   .drv.pm = &acpi_ec_pm,
 };
 
 int __init acpi_ec_init(void)
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 940218f..6996121 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -174,6 +174,8 @@ struct acpi_ec {
struct work_struct work;
unsigned long timestamp;
unsigned long nr_pending_queries;
+   bool saved_busy_polling;
+   unsigned int saved_polling_guard;
 };
 
 extern struct acpi_ec *first_ec;
-- 
1.7.10



[PATCH v2 2/2] ACPI / EC: Add PM operations to block event handling

2016-07-29 Thread Lv Zheng
Originally, EC driver stops handling both events and transactions in
acpi_ec_block_transactions(), and restarts to handle transactions in
acpi_ec_unblock_transactions_early(), restarts to handle both events and
transactions in acpi_ec_unblock_transactions().

Thus, the event handling is actually stopped after the IRQ is disabled, but
the EC driver is not capable of handling SCI_EVT in noirq stage, thus it is
likely the event is not detected by the EC driver.

This patch tries to restore the old behavior for the EC driver. However,
do we actually need to handle EC events during suspend/resume stage? EC
events are mostly useless for the suspend/resume period (key strokes and
battery/thermal updates, etc.,), and the useful ones (lid close,
power/sleep button press) should have already been delivered to OS to
trigger the power saving operations. Thus EC driver should stop handling
events during this period, just like what the EC driver does during the
boot stage. And tests show this behavior is working and can make suspend
even faster when many events is triggered during this stage (for example,
during this stage, frequently trigger wifi switches).

OTOH, delivering EC events too early may confuse drivers because when the
drivers see the events, the drivers themselves may not have been resumed.

Thus this patch implements PM hooks, stops to handle event in .suspend()
hook and restarts to handle event in .resume() hook. This is different
from the original implementation, enlarging the event handling blocking
period longer:
OriginalCurrent
suspend before EC   Y   Y
suspend after ECY   N
suspend_lateY   N
suspend_noirq   Y (actually N)  N
resume_noirqY (actually N)  N
resume_late Y   N
resume before ECY   N
resume after EC Y   Y
Since this is experimental, a boot parameter is prepared to not to
disable event handling during suspend/resume period.

By implementing .resume() hook to re-enable the event handling, the
following 2 APIs serve for the same purpose (restart transactions) and can
be combined:
acpi_ec_unblock_transactions_early()/acpi_ec_unblock_transactions().

Signed-off-by: Lv Zheng 
Tested-by: Todd E Brandt 
---
 drivers/acpi/ec.c   |  146 ---
 drivers/acpi/internal.h |1 -
 drivers/acpi/sleep.c|4 +-
 3 files changed, 103 insertions(+), 48 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 7cdcdf6..8c3034c 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -104,6 +104,7 @@ enum ec_command {
 #define ACPI_EC_MAX_QUERIES16  /* Maximum number of parallel queries */
 
 enum {
+   EC_FLAGS_QUERY_ENABLED, /* Query is enabled */
EC_FLAGS_QUERY_PENDING, /* Query is pending */
EC_FLAGS_QUERY_GUARDING,/* Guard for SCI_EVT check */
EC_FLAGS_GPE_HANDLER_INSTALLED, /* GPE handler installed */
@@ -145,6 +146,10 @@ static unsigned int ec_storm_threshold  __read_mostly = 8;
 module_param(ec_storm_threshold, uint, 0644);
 MODULE_PARM_DESC(ec_storm_threshold, "Maxim false GPE numbers not considered 
as GPE storm");
 
+static bool ec_freeze_events __read_mostly = true;
+module_param(ec_freeze_events, bool, 0644);
+MODULE_PARM_DESC(ec_freeze_events, "Disabling event handling during 
suspend/resume");
+
 struct acpi_ec_query_handler {
struct list_head node;
acpi_ec_query_func func;
@@ -427,13 +432,19 @@ static bool acpi_ec_submit_flushable_request(struct 
acpi_ec *ec)
return true;
 }
 
+static void __acpi_ec_submit_query(struct acpi_ec *ec)
+{
+   ec_dbg_evt("Command(%s) submitted/blocked",
+  acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY));
+   ec->nr_pending_queries++;
+   schedule_work(&ec->work);
+}
+
 static void acpi_ec_submit_query(struct acpi_ec *ec)
 {
if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) {
-   ec_dbg_evt("Command(%s) submitted/blocked",
-  acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY));
-   ec->nr_pending_queries++;
-   schedule_work(&ec->work);
+   if (test_bit(EC_FLAGS_QUERY_ENABLED, &ec->flags))
+   __acpi_ec_submit_query(ec);
}
 }
 
@@ -446,6 +457,70 @@ static void acpi_ec_complete_query(struct acpi_ec *ec)
}
 }
 
+static bool acpi_ec_query_flushed(struct acpi_ec *ec)
+{
+   bool flushed;
+   unsigned long flags;
+
+   spin_lock_irqsave(&ec->lock, flags);
+   flushed = !ec->nr_pending_queries;
+   spin_unlock_irqrestore(&ec->lock, flags);
+
+   return flushed;
+}
+
+/*
+ * Process _Q events that might have accumulated in the EC.
+ * Run with locked ec mutex.
+ */
+static void acpi_ec_clear(

[PATCH v2 0/4] ACPI / EC: Fix ECDT and boot_ec support

2016-09-07 Thread Lv Zheng
Linux uses ECDT only in boot stage (before the namespace is fully
initialized), but there are cases reported that Windows allows ECDT to be
used for OSPM runtime, responding EC events by evaluating _Qxx methods
under the device node indicated in the ECDT.

This patchset changes Linux ECDT support to follow Windows behavior and
also fixes related boot_ec support.

v2:
 Rebased on top of recent linux-pm.git/linux-next.
 Addressed 1 comment from Peter Wu.
 Update patch SOBs.

Lv Zheng (4):
  ACPI / EC: Cleanup first_ec/boot_ec code
  ACPI / EC: Fix a memory leakage issue in acpi_ec_add()
  ACPI / EC: Fix a gap that ECDT EC cannot handle EC events
  ACPI / EC: Fix issues related to boot_ec

 drivers/acpi/ec.c   |  240 +--
 drivers/acpi/internal.h |1 +
 drivers/acpi/scan.c |1 +
 3 files changed, 195 insertions(+), 47 deletions(-)

-- 
1.7.10



[PATCH v2 3/4] ACPI / EC: Fix a gap that ECDT EC cannot handle EC events

2016-09-07 Thread Lv Zheng
It is possible to register _Qxx from namespace and use the ECDT EC to
perform event handling. The reported bug reveals that Windows is using ECDT
in this way in case the namespace EC is not present. This patch facilitates
Linux to support ECDT in this way.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=115021
Reported-and-tested-by: Luya Tshimbalanga 
Tested-by: Jonh Henderson 
Reviewed-by: Peter Wu 
Signed-off-by: Lv Zheng 
Cc: Peter Wu 
---
 drivers/acpi/ec.c   |  119 ++-
 drivers/acpi/internal.h |1 +
 drivers/acpi/scan.c |1 +
 3 files changed, 98 insertions(+), 23 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 50895ff..2ae9194 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -109,6 +109,7 @@ enum {
EC_FLAGS_QUERY_GUARDING,/* Guard for SCI_EVT check */
EC_FLAGS_GPE_HANDLER_INSTALLED, /* GPE handler installed */
EC_FLAGS_EC_HANDLER_INSTALLED,  /* OpReg handler installed */
+   EC_FLAGS_EVT_HANDLER_INSTALLED, /* _Qxx handlers installed */
EC_FLAGS_STARTED,   /* Driver is started */
EC_FLAGS_STOPPED,   /* Driver is stopped */
EC_FLAGS_COMMAND_STORM, /* GPE storms occurred to the
@@ -1380,7 +1381,7 @@ ec_parse_device(acpi_handle handle, u32 Level, void 
*context, void **retval)
  *   handler is not installed, which means "not able to handle
  *   transactions".
  */
-static int ec_install_handlers(struct acpi_ec *ec)
+static int ec_install_handlers(struct acpi_ec *ec, bool handle_events)
 {
acpi_status status;
 
@@ -1409,6 +1410,16 @@ static int ec_install_handlers(struct acpi_ec *ec)
set_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags);
}
 
+   if (!handle_events)
+   return 0;
+
+   if (!test_bit(EC_FLAGS_EVT_HANDLER_INSTALLED, &ec->flags)) {
+   /* Find and register all query methods */
+   acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1,
+   acpi_ec_register_query_methods,
+   NULL, ec, NULL);
+   set_bit(EC_FLAGS_EVT_HANDLER_INSTALLED, &ec->flags);
+   }
if (!test_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags)) {
status = acpi_install_gpe_raw_handler(NULL, ec->gpe,
  ACPI_GPE_EDGE_TRIGGERED,
@@ -1419,6 +1430,9 @@ static int ec_install_handlers(struct acpi_ec *ec)
if (test_bit(EC_FLAGS_STARTED, &ec->flags) &&
ec->reference_count >= 1)
acpi_ec_enable_gpe(ec, true);
+
+   /* EC is fully operational, allow queries */
+   acpi_ec_enable_event(ec);
}
}
 
@@ -1453,13 +1467,17 @@ static void ec_remove_handlers(struct acpi_ec *ec)
pr_err("failed to remove gpe handler\n");
clear_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags);
}
+   if (test_bit(EC_FLAGS_EVT_HANDLER_INSTALLED, &ec->flags)) {
+   acpi_ec_remove_query_handlers(ec, true, 0);
+   clear_bit(EC_FLAGS_EVT_HANDLER_INSTALLED, &ec->flags);
+   }
 }
 
-static int acpi_ec_setup(struct acpi_ec *ec)
+static int acpi_ec_setup(struct acpi_ec *ec, bool handle_events)
 {
int ret;
 
-   ret = ec_install_handlers(ec);
+   ret = ec_install_handlers(ec, handle_events);
if (ret)
return ret;
 
@@ -1475,18 +1493,33 @@ static int acpi_ec_setup(struct acpi_ec *ec)
return ret;
 }
 
-static int acpi_config_boot_ec(struct acpi_ec *ec, bool is_ecdt)
+static int acpi_config_boot_ec(struct acpi_ec *ec, acpi_handle handle,
+  bool handle_events, bool is_ecdt)
 {
int ret;
 
-   if (boot_ec)
+   /*
+* Changing the ACPI handle results in a re-configuration of the
+* boot EC. And if it happens after the namespace initialization,
+* it causes _REG evaluations.
+*/
+   if (boot_ec && boot_ec->handle != handle)
ec_remove_handlers(boot_ec);
 
/* Unset old boot EC */
if (boot_ec != ec)
acpi_ec_free(boot_ec);
 
-   ret = acpi_ec_setup(ec);
+   /*
+* ECDT device creation is split into acpi_ec_ecdt_probe() and
+* acpi_ec_ecdt_start(). This function takes care of completing the
+* ECDT parsing logic as the handle update should be performed
+* between the installation/uninstallation of the handlers.
+*/
+   if (ec->handle != handle)
+   ec->handle = handle;
+
+   ret = acpi_ec_setup(ec, handle_events);
if (ret)
return ret;
 
@@ -1494,9 +1527,12 @@ stati

[PATCH v2 1/4] ACPI / EC: Cleanup first_ec/boot_ec code

2016-09-07 Thread Lv Zheng
In order to support full ECDT (driving the ECDT EC after probing the
namespace EC), we need to change our EC device alloc/free algorithm, ensure
not to free old boot EC before qualifying new boot EC.
This patch achieves this by cleaning up first_ec/boot_ec logic:
1. first_ec: used to perform transactions, so it is assigned in new
   acpi_ec_setup() function.
2. boot_ec: used to track early EC device, so it is assigned in new
   acpi_config_boot_ec() function which explictly tells the driver to save
   the EC device as early EC device.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=115021
Reported-and-tested-by: Luya Tshimbalanga 
Tested-by: Jonh Henderson 
Signed-off-by: Lv Zheng 
Cc: Peter Wu 
---
 drivers/acpi/ec.c |   96 +++--
 1 file changed, 63 insertions(+), 33 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 1925589..9eab651 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -184,6 +184,7 @@ static void acpi_ec_event_processor(struct work_struct 
*work);
 
 struct acpi_ec *boot_ec, *first_ec;
 EXPORT_SYMBOL(first_ec);
+static bool boot_ec_is_ecdt = false;
 static struct workqueue_struct *ec_query_wq;
 
 static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */
@@ -1304,7 +1305,16 @@ acpi_ec_space_handler(u32 function, 
acpi_physical_address address,
 static acpi_status
 ec_parse_io_ports(struct acpi_resource *resource, void *context);
 
-static struct acpi_ec *make_acpi_ec(void)
+static void acpi_ec_free(struct acpi_ec *ec)
+{
+   if (first_ec == ec)
+   first_ec = NULL;
+   if (boot_ec == ec)
+   boot_ec = NULL;
+   kfree(ec);
+}
+
+static struct acpi_ec *acpi_ec_alloc(void)
 {
struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
 
@@ -1365,6 +1375,11 @@ ec_parse_device(acpi_handle handle, u32 Level, void 
*context, void **retval)
return AE_CTRL_TERMINATE;
 }
 
+/*
+ * Note: This function returns an error code only when the address space
+ *   handler is not installed, which means "not able to handle
+ *   transactions".
+ */
 static int ec_install_handlers(struct acpi_ec *ec)
 {
acpi_status status;
@@ -1440,21 +1455,49 @@ static void ec_remove_handlers(struct acpi_ec *ec)
}
 }
 
-static struct acpi_ec *acpi_ec_alloc(void)
+static int acpi_ec_setup(struct acpi_ec *ec)
 {
-   struct acpi_ec *ec;
+   int ret;
 
-   /* Check for boot EC */
-   if (boot_ec) {
-   ec = boot_ec;
-   boot_ec = NULL;
-   ec_remove_handlers(ec);
-   if (first_ec == ec)
-   first_ec = NULL;
-   } else {
-   ec = make_acpi_ec();
+   ret = ec_install_handlers(ec);
+   if (ret)
+   return ret;
+
+   /* First EC capable of handling transactions */
+   if (!first_ec) {
+   first_ec = ec;
+   acpi_handle_info(first_ec->handle, "Used as first EC\n");
}
-   return ec;
+
+   acpi_handle_info(ec->handle,
+"GPE=0x%lx, EC_CMD/EC_SC=0x%lx, EC_DATA=0x%lx\n",
+ec->gpe, ec->command_addr, ec->data_addr);
+   return ret;
+}
+
+static int acpi_config_boot_ec(struct acpi_ec *ec, bool is_ecdt)
+{
+   int ret;
+
+   if (boot_ec)
+   ec_remove_handlers(boot_ec);
+
+   /* Unset old boot EC */
+   if (boot_ec != ec)
+   acpi_ec_free(boot_ec);
+
+   ret = acpi_ec_setup(ec);
+   if (ret)
+   return ret;
+
+   /* Set new boot EC */
+   if (!boot_ec) {
+   boot_ec = ec;
+   boot_ec_is_ecdt = is_ecdt;
+   acpi_handle_info(boot_ec->handle, "Used as boot %s EC\n",
+is_ecdt ? "ECDT" : "DSDT");
+   }
+   return ret;
 }
 
 static int acpi_ec_add(struct acpi_device *device)
@@ -1470,7 +1513,7 @@ static int acpi_ec_add(struct acpi_device *device)
return -ENOMEM;
if (ec_parse_device(device->handle, 0, ec, NULL) !=
AE_CTRL_TERMINATE) {
-   kfree(ec);
+   acpi_ec_free(ec);
return -EINVAL;
}
 
@@ -1478,8 +1521,6 @@ static int acpi_ec_add(struct acpi_device *device)
acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1,
acpi_ec_register_query_methods, NULL, ec, NULL);
 
-   if (!first_ec)
-   first_ec = ec;
device->driver_data = ec;
 
ret = !!request_region(ec->data_addr, 1, "EC data");
@@ -1487,10 +1528,7 @@ static int acpi_ec_add(struct acpi_device *device)
ret = !!request_region(ec->command_addr, 1, "EC cmd");
WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr);
 
-   pr_info(

[PATCH v2 2/4] ACPI / EC: Fix a memory leakage issue in acpi_ec_add()

2016-09-07 Thread Lv Zheng
When the handler installation failed, there was no code to free the
allocated EC device. This patch fixes this memory leakage issue.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=115021
Reported-and-tested-by: Luya Tshimbalanga 
Tested-by: Jonh Henderson 
Signed-off-by: Lv Zheng 
Cc: Peter Wu 
---
 drivers/acpi/ec.c |   16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 9eab651..50895ff 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -1513,14 +1513,18 @@ static int acpi_ec_add(struct acpi_device *device)
return -ENOMEM;
if (ec_parse_device(device->handle, 0, ec, NULL) !=
AE_CTRL_TERMINATE) {
-   acpi_ec_free(ec);
-   return -EINVAL;
+   ret = -EINVAL;
+   goto err_alloc;
}
 
/* Find and register all query methods */
acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1,
acpi_ec_register_query_methods, NULL, ec, NULL);
 
+   ret = acpi_config_boot_ec(ec, false);
+   if (ret)
+   goto err_query;
+
device->driver_data = ec;
 
ret = !!request_region(ec->data_addr, 1, "EC data");
@@ -1528,13 +1532,17 @@ static int acpi_ec_add(struct acpi_device *device)
ret = !!request_region(ec->command_addr, 1, "EC cmd");
WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr);
 
-   ret = acpi_config_boot_ec(ec, false);
-
/* Reprobe devices depending on the EC */
acpi_walk_dep_device_list(ec->handle);
 
/* EC is fully operational, allow queries */
acpi_ec_enable_event(ec);
+   return 0;
+
+err_query:
+   acpi_ec_remove_query_handlers(ec, true, 0);
+err_alloc:
+   acpi_ec_free(ec);
return ret;
 }
 
-- 
1.7.10



[PATCH v2 4/4] ACPI / EC: Fix issues related to boot_ec

2016-09-07 Thread Lv Zheng
There are issues related to the boot_ec:
1. If acpi_ec_remove() is invoked, boot_ec will also be freed, this is not
   expected as the boot_ec could be enumerated via ECDT.
2. Address space handler installation/unstallation lead to unexpected _REG
   evaluations.
This patch adds acpi_is_boot_ec() check to be used to fix the above issues.
However, since acpi_ec_remove() actually won't be invoked, this patch
doesn't handle the reference counting of "struct acpi_ec", it only ensures
the correctness of the boot_ec destruction during the boot.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=153511
Reported-and-tested-by: Jonh Henderson 
Signed-off-by: Lv Zheng 
Cc: Peter Wu 
---
 drivers/acpi/ec.c |   63 +
 1 file changed, 49 insertions(+), 14 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 2ae9194..6805310 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -1536,6 +1536,37 @@ static int acpi_config_boot_ec(struct acpi_ec *ec, 
acpi_handle handle,
return ret;
 }
 
+static bool acpi_ec_ecdt_get_handle(acpi_handle *phandle)
+{
+   struct acpi_table_ecdt *ecdt_ptr;
+   acpi_status status;
+   acpi_handle handle;
+
+   status = acpi_get_table(ACPI_SIG_ECDT, 1,
+   (struct acpi_table_header **)&ecdt_ptr);
+   if (ACPI_FAILURE(status))
+   return false;
+
+   status = acpi_get_handle(NULL, ecdt_ptr->id, &handle);
+   if (ACPI_FAILURE(status))
+   return false;
+
+   *phandle = handle;
+   return true;
+}
+
+static bool acpi_is_boot_ec(struct acpi_ec *ec)
+{
+   if (!boot_ec)
+   return false;
+   if (ec->handle == boot_ec->handle &&
+   ec->gpe == boot_ec->gpe &&
+   ec->command_addr == boot_ec->command_addr &&
+   ec->data_addr == boot_ec->data_addr)
+   return true;
+   return false;
+}
+
 static int acpi_ec_add(struct acpi_device *device)
 {
struct acpi_ec *ec = NULL;
@@ -1553,7 +1584,14 @@ static int acpi_ec_add(struct acpi_device *device)
goto err_alloc;
}
 
-   ret = acpi_config_boot_ec(ec, device->handle, true, false);
+   if (acpi_is_boot_ec(ec)) {
+   boot_ec_is_ecdt = false;
+   acpi_handle_debug(ec->handle, "duplicated.\n");
+   acpi_ec_free(ec);
+   ec = boot_ec;
+   ret = acpi_config_boot_ec(ec, ec->handle, true, false);
+   } else
+   ret = acpi_ec_setup(ec, true);
if (ret)
goto err_query;
 
@@ -1566,12 +1604,15 @@ static int acpi_ec_add(struct acpi_device *device)
 
/* Reprobe devices depending on the EC */
acpi_walk_dep_device_list(ec->handle);
+   acpi_handle_debug(ec->handle, "enumerated.\n");
return 0;
 
 err_query:
-   acpi_ec_remove_query_handlers(ec, true, 0);
+   if (ec != boot_ec)
+   acpi_ec_remove_query_handlers(ec, true, 0);
 err_alloc:
-   acpi_ec_free(ec);
+   if (ec != boot_ec)
+   acpi_ec_free(ec);
return ret;
 }
 
@@ -1583,11 +1624,13 @@ static int acpi_ec_remove(struct acpi_device *device)
return -EINVAL;
 
ec = acpi_driver_data(device);
-   ec_remove_handlers(ec);
release_region(ec->data_addr, 1);
release_region(ec->command_addr, 1);
device->driver_data = NULL;
-   acpi_ec_free(ec);
+   if (ec != boot_ec) {
+   ec_remove_handlers(ec);
+   acpi_ec_free(ec);
+   }
return 0;
 }
 
@@ -1659,8 +1702,6 @@ error:
  */
 int __init acpi_ec_ecdt_start(void)
 {
-   struct acpi_table_ecdt *ecdt_ptr;
-   acpi_status status;
acpi_handle handle;
 
if (!boot_ec)
@@ -1672,17 +1713,11 @@ int __init acpi_ec_ecdt_start(void)
if (!boot_ec_is_ecdt)
return -ENODEV;
 
-   status = acpi_get_table(ACPI_SIG_ECDT, 1,
-   (struct acpi_table_header **)&ecdt_ptr);
-   if (ACPI_FAILURE(status))
-   return -ENODEV;
-
/*
 * At this point, the namespace and the GPE is initialized, so
 * start to find the namespace objects and handle the events.
 */
-   status = acpi_get_handle(NULL, ecdt_ptr->id, &handle);
-   if (ACPI_FAILURE(status))
+   if (!acpi_ec_ecdt_get_handle(&handle))
return -ENODEV;
return acpi_config_boot_ec(boot_ec, handle, true, true);
 }
-- 
1.7.10



[RFC PATCH v6 0/5] ACPI: button: Fix button.lid_init_state=method mode

2017-06-21 Thread Lv Zheng
There are platform variations implementing ACPI lid device in different
way:
1. Some platforms send "open" events to OS and the events arrive before
   button driver is resumed;
2. Some platforms send "open" events to OS, but the events arrive after
   button driver is resumed, ex., Samsung N210+;
3. Some platforms never send "open" events to OS, but send "open" events to
   update the cached _LID return value, and the update events arrive before
   button driver is resumed;
4. Some platforms never send "open" events to OS, but send "open" events to
   update the cached _LID return value, but the update events arrive after
   button driver is resumed, ex., Surface Pro 3;
5. Some platforms never send "open" events, _LID returns value sticks to
   "close", ex., Surface Pro 1.

This series tries to provide solutions to fix all cases for old userspace
programs. These solutions include:
1. Fix order issue in case 2,4. Enabled by default.
2. Fix event missing issue in case 3,4. As newer systemd doesn't require
   this fix, and this fix is not power friendly, it is not enabled by
   default, but can be enabled by:
   2.1. button.lid_periodic_update=1: periodically sends _LID value to
the input layer.
3. Fix persistate close issue in case 5, as newer systemd doesn't require
   this fix, it is not enabled by default, but can be enabled in 2 means:
   3.1. button.lid_init_state=ignore: only adds complement open events.
   3.2. lid_unreliable=1: dymamically adds/removes input node.

Benjamin Tissoires (2):
  ACPI: button: extract input creation/destruction helpers
  ACPI: button: Add an optional workaround to fix a persistent close
issue for old userspace

Lv Zheng (3):
  ACPI: button: Add a workaround to fix an order issue for old userspace
  ACPI: button: Add an optional workaround to fix an event missing issue
for old userspace
  ACPI: button: Rework lid_init_state=ignore mode

 drivers/acpi/button.c | 302 +++---
 1 file changed, 186 insertions(+), 116 deletions(-)

-- 
2.7.4



[RFC PATCH v6 1/5] ACPI: button: Add a workaround to fix an order issue for old userspace

2017-06-21 Thread Lv Zheng
There are platform variations implementing ACPI lid device in different
ways:
1. Some platforms send "open" events to OS and the events arrive before
   button driver is resumed;
2. Some platforms send "open" events to OS, but the events arrive after
   button driver is resumed, ex., Samsung N210+;
3. Some platforms never send "open" events to OS, but send "open" events to
   update the cached _LID return value, and the update events arrive before
   button driver is resumed;
4. Some platforms never send "open" events to OS, but send "open" events to
   update the cached _LID return value, but the update events arrive after
   button driver is resumed, ex., Surface Pro 3;
5. Some platforms never send "open" events, _LID returns value sticks to
   "close", ex., Surface Pro 1.
Currently, all cases work find with systemd 233, but only case 1 works fine
with systemd 229.

Case 2,4 can be treated as an order issue:
   If the button driver always evaluates _LID after seeing a LID
   notification, there shouldn't be such a problem.

Note that this order issue cannot be fixed by sorting OS drivers' resume
code:
1. When acpi.ec_freeze_events=Y, the order depends on whether PNP0C0D(LID)
   or PNP0C09(EC) appears first in the namespace (probe order).
2. Even when acpi.ec_freeze_events=N, which forces OS to handle EC events
   as early as possible, the order issue can still be reproduced due to
   platform delays (reproduce ratio is lower than case 1).
3. Some platform simply has a very big delay for LID open events.

This patch tries to fix this issue for systemd 229 by defer sending initial
lid state 10 seconds later after resume, which ensures EC events can always
arrive before button driver evaluates _LID. It finally only fixes case 2
platforms as fixing case 4 platforms needs additional efforts (see known
issue below).

The users can configure wait timeout via button.lid_notify_timeout.

Known issu:
1. systemd/logind 229 still mis-bahaves with case 3,4 platforms
   After seeing a LID "close" event, systemd 229 will wait several seconds
   (HoldoffTimeoutSec) before suspending the platform. Thus on case 4
   platforms, if users close lid, and re-open it during the
   HoldoffTimeoutSec period, there is still no "open" events seen by the
   userspace. Thus systemd still considers the last state as "close" and
   suspends the platform after the HoldoffTimeoutSec times out.

Cc: 
Cc: Benjamin Tissoires 
Cc: Peter Hutterer 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/button.c | 36 ++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index e19f530..67a0d78 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -79,6 +80,7 @@ MODULE_DEVICE_TABLE(acpi, button_device_ids);
 static int acpi_button_add(struct acpi_device *device);
 static int acpi_button_remove(struct acpi_device *device);
 static void acpi_button_notify(struct acpi_device *device, u32 event);
+static void acpi_lid_timeout(ulong arg);
 
 #ifdef CONFIG_PM_SLEEP
 static int acpi_button_suspend(struct device *dev);
@@ -104,6 +106,7 @@ static struct acpi_driver acpi_button_driver = {
 struct acpi_button {
unsigned int type;
struct input_dev *input;
+   struct timer_list lid_timer;
char phys[32];  /* for input device */
unsigned long pushed;
int last_state;
@@ -119,6 +122,10 @@ static unsigned long lid_report_interval __read_mostly = 
500;
 module_param(lid_report_interval, ulong, 0644);
 MODULE_PARM_DESC(lid_report_interval, "Interval (ms) between lid key events");
 
+static unsigned long lid_notify_timeout __read_mostly = 10;
+module_param(lid_notify_timeout, ulong, 0644);
+MODULE_PARM_DESC(lid_notify_timeout, "Timeout (s) before receiving lid 
notification");
+
 /* --
   FS Interface (/proc)
-- 
*/
@@ -371,6 +378,15 @@ static int acpi_lid_update_state(struct acpi_device 
*device)
return acpi_lid_notify_state(device, state);
 }
 
+static void acpi_lid_start_timer(struct acpi_device *device,
+unsigned long msecs)
+{
+   struct acpi_button *button = acpi_driver_data(device);
+
+   mod_timer(&button->lid_timer,
+ jiffies + msecs_to_jiffies(msecs));
+}
+
 static void acpi_lid_initialize_state(struct acpi_device *device)
 {
switch (lid_init_state) {
@@ -386,6 +402,13 @@ static void acpi_lid_initialize_state(struct acpi_device 
*device)
}
 }
 
+static void acpi_lid_timeout(ulong arg)
+{
+   struct acpi_device *de

[RFC PATCH v6 5/5] ACPI: button: Add an optional workaround to fix a persistent close issue for old userspace

2017-06-21 Thread Lv Zheng
From: Benjamin Tissoires 

Because of the variation of firmware implementation, there is a chance
the LID state is unknown:
1. Some platforms send "open" ACPI notification to the OS and the event
   arrive before the button driver is resumed;
2. Some platforms send "open" ACPI notification to the OS, but the
event
   arrives after the button driver is resumed, ex., Samsung N210+;
3. Some platforms never send an "open" ACPI notification to the OS, but
   update the cached _LID return value to "open", and this update
arrives
   before the button driver is resumed;
4. Some platforms never send an "open" ACPI notification to the OS, but
   update the cached _LID return value to "open", but this update
arrives
   after the button driver is resumed, ex., Surface Pro 3;
5. Some platforms never send an "open" ACPI notification to the OS, and
   _LID ACPI method returns a value which stays to "close", ex.,
   Surface Pro 1.
Currently, all cases work find with systemd 233, but only case 1,2,3,4 work
fine with old userspace.

After fixing all the other issues for old userspace programs, case 5 is the
only case that the exported input node is still not fully compliant to
SW_LID ABI and thus needs quirks or ABI changes.

This patch provides a dynamic SW_LID input node solution to make sure we do
not export an input node with an unknown state to prevent suspend loops.

The database of unreliable devices is left to userspace to handle with a
hwdb file and a udev rule.

Reworked by Lv to make this solution optional, code based on top of old
"ignore" mode and make lid_reliable configurable to all lid devices to
eliminate the difficulties of synchronously handling global lid_device.

Signed-off-by: Benjamin Tissoires 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/button.c | 96 ++-
 1 file changed, 88 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 91c9989..f11045d 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -107,11 +107,13 @@ struct acpi_button {
unsigned int type;
struct input_dev *input;
struct timer_list lid_timer;
+   bool lid_reliable;
char phys[32];  /* for input device */
unsigned long pushed;
bool suspended;
 };
 
+static DEFINE_MUTEX(lid_input_lock);
 static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
 static struct acpi_device *lid_device;
 static u8 lid_init_state = ACPI_BUTTON_LID_INIT_METHOD;
@@ -128,6 +130,10 @@ static unsigned long lid_update_interval __read_mostly = 1 
* MSEC_PER_SEC;
 module_param(lid_update_interval, ulong, 0644);
 MODULE_PARM_DESC(lid_update_interval, "Interval (ms) between lid periodic 
updates");
 
+static bool lid_unreliable __read_mostly = false;
+module_param(lid_unreliable, bool, 0644);
+MODULE_PARM_DESC(lid_unreliable, "Dynamically adding/removing input node for 
unreliable lids");
+
 /* --
   FS Interface (/proc)
-- 
*/
@@ -152,6 +158,9 @@ static int acpi_lid_notify_state(struct acpi_device 
*device, int state)
struct acpi_button *button = acpi_driver_data(device);
int ret;
 
+   if (!button->input)
+   return -EINVAL;
+
if (lid_init_state == ACPI_BUTTON_LID_INIT_IGNORE)
input_report_switch(button->input, SW_LID, 0);
 
@@ -306,6 +315,8 @@ static void acpi_button_remove_input(struct acpi_device 
*device)
 {
struct acpi_button *button = acpi_driver_data(device);
 
+   if (!button->input)
+   return;
input_unregister_device(button->input);
button->input = NULL;
 }
@@ -316,6 +327,9 @@ static int acpi_button_add_input(struct acpi_device *device)
struct input_dev *input;
int error;
 
+   if (button->input)
+   return 0;
+
input = input_allocate_device();
if (!input) {
error = -ENOMEM;
@@ -378,8 +392,10 @@ static void acpi_lid_initialize_state(struct acpi_device 
*device)
break;
case ACPI_BUTTON_LID_INIT_METHOD:
(void)acpi_lid_update_state(device);
+   mutex_unlock(&lid_input_lock);
if (lid_periodic_update)
acpi_lid_start_timer(device, lid_update_interval);
+   mutex_lock(&lid_input_lock);
break;
case ACPI_BUTTON_LID_INIT_IGNORE:
default:
@@ -391,7 +407,9 @@ static void acpi_lid_timeout(ulong arg)
 {
struct acpi_device *device = (struct acpi_device *)arg;
 
+   mutex_lock(&lid_input_lock);
acpi_lid_initialize_state(device);
+   mutex_unlock(&lid_input_lock);
 }
 
 static void acpi

[RFC PATCH v6 2/5] ACPI: button: Add an optional workaround to fix an event missing issue for old userspace

2017-06-21 Thread Lv Zheng
There are platform variations implementing ACPI lid device in different
ways:
1. Some platforms send "open" events to OS and the events arrive before
   button driver is resumed;
2. Some platforms send "open" events to OS, but the events arrive after
   button driver is resumed, ex., Samsung N210+;
3. Some platforms never send "open" events to OS, but send "open" events to
   update the cached _LID return value, and the update events arrive before
   button driver is resumed;
4. Some platforms never send "open" events to OS, but send "open" events to
   update the cached _LID return value, but the update events arrive after
   button driver is resumed, ex., Surface Pro 3;
5. Some platforms never send "open" events, _LID returns value sticks to
   "close", ex., Surface Pro 1.
Currently, all cases work fine with systemd 233, but only case 1,2 work
fine with systemd 229.

Case 3,4 can be treated as an event missing issue:
   After seeing a LID "close" event, systemd 229 will wait several seconds
   (HoldoffTimeoutSec) before suspending the platform. Thus on case 4
   platforms, if users close lid, and re-open it during the
   HoldoffTimeoutSec period, there is still no "open" events seen by the
   userspace. Thus systemd still considers the last state as "close" and
   suspends the platform after the HoldoffTimeoutSec times out.

Note that not only systemd 229, desktop managers (ex.,
gnome-settings-daemon) also suffer from this issue.

This patch tries to fix this issue by periodically sending _LID return
value to userspace, which ensures to trigger a SW_LID event when the
underlying hardware state has changed. As adding a periodic timer is not a
power friendly way, this patch prepares an option for users to enable on
failure platforms for old userspace programs.

Users can configure update interval via button.lid_update_interval.
This should be configured to a smaller value than HoldoffTimeoutSec in
/etc/systemd/logind.conf.

Cc: 
Cc: Benjamin Tissoires 
Cc: Peter Hutterer 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/button.c | 17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 67a0d78..a8b119e 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -126,6 +126,14 @@ static unsigned long lid_notify_timeout __read_mostly = 10;
 module_param(lid_notify_timeout, ulong, 0644);
 MODULE_PARM_DESC(lid_notify_timeout, "Timeout (s) before receiving lid 
notification");
 
+static bool lid_periodic_update __read_mostly = false;
+module_param(lid_periodic_update, bool, 0644);
+MODULE_PARM_DESC(lid_periodic_update, "Periodically sending lid state 
updates");
+
+static unsigned long lid_update_interval __read_mostly = 1 * MSEC_PER_SEC;
+module_param(lid_update_interval, ulong, 0644);
+MODULE_PARM_DESC(lid_update_interval, "Interval (ms) between lid periodic 
updates");
+
 /* --
   FS Interface (/proc)
-- 
*/
@@ -395,6 +403,8 @@ static void acpi_lid_initialize_state(struct acpi_device 
*device)
break;
case ACPI_BUTTON_LID_INIT_METHOD:
(void)acpi_lid_update_state(device);
+   if (lid_periodic_update)
+   acpi_lid_start_timer(device, lid_update_interval);
break;
case ACPI_BUTTON_LID_INIT_IGNORE:
default:
@@ -560,8 +570,11 @@ static int acpi_button_add(struct acpi_device *device)
 * more we only care about the last one...
 */
lid_device = device;
-   acpi_lid_start_timer(device,
-   lid_notify_timeout * MSEC_PER_SEC);
+   if (lid_periodic_update)
+   acpi_lid_initialize_state(device);
+   else
+   acpi_lid_start_timer(device,
+   lid_notify_timeout * MSEC_PER_SEC);
}
 
printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device));
-- 
2.7.4



[RFC PATCH v6 3/5] ACPI: button: Rework lid_init_state=ignore mode

2017-06-21 Thread Lv Zheng
There are platform variations implementing ACPI lid device in different
ways:
1. Some platforms send "open" events to OS and the events arrive before
   button driver is resumed;
2. Some platforms send "open" events to OS, but the events arrive after
   button driver is resumed, ex., Samsung N210+;
3. Some platforms never send "open" events to OS, but send "open" events to
   update the cached _LID return value, and the update events arrive before
   button driver is resumed;
4. Some platforms never send "open" events to OS, but send "open" events to
   update the cached _LID return value, but the update events arrive after
   button driver is resumed, ex., Surface Pro 3;
5. Some platforms never send "open" events, _LID returns value sticks to
   "close", ex., Surface Pro 1.
Currently, all cases work find with systemd 233, but only case 1,2,3,4 work
fine with systemd 229.

After fixing all the other issues for old userspace programs, case 5 is the
only case that the exported input node is still not fully compliant to
SW_LID ABI and thus needs quirks or ABI changes.

The original button.lid_init_state=ignore ABI change solution is now too
complicated if its purpose is to only solve this final incompliant use
case. This patch re-works it by unconditionally prepending "open"
complement events.

Cc: 
Cc: Benjamin Tissoires 
Cc: Peter Hutterer 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/button.c | 85 +++
 1 file changed, 5 insertions(+), 80 deletions(-)

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index a8b119e..1256a8c 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -109,8 +109,6 @@ struct acpi_button {
struct timer_list lid_timer;
char phys[32];  /* for input device */
unsigned long pushed;
-   int last_state;
-   ktime_t last_time;
bool suspended;
 };
 
@@ -118,10 +116,6 @@ static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
 static struct acpi_device *lid_device;
 static u8 lid_init_state = ACPI_BUTTON_LID_INIT_METHOD;
 
-static unsigned long lid_report_interval __read_mostly = 500;
-module_param(lid_report_interval, ulong, 0644);
-MODULE_PARM_DESC(lid_report_interval, "Interval (ms) between lid key events");
-
 static unsigned long lid_notify_timeout __read_mostly = 10;
 module_param(lid_notify_timeout, ulong, 0644);
 MODULE_PARM_DESC(lid_notify_timeout, "Timeout (s) before receiving lid 
notification");
@@ -157,79 +151,12 @@ static int acpi_lid_notify_state(struct acpi_device 
*device, int state)
 {
struct acpi_button *button = acpi_driver_data(device);
int ret;
-   ktime_t next_report;
-   bool do_update;
-
-   /*
-* In lid_init_state=ignore mode, if user opens/closes lid
-* frequently with "open" missing, and "last_time" is also updated
-* frequently, "close" cannot be delivered to the userspace.
-* So "last_time" is only updated after a timeout or an actual
-* switch.
-*/
-   if (lid_init_state != ACPI_BUTTON_LID_INIT_IGNORE ||
-   button->last_state != !!state)
-   do_update = true;
-   else
-   do_update = false;
-
-   next_report = ktime_add(button->last_time,
-   ms_to_ktime(lid_report_interval));
-   if (button->last_state == !!state &&
-   ktime_after(ktime_get(), next_report)) {
-   /* Complain the buggy firmware */
-   pr_warn_once("The lid device is not compliant to SW_LID.\n");
 
-   /*
-* Send the unreliable complement switch event:
-*
-* On most platforms, the lid device is reliable. However
-* there are exceptions:
-* 1. Platforms returning initial lid state as "close" by
-*default after booting/resuming:
-* https://bugzilla.kernel.org/show_bug.cgi?id=89211
-* https://bugzilla.kernel.org/show_bug.cgi?id=106151
-* 2. Platforms never reporting "open" events:
-* https://bugzilla.kernel.org/show_bug.cgi?id=106941
-* On these buggy platforms, the usage model of the ACPI
-* lid device actually is:
-* 1. The initial returning value of _LID may not be
-*reliable.
-* 2. The open event may not be reliable.
-* 3. The close event is reliable.
-*
-* But SW_LID is typed as input switch event, the input
-* layer checks if the event is redundant. Hence if the
-* state is not switched, the userspace cannot see this
-* 

[RFC PATCH v6 4/5] ACPI: button: extract input creation/destruction helpers

2017-06-21 Thread Lv Zheng
From: Benjamin Tissoires 

When the LID switch ACPI implementation is unreliable, we might want
to remove the device when we are not sure about the state. This should
prevent any suspend/resume loops given that in that case, there will be
no more LID switch input node.

This patch prepares the dynamic creation/destruction of the input node.

Signed-off-by: Benjamin Tissoires 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/button.c | 86 +++
 1 file changed, 53 insertions(+), 33 deletions(-)

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 1256a8c..91c9989 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -302,6 +302,54 @@ int acpi_lid_open(void)
 }
 EXPORT_SYMBOL(acpi_lid_open);
 
+static void acpi_button_remove_input(struct acpi_device *device)
+{
+   struct acpi_button *button = acpi_driver_data(device);
+
+   input_unregister_device(button->input);
+   button->input = NULL;
+}
+
+static int acpi_button_add_input(struct acpi_device *device)
+{
+   struct acpi_button *button = acpi_driver_data(device);
+   struct input_dev *input;
+   int error;
+
+   input = input_allocate_device();
+   if (!input) {
+   error = -ENOMEM;
+   goto err;
+   }
+
+   input->name = acpi_device_name(device);
+   input->phys = button->phys;
+   input->id.bustype = BUS_HOST;
+   input->id.product = button->type;
+   input->dev.parent = &device->dev;
+   switch (button->type) {
+   case ACPI_BUTTON_TYPE_POWER:
+   input_set_capability(input, EV_KEY, KEY_POWER);
+   break;
+   case ACPI_BUTTON_TYPE_SLEEP:
+   input_set_capability(input, EV_KEY, KEY_SLEEP);
+   break;
+   case ACPI_BUTTON_TYPE_LID:
+   input_set_capability(input, EV_SW, SW_LID);
+   break;
+   }
+
+   error = input_register_device(input);
+   if (error)
+   goto err;
+
+   button->input = input;
+   return 0;
+ err:
+   input_free_device(input);
+   return error;
+}
+
 static int acpi_lid_update_state(struct acpi_device *device)
 {
int state;
@@ -414,7 +462,6 @@ static int acpi_button_resume(struct device *dev)
 static int acpi_button_add(struct acpi_device *device)
 {
struct acpi_button *button;
-   struct input_dev *input;
const char *hid = acpi_device_hid(device);
char *name, *class;
int error;
@@ -425,12 +472,6 @@ static int acpi_button_add(struct acpi_device *device)
 
device->driver_data = button;
 
-   button->input = input = input_allocate_device();
-   if (!input) {
-   error = -ENOMEM;
-   goto err_free_button;
-   }
-
name = acpi_device_name(device);
class = acpi_device_class(device);
 
@@ -457,38 +498,19 @@ static int acpi_button_add(struct acpi_device *device)
} else {
printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid);
error = -ENODEV;
-   goto err_free_input;
+   goto err_free_button;
}
 
error = acpi_button_add_fs(device);
if (error)
-   goto err_free_input;
+   goto err_free_button;
 
snprintf(button->phys, sizeof(button->phys), "%s/button/input0", hid);
 
-   input->name = name;
-   input->phys = button->phys;
-   input->id.bustype = BUS_HOST;
-   input->id.product = button->type;
-   input->dev.parent = &device->dev;
-
-   switch (button->type) {
-   case ACPI_BUTTON_TYPE_POWER:
-   input_set_capability(input, EV_KEY, KEY_POWER);
-   break;
-
-   case ACPI_BUTTON_TYPE_SLEEP:
-   input_set_capability(input, EV_KEY, KEY_SLEEP);
-   break;
-
-   case ACPI_BUTTON_TYPE_LID:
-   input_set_capability(input, EV_SW, SW_LID);
-   break;
-   }
-
-   error = input_register_device(input);
+   error = acpi_button_add_input(device);
if (error)
goto err_remove_fs;
+
if (button->type == ACPI_BUTTON_TYPE_LID) {
/*
 * This assumes there's only one lid device, or if there are
@@ -507,8 +529,6 @@ static int acpi_button_add(struct acpi_device *device)
 
  err_remove_fs:
acpi_button_remove_fs(device);
- err_free_input:
-   input_free_device(input);
  err_free_button:
kfree(button);
return error;
@@ -521,7 +541,7 @@ static int acpi_button_remove(struct acpi_device *device)
acpi_button_remove_fs(device);
if (button->type == ACPI_BUTTON_TYPE_LID)
del_timer_sync(&button->lid_timer);
-   input_unregister_device(button->input);
+   acpi_button_remove_input(device);
kfree(button);
return 0;
 }
-- 
2.7.4



[RFC PATCH v3 3/5] ACPI: button: Add lid event type debugging messages

2017-05-26 Thread Lv Zheng
This patch adds very useful debugging information to lid events.
These messages and with ec_log_drv() can be used to demonstrate the order
between acpi_ec_resume() and acpi_button_resume().

Cc: Benjamin Tissoires 
Cc: Peter Hutterer 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/button.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index a72f5bf..d3f90c6 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -201,12 +201,17 @@ static int acpi_lid_notify_state(struct acpi_device 
*device,
if (!state) {
input_report_switch(button->input, SW_LID, state);
input_sync(button->input);
+   pr_debug("faked open complement event.\n");
}
}
 
/* Send the platform triggered reliable event */
input_report_switch(button->input, SW_LID, !state);
input_sync(button->input);
+   if (bios_notify)
+   pr_debug("notified %s event.\n", state ? "open" : "close");
+   else
+   pr_debug("faked %s event.\n", state ? "open" : "close");
button->last_state = !!state;
button->last_time = ktime_get();
button->last_is_bios = bios_notify;
-- 
2.7.4



[RFC PATCH v3 4/5] ACPI: button: Fix lid notification

2017-05-26 Thread Lv Zheng
In acpi_lid_notify_state(), it now contains logic to avoid frequently
replayed events which originally was ensured by using blocking notifier.
On the contrary, using blocking notifier is wrong as it could keep on
returning NOTIFY_DONE, causing events lost.

This patch thus changes lid notification to raw notifier in order not to
have events lost.

Cc: Peter Hutterer 
Cc: Benjamin Tissoires 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/button.c | 53 ---
 1 file changed, 29 insertions(+), 24 deletions(-)

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index d3f90c6..4abf8ae 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -112,7 +112,7 @@ struct acpi_button {
bool suspended;
 };
 
-static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
+static RAW_NOTIFIER_HEAD(acpi_lid_notifier);
 static struct acpi_device *lid_device;
 static u8 lid_init_state = ACPI_BUTTON_LID_INIT_OPEN;
 
@@ -139,11 +139,16 @@ static int acpi_lid_evaluate_state(struct acpi_device 
*device)
return lid_state ? 1 : 0;
 }
 
-static int acpi_lid_notify_state(struct acpi_device *device,
+static inline void acpi_lid_notifier_call(struct acpi_device *device,
+ int state)
+{
+   (void)raw_notifier_call_chain(&acpi_lid_notifier, state, device);
+}
+
+static void acpi_lid_notify_state(struct acpi_device *device,
 int state, bool bios_notify)
 {
struct acpi_button *button = acpi_driver_data(device);
-   int ret;
ktime_t next_report;
 
/*
@@ -161,7 +166,7 @@ static int acpi_lid_notify_state(struct acpi_device *device,
ms_to_ktime(lid_report_interval));
if (button->last_is_bios && button->last_state == !!state &&
!ktime_after(ktime_get(), next_report))
-   return 0;
+   return;
 
/*
 * Send the unreliable complement switch event:
@@ -219,18 +224,7 @@ static int acpi_lid_notify_state(struct acpi_device 
*device,
if (state)
pm_wakeup_event(&device->dev, 0);
 
-   ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device);
-   if (ret == NOTIFY_DONE)
-   ret = blocking_notifier_call_chain(&acpi_lid_notifier, state,
-  device);
-   if (ret == NOTIFY_DONE || ret == NOTIFY_OK) {
-   /*
-* It is also regarded as success if the notifier_chain
-* returns NOTIFY_OK or NOTIFY_DONE.
-*/
-   ret = 0;
-   }
-   return ret;
+   acpi_lid_notifier_call(device, state);
 }
 
 static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
@@ -341,13 +335,24 @@ static int acpi_button_remove_fs(struct acpi_device 
*device)
-- 
*/
 int acpi_lid_notifier_register(struct notifier_block *nb)
 {
-   return blocking_notifier_chain_register(&acpi_lid_notifier, nb);
+   return raw_notifier_chain_register(&acpi_lid_notifier, nb);
 }
 EXPORT_SYMBOL(acpi_lid_notifier_register);
 
+static inline int __acpi_lid_notifier_unregister(struct notifier_block *nb,
+bool sync)
+{
+   int ret;
+
+   ret = raw_notifier_chain_unregister(&acpi_lid_notifier, nb);
+   if (sync)
+   synchronize_rcu();
+   return ret;
+}
+
 int acpi_lid_notifier_unregister(struct notifier_block *nb)
 {
-   return blocking_notifier_chain_unregister(&acpi_lid_notifier, nb);
+   return __acpi_lid_notifier_unregister(nb, false);
 }
 EXPORT_SYMBOL(acpi_lid_notifier_unregister);
 
@@ -360,26 +365,26 @@ int acpi_lid_open(void)
 }
 EXPORT_SYMBOL(acpi_lid_open);
 
-static int acpi_lid_update_state(struct acpi_device *device,
-bool bios_notify)
+static void acpi_lid_update_state(struct acpi_device *device,
+ bool bios_notify)
 {
int state;
 
state = acpi_lid_evaluate_state(device);
if (state < 0)
-   return state;
+   return;
 
-   return acpi_lid_notify_state(device, state, bios_notify);
+   acpi_lid_notify_state(device, state, bios_notify);
 }
 
 static void acpi_lid_initialize_state(struct acpi_device *device)
 {
switch (lid_init_state) {
case ACPI_BUTTON_LID_INIT_OPEN:
-   (void)acpi_lid_notify_state(device, 1, false);
+   acpi_lid_notify_state(device, 1, false);
break;
case ACPI_BUTTON_LID_INIT_METHOD:
-   (void)acpi_lid_update_state(device, false);
+   acpi_lid_update_state(device, false);
break;
case ACPI_BUTTON_LID_INIT_IGNORE:
default:
-- 
2.7.4



[RFC PATCH v3 5/5] ACPI: button: Always notify kernel space using _LID returning value

2017-05-26 Thread Lv Zheng
Both nouveau and i915, the only 2 kernel space lid notification listeners,
invoke acpi_lid_open() API to obtain _LID returning value instead of using
the notified value.

So this patch moves this logic from listeners to lid driver, always notify
kernel space listeners using _LID returning value.

This is a no-op cleanup, but facilitates administrators to configure to
notify kernel drivers with faked lid init states via command line
"button.lid_notify_init_state=Y".

Cc: 
Cc: 
Cc: Benjamin Tissoires 
Cc: Peter Hutterer 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/button.c | 16 ++--
 drivers/gpu/drm/i915/intel_lvds.c |  2 +-
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 4abf8ae..e047d34 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -119,6 +119,9 @@ static u8 lid_init_state = ACPI_BUTTON_LID_INIT_OPEN;
 static unsigned long lid_report_interval __read_mostly = 500;
 module_param(lid_report_interval, ulong, 0644);
 MODULE_PARM_DESC(lid_report_interval, "Interval (ms) between lid key events");
+static bool lid_notify_init_state __read_mostly = false;
+module_param(lid_notify_init_state, bool, 0644);
+MODULE_PARM_DESC(lid_notify_init_state, "Notify init lid state to kernel 
drivers after boot/resume");
 
 /* --
   FS Interface (/proc)
@@ -224,6 +227,15 @@ static void acpi_lid_notify_state(struct acpi_device 
*device,
if (state)
pm_wakeup_event(&device->dev, 0);
 
+   if (!lid_notify_init_state) {
+   /*
+* There are cases "state" is not a _LID return value, so
+* correct it before notification.
+*/
+   if (!bios_notify &&
+   lid_init_state != ACPI_BUTTON_LID_INIT_METHOD)
+   state = acpi_lid_evaluate_state(device);
+   }
acpi_lid_notifier_call(device, state);
 }
 
@@ -572,10 +584,10 @@ static int param_set_lid_init_state(const char *val, 
struct kernel_param *kp)
 
if (!strncmp(val, "open", sizeof("open") - 1)) {
lid_init_state = ACPI_BUTTON_LID_INIT_OPEN;
-   pr_info("Notify initial lid state as open\n");
+   pr_info("Notify initial lid state to users space as open and 
kernel drivers with _LID return value\n");
} else if (!strncmp(val, "method", sizeof("method") - 1)) {
lid_init_state = ACPI_BUTTON_LID_INIT_METHOD;
-   pr_info("Notify initial lid state with _LID return value\n");
+   pr_info("Notify initial lid state to user/kernel space with 
_LID return value\n");
} else if (!strncmp(val, "ignore", sizeof("ignore") - 1)) {
lid_init_state = ACPI_BUTTON_LID_INIT_IGNORE;
pr_info("Do not notify initial lid state\n");
diff --git a/drivers/gpu/drm/i915/intel_lvds.c 
b/drivers/gpu/drm/i915/intel_lvds.c
index 9ca4dc4..8ca9080 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -548,7 +548,7 @@ static int intel_lid_notify(struct notifier_block *nb, 
unsigned long val,
/* Don't force modeset on machines where it causes a GPU lockup */
if (dmi_check_system(intel_no_modeset_on_lid))
goto exit;
-   if (!acpi_lid_open()) {
+   if (!val) {
/* do modeset on next lid open event */
dev_priv->modeset_restore = MODESET_ON_LID_OPEN;
goto exit;
-- 
2.7.4



[RFC PATCH v3 2/5] ACPI: button: Extends complement switch event support for all modes

2017-05-26 Thread Lv Zheng
Surface Pro 3 is a typical platform where suspend/resume loop problem
can be seen.

The problem is due to a systemd 229 bug:
1. "ignore": always can trigger endless suspend/resume loop
2. "open": sometimes suspend/resume loop can be stopped
3. "method": always can trigger endless susped/resume loop
The buggy systemd unexpectedly waits for an explicit "open" event after
boot/resume or it will suspends. However even when kernel can send a
faked "open" to it, its state machine is still wrong, systemd may not
respond "close" events arrived after "open" or may suddenly suspend
without seeing any instant events.

Recent systemd 233 has fixed this issue:
1. "ignore": everything works fine;
2. "open": no suspend/resume cycle, but sometimes cannot suspend the
   platform again after the first resume;
3. "method": no suspend/resume cycle, but always cannot suspend the
 platform again after the first resume.
The conclusion is: for suspend/resume cycle issue, "ignore" mode fixes
everything, but current "method" mode is still buggy.
Differences are because button driver only implements complement switch
events for "ignore" mode. Without complement switch events, firmware
triggered "close" cannot be delivered to userspace (confirmed by
evemu-record).

The root cause of the lid state issues is the variation of the platform
firmware implementations:
1. Some platforms send "open" events to OS and the events arrive before
   button driver is resumed;
2. Some platforms send "open" events to OS, but the events arrive after
   button driver is resumed, ex., Samsung N210+;
3. Some platforms never send "open" events to OS, but send "open" events to
   update the cached _LID return value, and the update events arrive before
   button driver is resumed;
4. Some platforms never send "open" events to OS, but send "open" events to
   update the cached _LID return value, but the update events arrive after
   button driver is resumed, ex., Surface Pro 3;
5. Some platforms never send "open" events, _LID returns value sticks to
   "close", ex., Surface Pro 1.

Let's check the docking external display issues (see links below):
1. For case 1, both "method"/"ignore" modes can work correctly;
2. For case 2/4/5, both "method"/"ignore" modes cannot work correctly;
3. For case 3, "method" can work correctly while "ignore" mode cannot.
The conclusion is: for docking external display issue, though the issue
still needs graphics layer (graphics drivers or desktop managers) to be
improved to ensure no breakages for case 2/4/5 platforms, there is a case
where "method" mode plays better.

Thus ACPI subsystem has been pushed to revert back to "method" mode due to
regression rule and case 3 (platforms reported on the links should all be
case 3 platforms), and libinput developers have volunteered to help to
provide workarounds when graphics layer is not fixed or systemd is not
updated.

Thus this patch extends the complement switch event support to other modes
using new indication: generating complement switch event for BIOS notified
"close". So that when button driver is reverted back to "method" mode, it
won't act worse than "ignore" mode on fixed systemd.

Tested with systemd 233, all modes worked fine (no suspend/resume loop and
can suspend any times) after applying this patch.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=195455
  https://bugzilla.redhat.com/show_bug.cgi?id=1430259
Cc: 
Cc: Benjamin Tissoires 
Cc: Peter Hutterer 
Signed-off-by: Lv Zheng 

Signed-off-by: Lv Zheng 
---
 drivers/acpi/button.c | 116 +-
 1 file changed, 57 insertions(+), 59 deletions(-)

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 874ba60..a72f5bf 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -108,6 +108,7 @@ struct acpi_button {
unsigned long pushed;
int last_state;
ktime_t last_time;
+   bool last_is_bios;
bool suspended;
 };
 
@@ -144,78 +145,71 @@ static int acpi_lid_notify_state(struct acpi_device 
*device,
struct acpi_button *button = acpi_driver_data(device);
int ret;
ktime_t next_report;
-   bool do_update;
 
/*
-* In lid_init_state=ignore mode, if user opens/closes lid
-* frequently with "open" missing, and "last_time" is also updated
-* frequently, "close" cannot be delivered to the userspace.
-* So "last_time" is only updated after a timeout or an actual
-* switch.
+* Ignore frequently replayed switch events.
+*
+* AML tables can p

[RFC PATCH v3 1/5] ACPI: button: Add indication of BIOS notification and faked events

2017-05-26 Thread Lv Zheng
This patch adds a parameter to acpi_lid_notify_state() so that it can act
differently against BIOS notification and kernel faked events.

Cc: 
Cc: Benjamin Tissoires 
Cc: Peter Hutterer 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/button.c | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 6d5a8c1..874ba60 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -138,7 +138,8 @@ static int acpi_lid_evaluate_state(struct acpi_device 
*device)
return lid_state ? 1 : 0;
 }
 
-static int acpi_lid_notify_state(struct acpi_device *device, int state)
+static int acpi_lid_notify_state(struct acpi_device *device,
+int state, bool bios_notify)
 {
struct acpi_button *button = acpi_driver_data(device);
int ret;
@@ -360,7 +361,8 @@ int acpi_lid_open(void)
 }
 EXPORT_SYMBOL(acpi_lid_open);
 
-static int acpi_lid_update_state(struct acpi_device *device)
+static int acpi_lid_update_state(struct acpi_device *device,
+bool bios_notify)
 {
int state;
 
@@ -368,17 +370,17 @@ static int acpi_lid_update_state(struct acpi_device 
*device)
if (state < 0)
return state;
 
-   return acpi_lid_notify_state(device, state);
+   return acpi_lid_notify_state(device, state, bios_notify);
 }
 
 static void acpi_lid_initialize_state(struct acpi_device *device)
 {
switch (lid_init_state) {
case ACPI_BUTTON_LID_INIT_OPEN:
-   (void)acpi_lid_notify_state(device, 1);
+   (void)acpi_lid_notify_state(device, 1, false);
break;
case ACPI_BUTTON_LID_INIT_METHOD:
-   (void)acpi_lid_update_state(device);
+   (void)acpi_lid_update_state(device, false);
break;
case ACPI_BUTTON_LID_INIT_IGNORE:
default:
@@ -398,7 +400,7 @@ static void acpi_button_notify(struct acpi_device *device, 
u32 event)
case ACPI_BUTTON_NOTIFY_STATUS:
input = button->input;
if (button->type == ACPI_BUTTON_TYPE_LID) {
-   acpi_lid_update_state(device);
+   acpi_lid_update_state(device, true);
} else {
int keycode;
 
-- 
2.7.4



[PATCH] ACPICA: Tables: Fix FADT dependency regression

2015-10-13 Thread Lv Zheng
Some logics actually relying on the existence of FADT, currently relies on
the number of loaded tables. This false dependency can easily trigger
regressions. The reported regression can be seen on the following commit:
  Commit: 8ec3f459073e67e5c6d78507dec693064b3040a2
  Subject: ACPICA: Tables: Fix global table list issues by removing fixed table
The commit changing the fixed table indexes results in the change of FADT
table index, originally, it was 3 (thus the installed table count should be
greater than 4), while currently it is 0 (and the installed table count may
be 3).

This patch fixes this regression by cleaning up the code. Lv Zheng.

Reference: https://bugzilla.kernel.org/show_bug.cgi?id=105351
Reported-and-tested-by: Meelis Roos 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/acpica/acglobal.h |1 +
 drivers/acpi/acpica/actables.h |4 +---
 drivers/acpi/acpica/evxfevnt.c |2 +-
 drivers/acpi/acpica/tbfadt.c   |   10 +-
 drivers/acpi/acpica/tbutils.c  |   26 ++
 5 files changed, 10 insertions(+), 33 deletions(-)

diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index 09f37b5..4dde37c 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -61,6 +61,7 @@ ACPI_GLOBAL(struct acpi_table_header, 
acpi_gbl_original_dsdt_header);
 ACPI_INIT_GLOBAL(u32, acpi_gbl_dsdt_index, ACPI_INVALID_TABLE_INDEX);
 ACPI_INIT_GLOBAL(u32, acpi_gbl_facs_index, ACPI_INVALID_TABLE_INDEX);
 ACPI_INIT_GLOBAL(u32, acpi_gbl_xfacs_index, ACPI_INVALID_TABLE_INDEX);
+ACPI_INIT_GLOBAL(u32, acpi_gbl_fadt_index, ACPI_INVALID_TABLE_INDEX);
 
 #if (!ACPI_REDUCED_HARDWARE)
 ACPI_GLOBAL(struct acpi_table_facs *, acpi_gbl_FACS);
diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h
index f7731f2..591ea95 100644
--- a/drivers/acpi/acpica/actables.h
+++ b/drivers/acpi/acpica/actables.h
@@ -85,7 +85,7 @@ void acpi_tb_set_table_loaded_flag(u32 table_index, u8 
is_loaded);
 /*
  * tbfadt - FADT parse/convert/validate
  */
-void acpi_tb_parse_fadt(u32 table_index);
+void acpi_tb_parse_fadt(void);
 
 void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length);
 
@@ -138,8 +138,6 @@ acpi_status acpi_tb_get_owner_id(u32 table_index, 
acpi_owner_id *owner_id);
  */
 acpi_status acpi_tb_initialize_facs(void);
 
-u8 acpi_tb_tables_loaded(void);
-
 void
 acpi_tb_print_table_header(acpi_physical_address address,
   struct acpi_table_header *header);
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index faad911..10ce48e 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -71,7 +71,7 @@ acpi_status acpi_enable(void)
 
/* ACPI tables must be present */
 
-   if (!acpi_tb_tables_loaded()) {
+   if (acpi_gbl_fadt_index == ACPI_INVALID_TABLE_INDEX) {
return_ACPI_STATUS(AE_NO_ACPI_TABLES);
}
 
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c
index 455a070..a6454f4 100644
--- a/drivers/acpi/acpica/tbfadt.c
+++ b/drivers/acpi/acpica/tbfadt.c
@@ -298,7 +298,7 @@ acpi_tb_select_address(char *register_name, u32 address32, 
u64 address64)
  *
  * FUNCTION:acpi_tb_parse_fadt
  *
- * PARAMETERS:  table_index - Index for the FADT
+ * PARAMETERS:  None
  *
  * RETURN:  None
  *
@@ -307,7 +307,7 @@ acpi_tb_select_address(char *register_name, u32 address32, 
u64 address64)
  *
  
**/
 
-void acpi_tb_parse_fadt(u32 table_index)
+void acpi_tb_parse_fadt(void)
 {
u32 length;
struct acpi_table_header *table;
@@ -319,11 +319,11 @@ void acpi_tb_parse_fadt(u32 table_index)
 * Get a local copy of the FADT and convert it to a common format
 * Map entire FADT, assumed to be smaller than one page.
 */
-   length = acpi_gbl_root_table_list.tables[table_index].length;
+   length = acpi_gbl_root_table_list.tables[acpi_gbl_fadt_index].length;
 
table =
-   acpi_os_map_memory(acpi_gbl_root_table_list.tables[table_index].
-  address, length);
+   acpi_os_map_memory(acpi_gbl_root_table_list.
+  tables[acpi_gbl_fadt_index].address, length);
if (!table) {
return;
}
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index 4337990..d8ddef3 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -99,29 +99,6 @@ acpi_status acpi_tb_initialize_facs(void)
 
 
/***
  *
- * FUNCTION:acpi_tb_tables_loaded
- *
- * PARAMETERS:  None
- *
- * RETURN:  TRUE if required ACPI tables are loaded
- *
- * DESCRIPTION: Determine if the minimum required ACPI tables are present
- *  (FADT, FACS, DSDT

[PATCH 07/13] ACPICA: iASL: General cleanup of the file suffix #defines

2015-10-14 Thread Lv Zheng
From: Bob Moore 

ACPICA commit bed456ed2976bdaafdef406b982fdf6c539befc0

Removed some extraneous defines, reordered others.

Link: https://github.com/acpica/acpica/commit/bed456ed
Signed-off-by: Bob Moore 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/acpica/acapps.h  |2 +-
 tools/power/acpi/tools/acpidump/apfiles.c |2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/acpica/acapps.h b/drivers/acpi/acpica/acapps.h
index e9f0833..e4cc48f 100644
--- a/drivers/acpi/acpica/acapps.h
+++ b/drivers/acpi/acpica/acapps.h
@@ -88,7 +88,7 @@
acpi_os_printf (" %-18s%s\n", name, description);
 
 #define FILE_SUFFIX_DISASSEMBLY "dsl"
-#define ACPI_TABLE_FILE_SUFFIX  ".dat"
+#define FILE_SUFFIX_BINARY_TABLE".dat" /* Needs the dot */
 
 /*
  * getopt
diff --git a/tools/power/acpi/tools/acpidump/apfiles.c 
b/tools/power/acpi/tools/acpidump/apfiles.c
index a37f970..a1c62de 100644
--- a/tools/power/acpi/tools/acpidump/apfiles.c
+++ b/tools/power/acpi/tools/acpidump/apfiles.c
@@ -150,7 +150,7 @@ int ap_write_to_binary_file(struct acpi_table_header 
*table, u32 instance)
strcat(filename, instance_str);
}
 
-   strcat(filename, ACPI_TABLE_FILE_SUFFIX);
+   strcat(filename, FILE_SUFFIX_BINARY_TABLE);
 
if (gbl_verbose_mode) {
acpi_log_error
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 05/13] ACPICA: Update NFIT table to rename a flags field

2015-10-14 Thread Lv Zheng
From: Bob Moore 

ACPICA commit 534deab97fb416a13bfede15c538e2c9eac9384a

Updated one of the memory subtable flags to clarify.

Link: https://github.com/acpica/acpica/commit/534deab9
Signed-off-by: Bob Moore 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/nfit.c   |6 +++---
 drivers/acpi/nfit.h   |2 +-
 include/acpi/actbl1.h |2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/acpi/nfit.c b/drivers/acpi/nfit.c
index c1b8d03..bc18aa2 100644
--- a/drivers/acpi/nfit.c
+++ b/drivers/acpi/nfit.c
@@ -706,7 +706,7 @@ static ssize_t flags_show(struct device *dev,
flags & ACPI_NFIT_MEM_SAVE_FAILED ? "save_fail " : "",
flags & ACPI_NFIT_MEM_RESTORE_FAILED ? "restore_fail " : "",
flags & ACPI_NFIT_MEM_FLUSH_FAILED ? "flush_fail " : "",
-   flags & ACPI_NFIT_MEM_ARMED ? "not_armed " : "",
+   flags & ACPI_NFIT_MEM_NOT_ARMED ? "not_armed " : "",
flags & ACPI_NFIT_MEM_HEALTH_OBSERVED ? "smart_event " : "");
 }
 static DEVICE_ATTR_RO(flags);
@@ -815,7 +815,7 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc 
*acpi_desc)
flags |= NDD_ALIASING;
 
mem_flags = __to_nfit_memdev(nfit_mem)->flags;
-   if (mem_flags & ACPI_NFIT_MEM_ARMED)
+   if (mem_flags & ACPI_NFIT_MEM_NOT_ARMED)
flags |= NDD_UNARMED;
 
rc = acpi_nfit_add_dimm(acpi_desc, nfit_mem, device_handle);
@@ -839,7 +839,7 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc 
*acpi_desc)
  mem_flags & ACPI_NFIT_MEM_SAVE_FAILED ? " save_fail" : "",
  mem_flags & ACPI_NFIT_MEM_RESTORE_FAILED ? " restore_fail":"",
  mem_flags & ACPI_NFIT_MEM_FLUSH_FAILED ? " flush_fail" : "",
- mem_flags & ACPI_NFIT_MEM_ARMED ? " not_armed" : "");
+ mem_flags & ACPI_NFIT_MEM_NOT_ARMED ? " not_armed" : "");
 
}
 
diff --git a/drivers/acpi/nfit.h b/drivers/acpi/nfit.h
index 7e74015..329a1eb 100644
--- a/drivers/acpi/nfit.h
+++ b/drivers/acpi/nfit.h
@@ -24,7 +24,7 @@
 #define UUID_NFIT_DIMM "4309ac30-0d11-11e4-9191-0800200c9a66"
 #define ACPI_NFIT_MEM_FAILED_MASK (ACPI_NFIT_MEM_SAVE_FAILED \
| ACPI_NFIT_MEM_RESTORE_FAILED | ACPI_NFIT_MEM_FLUSH_FAILED \
-   | ACPI_NFIT_MEM_ARMED)
+   | ACPI_NFIT_MEM_NOT_ARMED)
 
 enum nfit_uuids {
NFIT_SPA_VOLATILE,
diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
index fcd5709..1bb979e 100644
--- a/include/acpi/actbl1.h
+++ b/include/acpi/actbl1.h
@@ -1012,7 +1012,7 @@ struct acpi_nfit_memory_map {
 #define ACPI_NFIT_MEM_SAVE_FAILED   (1)/* 00: Last SAVE to Memory 
Device failed */
 #define ACPI_NFIT_MEM_RESTORE_FAILED(1<<1) /* 01: Last RESTORE from Memory 
Device failed */
 #define ACPI_NFIT_MEM_FLUSH_FAILED  (1<<2) /* 02: Platform flush failed */
-#define ACPI_NFIT_MEM_ARMED (1<<3) /* 03: Memory Device observed 
to be not armed */
+#define ACPI_NFIT_MEM_NOT_ARMED (1<<3) /* 03: Memory Device is not 
armed */
 #define ACPI_NFIT_MEM_HEALTH_OBSERVED   (1<<4) /* 04: Memory Device observed 
SMART/health events */
 #define ACPI_NFIT_MEM_HEALTH_ENABLED(1<<5) /* 05: SMART/health events 
enabled */
 
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 01/13] ACPICA: Remove unnecessary conditional compilation.

2015-10-14 Thread Lv Zheng
From: Bob Moore 

ACPICA commit eea1f0e561893b6d6417913b2d224082fe3a0a5e

Remove use of ACPI_DEBUGGER and ACPI_DISASSEMBLER where these
defines are used around entire modules.

Note: This type of code also causes problems with IDEs.

Link: https://github.com/acpica/acpica/commit/eea1f0e5
Signed-off-by: Bob Moore 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/acpica/acdebug.h |6 ++
 drivers/acpi/acpica/rsdump.c  |3 ---
 include/acpi/platform/acenv.h |2 +-
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h
index eb2e926..c928ba4 100644
--- a/drivers/acpi/acpica/acdebug.h
+++ b/drivers/acpi/acpica/acdebug.h
@@ -44,6 +44,12 @@
 #ifndef __ACDEBUG_H__
 #define __ACDEBUG_H__
 
+/* The debugger is used in conjunction with the disassembler most of time */
+
+#ifdef ACPI_DISASSEMBLER
+#include "acdisasm.h"
+#endif
+
 #define ACPI_DEBUG_BUFFER_SIZE  0x4000 /* 16K buffer for return objects */
 
 struct acpi_db_command_info {
diff --git a/drivers/acpi/acpica/rsdump.c b/drivers/acpi/acpica/rsdump.c
index c428bb3..2a09288 100644
--- a/drivers/acpi/acpica/rsdump.c
+++ b/drivers/acpi/acpica/rsdump.c
@@ -51,7 +51,6 @@ ACPI_MODULE_NAME("rsdump")
 /*
  * All functions in this module are used by the AML Debugger only
  */
-#if defined(ACPI_DEBUGGER)
 /* Local prototypes */
 static void acpi_rs_out_string(char *title, char *value);
 
@@ -565,5 +564,3 @@ static void acpi_rs_dump_word_list(u16 length, u16 *data)
acpi_os_printf("%25s%2.2X : %4.4X\n", "Word", i, data[i]);
}
 }
-
-#endif
diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h
index ec00e2b..15ef08c 100644
--- a/include/acpi/platform/acenv.h
+++ b/include/acpi/platform/acenv.h
@@ -142,7 +142,7 @@
 
 #ifdef ACPI_LIBRARY
 #define ACPI_USE_LOCAL_CACHE
-#define ACPI_FUTURE_USAGE
+#define ACPI_FULL_DEBUG
 #endif
 
 /* Common for all ACPICA applications */
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 03/13] ACPICA: Update exception code for "file not found" error

2015-10-14 Thread Lv Zheng
From: Bob Moore 

ACPICA commit ac1564c26d239348ef13455f61d5616f3961ff43

Used by the ACPICA applications.

This patch is a bit broken due to non-portable  inclusion as on
some platforms, there is no such a header file for their lib-c exports.
Fortunately, Linux doesn't compile utfileio.c for either the kernel
space ACPICA core (drivers/acpi/acpica) or the userspace ACPICA tools
(tools/power/acpi) for now, so it's safe to leave this patch as it is.

Link: https://github.com/acpica/acpica/commit/ac1564c2
Signed-off-by: Bob Moore 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/acpica/utfileio.c |6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/acpi/acpica/utfileio.c b/drivers/acpi/acpica/utfileio.c
index 75a94f5..d435b7b 100644
--- a/drivers/acpi/acpica/utfileio.c
+++ b/drivers/acpi/acpica/utfileio.c
@@ -45,6 +45,7 @@
 #include "accommon.h"
 #include "actables.h"
 #include "acapps.h"
+#include "errno.h"
 
 #ifdef ACPI_ASL_COMPILER
 #include "aslcompiler.h"
@@ -301,6 +302,11 @@ acpi_ut_read_table_from_file(char *filename, struct 
acpi_table_header ** table)
file = fopen(filename, "rb");
if (!file) {
perror("Could not open input file");
+
+   if (errno == ENOENT) {
+   return (AE_NOT_EXIST);
+   }
+
return (status);
}
 
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 10/13] ACPICA: Debugger: Fix "terminate" command by cleaning up subsystem shutdown logic

2015-10-14 Thread Lv Zheng
ACPICA commit 7e823714911480be47e310fb1b3590d289b9fd99

Segmentation fault can be seen for executing the "terminate" command. This
is because acpi_ut_subsystem_shutdown() is errnously called multiple times.

This patch cleans up acpi_ut_subsystem_shutdown() logics to fix this
issue. Lv Zheng.

Link: https://github.com/acpica/acpica/commit/7e823714
Signed-off-by: Lv Zheng 
Signed-off-by: Bob Moore 
---
 drivers/acpi/acpica/dbinput.c |3 ++-
 drivers/acpi/acpica/utinit.c  |   13 +
 drivers/acpi/acpica/utxface.c |   13 -
 3 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/acpi/acpica/dbinput.c b/drivers/acpi/acpica/dbinput.c
index f8cddd6..0480254 100644
--- a/drivers/acpi/acpica/dbinput.c
+++ b/drivers/acpi/acpica/dbinput.c
@@ -1074,6 +1074,7 @@ acpi_db_command_dispatch(char *input_buffer,
 * re-creating the semaphores!
 */
 
+   acpi_gbl_db_terminate_loop = TRUE;
/*  acpi_initialize (NULL); */
break;
 
@@ -1151,7 +1152,7 @@ void ACPI_SYSTEM_XFACE acpi_db_execute_thread(void 
*context)
acpi_status status = AE_OK;
acpi_status Mstatus;
 
-   while (status != AE_CTRL_TERMINATE) {
+   while (status != AE_CTRL_TERMINATE && !acpi_gbl_db_terminate_loop) {
acpi_gbl_method_executing = FALSE;
acpi_gbl_step_to_next_call = FALSE;
 
diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c
index d8699df..ccd0745 100644
--- a/drivers/acpi/acpica/utinit.c
+++ b/drivers/acpi/acpica/utinit.c
@@ -282,6 +282,19 @@ void acpi_ut_subsystem_shutdown(void)
 {
ACPI_FUNCTION_TRACE(ut_subsystem_shutdown);
 
+   /* Just exit if subsystem is already shutdown */
+
+   if (acpi_gbl_shutdown) {
+   ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated"));
+   return_VOID;
+   }
+
+   /* Subsystem appears active, go ahead and shut it down */
+
+   acpi_gbl_shutdown = TRUE;
+   acpi_gbl_startup_flags = 0;
+   ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n"));
+
 #ifndef ACPI_ASL_COMPILER
 
/* Close the acpi_event Handling */
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c
index f183daf..a6b0eb0 100644
--- a/drivers/acpi/acpica/utxface.c
+++ b/drivers/acpi/acpica/utxface.c
@@ -67,19 +67,6 @@ acpi_status __init acpi_terminate(void)
 
ACPI_FUNCTION_TRACE(acpi_terminate);
 
-   /* Just exit if subsystem is already shutdown */
-
-   if (acpi_gbl_shutdown) {
-   ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated"));
-   return_ACPI_STATUS(AE_OK);
-   }
-
-   /* Subsystem appears active, go ahead and shut it down */
-
-   acpi_gbl_shutdown = TRUE;
-   acpi_gbl_startup_flags = 0;
-   ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n"));
-
/* Shutdown and free all resources */
 
acpi_ut_subsystem_shutdown();
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 12/13] ACPICA: Debugger: Fix dead lock issue ocurred in single stepping mode

2015-10-14 Thread Lv Zheng
ACPICA commit 35273add90da19cd8790fdb5735f52e3c9861684

When single step execution is not ended, executing another control methods
leads to dead locks around interpreter lock/namespace lock/method
serialization lock. So we should only allow one execution from the debugger
at same time. Lv Zheng.

Link: https://github.com/acpica/acpica/commit/35273add
Signed-off-by: Lv Zheng 
Signed-off-by: Bob Moore 
---
 drivers/acpi/acpica/dbexec.c |   10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/acpi/acpica/dbexec.c b/drivers/acpi/acpica/dbexec.c
index 8eef298..9da2daa 100644
--- a/drivers/acpi/acpica/dbexec.c
+++ b/drivers/acpi/acpica/dbexec.c
@@ -370,7 +370,17 @@ acpi_db_execute(char *name, char **args, acpi_object_type 
* types, u32 flags)
 #ifdef ACPI_DEBUG_OUTPUT
u32 previous_allocations;
u32 allocations;
+#endif
 
+   /*
+* Allow one execution to be performed by debugger or single step
+* execution will be dead locked by the interpreter mutexes.
+*/
+   if (acpi_gbl_method_executing) {
+   acpi_os_printf("Only one debugger execution is allowed.\n");
+   return;
+   }
+#ifdef ACPI_DEBUG_OUTPUT
/* Memory allocation tracking */
 
previous_allocations = acpi_db_get_outstanding_allocations();
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 11/13] ACPI: Enable build of AML interpreter debugger

2015-10-14 Thread Lv Zheng
This patch enables ACPICA debugger files using a configurable
CONFIG_ACPI_DEBUGGER configuration item. Those debugger related code that
was originally masked as ACPI_FUTURE_USAGE now gets unmasked.

Necessary OSL stubs are also added in this patch:
1. acpi_os_readable(): This should be arch specific in Linux, while this
patch doesn't introduce real implementation and a complex mechanism to
allow architecture specific acpi_os_readable() to be implemented to
validate the address. It may be done by future commits.
2. acpi_os_get_line(): This is used to obtain debugger command input. This
patch only introduces a simple KDB concept example in it and the
example should be co-working with the code implemented in
acpi_os_printf(). Since this KDB example won't be compiled unless
ENABLE_DEBUGGER is defined and it seems Linux has already stopped to
use ENABLE_DEBUGGER, thus do not expect it can work properly.

This patch also cleans up all other ACPI_FUTURE_USAGE surroundings
accordingly.
1. Since linkage error can be automatically detected, declaration in the
   headers needn't be surrounded by ACPI_FUTURE_USAGE.
   So only the following separate exported fuction bodies are masked by
   this macro (other exported fucntions may have already been masked at
   entire module level via drivers/acpi/acpica/Makefile):
 acpi_install_exception_handler()
 acpi_subsystem_status()
 acpi_get_system_info()
 acpi_get_statistics()
 acpi_install_initialization_handler()
2. Since strip can automatically zap the no-user functions, functions that
   are not marked with ACPI_EXPORT_SYMBOL() needn't get surrounded by
   ACPI_FUTURE_USAGE.
   So the following function which is not used by Linux kernel now won't
   get surrounded by this macro:
 acpi_ps_get_name()

Signed-off-by: Lv Zheng 
---
 drivers/acpi/Kconfig  |9 +
 drivers/acpi/acpica/Makefile  |   16 
 drivers/acpi/acpica/acinterp.h|2 --
 drivers/acpi/acpica/acnamesp.h|4 
 drivers/acpi/acpica/acparser.h|4 
 drivers/acpi/acpica/acutils.h |2 --
 drivers/acpi/acpica/evxface.c |2 +-
 drivers/acpi/acpica/nsdump.c  |6 --
 drivers/acpi/acpica/pstree.c  |2 --
 drivers/acpi/acpica/psutils.c |2 --
 drivers/acpi/acpica/rsutils.c |2 --
 drivers/acpi/acpica/rsxface.c |4 ++--
 drivers/acpi/acpica/utxface.c |2 +-
 drivers/acpi/osl.c|   11 +++
 include/acpi/acpixf.h |   10 --
 include/acpi/platform/aclinux.h   |7 +--
 include/acpi/platform/aclinuxex.h |5 +
 17 files changed, 42 insertions(+), 48 deletions(-)

diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 5d1015c..706c2e9 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -57,6 +57,15 @@ config ACPI_SYSTEM_POWER_STATES_SUPPORT
 config ACPI_CCA_REQUIRED
bool
 
+config ACPI_DEBUGGER
+   bool "In-kernel debugger (EXPERIMENTAL)"
+   select ACPI_DEBUG
+   help
+ Enable in-kernel debugging facilities: statistics, internal
+ object dump, single step control method execution.
+ This is still under development, currently enabling this only
+ results in the compilation of the ACPICA debugger files.
+
 config ACPI_SLEEP
bool
depends on SUSPEND || HIBERNATION
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
index fedcc16..a57f019 100644
--- a/drivers/acpi/acpica/Makefile
+++ b/drivers/acpi/acpica/Makefile
@@ -178,7 +178,23 @@ acpi-y +=  \
utxferror.o \
utxfmutex.o
 
+acpi-$(CONFIG_ACPI_DEBUGGER) +=\
+   dbcmds.o\
+   dbconvert.o \
+   dbdisply.o  \
+   dbexec.o\
+   dbhistry.o  \
+   dbinput.o   \
+   dbmethod.o  \
+   dbnames.o   \
+   dbobject.o  \
+   dbstats.o   \
+   dbutils.o   \
+   dbxface.o
+
 acpi-$(ACPI_FUTURE_USAGE) +=   \
+   dbfileio.o  \
+   dbtest.o\
utcache.o   \
utfileio.o  \
utprint.o   \
diff --git a/drivers/acpi/acpica/acinterp.h b/drivers/acpi/acpica/acinterp.h
index e820ed8..e9e936e 100644
--- a/drivers/acpi/acpica/acinterp.h
+++ b/drivers/acpi/acpica/acinterp.h
@@ -397,12 +397,10 @@ void
 acpi_ex_dump_operands(union acpi_operand_object **operands,
  const char *opcode_name, u32 num_opcodes);
 
-#ifdef ACPI_FUTURE_USAGE
 void
 acpi_ex_dump_object_descriptor(union acpi_operand_object *object, u32 flags);
 
 void acpi_ex_dump_namespace_node(struct acpi_namespace_node *node, u32 flags);
-#endif /* ACPI_FUTURE_USAGE */
 
 /*
  * exnames - AML namestring support
diff --git

[PATCH 13/13] ACPICA: Update version to 20150930

2015-10-14 Thread Lv Zheng
From: Bob Moore 

ACPICA commit e9c75ca267262326e80d49a290e8387a5963e2d2

Version 20150930.

Link: https://github.com/acpica/acpica/commit/e9c75ca2
Signed-off-by: Bob Moore 
Signed-off-by: Lv Zheng 
---
 include/acpi/acpixf.h |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 89a4018..b9ee2fb 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -46,7 +46,7 @@
 
 /* Current ACPICA subsystem version in MMDD format */
 
-#define ACPI_CA_VERSION 0x20150818
+#define ACPI_CA_VERSION 0x20150930
 
 #include 
 #include 
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 09/13] ACPICA: Debugger: Fix "quit/exit" command by cleaning up user commands termination logic

2015-10-14 Thread Lv Zheng
ACPICA commit 0dd68e16274cd38224aa4781eddc57dc2cbaa108

The quit/exit commands shouldn't invoke acpi_terminate_debugger() and
acpi_terminate() right in the user command loop, because when the debugger
exits, the kernel ACPI subsystem shouldn't be terminated (acpi_terminate())
and the debugger should only be terminated by its users
(acpi_terminate_debugger()) rather than being terminated itself. Leaving such
invocations causes kernel panic when the debugger is shipped in the Linux
kernel.

This patch fixes this issue. Lv Zheng.

Link: https://github.com/acpica/acpica/commit/0dd68e16
Signed-off-by: Lv Zheng 
Signed-off-by: Bob Moore 
---
 drivers/acpi/acpica/acglobal.h |3 ++-
 drivers/acpi/acpica/dbinput.c  |   16 
 drivers/acpi/acpica/dbxface.c  |   20 
 drivers/acpi/acpica/utinit.c   |2 --
 drivers/acpi/acpica/utxface.c  |4 
 5 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index 593de41..d82249c 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -324,7 +324,6 @@ ACPI_GLOBAL(struct acpi_external_file *, 
acpi_gbl_external_file_list);
 
 #ifdef ACPI_DEBUGGER
 
-ACPI_INIT_GLOBAL(u8, acpi_gbl_db_terminate_threads, FALSE);
 ACPI_INIT_GLOBAL(u8, acpi_gbl_abort_method, FALSE);
 ACPI_INIT_GLOBAL(u8, acpi_gbl_method_executing, FALSE);
 
@@ -336,6 +335,8 @@ ACPI_GLOBAL(char *, acpi_gbl_db_filename);
 ACPI_GLOBAL(u32, acpi_gbl_db_debug_level);
 ACPI_GLOBAL(u32, acpi_gbl_db_console_debug_level);
 ACPI_GLOBAL(struct acpi_namespace_node *, acpi_gbl_db_scope_node);
+ACPI_GLOBAL(u8, acpi_gbl_db_terminate_loop);
+ACPI_GLOBAL(u8, acpi_gbl_db_threads_terminated);
 
 ACPI_GLOBAL(char *, acpi_gbl_db_args[ACPI_DEBUGGER_MAX_ARGS]);
 ACPI_GLOBAL(acpi_object_type, acpi_gbl_db_arg_types[ACPI_DEBUGGER_MAX_ARGS]);
diff --git a/drivers/acpi/acpica/dbinput.c b/drivers/acpi/acpica/dbinput.c
index 7f1b6ec..f8cddd6 100644
--- a/drivers/acpi/acpica/dbinput.c
+++ b/drivers/acpi/acpica/dbinput.c
@@ -694,7 +694,7 @@ acpi_db_command_dispatch(char *input_buffer,
 
/* If acpi_terminate has been called, terminate this thread */
 
-   if (acpi_gbl_db_terminate_threads) {
+   if (acpi_gbl_db_terminate_loop) {
return (AE_CTRL_TERMINATE);
}
 
@@ -1116,7 +1116,7 @@ acpi_db_command_dispatch(char *input_buffer,
 #ifdef ACPI_APPLICATION
acpi_db_close_debug_file();
 #endif
-   acpi_gbl_db_terminate_threads = TRUE;
+   acpi_gbl_db_terminate_loop = TRUE;
return (AE_CTRL_TERMINATE);
 
case CMD_NOT_FOUND:
@@ -1166,6 +1166,7 @@ void ACPI_SYSTEM_XFACE acpi_db_execute_thread(void 
*context)
 
acpi_os_release_mutex(acpi_gbl_db_command_complete);
}
+   acpi_gbl_db_threads_terminated = TRUE;
 }
 
 
/***
@@ -1212,7 +1213,7 @@ acpi_status acpi_db_user_commands(char prompt, union 
acpi_parse_object *op)
 
/* TBD: [Restructure] Need a separate command line buffer for step mode 
*/
 
-   while (!acpi_gbl_db_terminate_threads) {
+   while (!acpi_gbl_db_terminate_loop) {
 
/* Force output to console until a command is entered */
 
@@ -1261,14 +1262,5 @@ acpi_status acpi_db_user_commands(char prompt, union 
acpi_parse_object *op)
}
}
 
-   /* Shut down the debugger */
-
-   acpi_terminate_debugger();
-
-   /*
-* Only this thread (the original thread) should actually terminate the
-* subsystem, because all the semaphores are deleted during termination
-*/
-   status = acpi_terminate();
return (status);
 }
diff --git a/drivers/acpi/acpica/dbxface.c b/drivers/acpi/acpica/dbxface.c
index 26023bd..bef5f4e 100644
--- a/drivers/acpi/acpica/dbxface.c
+++ b/drivers/acpi/acpica/dbxface.c
@@ -401,6 +401,10 @@ acpi_status acpi_initialize_debugger(void)
acpi_gbl_db_scope_buf[1] = 0;
acpi_gbl_db_scope_node = acpi_gbl_root_node;
 
+   /* Initialize user commands loop */
+
+   acpi_gbl_db_terminate_loop = FALSE;
+
/*
 * If configured for multi-thread support, the debug executor runs in
 * a separate thread so that the front end can be in another address
@@ -426,11 +430,13 @@ acpi_status acpi_initialize_debugger(void)
 
/* Create the debug execution thread to execute commands */
 
+   acpi_gbl_db_threads_terminated = FALSE;
status = acpi_os_execute(OSL_DEBUGGER_THREAD,
 acpi_db_execute_thread, NULL);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"Could not start debugger thread"));
+   acpi_gbl_db_threads_terminated = TRUE;
retur

[PATCH 06/13] ACPICA: Improve typechecking, both compile-time and runtime

2015-10-14 Thread Lv Zheng
From: Bob Moore 

ACPICA commit 8d0f96e2a11a4ceabb2cae4b41e0ce1f4d3786b9

Adds much stricter typechecking in the iASL compiler, and
also adds some additional checking in the interpreter.

Link: https://github.com/acpica/acpica/commit/8d0f96e2
Signed-off-by: Bob Moore 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/acpica/aclocal.h  |8 ++-
 drivers/acpi/acpica/acopcode.h |4 +-
 drivers/acpi/acpica/amlcode.h  |   11 ++--
 drivers/acpi/acpica/exconvrt.c |1 +
 drivers/acpi/acpica/exresolv.c |1 -
 drivers/acpi/acpica/exresop.c  |2 +
 drivers/acpi/acpica/exstore.c  |  120 ++--
 drivers/acpi/acpica/exstoren.c |5 +-
 drivers/acpi/acpica/nspredef.c |2 +-
 drivers/acpi/acpica/utdecode.c |   19 ++-
 include/acpi/acexcep.h |7 ++-
 11 files changed, 134 insertions(+), 46 deletions(-)

diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 918f70d..4e41b43 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -285,13 +285,17 @@ acpi_status(*acpi_internal_method) (struct 
acpi_walk_state * walk_state);
 #define ACPI_BTYPE_BUFFER_FIELD 0x2000
 #define ACPI_BTYPE_DDB_HANDLE   0x4000
 #define ACPI_BTYPE_DEBUG_OBJECT 0x8000
-#define ACPI_BTYPE_REFERENCE0x0001
+#define ACPI_BTYPE_REFERENCE_OBJECT 0x0001 /* From Index(), 
ref_of(), etc (type6_opcodes) */
 #define ACPI_BTYPE_RESOURCE 0x0002
+#define ACPI_BTYPE_NAMED_REFERENCE  0x0004 /* Generic unresolved 
Name or Namepath */
 
 #define ACPI_BTYPE_COMPUTE_DATA (ACPI_BTYPE_INTEGER | 
ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER)
 
 #define ACPI_BTYPE_DATA (ACPI_BTYPE_COMPUTE_DATA  | 
ACPI_BTYPE_PACKAGE)
-#define ACPI_BTYPE_DATA_REFERENCE   (ACPI_BTYPE_DATA | 
ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE)
+
+   /* Used by Copy, de_ref_of, Store, Printf, Fprintf */
+
+#define ACPI_BTYPE_DATA_REFERENCE   (ACPI_BTYPE_DATA | 
ACPI_BTYPE_REFERENCE_OBJECT | ACPI_BTYPE_DDB_HANDLE)
 #define ACPI_BTYPE_DEVICE_OBJECTS   (ACPI_BTYPE_DEVICE | 
ACPI_BTYPE_THERMAL | ACPI_BTYPE_PROCESSOR)
 #define ACPI_BTYPE_OBJECTS_AND_REFS 0x0001 /* ARG or LOCAL */
 #define ACPI_BTYPE_ALL_OBJECTS  0x
diff --git a/drivers/acpi/acpica/acopcode.h b/drivers/acpi/acpica/acopcode.h
index fd85ad0..f9acf92 100644
--- a/drivers/acpi/acpica/acopcode.h
+++ b/drivers/acpi/acpica/acopcode.h
@@ -211,7 +211,7 @@
 #define ARGI_ARG4   ARG_NONE
 #define ARGI_ARG5   ARG_NONE
 #define ARGI_ARG6   ARG_NONE
-#define ARGI_BANK_FIELD_OP  ARGI_INVALID_OPCODE
+#define ARGI_BANK_FIELD_OP  ARGI_LIST1 (ARGI_INTEGER)
 #define ARGI_BIT_AND_OP ARGI_LIST3 (ARGI_INTEGER,
ARGI_INTEGER,   ARGI_TARGETREF)
 #define ARGI_BIT_NAND_OPARGI_LIST3 (ARGI_INTEGER,
ARGI_INTEGER,   ARGI_TARGETREF)
 #define ARGI_BIT_NOR_OP ARGI_LIST3 (ARGI_INTEGER,
ARGI_INTEGER,   ARGI_TARGETREF)
@@ -307,7 +307,7 @@
 #define ARGI_SLEEP_OP   ARGI_LIST1 (ARGI_INTEGER)
 #define ARGI_STALL_OP   ARGI_LIST1 (ARGI_INTEGER)
 #define ARGI_STATICSTRING_OPARGI_INVALID_OPCODE
-#define ARGI_STORE_OP   ARGI_LIST2 (ARGI_DATAREFOBJ, 
ARGI_TARGETREF)
+#define ARGI_STORE_OP   ARGI_LIST2 (ARGI_DATAREFOBJ, 
ARGI_STORE_TARGET)
 #define ARGI_STRING_OP  ARGI_INVALID_OPCODE
 #define ARGI_SUBTRACT_OPARGI_LIST3 (ARGI_INTEGER,
ARGI_INTEGER,   ARGI_TARGETREF)
 #define ARGI_THERMAL_ZONE_OPARGI_INVALID_OPCODE
diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h
index be9fd00..883f20c 100644
--- a/drivers/acpi/acpica/amlcode.h
+++ b/drivers/acpi/acpica/amlcode.h
@@ -277,14 +277,15 @@
 #define ARGI_TARGETREF  0x0F   /* Target, subject to implicit 
conversion */
 #define ARGI_FIXED_TARGET   0x10   /* Target, no implicit 
conversion */
 #define ARGI_SIMPLE_TARGET  0x11   /* Name, Local, Arg -- no 
implicit conversion */
+#define ARGI_STORE_TARGET   0x12   /* Target for store is 
TARGETREF + package objects */
 
 /* Multiple/complex types */
 
-#define ARGI_DATAOBJECT 0x12   /* Buffer, String, package or 
reference to a node - Used only by size_of operator */
-#define ARGI_COMPLEXOBJ 0x13   /* Buffer, String, or package 
(Used by INDEX op only) */
-#define ARGI_REF_OR_STRING  0x14   /* Reference or String (Used by 
DEREFOF op only) */
-#define ARGI_REGION_OR_BUFFER   0x15   /* Used by LOAD op only */
-#define ARGI_DATAREFOBJ 0x16
+#define ARGI_DATAOBJECT 0x13   /* Buffer, String, package or 
reference to a node - Used only by size_of operator */
+#define ARGI_COMPLEXOBJ 0x14

[PATCH 04/13] ACPICA: Debugger: Update mutexes used for multithreaded debugger

2015-10-14 Thread Lv Zheng
From: Bob Moore 

ACPICA commit 6b2701f619040e803313363f516b200e362a9100

Make these mutex objects independent of the deadlock detection mechanism.
This mechanism caused failures with the multithread debugger.

This patch doesn't affect Linux kernel as debugger is currently not fully
functioning in the Linux kernel. And the further debugger cleanups will
take care of handling debugger command signalling correctly instead of
using such kind of mutexes. So it is safe to leave this patch as it is.

Link: https://github.com/acpica/acpica/commit/6b2701f6
Signed-off-by: Bob Moore 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/acpica/acglobal.h |3 +++
 drivers/acpi/acpica/aclocal.h  |4 +---
 drivers/acpi/acpica/utdecode.c |2 --
 drivers/acpi/acpica/utmutex.c  |   21 +
 include/acpi/platform/acenv.h  |6 +++---
 5 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index 09f37b5..593de41 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -357,6 +357,9 @@ ACPI_GLOBAL(u16, acpi_gbl_node_type_count_misc);
 ACPI_GLOBAL(u32, acpi_gbl_num_nodes);
 ACPI_GLOBAL(u32, acpi_gbl_num_objects);
 
+ACPI_GLOBAL(acpi_mutex, acpi_gbl_db_command_ready);
+ACPI_GLOBAL(acpi_mutex, acpi_gbl_db_command_complete);
+
 #endif /* ACPI_DEBUGGER */
 
 /*
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 8a66fef..918f70d 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -83,10 +83,8 @@ union acpi_parse_object;
 #define ACPI_MTX_EVENTS 3  /* Data for ACPI events */
 #define ACPI_MTX_CACHES 4  /* Internal caches, general 
purposes */
 #define ACPI_MTX_MEMORY 5  /* Debug memory tracking lists 
*/
-#define ACPI_MTX_DEBUG_CMD_COMPLETE 6  /* AML debugger */
-#define ACPI_MTX_DEBUG_CMD_READY7  /* AML debugger */
 
-#define ACPI_MAX_MUTEX  7
+#define ACPI_MAX_MUTEX  5
 #define ACPI_NUM_MUTEX  ACPI_MAX_MUTEX+1
 
 /* Lock structure for reader/writer interfaces */
diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c
index 988e23b..d452a78 100644
--- a/drivers/acpi/acpica/utdecode.c
+++ b/drivers/acpi/acpica/utdecode.c
@@ -407,8 +407,6 @@ static char *acpi_gbl_mutex_names[ACPI_NUM_MUTEX] = {
"ACPI_MTX_Events",
"ACPI_MTX_Caches",
"ACPI_MTX_Memory",
-   "ACPI_MTX_CommandComplete",
-   "ACPI_MTX_CommandReady"
 };
 
 char *acpi_ut_get_mutex_name(u32 mutex_id)
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c
index 37b8b58..ce406e3 100644
--- a/drivers/acpi/acpica/utmutex.c
+++ b/drivers/acpi/acpica/utmutex.c
@@ -108,6 +108,21 @@ acpi_status acpi_ut_mutex_initialize(void)
/* Create the reader/writer lock for namespace access */
 
status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock);
+   if (ACPI_FAILURE(status)) {
+   return_ACPI_STATUS(status);
+   }
+#ifdef ACPI_DEBUGGER
+
+   /* Debugger Support */
+
+   status = acpi_os_create_mutex(&acpi_gbl_db_command_ready);
+   if (ACPI_FAILURE(status)) {
+   return_ACPI_STATUS(status);
+   }
+
+   status = acpi_os_create_mutex(&acpi_gbl_db_command_complete);
+#endif
+
return_ACPI_STATUS(status);
 }
 
@@ -147,6 +162,12 @@ void acpi_ut_mutex_terminate(void)
/* Delete the reader/writer lock */
 
acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
+
+#ifdef ACPI_DEBUGGER
+   acpi_os_delete_mutex(acpi_gbl_db_command_ready);
+   acpi_os_delete_mutex(acpi_gbl_db_command_complete);
+#endif
+
return_VOID;
 }
 
diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h
index 15ef08c..056f245 100644
--- a/include/acpi/platform/acenv.h
+++ b/include/acpi/platform/acenv.h
@@ -304,11 +304,11 @@
  * multi-threaded if ACPI_APPLICATION is not set.
  */
 #ifndef DEBUGGER_THREADING
-#ifdef ACPI_APPLICATION
-#define DEBUGGER_THREADING  DEBUGGER_SINGLE_THREADED
+#if !defined (ACPI_APPLICATION) || defined (ACPI_EXEC_APP)
+#define DEBUGGER_THREADING  DEBUGGER_MULTI_THREADED
 
 #else
-#define DEBUGGER_THREADING  DEBUGGER_MULTI_THREADED
+#define DEBUGGER_THREADING  DEBUGGER_SINGLE_THREADED
 #endif
 #endif /* !DEBUGGER_THREADING */
 
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 02/13] ACPICA: iASL: Add symbolic operator support for Index() operator.

2015-10-14 Thread Lv Zheng
From: Bob Moore 

ACPICA commit fbe67c46830f10c839941f8512cac5bddcb86bd3

Index (, 2) is now supported by  [2]

This patch doesn't affect Linux kernel.

Link: https://github.com/acpica/acpica/commit/fbe67c46
Signed-off-by: Bob Moore 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/acpica/aclocal.h |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 6f70826..8a66fef 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -848,7 +848,7 @@ struct acpi_parse_state {
 #define ACPI_PARSEOP_PARAMLIST  0x02
 #define ACPI_PARSEOP_EMPTY_TERMLIST 0x04
 #define ACPI_PARSEOP_PREDEF_CHECKED 0x08
-#define ACPI_PARSEOP_SPECIAL0x10
+#define ACPI_PARSEOP_CLOSING_PAREN  0x10
 #define ACPI_PARSEOP_COMPOUND   0x20
 #define ACPI_PARSEOP_ASSIGNMENT 0x40
 
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 00/13] ACPICA: 20150930 Release

2015-10-14 Thread Lv Zheng
The 20150930 ACPICA kernel-resident subsystem updates are linuxized based
on the linux-pm/linux-next branch.

The patchset has passed the following build/boot tests.
Build tests are performed as follows:
1. i386 + allyes
2. i386 + allno
3. i386 + default + ACPI_DEBUGGER=y
4. i386 + default + ACPI_DEBUGGER=n + ACPI_DEBUG=y
5. i386 + default + ACPI_DEBUG=n + ACPI=y
6. i386 + default + ACPI=n
7. x86_64 + allyes
8. x86_64 + allno
9. x86_64 + default + ACPI_DEBUGGER=y
10.x86_64 + default + ACPI_DEBUGGER=n + ACPI_DEBUG=y
11.x86_64 + default + ACPI_DEBUG=n + ACPI=y
12.x86_64 + default + ACPI=n
Boot tests are performed as follows:
1. i386 + default + ACPI_DEBUGGER=y
2. x86_64 + default + ACPI_DEBUGGER=y
Where:
1. i386: machine named as "Dell Inspiron Mini 1010"
2. x86_64: machine named as "HP Compaq 8200 Elite SFF PC"
3. default: kernel configuration with following items enabled:
   All hardware drivers related to the machines of i386/x86_64
   All "drivers/acpi" configurations
   All "drivers/platform" drivers
   All other drivers that link the APIs provided by ACPICA subsystem

The divergences checking result:
Before applying (20150818 Release):
  517 lines
After applying (20150930 Release):
  517 lines

Note there are still 2 ACPICA debugger patches not released during this
release cycle, so the debugger IO driver is not released in this cycle. In
this series the ACPICA debugger core is compile time enabled as all ACPICA
debugger files can be built with ACPI_DEBUGGER=y, but not runtime enabled
as there is no invocations calling ACPICA debugger APIs and its required
OSls are just stubs.

Bob Moore (8):
  ACPICA: Remove unnecessary conditional compilation.
  ACPICA: iASL: Add symbolic operator support for Index() operator.
  ACPICA: Update exception code for "file not found" error
  ACPICA: Debugger: Update mutexes used for multithreaded debugger
  ACPICA: Update NFIT table to rename a flags field
  ACPICA: Improve typechecking, both compile-time and runtime
  ACPICA: iASL: General cleanup of the file suffix #defines
  ACPICA: Update version to 20150930

Lv Zheng (5):
  ACPICA: Linuxize: Export debugger files to Linux
  ACPICA: Debugger: Fix "quit/exit" command by cleaning up user
commands termination logic
  ACPICA: Debugger: Fix "terminate" command by cleaning up subsystem
shutdown logic
  ACPI: Enable build of AML interpreter debugger
  ACPICA: Debugger: Fix dead lock issue ocurred in single stepping mode

 drivers/acpi/Kconfig  |9 +
 drivers/acpi/acpica/Makefile  |   16 +
 drivers/acpi/acpica/acapps.h  |2 +-
 drivers/acpi/acpica/acdebug.h |6 +
 drivers/acpi/acpica/acglobal.h|6 +-
 drivers/acpi/acpica/acinterp.h|2 -
 drivers/acpi/acpica/aclocal.h |   14 +-
 drivers/acpi/acpica/acnamesp.h|4 -
 drivers/acpi/acpica/acopcode.h|4 +-
 drivers/acpi/acpica/acparser.h|4 -
 drivers/acpi/acpica/acutils.h |2 -
 drivers/acpi/acpica/amlcode.h |   11 +-
 drivers/acpi/acpica/dbcmds.c  | 1187 +++
 drivers/acpi/acpica/dbconvert.c   |  484 +++
 drivers/acpi/acpica/dbdisply.c| 1108 +
 drivers/acpi/acpica/dbexec.c  |  763 +
 drivers/acpi/acpica/dbfileio.c|  256 ++
 drivers/acpi/acpica/dbhistry.c|  239 ++
 drivers/acpi/acpica/dbinput.c | 1267 +
 drivers/acpi/acpica/dbmethod.c|  369 +
 drivers/acpi/acpica/dbnames.c |  947 +
 drivers/acpi/acpica/dbobject.c|  533 
 drivers/acpi/acpica/dbstats.c |  546 +
 drivers/acpi/acpica/dbtest.c  | 1057 
 drivers/acpi/acpica/dbutils.c |  457 +++
 drivers/acpi/acpica/dbxface.c |  487 +++
 drivers/acpi/acpica/evxface.c |2 +-
 drivers/acpi/acpica/exconvrt.c|1 +
 drivers/acpi/acpica/exresolv.c|1 -
 drivers/acpi/acpica/exresop.c |2 +
 drivers/acpi/acpica/exstore.c |  120 ++-
 drivers/acpi/acpica/exstoren.c|5 +-
 drivers/acpi/acpica/nsdump.c  |6 -
 drivers/acpi/acpica/nspredef.c|2 +-
 drivers/acpi/acpica/pstree.c  |2 -
 drivers/acpi/acpica/psutils.c |2 -
 drivers/acpi/acpica/rsdump.c  |3 -
 drivers/acpi/acpica/rsutils.c |2 -
 drivers/acpi/acpica/rsxface.c |4 +-
 drivers/acpi/acpica/utdecode.c|   21 +-
 drivers/acpi/acpica/utfileio.c|6 +
 drivers/acpi/acpica/utinit.c  |   15 +-
 drivers/acpi/acpica/utmutex.c |   21 +
 dr

[PATCH v2 00/14] ACPICA: 20150930 Release

2015-10-18 Thread Lv Zheng
The 20150930 ACPICA kernel-resident subsystem updates are linuxized based
on the linux-pm/linux-next branch.

The patchset has passed the following build/boot tests.
Build tests are performed as follows:
1. i386 + allyes
2. i386 + allno
3. i386 + default + ACPI_DEBUGGER=y
4. i386 + default + ACPI_DEBUGGER=n + ACPI_DEBUG=y
5. i386 + default + ACPI_DEBUG=n + ACPI=y
6. i386 + default + ACPI=n
7. x86_64 + allyes
8. x86_64 + allno
9. x86_64 + default + ACPI_DEBUGGER=y
10.x86_64 + default + ACPI_DEBUGGER=n + ACPI_DEBUG=y
11.x86_64 + default + ACPI_DEBUG=n + ACPI=y
12.x86_64 + default + ACPI=n
Boot tests are performed as follows:
1. i386 + default + ACPI_DEBUGGER=y
2. x86_64 + default + ACPI_DEBUGGER=y
Where:
1. i386: machine named as "Dell Inspiron Mini 1010"
2. x86_64: machine named as "HP Compaq 8200 Elite SFF PC"
3. default: kernel configuration with following items enabled:
   All hardware drivers related to the machines of i386/x86_64
   All "drivers/acpi" configurations
   All "drivers/platform" drivers
   All other drivers that link the APIs provided by ACPICA subsystem

The divergences checking result:
Before applying (20150818 Release):
  517 lines
After applying (20150930 Release):
  517 lines

Note there are still 2 ACPICA debugger patches not released during this
release cycle, so the debugger IO driver is not released in this cycle. In
this series the ACPICA debugger core is compile time enabled as all ACPICA
debugger files can be built with ACPI_DEBUGGER=y, but not runtime enabled
as there is no invocations calling ACPICA debugger APIs and its required
OSls are just stubs. The embedded debugger invocation acpi_db_single_step()
is also stubbed via debugger thread ID support.

Bob Moore (8):
  ACPICA: Remove unnecessary conditional compilation.
  ACPICA: iASL: Add symbolic operator support for Index() operator.
  ACPICA: Update exception code for "file not found" error
  ACPICA: Debugger: Update mutexes used for multithreaded debugger
  ACPICA: Update NFIT table to rename a flags field
  ACPICA: Improve typechecking, both compile-time and runtime
  ACPICA: iASL: General cleanup of the file suffix #defines
  ACPICA: Update version to 20150930

Lv Zheng (6):
  ACPICA: Linuxize: Export debugger files to Linux
  ACPICA: Debugger: Fix "quit/exit" command by cleaning up user
commands termination logic
  ACPICA: Debugger: Fix "terminate" command by cleaning up subsystem
shutdown logic
  ACPICA: Debugger: Add thread ID support so that single step mode can
only apply to the debugger thread
  ACPI: Enable build of AML interpreter debugger
  ACPICA: Debugger: Fix dead lock issue ocurred in single stepping mode

 drivers/acpi/Kconfig  |9 +
 drivers/acpi/acpica/Makefile  |   18 +-
 drivers/acpi/acpica/acapps.h  |2 +-
 drivers/acpi/acpica/acdebug.h |6 +
 drivers/acpi/acpica/acglobal.h|7 +-
 drivers/acpi/acpica/acinterp.h|2 -
 drivers/acpi/acpica/aclocal.h |   22 +-
 drivers/acpi/acpica/acnamesp.h|4 -
 drivers/acpi/acpica/acopcode.h|4 +-
 drivers/acpi/acpica/acparser.h|4 -
 drivers/acpi/acpica/acutils.h |2 -
 drivers/acpi/acpica/amlcode.h |   11 +-
 drivers/acpi/acpica/dbcmds.c  | 1187 +++
 drivers/acpi/acpica/dbconvert.c   |  484 +++
 drivers/acpi/acpica/dbdisply.c| 1108 +
 drivers/acpi/acpica/dbexec.c  |  764 +
 drivers/acpi/acpica/dbfileio.c|  256 ++
 drivers/acpi/acpica/dbhistry.c|  239 ++
 drivers/acpi/acpica/dbinput.c | 1267 +
 drivers/acpi/acpica/dbmethod.c|  369 +
 drivers/acpi/acpica/dbnames.c |  947 +
 drivers/acpi/acpica/dbobject.c|  533 
 drivers/acpi/acpica/dbstats.c |  546 +
 drivers/acpi/acpica/dbtest.c  | 1057 
 drivers/acpi/acpica/dbutils.c |  457 +++
 drivers/acpi/acpica/dbxface.c |  513 
 drivers/acpi/acpica/evxface.c |2 +-
 drivers/acpi/acpica/exconvrt.c|1 +
 drivers/acpi/acpica/exresolv.c|1 -
 drivers/acpi/acpica/exresop.c |2 +
 drivers/acpi/acpica/exstore.c |  120 ++-
 drivers/acpi/acpica/exstoren.c|5 +-
 drivers/acpi/acpica/nsdump.c  |6 -
 drivers/acpi/acpica/nspredef.c|2 +-
 drivers/acpi/acpica/pstree.c  |2 -
 drivers/acpi/acpica/psutils.c |2 -
 drivers/acpi/acpica/rsdump.c  |3 -
 drivers/acpi/acpica/rsutils.c |2 -
 drivers/acpi/acpica/rsxface.c |4 +-
 dr

[PATCH v2 01/14] ACPICA: Remove unnecessary conditional compilation.

2015-10-18 Thread Lv Zheng
From: Bob Moore 

ACPICA commit eea1f0e561893b6d6417913b2d224082fe3a0a5e

Remove use of ACPI_DEBUGGER and ACPI_DISASSEMBLER where these
defines are used around entire modules.

Note: This type of code also causes problems with IDEs.

Link: https://github.com/acpica/acpica/commit/eea1f0e5
Signed-off-by: Bob Moore 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/acpica/Makefile  |2 +-
 drivers/acpi/acpica/acdebug.h |6 ++
 drivers/acpi/acpica/rsdump.c  |3 ---
 include/acpi/platform/acenv.h |2 +-
 4 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
index fedcc16..ac78d76 100644
--- a/drivers/acpi/acpica/Makefile
+++ b/drivers/acpi/acpica/Makefile
@@ -123,7 +123,6 @@ acpi-y +=   \
rsaddr.o\
rscalc.o\
rscreate.o  \
-   rsdump.o\
rsdumpinfo.o\
rsinfo.o\
rsio.o  \
@@ -179,6 +178,7 @@ acpi-y +=   \
utxfmutex.o
 
 acpi-$(ACPI_FUTURE_USAGE) +=   \
+   rsdump.o\
utcache.o   \
utfileio.o  \
utprint.o   \
diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h
index eb2e926..c928ba4 100644
--- a/drivers/acpi/acpica/acdebug.h
+++ b/drivers/acpi/acpica/acdebug.h
@@ -44,6 +44,12 @@
 #ifndef __ACDEBUG_H__
 #define __ACDEBUG_H__
 
+/* The debugger is used in conjunction with the disassembler most of time */
+
+#ifdef ACPI_DISASSEMBLER
+#include "acdisasm.h"
+#endif
+
 #define ACPI_DEBUG_BUFFER_SIZE  0x4000 /* 16K buffer for return objects */
 
 struct acpi_db_command_info {
diff --git a/drivers/acpi/acpica/rsdump.c b/drivers/acpi/acpica/rsdump.c
index c428bb3..2a09288 100644
--- a/drivers/acpi/acpica/rsdump.c
+++ b/drivers/acpi/acpica/rsdump.c
@@ -51,7 +51,6 @@ ACPI_MODULE_NAME("rsdump")
 /*
  * All functions in this module are used by the AML Debugger only
  */
-#if defined(ACPI_DEBUGGER)
 /* Local prototypes */
 static void acpi_rs_out_string(char *title, char *value);
 
@@ -565,5 +564,3 @@ static void acpi_rs_dump_word_list(u16 length, u16 *data)
acpi_os_printf("%25s%2.2X : %4.4X\n", "Word", i, data[i]);
}
 }
-
-#endif
diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h
index ec00e2b..15ef08c 100644
--- a/include/acpi/platform/acenv.h
+++ b/include/acpi/platform/acenv.h
@@ -142,7 +142,7 @@
 
 #ifdef ACPI_LIBRARY
 #define ACPI_USE_LOCAL_CACHE
-#define ACPI_FUTURE_USAGE
+#define ACPI_FULL_DEBUG
 #endif
 
 /* Common for all ACPICA applications */
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 05/14] ACPICA: Update NFIT table to rename a flags field

2015-10-18 Thread Lv Zheng
From: Bob Moore 

ACPICA commit 534deab97fb416a13bfede15c538e2c9eac9384a

Updated one of the memory subtable flags to clarify.

Link: https://github.com/acpica/acpica/commit/534deab9
Signed-off-by: Bob Moore 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/nfit.c   |6 +++---
 drivers/acpi/nfit.h   |2 +-
 include/acpi/actbl1.h |2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/acpi/nfit.c b/drivers/acpi/nfit.c
index c1b8d03..bc18aa2 100644
--- a/drivers/acpi/nfit.c
+++ b/drivers/acpi/nfit.c
@@ -706,7 +706,7 @@ static ssize_t flags_show(struct device *dev,
flags & ACPI_NFIT_MEM_SAVE_FAILED ? "save_fail " : "",
flags & ACPI_NFIT_MEM_RESTORE_FAILED ? "restore_fail " : "",
flags & ACPI_NFIT_MEM_FLUSH_FAILED ? "flush_fail " : "",
-   flags & ACPI_NFIT_MEM_ARMED ? "not_armed " : "",
+   flags & ACPI_NFIT_MEM_NOT_ARMED ? "not_armed " : "",
flags & ACPI_NFIT_MEM_HEALTH_OBSERVED ? "smart_event " : "");
 }
 static DEVICE_ATTR_RO(flags);
@@ -815,7 +815,7 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc 
*acpi_desc)
flags |= NDD_ALIASING;
 
mem_flags = __to_nfit_memdev(nfit_mem)->flags;
-   if (mem_flags & ACPI_NFIT_MEM_ARMED)
+   if (mem_flags & ACPI_NFIT_MEM_NOT_ARMED)
flags |= NDD_UNARMED;
 
rc = acpi_nfit_add_dimm(acpi_desc, nfit_mem, device_handle);
@@ -839,7 +839,7 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc 
*acpi_desc)
  mem_flags & ACPI_NFIT_MEM_SAVE_FAILED ? " save_fail" : "",
  mem_flags & ACPI_NFIT_MEM_RESTORE_FAILED ? " restore_fail":"",
  mem_flags & ACPI_NFIT_MEM_FLUSH_FAILED ? " flush_fail" : "",
- mem_flags & ACPI_NFIT_MEM_ARMED ? " not_armed" : "");
+ mem_flags & ACPI_NFIT_MEM_NOT_ARMED ? " not_armed" : "");
 
}
 
diff --git a/drivers/acpi/nfit.h b/drivers/acpi/nfit.h
index 7e74015..329a1eb 100644
--- a/drivers/acpi/nfit.h
+++ b/drivers/acpi/nfit.h
@@ -24,7 +24,7 @@
 #define UUID_NFIT_DIMM "4309ac30-0d11-11e4-9191-0800200c9a66"
 #define ACPI_NFIT_MEM_FAILED_MASK (ACPI_NFIT_MEM_SAVE_FAILED \
| ACPI_NFIT_MEM_RESTORE_FAILED | ACPI_NFIT_MEM_FLUSH_FAILED \
-   | ACPI_NFIT_MEM_ARMED)
+   | ACPI_NFIT_MEM_NOT_ARMED)
 
 enum nfit_uuids {
NFIT_SPA_VOLATILE,
diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
index fcd5709..1bb979e 100644
--- a/include/acpi/actbl1.h
+++ b/include/acpi/actbl1.h
@@ -1012,7 +1012,7 @@ struct acpi_nfit_memory_map {
 #define ACPI_NFIT_MEM_SAVE_FAILED   (1)/* 00: Last SAVE to Memory 
Device failed */
 #define ACPI_NFIT_MEM_RESTORE_FAILED(1<<1) /* 01: Last RESTORE from Memory 
Device failed */
 #define ACPI_NFIT_MEM_FLUSH_FAILED  (1<<2) /* 02: Platform flush failed */
-#define ACPI_NFIT_MEM_ARMED (1<<3) /* 03: Memory Device observed 
to be not armed */
+#define ACPI_NFIT_MEM_NOT_ARMED (1<<3) /* 03: Memory Device is not 
armed */
 #define ACPI_NFIT_MEM_HEALTH_OBSERVED   (1<<4) /* 04: Memory Device observed 
SMART/health events */
 #define ACPI_NFIT_MEM_HEALTH_ENABLED(1<<5) /* 05: SMART/health events 
enabled */
 
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 04/14] ACPICA: Debugger: Update mutexes used for multithreaded debugger

2015-10-18 Thread Lv Zheng
From: Bob Moore 

ACPICA commit 6b2701f619040e803313363f516b200e362a9100

Make these mutex objects independent of the deadlock detection mechanism.
This mechanism caused failures with the multithread debugger.

This patch doesn't affect Linux kernel as debugger is currently not fully
functioning in the Linux kernel. And the further debugger cleanups will
take care of handling debugger command signalling correctly instead of
using such kind of mutexes. So it is safe to leave this patch as it is.

Link: https://github.com/acpica/acpica/commit/6b2701f6
Signed-off-by: Bob Moore 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/acpica/acglobal.h |3 +++
 drivers/acpi/acpica/aclocal.h  |4 +---
 drivers/acpi/acpica/utdecode.c |2 --
 drivers/acpi/acpica/utmutex.c  |   21 +
 include/acpi/platform/acenv.h  |6 +++---
 5 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index 09f37b5..593de41 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -357,6 +357,9 @@ ACPI_GLOBAL(u16, acpi_gbl_node_type_count_misc);
 ACPI_GLOBAL(u32, acpi_gbl_num_nodes);
 ACPI_GLOBAL(u32, acpi_gbl_num_objects);
 
+ACPI_GLOBAL(acpi_mutex, acpi_gbl_db_command_ready);
+ACPI_GLOBAL(acpi_mutex, acpi_gbl_db_command_complete);
+
 #endif /* ACPI_DEBUGGER */
 
 /*
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 8a66fef..918f70d 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -83,10 +83,8 @@ union acpi_parse_object;
 #define ACPI_MTX_EVENTS 3  /* Data for ACPI events */
 #define ACPI_MTX_CACHES 4  /* Internal caches, general 
purposes */
 #define ACPI_MTX_MEMORY 5  /* Debug memory tracking lists 
*/
-#define ACPI_MTX_DEBUG_CMD_COMPLETE 6  /* AML debugger */
-#define ACPI_MTX_DEBUG_CMD_READY7  /* AML debugger */
 
-#define ACPI_MAX_MUTEX  7
+#define ACPI_MAX_MUTEX  5
 #define ACPI_NUM_MUTEX  ACPI_MAX_MUTEX+1
 
 /* Lock structure for reader/writer interfaces */
diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c
index 988e23b..d452a78 100644
--- a/drivers/acpi/acpica/utdecode.c
+++ b/drivers/acpi/acpica/utdecode.c
@@ -407,8 +407,6 @@ static char *acpi_gbl_mutex_names[ACPI_NUM_MUTEX] = {
"ACPI_MTX_Events",
"ACPI_MTX_Caches",
"ACPI_MTX_Memory",
-   "ACPI_MTX_CommandComplete",
-   "ACPI_MTX_CommandReady"
 };
 
 char *acpi_ut_get_mutex_name(u32 mutex_id)
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c
index 37b8b58..ce406e3 100644
--- a/drivers/acpi/acpica/utmutex.c
+++ b/drivers/acpi/acpica/utmutex.c
@@ -108,6 +108,21 @@ acpi_status acpi_ut_mutex_initialize(void)
/* Create the reader/writer lock for namespace access */
 
status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock);
+   if (ACPI_FAILURE(status)) {
+   return_ACPI_STATUS(status);
+   }
+#ifdef ACPI_DEBUGGER
+
+   /* Debugger Support */
+
+   status = acpi_os_create_mutex(&acpi_gbl_db_command_ready);
+   if (ACPI_FAILURE(status)) {
+   return_ACPI_STATUS(status);
+   }
+
+   status = acpi_os_create_mutex(&acpi_gbl_db_command_complete);
+#endif
+
return_ACPI_STATUS(status);
 }
 
@@ -147,6 +162,12 @@ void acpi_ut_mutex_terminate(void)
/* Delete the reader/writer lock */
 
acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
+
+#ifdef ACPI_DEBUGGER
+   acpi_os_delete_mutex(acpi_gbl_db_command_ready);
+   acpi_os_delete_mutex(acpi_gbl_db_command_complete);
+#endif
+
return_VOID;
 }
 
diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h
index 15ef08c..056f245 100644
--- a/include/acpi/platform/acenv.h
+++ b/include/acpi/platform/acenv.h
@@ -304,11 +304,11 @@
  * multi-threaded if ACPI_APPLICATION is not set.
  */
 #ifndef DEBUGGER_THREADING
-#ifdef ACPI_APPLICATION
-#define DEBUGGER_THREADING  DEBUGGER_SINGLE_THREADED
+#if !defined (ACPI_APPLICATION) || defined (ACPI_EXEC_APP)
+#define DEBUGGER_THREADING  DEBUGGER_MULTI_THREADED
 
 #else
-#define DEBUGGER_THREADING  DEBUGGER_MULTI_THREADED
+#define DEBUGGER_THREADING  DEBUGGER_SINGLE_THREADED
 #endif
 #endif /* !DEBUGGER_THREADING */
 
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 02/14] ACPICA: iASL: Add symbolic operator support for Index() operator.

2015-10-18 Thread Lv Zheng
From: Bob Moore 

ACPICA commit fbe67c46830f10c839941f8512cac5bddcb86bd3

Index (, 2) is now supported by  [2]

This patch doesn't affect Linux kernel.

Link: https://github.com/acpica/acpica/commit/fbe67c46
Signed-off-by: Bob Moore 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/acpica/aclocal.h |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 6f70826..8a66fef 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -848,7 +848,7 @@ struct acpi_parse_state {
 #define ACPI_PARSEOP_PARAMLIST  0x02
 #define ACPI_PARSEOP_EMPTY_TERMLIST 0x04
 #define ACPI_PARSEOP_PREDEF_CHECKED 0x08
-#define ACPI_PARSEOP_SPECIAL0x10
+#define ACPI_PARSEOP_CLOSING_PAREN  0x10
 #define ACPI_PARSEOP_COMPOUND   0x20
 #define ACPI_PARSEOP_ASSIGNMENT 0x40
 
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 06/14] ACPICA: Improve typechecking, both compile-time and runtime

2015-10-18 Thread Lv Zheng
From: Bob Moore 

ACPICA commit 8d0f96e2a11a4ceabb2cae4b41e0ce1f4d3786b9

Adds much stricter typechecking in the iASL compiler, and
also adds some additional checking in the interpreter.

Link: https://github.com/acpica/acpica/commit/8d0f96e2
Signed-off-by: Bob Moore 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/acpica/aclocal.h  |8 ++-
 drivers/acpi/acpica/acopcode.h |4 +-
 drivers/acpi/acpica/amlcode.h  |   11 ++--
 drivers/acpi/acpica/exconvrt.c |1 +
 drivers/acpi/acpica/exresolv.c |1 -
 drivers/acpi/acpica/exresop.c  |2 +
 drivers/acpi/acpica/exstore.c  |  120 ++--
 drivers/acpi/acpica/exstoren.c |5 +-
 drivers/acpi/acpica/nspredef.c |2 +-
 drivers/acpi/acpica/utdecode.c |   19 ++-
 include/acpi/acexcep.h |7 ++-
 11 files changed, 134 insertions(+), 46 deletions(-)

diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 918f70d..4e41b43 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -285,13 +285,17 @@ acpi_status(*acpi_internal_method) (struct 
acpi_walk_state * walk_state);
 #define ACPI_BTYPE_BUFFER_FIELD 0x2000
 #define ACPI_BTYPE_DDB_HANDLE   0x4000
 #define ACPI_BTYPE_DEBUG_OBJECT 0x8000
-#define ACPI_BTYPE_REFERENCE0x0001
+#define ACPI_BTYPE_REFERENCE_OBJECT 0x0001 /* From Index(), 
ref_of(), etc (type6_opcodes) */
 #define ACPI_BTYPE_RESOURCE 0x0002
+#define ACPI_BTYPE_NAMED_REFERENCE  0x0004 /* Generic unresolved 
Name or Namepath */
 
 #define ACPI_BTYPE_COMPUTE_DATA (ACPI_BTYPE_INTEGER | 
ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER)
 
 #define ACPI_BTYPE_DATA (ACPI_BTYPE_COMPUTE_DATA  | 
ACPI_BTYPE_PACKAGE)
-#define ACPI_BTYPE_DATA_REFERENCE   (ACPI_BTYPE_DATA | 
ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE)
+
+   /* Used by Copy, de_ref_of, Store, Printf, Fprintf */
+
+#define ACPI_BTYPE_DATA_REFERENCE   (ACPI_BTYPE_DATA | 
ACPI_BTYPE_REFERENCE_OBJECT | ACPI_BTYPE_DDB_HANDLE)
 #define ACPI_BTYPE_DEVICE_OBJECTS   (ACPI_BTYPE_DEVICE | 
ACPI_BTYPE_THERMAL | ACPI_BTYPE_PROCESSOR)
 #define ACPI_BTYPE_OBJECTS_AND_REFS 0x0001 /* ARG or LOCAL */
 #define ACPI_BTYPE_ALL_OBJECTS  0x
diff --git a/drivers/acpi/acpica/acopcode.h b/drivers/acpi/acpica/acopcode.h
index fd85ad0..f9acf92 100644
--- a/drivers/acpi/acpica/acopcode.h
+++ b/drivers/acpi/acpica/acopcode.h
@@ -211,7 +211,7 @@
 #define ARGI_ARG4   ARG_NONE
 #define ARGI_ARG5   ARG_NONE
 #define ARGI_ARG6   ARG_NONE
-#define ARGI_BANK_FIELD_OP  ARGI_INVALID_OPCODE
+#define ARGI_BANK_FIELD_OP  ARGI_LIST1 (ARGI_INTEGER)
 #define ARGI_BIT_AND_OP ARGI_LIST3 (ARGI_INTEGER,
ARGI_INTEGER,   ARGI_TARGETREF)
 #define ARGI_BIT_NAND_OPARGI_LIST3 (ARGI_INTEGER,
ARGI_INTEGER,   ARGI_TARGETREF)
 #define ARGI_BIT_NOR_OP ARGI_LIST3 (ARGI_INTEGER,
ARGI_INTEGER,   ARGI_TARGETREF)
@@ -307,7 +307,7 @@
 #define ARGI_SLEEP_OP   ARGI_LIST1 (ARGI_INTEGER)
 #define ARGI_STALL_OP   ARGI_LIST1 (ARGI_INTEGER)
 #define ARGI_STATICSTRING_OPARGI_INVALID_OPCODE
-#define ARGI_STORE_OP   ARGI_LIST2 (ARGI_DATAREFOBJ, 
ARGI_TARGETREF)
+#define ARGI_STORE_OP   ARGI_LIST2 (ARGI_DATAREFOBJ, 
ARGI_STORE_TARGET)
 #define ARGI_STRING_OP  ARGI_INVALID_OPCODE
 #define ARGI_SUBTRACT_OPARGI_LIST3 (ARGI_INTEGER,
ARGI_INTEGER,   ARGI_TARGETREF)
 #define ARGI_THERMAL_ZONE_OPARGI_INVALID_OPCODE
diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h
index be9fd00..883f20c 100644
--- a/drivers/acpi/acpica/amlcode.h
+++ b/drivers/acpi/acpica/amlcode.h
@@ -277,14 +277,15 @@
 #define ARGI_TARGETREF  0x0F   /* Target, subject to implicit 
conversion */
 #define ARGI_FIXED_TARGET   0x10   /* Target, no implicit 
conversion */
 #define ARGI_SIMPLE_TARGET  0x11   /* Name, Local, Arg -- no 
implicit conversion */
+#define ARGI_STORE_TARGET   0x12   /* Target for store is 
TARGETREF + package objects */
 
 /* Multiple/complex types */
 
-#define ARGI_DATAOBJECT 0x12   /* Buffer, String, package or 
reference to a node - Used only by size_of operator */
-#define ARGI_COMPLEXOBJ 0x13   /* Buffer, String, or package 
(Used by INDEX op only) */
-#define ARGI_REF_OR_STRING  0x14   /* Reference or String (Used by 
DEREFOF op only) */
-#define ARGI_REGION_OR_BUFFER   0x15   /* Used by LOAD op only */
-#define ARGI_DATAREFOBJ 0x16
+#define ARGI_DATAOBJECT 0x13   /* Buffer, String, package or 
reference to a node - Used only by size_of operator */
+#define ARGI_COMPLEXOBJ 0x14

[PATCH v2 07/14] ACPICA: iASL: General cleanup of the file suffix #defines

2015-10-18 Thread Lv Zheng
From: Bob Moore 

ACPICA commit bed456ed2976bdaafdef406b982fdf6c539befc0

Removed some extraneous defines, reordered others.

Link: https://github.com/acpica/acpica/commit/bed456ed
Signed-off-by: Bob Moore 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/acpica/acapps.h  |2 +-
 tools/power/acpi/tools/acpidump/apfiles.c |2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/acpica/acapps.h b/drivers/acpi/acpica/acapps.h
index e9f0833..e4cc48f 100644
--- a/drivers/acpi/acpica/acapps.h
+++ b/drivers/acpi/acpica/acapps.h
@@ -88,7 +88,7 @@
acpi_os_printf (" %-18s%s\n", name, description);
 
 #define FILE_SUFFIX_DISASSEMBLY "dsl"
-#define ACPI_TABLE_FILE_SUFFIX  ".dat"
+#define FILE_SUFFIX_BINARY_TABLE".dat" /* Needs the dot */
 
 /*
  * getopt
diff --git a/tools/power/acpi/tools/acpidump/apfiles.c 
b/tools/power/acpi/tools/acpidump/apfiles.c
index a37f970..a1c62de 100644
--- a/tools/power/acpi/tools/acpidump/apfiles.c
+++ b/tools/power/acpi/tools/acpidump/apfiles.c
@@ -150,7 +150,7 @@ int ap_write_to_binary_file(struct acpi_table_header 
*table, u32 instance)
strcat(filename, instance_str);
}
 
-   strcat(filename, ACPI_TABLE_FILE_SUFFIX);
+   strcat(filename, FILE_SUFFIX_BINARY_TABLE);
 
if (gbl_verbose_mode) {
acpi_log_error
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 03/14] ACPICA: Update exception code for "file not found" error

2015-10-18 Thread Lv Zheng
From: Bob Moore 

ACPICA commit ac1564c26d239348ef13455f61d5616f3961ff43

Used by the ACPICA applications.

This patch is a bit broken due to non-portable  inclusion as on
some platforms, there is no such a header file for their lib-c exports.
Fortunately, Linux doesn't compile utfileio.c for either the kernel
space ACPICA core (drivers/acpi/acpica) or the userspace ACPICA tools
(tools/power/acpi) for now, so it's safe to leave this patch as it is.

Link: https://github.com/acpica/acpica/commit/ac1564c2
Signed-off-by: Bob Moore 
Signed-off-by: Lv Zheng 
---
 drivers/acpi/acpica/utfileio.c |6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/acpi/acpica/utfileio.c b/drivers/acpi/acpica/utfileio.c
index 75a94f5..d435b7b 100644
--- a/drivers/acpi/acpica/utfileio.c
+++ b/drivers/acpi/acpica/utfileio.c
@@ -45,6 +45,7 @@
 #include "accommon.h"
 #include "actables.h"
 #include "acapps.h"
+#include "errno.h"
 
 #ifdef ACPI_ASL_COMPILER
 #include "aslcompiler.h"
@@ -301,6 +302,11 @@ acpi_ut_read_table_from_file(char *filename, struct 
acpi_table_header ** table)
file = fopen(filename, "rb");
if (!file) {
perror("Could not open input file");
+
+   if (errno == ENOENT) {
+   return (AE_NOT_EXIST);
+   }
+
return (status);
}
 
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 10/14] ACPICA: Debugger: Fix "terminate" command by cleaning up subsystem shutdown logic

2015-10-18 Thread Lv Zheng
ACPICA commit 7e823714911480be47e310fb1b3590d289b9fd99

Segmentation fault can be seen for executing the "terminate" command. This
is because acpi_ut_subsystem_shutdown() is errnously called multiple times.

This patch cleans up acpi_ut_subsystem_shutdown() logics to fix this
issue. Lv Zheng.

Link: https://github.com/acpica/acpica/commit/7e823714
Signed-off-by: Lv Zheng 
Signed-off-by: Bob Moore 
---
 drivers/acpi/acpica/dbinput.c |3 ++-
 drivers/acpi/acpica/utinit.c  |   13 +
 drivers/acpi/acpica/utxface.c |   13 -
 3 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/acpi/acpica/dbinput.c b/drivers/acpi/acpica/dbinput.c
index f8cddd6..0480254 100644
--- a/drivers/acpi/acpica/dbinput.c
+++ b/drivers/acpi/acpica/dbinput.c
@@ -1074,6 +1074,7 @@ acpi_db_command_dispatch(char *input_buffer,
 * re-creating the semaphores!
 */
 
+   acpi_gbl_db_terminate_loop = TRUE;
/*  acpi_initialize (NULL); */
break;
 
@@ -1151,7 +1152,7 @@ void ACPI_SYSTEM_XFACE acpi_db_execute_thread(void 
*context)
acpi_status status = AE_OK;
acpi_status Mstatus;
 
-   while (status != AE_CTRL_TERMINATE) {
+   while (status != AE_CTRL_TERMINATE && !acpi_gbl_db_terminate_loop) {
acpi_gbl_method_executing = FALSE;
acpi_gbl_step_to_next_call = FALSE;
 
diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c
index d8699df..ccd0745 100644
--- a/drivers/acpi/acpica/utinit.c
+++ b/drivers/acpi/acpica/utinit.c
@@ -282,6 +282,19 @@ void acpi_ut_subsystem_shutdown(void)
 {
ACPI_FUNCTION_TRACE(ut_subsystem_shutdown);
 
+   /* Just exit if subsystem is already shutdown */
+
+   if (acpi_gbl_shutdown) {
+   ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated"));
+   return_VOID;
+   }
+
+   /* Subsystem appears active, go ahead and shut it down */
+
+   acpi_gbl_shutdown = TRUE;
+   acpi_gbl_startup_flags = 0;
+   ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n"));
+
 #ifndef ACPI_ASL_COMPILER
 
/* Close the acpi_event Handling */
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c
index f183daf..a6b0eb0 100644
--- a/drivers/acpi/acpica/utxface.c
+++ b/drivers/acpi/acpica/utxface.c
@@ -67,19 +67,6 @@ acpi_status __init acpi_terminate(void)
 
ACPI_FUNCTION_TRACE(acpi_terminate);
 
-   /* Just exit if subsystem is already shutdown */
-
-   if (acpi_gbl_shutdown) {
-   ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated"));
-   return_ACPI_STATUS(AE_OK);
-   }
-
-   /* Subsystem appears active, go ahead and shut it down */
-
-   acpi_gbl_shutdown = TRUE;
-   acpi_gbl_startup_flags = 0;
-   ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n"));
-
/* Shutdown and free all resources */
 
acpi_ut_subsystem_shutdown();
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 12/14] ACPI: Enable build of AML interpreter debugger

2015-10-18 Thread Lv Zheng
This patch enables ACPICA debugger files using a configurable
CONFIG_ACPI_DEBUGGER configuration item. Those debugger related code that
was originally masked as ACPI_FUTURE_USAGE now gets unmasked.

Necessary OSL stubs are also added in this patch:
1. acpi_os_readable(): This should be arch specific in Linux, while this
patch doesn't introduce real implementation and a complex mechanism to
allow architecture specific acpi_os_readable() to be implemented to
validate the address. It may be done by future commits.
2. acpi_os_get_line(): This is used to obtain debugger command input. This
patch only introduces a simple KDB concept example in it and the
example should be co-working with the code implemented in
acpi_os_printf(). Since this KDB example won't be compiled unless
ENABLE_DEBUGGER is defined and it seems Linux has already stopped to
use ENABLE_DEBUGGER, thus do not expect it can work properly.

This patch also cleans up all other ACPI_FUTURE_USAGE surroundings
accordingly.
1. Since linkage error can be automatically detected, declaration in the
   headers needn't be surrounded by ACPI_FUTURE_USAGE.
   So only the following separate exported fuction bodies are masked by
   this macro (other exported fucntions may have already been masked at
   entire module level via drivers/acpi/acpica/Makefile):
 acpi_install_exception_handler()
 acpi_subsystem_status()
 acpi_get_system_info()
 acpi_get_statistics()
 acpi_install_initialization_handler()
2. Since strip can automatically zap the no-user functions, functions that
   are not marked with ACPI_EXPORT_SYMBOL() needn't get surrounded by
   ACPI_FUTURE_USAGE.
   So the following function which is not used by Linux kernel now won't
   get surrounded by this macro:
 acpi_ps_get_name()

Signed-off-by: Lv Zheng 
---
 drivers/acpi/Kconfig  |9 +
 drivers/acpi/acpica/Makefile  |   18 +-
 drivers/acpi/acpica/acinterp.h|2 --
 drivers/acpi/acpica/acnamesp.h|4 
 drivers/acpi/acpica/acparser.h|4 
 drivers/acpi/acpica/acutils.h |2 --
 drivers/acpi/acpica/evxface.c |2 +-
 drivers/acpi/acpica/nsdump.c  |6 --
 drivers/acpi/acpica/pstree.c  |2 --
 drivers/acpi/acpica/psutils.c |2 --
 drivers/acpi/acpica/rsutils.c |2 --
 drivers/acpi/acpica/rsxface.c |4 ++--
 drivers/acpi/acpica/utxface.c |2 +-
 drivers/acpi/osl.c|   11 +++
 include/acpi/acpixf.h |   10 --
 include/acpi/platform/aclinux.h   |7 +--
 include/acpi/platform/aclinuxex.h |5 +
 17 files changed, 43 insertions(+), 49 deletions(-)

diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 5d1015c..706c2e9 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -57,6 +57,15 @@ config ACPI_SYSTEM_POWER_STATES_SUPPORT
 config ACPI_CCA_REQUIRED
bool
 
+config ACPI_DEBUGGER
+   bool "In-kernel debugger (EXPERIMENTAL)"
+   select ACPI_DEBUG
+   help
+ Enable in-kernel debugging facilities: statistics, internal
+ object dump, single step control method execution.
+ This is still under development, currently enabling this only
+ results in the compilation of the ACPICA debugger files.
+
 config ACPI_SLEEP
bool
depends on SUSPEND || HIBERNATION
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
index ac78d76..885936f 100644
--- a/drivers/acpi/acpica/Makefile
+++ b/drivers/acpi/acpica/Makefile
@@ -177,8 +177,24 @@ acpi-y +=  \
utxferror.o \
utxfmutex.o
 
-acpi-$(ACPI_FUTURE_USAGE) +=   \
+acpi-$(CONFIG_ACPI_DEBUGGER) +=\
+   dbcmds.o\
+   dbconvert.o \
+   dbdisply.o  \
+   dbexec.o\
+   dbhistry.o  \
+   dbinput.o   \
+   dbmethod.o  \
+   dbnames.o   \
+   dbobject.o  \
+   dbstats.o   \
+   dbutils.o   \
+   dbxface.o   \
rsdump.o\
+
+acpi-$(ACPI_FUTURE_USAGE) +=   \
+   dbfileio.o  \
+   dbtest.o\
utcache.o   \
utfileio.o  \
utprint.o   \
diff --git a/drivers/acpi/acpica/acinterp.h b/drivers/acpi/acpica/acinterp.h
index e820ed8..e9e936e 100644
--- a/drivers/acpi/acpica/acinterp.h
+++ b/drivers/acpi/acpica/acinterp.h
@@ -397,12 +397,10 @@ void
 acpi_ex_dump_operands(union acpi_operand_object **operands,
  const char *opcode_name, u32 num_opcodes);
 
-#ifdef ACPI_FUTURE_USAGE
 void
 acpi_ex_dump_object_descriptor(union acpi_operand_object *object, u32 flags);
 
 void acpi_ex_dump_namespace_node(struct acpi_namespace_node *node, u32 flags);
-#endif  

[PATCH v2 11/14] ACPICA: Debugger: Add thread ID support so that single step mode can only apply to the debugger thread

2015-10-18 Thread Lv Zheng
When the debugger is running in the kernel mode, acpi_db_single_step() may
also be invoked by the kernel runtime code path but the single stepping
command prompt may be erronously logged as the kernel logs and runtime code
path cannot proceed.

This patch fixes this issue by adding acpi_gbl_db_thread_id for the debugger
thread and preventing acpi_db_single_step() to be invoked from other threads.

It is not suitable to add acpi_thread_id parameter for acpi_os_execute() as
the function may be implemented as work queue on some hosts. So it is
better to let the hosts invoke acpi_set_debugger_thread_id(). Currently
acpiexec is not configured as DEBUGGER_MULTI_THREADED, but we can do this.
When we do this, it is better to invoke acpi_set_debugger_thread_id() in
acpi_os_execute() when the execution type is OSL_DEBUGGER_MAIN_THREAD. The
support should look like:
  create_thread(&tid);
  if (type == OSL_DEBUGGER_MAIN_THREAD)
  acpi_set_debugger_thread_id(tid);
  resume_thread(tid);
Similarly, semop() may be used for pthread implementation. But this patch
simply skips debugger thread ID check for application instead of
introducing such complications as there is no need to skip
acpi_db_single_step() for an application debugger - acpiexec.

Note that the debugger thread ID can also be used by acpi_os_printf() to
filter out debugger output. Lv Zheng.

Signed-off-by: Lv Zheng 
---
 drivers/acpi/acpica/acglobal.h |1 +
 drivers/acpi/acpica/aclocal.h  |8 
 drivers/acpi/acpica/dbexec.c   |3 ++-
 drivers/acpi/acpica/dbxface.c  |   28 +++-
 include/acpi/acpiosxf.h|3 ++-
 include/acpi/acpixf.h  |2 ++
 6 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index d82249c..fdef15f 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -326,6 +326,7 @@ ACPI_GLOBAL(struct acpi_external_file *, 
acpi_gbl_external_file_list);
 
 ACPI_INIT_GLOBAL(u8, acpi_gbl_abort_method, FALSE);
 ACPI_INIT_GLOBAL(u8, acpi_gbl_method_executing, FALSE);
+ACPI_INIT_GLOBAL(acpi_thread_id, acpi_gbl_db_thread_id, 
ACPI_INVALID_THREAD_ID);
 
 ACPI_GLOBAL(u8, acpi_gbl_db_opt_no_ini_methods);
 ACPI_GLOBAL(u8, acpi_gbl_db_opt_no_region_support);
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 4e41b43..e1dd784 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -109,6 +109,14 @@ struct acpi_rw_lock {
 
 #define ACPI_MUTEX_NOT_ACQUIRED (acpi_thread_id) 0
 
+/* This Thread ID means an invalid thread ID */
+
+#ifdef ACPI_OS_INVALID_THREAD_ID
+#define ACPI_INVALID_THREAD_ID  ACPI_OS_INVALID_THREAD_ID
+#else
+#define ACPI_INVALID_THREAD_ID  ((acpi_thread_id) 0x)
+#endif
+
 /* Table for the global mutexes */
 
 struct acpi_mutex_info {
diff --git a/drivers/acpi/acpica/dbexec.c b/drivers/acpi/acpica/dbexec.c
index 8eef298..258e615 100644
--- a/drivers/acpi/acpica/dbexec.c
+++ b/drivers/acpi/acpica/dbexec.c
@@ -725,7 +725,8 @@ acpi_db_create_execution_threads(char *num_threads_arg,
 
for (i = 0; i < (num_threads); i++) {
status =
-   acpi_os_execute(OSL_DEBUGGER_THREAD, acpi_db_method_thread,
+   acpi_os_execute(OSL_DEBUGGER_EXEC_THREAD,
+   acpi_db_method_thread,
&acpi_gbl_db_method_info);
if (ACPI_FAILURE(status)) {
break;
diff --git a/drivers/acpi/acpica/dbxface.c b/drivers/acpi/acpica/dbxface.c
index bef5f4e..342298a 100644
--- a/drivers/acpi/acpica/dbxface.c
+++ b/drivers/acpi/acpica/dbxface.c
@@ -164,6 +164,12 @@ acpi_db_single_step(struct acpi_walk_state * walk_state,
 
ACPI_FUNCTION_ENTRY();
 
+#ifndef ACPI_APPLICATION
+   if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
+   return (AE_OK);
+   }
+#endif
+
/* Check the abort flag */
 
if (acpi_gbl_abort_method) {
@@ -431,7 +437,7 @@ acpi_status acpi_initialize_debugger(void)
/* Create the debug execution thread to execute commands */
 
acpi_gbl_db_threads_terminated = FALSE;
-   status = acpi_os_execute(OSL_DEBUGGER_THREAD,
+   status = acpi_os_execute(OSL_DEBUGGER_MAIN_THREAD,
 acpi_db_execute_thread, NULL);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
@@ -439,6 +445,8 @@ acpi_status acpi_initialize_debugger(void)
acpi_gbl_db_threads_terminated = TRUE;
return_ACPI_STATUS(status);
}
+   } else {
+   acpi_gbl_db_thread_id = acpi_os_get_thread_id();
}
 
return_ACPI_STATUS(AE_OK);
@@ -485,3 +493,21 @@ void acpi_terminate_debugger(void)
 }
 
 ACPI_EXPORT_SYMBOL(acpi_termina

[PATCH v2 14/14] ACPICA: Update version to 20150930

2015-10-18 Thread Lv Zheng
From: Bob Moore 

ACPICA commit e9c75ca267262326e80d49a290e8387a5963e2d2

Version 20150930.

Link: https://github.com/acpica/acpica/commit/e9c75ca2
Signed-off-by: Bob Moore 
Signed-off-by: Lv Zheng 
---
 include/acpi/acpixf.h |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index ded9fa3..386 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -46,7 +46,7 @@
 
 /* Current ACPICA subsystem version in MMDD format */
 
-#define ACPI_CA_VERSION 0x20150818
+#define ACPI_CA_VERSION 0x20150930
 
 #include 
 #include 
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 13/14] ACPICA: Debugger: Fix dead lock issue ocurred in single stepping mode

2015-10-18 Thread Lv Zheng
ACPICA commit 35273add90da19cd8790fdb5735f52e3c9861684

When single step execution is not ended, executing another control methods
leads to dead locks around interpreter lock/namespace lock/method
serialization lock. So we should only allow one execution from the debugger
at same time. Lv Zheng.

Link: https://github.com/acpica/acpica/commit/35273add
Signed-off-by: Lv Zheng 
Signed-off-by: Bob Moore 
---
 drivers/acpi/acpica/dbexec.c |   10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/acpi/acpica/dbexec.c b/drivers/acpi/acpica/dbexec.c
index 258e615..d713e2d 100644
--- a/drivers/acpi/acpica/dbexec.c
+++ b/drivers/acpi/acpica/dbexec.c
@@ -370,7 +370,17 @@ acpi_db_execute(char *name, char **args, acpi_object_type 
* types, u32 flags)
 #ifdef ACPI_DEBUG_OUTPUT
u32 previous_allocations;
u32 allocations;
+#endif
 
+   /*
+* Allow one execution to be performed by debugger or single step
+* execution will be dead locked by the interpreter mutexes.
+*/
+   if (acpi_gbl_method_executing) {
+   acpi_os_printf("Only one debugger execution is allowed.\n");
+   return;
+   }
+#ifdef ACPI_DEBUG_OUTPUT
/* Memory allocation tracking */
 
previous_allocations = acpi_db_get_outstanding_allocations();
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


  1   2   3   4   5   6   7   8   9   10   >