aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/ac.c2
-rw-r--r--drivers/acpi/acpica/acconfig.h2
-rw-r--r--drivers/acpi/acpica/acglobal.h6
-rw-r--r--drivers/acpi/acpica/aclocal.h1
-rw-r--r--drivers/acpi/acpica/acpredef.h1
-rw-r--r--drivers/acpi/acpica/evxface.c1
-rw-r--r--drivers/acpi/acpica/evxfevnt.c1
-rw-r--r--drivers/acpi/acpica/evxfgpe.c1
-rw-r--r--drivers/acpi/acpica/evxfregn.c1
-rw-r--r--drivers/acpi/acpica/hwsleep.c1
-rw-r--r--drivers/acpi/acpica/hwtimer.c1
-rw-r--r--drivers/acpi/acpica/hwxface.c1
-rw-r--r--drivers/acpi/acpica/nspredef.c19
-rw-r--r--drivers/acpi/acpica/nsrepair2.c15
-rw-r--r--drivers/acpi/acpica/nsxfeval.c1
-rw-r--r--drivers/acpi/acpica/nsxfname.c1
-rw-r--r--drivers/acpi/acpica/nsxfobj.c1
-rw-r--r--drivers/acpi/acpica/rsxface.c1
-rw-r--r--drivers/acpi/acpica/tbinstal.c27
-rw-r--r--drivers/acpi/acpica/tbxface.c1
-rw-r--r--drivers/acpi/acpica/utdebug.c1
-rw-r--r--drivers/acpi/acpica/utdecode.c1
-rw-r--r--drivers/acpi/acpica/utglobal.c1
-rw-r--r--drivers/acpi/acpica/utxface.c1
-rw-r--r--drivers/acpi/acpica/utxferror.c1
-rw-r--r--drivers/acpi/apei/Kconfig11
-rw-r--r--drivers/acpi/apei/apei-base.c35
-rw-r--r--drivers/acpi/apei/apei-internal.h15
-rw-r--r--drivers/acpi/apei/einj.c43
-rw-r--r--drivers/acpi/apei/erst-dbg.c6
-rw-r--r--drivers/acpi/apei/erst.c40
-rw-r--r--drivers/acpi/apei/ghes.c451
-rw-r--r--drivers/acpi/apei/hest.c17
-rw-r--r--drivers/acpi/atomicio.c2
-rw-r--r--drivers/acpi/battery.c88
-rw-r--r--drivers/acpi/blacklist.c1
-rw-r--r--drivers/acpi/bus.c14
-rw-r--r--drivers/acpi/debugfs.c1
-rw-r--r--drivers/acpi/dock.c4
-rw-r--r--drivers/acpi/ec_sys.c3
-rw-r--r--drivers/acpi/event.c1
-rw-r--r--drivers/acpi/fan.c2
-rw-r--r--drivers/acpi/glue.c1
-rw-r--r--drivers/acpi/osl.c28
-rw-r--r--drivers/acpi/pci_irq.c58
-rw-r--r--drivers/acpi/pci_root.c3
-rw-r--r--drivers/acpi/proc.c1
-rw-r--r--drivers/acpi/processor_core.c1
-rw-r--r--drivers/acpi/processor_idle.c12
-rw-r--r--drivers/acpi/processor_thermal.c2
-rw-r--r--drivers/acpi/sbs.c15
-rw-r--r--drivers/acpi/sbshc.c1
-rw-r--r--drivers/acpi/sleep.c48
-rw-r--r--drivers/acpi/sysfs.c4
-rw-r--r--drivers/acpi/thermal.c2
-rw-r--r--drivers/acpi/video.c9
-rw-r--r--drivers/acpi/video_detect.c1
57 files changed, 848 insertions, 162 deletions
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 58c3f74bd84c..6512b20aeccd 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -89,7 +89,7 @@ struct acpi_ac {
89 unsigned long long state; 89 unsigned long long state;
90}; 90};
91 91
92#define to_acpi_ac(x) container_of(x, struct acpi_ac, charger); 92#define to_acpi_ac(x) container_of(x, struct acpi_ac, charger)
93 93
94#ifdef CONFIG_ACPI_PROCFS_POWER 94#ifdef CONFIG_ACPI_PROCFS_POWER
95static const struct file_operations acpi_ac_fops = { 95static const struct file_operations acpi_ac_fops = {
diff --git a/drivers/acpi/acpica/acconfig.h b/drivers/acpi/acpica/acconfig.h
index bc533dde16c4..f895a244ca7e 100644
--- a/drivers/acpi/acpica/acconfig.h
+++ b/drivers/acpi/acpica/acconfig.h
@@ -121,7 +121,7 @@
121 121
122/* Maximum sleep allowed via Sleep() operator */ 122/* Maximum sleep allowed via Sleep() operator */
123 123
124#define ACPI_MAX_SLEEP 20000 /* Two seconds */ 124#define ACPI_MAX_SLEEP 2000 /* Two seconds */
125 125
126/****************************************************************************** 126/******************************************************************************
127 * 127 *
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index 73863d86f022..76dc02f15574 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -126,6 +126,12 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_copy_dsdt_locally, FALSE);
126 */ 126 */
127u8 ACPI_INIT_GLOBAL(acpi_gbl_truncate_io_addresses, FALSE); 127u8 ACPI_INIT_GLOBAL(acpi_gbl_truncate_io_addresses, FALSE);
128 128
129/*
130 * Disable runtime checking and repair of values returned by control methods.
131 * Use only if the repair is causing a problem on a particular machine.
132 */
133u8 ACPI_INIT_GLOBAL(acpi_gbl_disable_auto_repair, FALSE);
134
129/* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */ 135/* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */
130 136
131struct acpi_table_fadt acpi_gbl_FADT; 137struct acpi_table_fadt acpi_gbl_FADT;
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index c7f743ca395b..5552125d8340 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -357,6 +357,7 @@ struct acpi_predefined_data {
357 char *pathname; 357 char *pathname;
358 const union acpi_predefined_info *predefined; 358 const union acpi_predefined_info *predefined;
359 union acpi_operand_object *parent_package; 359 union acpi_operand_object *parent_package;
360 struct acpi_namespace_node *node;
360 u32 flags; 361 u32 flags;
361 u8 node_flags; 362 u8 node_flags;
362}; 363};
diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h
index 94e73c97cf85..c445cca490ea 100644
--- a/drivers/acpi/acpica/acpredef.h
+++ b/drivers/acpi/acpica/acpredef.h
@@ -468,6 +468,7 @@ static const union acpi_predefined_info predefined_names[] =
468 {{"_SWS", 0, ACPI_RTYPE_INTEGER}}, 468 {{"_SWS", 0, ACPI_RTYPE_INTEGER}},
469 {{"_TC1", 0, ACPI_RTYPE_INTEGER}}, 469 {{"_TC1", 0, ACPI_RTYPE_INTEGER}},
470 {{"_TC2", 0, ACPI_RTYPE_INTEGER}}, 470 {{"_TC2", 0, ACPI_RTYPE_INTEGER}},
471 {{"_TDL", 0, ACPI_RTYPE_INTEGER}},
471 {{"_TIP", 1, ACPI_RTYPE_INTEGER}}, 472 {{"_TIP", 1, ACPI_RTYPE_INTEGER}},
472 {{"_TIV", 1, ACPI_RTYPE_INTEGER}}, 473 {{"_TIV", 1, ACPI_RTYPE_INTEGER}},
473 {{"_TMP", 0, ACPI_RTYPE_INTEGER}}, 474 {{"_TMP", 0, ACPI_RTYPE_INTEGER}},
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c
index e1141402dbed..f4f523bf5939 100644
--- a/drivers/acpi/acpica/evxface.c
+++ b/drivers/acpi/acpica/evxface.c
@@ -41,6 +41,7 @@
41 * POSSIBILITY OF SUCH DAMAGES. 41 * POSSIBILITY OF SUCH DAMAGES.
42 */ 42 */
43 43
44#include <linux/export.h>
44#include <acpi/acpi.h> 45#include <acpi/acpi.h>
45#include "accommon.h" 46#include "accommon.h"
46#include "acnamesp.h" 47#include "acnamesp.h"
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index c57b5c707a77..20516e599476 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -41,6 +41,7 @@
41 * POSSIBILITY OF SUCH DAMAGES. 41 * POSSIBILITY OF SUCH DAMAGES.
42 */ 42 */
43 43
44#include <linux/export.h>
44#include <acpi/acpi.h> 45#include <acpi/acpi.h>
45#include "accommon.h" 46#include "accommon.h"
46#include "actables.h" 47#include "actables.h"
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c
index 52aaff3df562..f06a3ee356ba 100644
--- a/drivers/acpi/acpica/evxfgpe.c
+++ b/drivers/acpi/acpica/evxfgpe.c
@@ -41,6 +41,7 @@
41 * POSSIBILITY OF SUCH DAMAGES. 41 * POSSIBILITY OF SUCH DAMAGES.
42 */ 42 */
43 43
44#include <linux/export.h>
44#include <acpi/acpi.h> 45#include <acpi/acpi.h>
45#include "accommon.h" 46#include "accommon.h"
46#include "acevents.h" 47#include "acevents.h"
diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c
index 00cd95692a91..aee887e3ca5c 100644
--- a/drivers/acpi/acpica/evxfregn.c
+++ b/drivers/acpi/acpica/evxfregn.c
@@ -42,6 +42,7 @@
42 * POSSIBILITY OF SUCH DAMAGES. 42 * POSSIBILITY OF SUCH DAMAGES.
43 */ 43 */
44 44
45#include <linux/export.h>
45#include <acpi/acpi.h> 46#include <acpi/acpi.h>
46#include "accommon.h" 47#include "accommon.h"
47#include "acnamesp.h" 48#include "acnamesp.h"
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c
index 2ac28bbe8827..d52da3073650 100644
--- a/drivers/acpi/acpica/hwsleep.c
+++ b/drivers/acpi/acpica/hwsleep.c
@@ -46,6 +46,7 @@
46#include "accommon.h" 46#include "accommon.h"
47#include "actables.h" 47#include "actables.h"
48#include <linux/tboot.h> 48#include <linux/tboot.h>
49#include <linux/module.h>
49 50
50#define _COMPONENT ACPI_HARDWARE 51#define _COMPONENT ACPI_HARDWARE
51ACPI_MODULE_NAME("hwsleep") 52ACPI_MODULE_NAME("hwsleep")
diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c
index 9c8eb71a12fb..50d21c40b5c1 100644
--- a/drivers/acpi/acpica/hwtimer.c
+++ b/drivers/acpi/acpica/hwtimer.c
@@ -42,6 +42,7 @@
42 * POSSIBILITY OF SUCH DAMAGES. 42 * POSSIBILITY OF SUCH DAMAGES.
43 */ 43 */
44 44
45#include <linux/export.h>
45#include <acpi/acpi.h> 46#include <acpi/acpi.h>
46#include "accommon.h" 47#include "accommon.h"
47 48
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c
index f75f81ad15c9..c2793a82f120 100644
--- a/drivers/acpi/acpica/hwxface.c
+++ b/drivers/acpi/acpica/hwxface.c
@@ -42,6 +42,7 @@
42 * POSSIBILITY OF SUCH DAMAGES. 42 * POSSIBILITY OF SUCH DAMAGES.
43 */ 43 */
44 44
45#include <linux/export.h>
45#include <acpi/acpi.h> 46#include <acpi/acpi.h>
46#include "accommon.h" 47#include "accommon.h"
47#include "acnamesp.h" 48#include "acnamesp.h"
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c
index 9fb03fa8ffde..c845c8089f39 100644
--- a/drivers/acpi/acpica/nspredef.c
+++ b/drivers/acpi/acpica/nspredef.c
@@ -193,14 +193,20 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
193 } 193 }
194 194
195 /* 195 /*
196 * 1) We have a return value, but if one wasn't expected, just exit, this is 196 * Return value validation and possible repair.
197 * not a problem. For example, if the "Implicit Return" feature is
198 * enabled, methods will always return a value.
199 * 197 *
200 * 2) If the return value can be of any type, then we cannot perform any 198 * 1) Don't perform return value validation/repair if this feature
201 * validation, exit. 199 * has been disabled via a global option.
200 *
201 * 2) We have a return value, but if one wasn't expected, just exit,
202 * this is not a problem. For example, if the "Implicit Return"
203 * feature is enabled, methods will always return a value.
204 *
205 * 3) If the return value can be of any type, then we cannot perform
206 * any validation, just exit.
202 */ 207 */
203 if ((!predefined->info.expected_btypes) || 208 if (acpi_gbl_disable_auto_repair ||
209 (!predefined->info.expected_btypes) ||
204 (predefined->info.expected_btypes == ACPI_RTYPE_ALL)) { 210 (predefined->info.expected_btypes == ACPI_RTYPE_ALL)) {
205 goto cleanup; 211 goto cleanup;
206 } 212 }
@@ -212,6 +218,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
212 goto cleanup; 218 goto cleanup;
213 } 219 }
214 data->predefined = predefined; 220 data->predefined = predefined;
221 data->node = node;
215 data->node_flags = node->flags; 222 data->node_flags = node->flags;
216 data->pathname = pathname; 223 data->pathname = pathname;
217 224
diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c
index 973883babee1..024c4f263f87 100644
--- a/drivers/acpi/acpica/nsrepair2.c
+++ b/drivers/acpi/acpica/nsrepair2.c
@@ -503,6 +503,21 @@ acpi_ns_repair_TSS(struct acpi_predefined_data *data,
503{ 503{
504 union acpi_operand_object *return_object = *return_object_ptr; 504 union acpi_operand_object *return_object = *return_object_ptr;
505 acpi_status status; 505 acpi_status status;
506 struct acpi_namespace_node *node;
507
508 /*
509 * We can only sort the _TSS return package if there is no _PSS in the
510 * same scope. This is because if _PSS is present, the ACPI specification
511 * dictates that the _TSS Power Dissipation field is to be ignored, and
512 * therefore some BIOSs leave garbage values in the _TSS Power field(s).
513 * In this case, it is best to just return the _TSS package as-is.
514 * (May, 2011)
515 */
516 status =
517 acpi_ns_get_node(data->node, "^_PSS", ACPI_NS_NO_UPSEARCH, &node);
518 if (ACPI_SUCCESS(status)) {
519 return (AE_OK);
520 }
506 521
507 status = acpi_ns_check_sorted_list(data, return_object, 5, 1, 522 status = acpi_ns_check_sorted_list(data, return_object, 5, 1,
508 ACPI_SORT_DESCENDING, 523 ACPI_SORT_DESCENDING,
diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c
index c53f0040e490..e7f016d1b226 100644
--- a/drivers/acpi/acpica/nsxfeval.c
+++ b/drivers/acpi/acpica/nsxfeval.c
@@ -42,6 +42,7 @@
42 * POSSIBILITY OF SUCH DAMAGES. 42 * POSSIBILITY OF SUCH DAMAGES.
43 */ 43 */
44 44
45#include <linux/export.h>
45#include <acpi/acpi.h> 46#include <acpi/acpi.h>
46#include "accommon.h" 47#include "accommon.h"
47#include "acnamesp.h" 48#include "acnamesp.h"
diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c
index 3fd4526f3dba..83bf93024303 100644
--- a/drivers/acpi/acpica/nsxfname.c
+++ b/drivers/acpi/acpica/nsxfname.c
@@ -42,6 +42,7 @@
42 * POSSIBILITY OF SUCH DAMAGES. 42 * POSSIBILITY OF SUCH DAMAGES.
43 */ 43 */
44 44
45#include <linux/export.h>
45#include <acpi/acpi.h> 46#include <acpi/acpi.h>
46#include "accommon.h" 47#include "accommon.h"
47#include "acnamesp.h" 48#include "acnamesp.h"
diff --git a/drivers/acpi/acpica/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c
index db7660f8b869..57e6d825ed84 100644
--- a/drivers/acpi/acpica/nsxfobj.c
+++ b/drivers/acpi/acpica/nsxfobj.c
@@ -42,6 +42,7 @@
42 * POSSIBILITY OF SUCH DAMAGES. 42 * POSSIBILITY OF SUCH DAMAGES.
43 */ 43 */
44 44
45#include <linux/export.h>
45#include <acpi/acpi.h> 46#include <acpi/acpi.h>
46#include "accommon.h" 47#include "accommon.h"
47#include "acnamesp.h" 48#include "acnamesp.h"
diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c
index 2ff657a28f26..fe86b37b16ce 100644
--- a/drivers/acpi/acpica/rsxface.c
+++ b/drivers/acpi/acpica/rsxface.c
@@ -41,6 +41,7 @@
41 * POSSIBILITY OF SUCH DAMAGES. 41 * POSSIBILITY OF SUCH DAMAGES.
42 */ 42 */
43 43
44#include <linux/export.h>
44#include <acpi/acpi.h> 45#include <acpi/acpi.h>
45#include "accommon.h" 46#include "accommon.h"
46#include "acresrc.h" 47#include "acresrc.h"
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 48db0944ce4a..62365f6075dd 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -126,12 +126,29 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
126 } 126 }
127 127
128 /* 128 /*
129 * Originally, we checked the table signature for "SSDT" or "PSDT" here. 129 * Validate the incoming table signature.
130 * Next, we added support for OEMx tables, signature "OEM". 130 *
131 * Valid tables were encountered with a null signature, so we've just 131 * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
132 * given up on validating the signature, since it seems to be a waste 132 * 2) We added support for OEMx tables, signature "OEM".
133 * of code. The original code was removed (05/2008). 133 * 3) Valid tables were encountered with a null signature, so we just
134 * gave up on validating the signature, (05/2008).
135 * 4) We encountered non-AML tables such as the MADT, which caused
136 * interpreter errors and kernel faults. So now, we once again allow
137 * only "SSDT", "OEMx", and now, also a null signature. (05/2011).
134 */ 138 */
139 if ((table_desc->pointer->signature[0] != 0x00) &&
140 (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT))
141 && (ACPI_STRNCMP(table_desc->pointer->signature, "OEM", 3))) {
142 ACPI_ERROR((AE_INFO,
143 "Table has invalid signature [%4.4s] (0x%8.8X), must be SSDT or OEMx",
144 acpi_ut_valid_acpi_name(*(u32 *)table_desc->
145 pointer->
146 signature) ? table_desc->
147 pointer->signature : "????",
148 *(u32 *)table_desc->pointer->signature));
149
150 return_ACPI_STATUS(AE_BAD_SIGNATURE);
151 }
135 152
136 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 153 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
137 154
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index 4b7085dfc683..e7d13f5d3f2d 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -42,6 +42,7 @@
42 * POSSIBILITY OF SUCH DAMAGES. 42 * POSSIBILITY OF SUCH DAMAGES.
43 */ 43 */
44 44
45#include <linux/export.h>
45#include <acpi/acpi.h> 46#include <acpi/acpi.h>
46#include "accommon.h" 47#include "accommon.h"
47#include "acnamesp.h" 48#include "acnamesp.h"
diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c
index a9bcd816dc29..a1f8d7509e66 100644
--- a/drivers/acpi/acpica/utdebug.c
+++ b/drivers/acpi/acpica/utdebug.c
@@ -41,6 +41,7 @@
41 * POSSIBILITY OF SUCH DAMAGES. 41 * POSSIBILITY OF SUCH DAMAGES.
42 */ 42 */
43 43
44#include <linux/export.h>
44#include <acpi/acpi.h> 45#include <acpi/acpi.h>
45#include "accommon.h" 46#include "accommon.h"
46 47
diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c
index 97cb36f85ce9..8b087e2d64f4 100644
--- a/drivers/acpi/acpica/utdecode.c
+++ b/drivers/acpi/acpica/utdecode.c
@@ -41,6 +41,7 @@
41 * POSSIBILITY OF SUCH DAMAGES. 41 * POSSIBILITY OF SUCH DAMAGES.
42 */ 42 */
43 43
44#include <linux/export.h>
44#include <acpi/acpi.h> 45#include <acpi/acpi.h>
45#include "accommon.h" 46#include "accommon.h"
46#include "acnamesp.h" 47#include "acnamesp.h"
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c
index 833a38a9c905..ffba0a39c3e8 100644
--- a/drivers/acpi/acpica/utglobal.c
+++ b/drivers/acpi/acpica/utglobal.c
@@ -43,6 +43,7 @@
43 43
44#define DEFINE_ACPI_GLOBALS 44#define DEFINE_ACPI_GLOBALS
45 45
46#include <linux/export.h>
46#include <acpi/acpi.h> 47#include <acpi/acpi.h>
47#include "accommon.h" 48#include "accommon.h"
48 49
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c
index 98ad125e14ff..420ebfe08c72 100644
--- a/drivers/acpi/acpica/utxface.c
+++ b/drivers/acpi/acpica/utxface.c
@@ -41,6 +41,7 @@
41 * POSSIBILITY OF SUCH DAMAGES. 41 * POSSIBILITY OF SUCH DAMAGES.
42 */ 42 */
43 43
44#include <linux/export.h>
44#include <acpi/acpi.h> 45#include <acpi/acpi.h>
45#include "accommon.h" 46#include "accommon.h"
46#include "acevents.h" 47#include "acevents.h"
diff --git a/drivers/acpi/acpica/utxferror.c b/drivers/acpi/acpica/utxferror.c
index 916ae097c43c..8d0245ec4315 100644
--- a/drivers/acpi/acpica/utxferror.c
+++ b/drivers/acpi/acpica/utxferror.c
@@ -41,6 +41,7 @@
41 * POSSIBILITY OF SUCH DAMAGES. 41 * POSSIBILITY OF SUCH DAMAGES.
42 */ 42 */
43 43
44#include <linux/export.h>
44#include <acpi/acpi.h> 45#include <acpi/acpi.h>
45#include "accommon.h" 46#include "accommon.h"
46#include "acnamesp.h" 47#include "acnamesp.h"
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig
index f739a70b1c70..f0c1ce95a0ec 100644
--- a/drivers/acpi/apei/Kconfig
+++ b/drivers/acpi/apei/Kconfig
@@ -10,9 +10,11 @@ config ACPI_APEI
10 error injection. 10 error injection.
11 11
12config ACPI_APEI_GHES 12config ACPI_APEI_GHES
13 tristate "APEI Generic Hardware Error Source" 13 bool "APEI Generic Hardware Error Source"
14 depends on ACPI_APEI && X86 14 depends on ACPI_APEI && X86
15 select ACPI_HED 15 select ACPI_HED
16 select IRQ_WORK
17 select GENERIC_ALLOCATOR
16 help 18 help
17 Generic Hardware Error Source provides a way to report 19 Generic Hardware Error Source provides a way to report
18 platform hardware errors (such as that from chipset). It 20 platform hardware errors (such as that from chipset). It
@@ -30,6 +32,13 @@ config ACPI_APEI_PCIEAER
30 PCIe AER errors may be reported via APEI firmware first mode. 32 PCIe AER errors may be reported via APEI firmware first mode.
31 Turn on this option to enable the corresponding support. 33 Turn on this option to enable the corresponding support.
32 34
35config ACPI_APEI_MEMORY_FAILURE
36 bool "APEI memory error recovering support"
37 depends on ACPI_APEI && MEMORY_FAILURE
38 help
39 Memory errors may be reported via APEI firmware first mode.
40 Turn on this option to enable the memory recovering support.
41
33config ACPI_APEI_EINJ 42config ACPI_APEI_EINJ
34 tristate "APEI Error INJection (EINJ)" 43 tristate "APEI Error INJection (EINJ)"
35 depends on ACPI_APEI && DEBUG_FS 44 depends on ACPI_APEI && DEBUG_FS
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c
index 4a904a4bf05f..61540360d5ce 100644
--- a/drivers/acpi/apei/apei-base.c
+++ b/drivers/acpi/apei/apei-base.c
@@ -157,9 +157,10 @@ EXPORT_SYMBOL_GPL(apei_exec_noop);
157 * Interpret the specified action. Go through whole action table, 157 * Interpret the specified action. Go through whole action table,
158 * execute all instructions belong to the action. 158 * execute all instructions belong to the action.
159 */ 159 */
160int apei_exec_run(struct apei_exec_context *ctx, u8 action) 160int __apei_exec_run(struct apei_exec_context *ctx, u8 action,
161 bool optional)
161{ 162{
162 int rc; 163 int rc = -ENOENT;
163 u32 i, ip; 164 u32 i, ip;
164 struct acpi_whea_header *entry; 165 struct acpi_whea_header *entry;
165 apei_exec_ins_func_t run; 166 apei_exec_ins_func_t run;
@@ -198,9 +199,9 @@ rewind:
198 goto rewind; 199 goto rewind;
199 } 200 }
200 201
201 return 0; 202 return !optional && rc < 0 ? rc : 0;
202} 203}
203EXPORT_SYMBOL_GPL(apei_exec_run); 204EXPORT_SYMBOL_GPL(__apei_exec_run);
204 205
205typedef int (*apei_exec_entry_func_t)(struct apei_exec_context *ctx, 206typedef int (*apei_exec_entry_func_t)(struct apei_exec_context *ctx,
206 struct acpi_whea_header *entry, 207 struct acpi_whea_header *entry,
@@ -603,3 +604,29 @@ struct dentry *apei_get_debugfs_dir(void)
603 return dapei; 604 return dapei;
604} 605}
605EXPORT_SYMBOL_GPL(apei_get_debugfs_dir); 606EXPORT_SYMBOL_GPL(apei_get_debugfs_dir);
607
608int apei_osc_setup(void)
609{
610 static u8 whea_uuid_str[] = "ed855e0c-6c90-47bf-a62a-26de0fc5ad5c";
611 acpi_handle handle;
612 u32 capbuf[3];
613 struct acpi_osc_context context = {
614 .uuid_str = whea_uuid_str,
615 .rev = 1,
616 .cap.length = sizeof(capbuf),
617 .cap.pointer = capbuf,
618 };
619
620 capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
621 capbuf[OSC_SUPPORT_TYPE] = 1;
622 capbuf[OSC_CONTROL_TYPE] = 0;
623
624 if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))
625 || ACPI_FAILURE(acpi_run_osc(handle, &context)))
626 return -EIO;
627 else {
628 kfree(context.ret.pointer);
629 return 0;
630 }
631}
632EXPORT_SYMBOL_GPL(apei_osc_setup);
diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h
index ef0581f2094d..f57050e7a5e7 100644
--- a/drivers/acpi/apei/apei-internal.h
+++ b/drivers/acpi/apei/apei-internal.h
@@ -50,7 +50,18 @@ static inline u64 apei_exec_ctx_get_output(struct apei_exec_context *ctx)
50 return ctx->value; 50 return ctx->value;
51} 51}
52 52
53int apei_exec_run(struct apei_exec_context *ctx, u8 action); 53int __apei_exec_run(struct apei_exec_context *ctx, u8 action, bool optional);
54
55static inline int apei_exec_run(struct apei_exec_context *ctx, u8 action)
56{
57 return __apei_exec_run(ctx, action, 0);
58}
59
60/* It is optional whether the firmware provides the action */
61static inline int apei_exec_run_optional(struct apei_exec_context *ctx, u8 action)
62{
63 return __apei_exec_run(ctx, action, 1);
64}
54 65
55/* Common instruction implementation */ 66/* Common instruction implementation */
56 67
@@ -113,4 +124,6 @@ void apei_estatus_print(const char *pfx,
113 const struct acpi_hest_generic_status *estatus); 124 const struct acpi_hest_generic_status *estatus);
114int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus); 125int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus);
115int apei_estatus_check(const struct acpi_hest_generic_status *estatus); 126int apei_estatus_check(const struct acpi_hest_generic_status *estatus);
127
128int apei_osc_setup(void);
116#endif 129#endif
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
index f74b2ea11f21..589b96c38704 100644
--- a/drivers/acpi/apei/einj.c
+++ b/drivers/acpi/apei/einj.c
@@ -46,7 +46,8 @@
46 * Some BIOSes allow parameters to the SET_ERROR_TYPE entries in the 46 * Some BIOSes allow parameters to the SET_ERROR_TYPE entries in the
47 * EINJ table through an unpublished extension. Use with caution as 47 * EINJ table through an unpublished extension. Use with caution as
48 * most will ignore the parameter and make their own choice of address 48 * most will ignore the parameter and make their own choice of address
49 * for error injection. 49 * for error injection. This extension is used only if
50 * param_extension module parameter is specified.
50 */ 51 */
51struct einj_parameter { 52struct einj_parameter {
52 u64 type; 53 u64 type;
@@ -65,6 +66,9 @@ struct einj_parameter {
65 ((struct acpi_whea_header *)((char *)(tab) + \ 66 ((struct acpi_whea_header *)((char *)(tab) + \
66 sizeof(struct acpi_table_einj))) 67 sizeof(struct acpi_table_einj)))
67 68
69static bool param_extension;
70module_param(param_extension, bool, 0);
71
68static struct acpi_table_einj *einj_tab; 72static struct acpi_table_einj *einj_tab;
69 73
70static struct apei_resources einj_resources; 74static struct apei_resources einj_resources;
@@ -285,7 +289,7 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2)
285 289
286 einj_exec_ctx_init(&ctx); 290 einj_exec_ctx_init(&ctx);
287 291
288 rc = apei_exec_run(&ctx, ACPI_EINJ_BEGIN_OPERATION); 292 rc = apei_exec_run_optional(&ctx, ACPI_EINJ_BEGIN_OPERATION);
289 if (rc) 293 if (rc)
290 return rc; 294 return rc;
291 apei_exec_ctx_set_input(&ctx, type); 295 apei_exec_ctx_set_input(&ctx, type);
@@ -323,7 +327,7 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2)
323 rc = __einj_error_trigger(trigger_paddr); 327 rc = __einj_error_trigger(trigger_paddr);
324 if (rc) 328 if (rc)
325 return rc; 329 return rc;
326 rc = apei_exec_run(&ctx, ACPI_EINJ_END_OPERATION); 330 rc = apei_exec_run_optional(&ctx, ACPI_EINJ_END_OPERATION);
327 331
328 return rc; 332 return rc;
329} 333}
@@ -489,14 +493,6 @@ static int __init einj_init(void)
489 einj_debug_dir, NULL, &error_type_fops); 493 einj_debug_dir, NULL, &error_type_fops);
490 if (!fentry) 494 if (!fentry)
491 goto err_cleanup; 495 goto err_cleanup;
492 fentry = debugfs_create_x64("param1", S_IRUSR | S_IWUSR,
493 einj_debug_dir, &error_param1);
494 if (!fentry)
495 goto err_cleanup;
496 fentry = debugfs_create_x64("param2", S_IRUSR | S_IWUSR,
497 einj_debug_dir, &error_param2);
498 if (!fentry)
499 goto err_cleanup;
500 fentry = debugfs_create_file("error_inject", S_IWUSR, 496 fentry = debugfs_create_file("error_inject", S_IWUSR,
501 einj_debug_dir, NULL, &error_inject_fops); 497 einj_debug_dir, NULL, &error_inject_fops);
502 if (!fentry) 498 if (!fentry)
@@ -513,12 +509,23 @@ static int __init einj_init(void)
513 rc = apei_exec_pre_map_gars(&ctx); 509 rc = apei_exec_pre_map_gars(&ctx);
514 if (rc) 510 if (rc)
515 goto err_release; 511 goto err_release;
516 param_paddr = einj_get_parameter_address(); 512 if (param_extension) {
517 if (param_paddr) { 513 param_paddr = einj_get_parameter_address();
518 einj_param = ioremap(param_paddr, sizeof(*einj_param)); 514 if (param_paddr) {
519 rc = -ENOMEM; 515 einj_param = ioremap(param_paddr, sizeof(*einj_param));
520 if (!einj_param) 516 rc = -ENOMEM;
521 goto err_unmap; 517 if (!einj_param)
518 goto err_unmap;
519 fentry = debugfs_create_x64("param1", S_IRUSR | S_IWUSR,
520 einj_debug_dir, &error_param1);
521 if (!fentry)
522 goto err_unmap;
523 fentry = debugfs_create_x64("param2", S_IRUSR | S_IWUSR,
524 einj_debug_dir, &error_param2);
525 if (!fentry)
526 goto err_unmap;
527 } else
528 pr_warn(EINJ_PFX "Parameter extension is not supported.\n");
522 } 529 }
523 530
524 pr_info(EINJ_PFX "Error INJection is initialized.\n"); 531 pr_info(EINJ_PFX "Error INJection is initialized.\n");
@@ -526,6 +533,8 @@ static int __init einj_init(void)
526 return 0; 533 return 0;
527 534
528err_unmap: 535err_unmap:
536 if (einj_param)
537 iounmap(einj_param);
529 apei_exec_post_unmap_gars(&ctx); 538 apei_exec_post_unmap_gars(&ctx);
530err_release: 539err_release:
531 apei_resources_release(&einj_resources); 540 apei_resources_release(&einj_resources);
diff --git a/drivers/acpi/apei/erst-dbg.c b/drivers/acpi/apei/erst-dbg.c
index a4cfb64c86a1..903549df809b 100644
--- a/drivers/acpi/apei/erst-dbg.c
+++ b/drivers/acpi/apei/erst-dbg.c
@@ -33,7 +33,7 @@
33 33
34#define ERST_DBG_PFX "ERST DBG: " 34#define ERST_DBG_PFX "ERST DBG: "
35 35
36#define ERST_DBG_RECORD_LEN_MAX 4096 36#define ERST_DBG_RECORD_LEN_MAX 0x4000
37 37
38static void *erst_dbg_buf; 38static void *erst_dbg_buf;
39static unsigned int erst_dbg_buf_len; 39static unsigned int erst_dbg_buf_len;
@@ -213,6 +213,10 @@ static struct miscdevice erst_dbg_dev = {
213 213
214static __init int erst_dbg_init(void) 214static __init int erst_dbg_init(void)
215{ 215{
216 if (erst_disable) {
217 pr_info(ERST_DBG_PFX "ERST support is disabled.\n");
218 return -ENODEV;
219 }
216 return misc_register(&erst_dbg_dev); 220 return misc_register(&erst_dbg_dev);
217} 221}
218 222
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c
index e6cef8e1b534..127408069ca7 100644
--- a/drivers/acpi/apei/erst.c
+++ b/drivers/acpi/apei/erst.c
@@ -642,7 +642,7 @@ static int __erst_write_to_storage(u64 offset)
642 int rc; 642 int rc;
643 643
644 erst_exec_ctx_init(&ctx); 644 erst_exec_ctx_init(&ctx);
645 rc = apei_exec_run(&ctx, ACPI_ERST_BEGIN_WRITE); 645 rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_WRITE);
646 if (rc) 646 if (rc)
647 return rc; 647 return rc;
648 apei_exec_ctx_set_input(&ctx, offset); 648 apei_exec_ctx_set_input(&ctx, offset);
@@ -666,7 +666,7 @@ static int __erst_write_to_storage(u64 offset)
666 if (rc) 666 if (rc)
667 return rc; 667 return rc;
668 val = apei_exec_ctx_get_output(&ctx); 668 val = apei_exec_ctx_get_output(&ctx);
669 rc = apei_exec_run(&ctx, ACPI_ERST_END); 669 rc = apei_exec_run_optional(&ctx, ACPI_ERST_END);
670 if (rc) 670 if (rc)
671 return rc; 671 return rc;
672 672
@@ -681,7 +681,7 @@ static int __erst_read_from_storage(u64 record_id, u64 offset)
681 int rc; 681 int rc;
682 682
683 erst_exec_ctx_init(&ctx); 683 erst_exec_ctx_init(&ctx);
684 rc = apei_exec_run(&ctx, ACPI_ERST_BEGIN_READ); 684 rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_READ);
685 if (rc) 685 if (rc)
686 return rc; 686 return rc;
687 apei_exec_ctx_set_input(&ctx, offset); 687 apei_exec_ctx_set_input(&ctx, offset);
@@ -709,7 +709,7 @@ static int __erst_read_from_storage(u64 record_id, u64 offset)
709 if (rc) 709 if (rc)
710 return rc; 710 return rc;
711 val = apei_exec_ctx_get_output(&ctx); 711 val = apei_exec_ctx_get_output(&ctx);
712 rc = apei_exec_run(&ctx, ACPI_ERST_END); 712 rc = apei_exec_run_optional(&ctx, ACPI_ERST_END);
713 if (rc) 713 if (rc)
714 return rc; 714 return rc;
715 715
@@ -724,7 +724,7 @@ static int __erst_clear_from_storage(u64 record_id)
724 int rc; 724 int rc;
725 725
726 erst_exec_ctx_init(&ctx); 726 erst_exec_ctx_init(&ctx);
727 rc = apei_exec_run(&ctx, ACPI_ERST_BEGIN_CLEAR); 727 rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_CLEAR);
728 if (rc) 728 if (rc)
729 return rc; 729 return rc;
730 apei_exec_ctx_set_input(&ctx, record_id); 730 apei_exec_ctx_set_input(&ctx, record_id);
@@ -748,7 +748,7 @@ static int __erst_clear_from_storage(u64 record_id)
748 if (rc) 748 if (rc)
749 return rc; 749 return rc;
750 val = apei_exec_ctx_get_output(&ctx); 750 val = apei_exec_ctx_get_output(&ctx);
751 rc = apei_exec_run(&ctx, ACPI_ERST_END); 751 rc = apei_exec_run_optional(&ctx, ACPI_ERST_END);
752 if (rc) 752 if (rc)
753 return rc; 753 return rc;
754 754
@@ -932,8 +932,11 @@ static int erst_check_table(struct acpi_table_erst *erst_tab)
932static int erst_open_pstore(struct pstore_info *psi); 932static int erst_open_pstore(struct pstore_info *psi);
933static int erst_close_pstore(struct pstore_info *psi); 933static int erst_close_pstore(struct pstore_info *psi);
934static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, 934static ssize_t erst_reader(u64 *id, enum pstore_type_id *type,
935 struct timespec *time); 935 struct timespec *time, struct pstore_info *psi);
936static u64 erst_writer(enum pstore_type_id type, size_t size); 936static int erst_writer(enum pstore_type_id type, u64 *id, unsigned int part,
937 size_t size, struct pstore_info *psi);
938static int erst_clearer(enum pstore_type_id type, u64 id,
939 struct pstore_info *psi);
937 940
938static struct pstore_info erst_info = { 941static struct pstore_info erst_info = {
939 .owner = THIS_MODULE, 942 .owner = THIS_MODULE,
@@ -942,7 +945,7 @@ static struct pstore_info erst_info = {
942 .close = erst_close_pstore, 945 .close = erst_close_pstore,
943 .read = erst_reader, 946 .read = erst_reader,
944 .write = erst_writer, 947 .write = erst_writer,
945 .erase = erst_clear 948 .erase = erst_clearer
946}; 949};
947 950
948#define CPER_CREATOR_PSTORE \ 951#define CPER_CREATOR_PSTORE \
@@ -983,7 +986,7 @@ static int erst_close_pstore(struct pstore_info *psi)
983} 986}
984 987
985static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, 988static ssize_t erst_reader(u64 *id, enum pstore_type_id *type,
986 struct timespec *time) 989 struct timespec *time, struct pstore_info *psi)
987{ 990{
988 int rc; 991 int rc;
989 ssize_t len = 0; 992 ssize_t len = 0;
@@ -1037,10 +1040,12 @@ out:
1037 return (rc < 0) ? rc : (len - sizeof(*rcd)); 1040 return (rc < 0) ? rc : (len - sizeof(*rcd));
1038} 1041}
1039 1042
1040static u64 erst_writer(enum pstore_type_id type, size_t size) 1043static int erst_writer(enum pstore_type_id type, u64 *id, unsigned int part,
1044 size_t size, struct pstore_info *psi)
1041{ 1045{
1042 struct cper_pstore_record *rcd = (struct cper_pstore_record *) 1046 struct cper_pstore_record *rcd = (struct cper_pstore_record *)
1043 (erst_info.buf - sizeof(*rcd)); 1047 (erst_info.buf - sizeof(*rcd));
1048 int ret;
1044 1049
1045 memset(rcd, 0, sizeof(*rcd)); 1050 memset(rcd, 0, sizeof(*rcd));
1046 memcpy(rcd->hdr.signature, CPER_SIG_RECORD, CPER_SIG_SIZE); 1051 memcpy(rcd->hdr.signature, CPER_SIG_RECORD, CPER_SIG_SIZE);
@@ -1075,9 +1080,16 @@ static u64 erst_writer(enum pstore_type_id type, size_t size)
1075 } 1080 }
1076 rcd->sec_hdr.section_severity = CPER_SEV_FATAL; 1081 rcd->sec_hdr.section_severity = CPER_SEV_FATAL;
1077 1082
1078 erst_write(&rcd->hdr); 1083 ret = erst_write(&rcd->hdr);
1084 *id = rcd->hdr.record_id;
1079 1085
1080 return rcd->hdr.record_id; 1086 return ret;
1087}
1088
1089static int erst_clearer(enum pstore_type_id type, u64 id,
1090 struct pstore_info *psi)
1091{
1092 return erst_clear(id);
1081} 1093}
1082 1094
1083static int __init erst_init(void) 1095static int __init erst_init(void)
@@ -1155,7 +1167,7 @@ static int __init erst_init(void)
1155 goto err_release_erange; 1167 goto err_release_erange;
1156 1168
1157 buf = kmalloc(erst_erange.size, GFP_KERNEL); 1169 buf = kmalloc(erst_erange.size, GFP_KERNEL);
1158 mutex_init(&erst_info.buf_mutex); 1170 spin_lock_init(&erst_info.buf_lock);
1159 if (buf) { 1171 if (buf) {
1160 erst_info.buf = buf + sizeof(struct cper_pstore_record); 1172 erst_info.buf = buf + sizeof(struct cper_pstore_record);
1161 erst_info.bufsize = erst_erange.size - 1173 erst_info.bufsize = erst_erange.size -
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index f703b2881153..b8e08cb67a18 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -12,7 +12,7 @@
12 * For more information about Generic Hardware Error Source, please 12 * For more information about Generic Hardware Error Source, please
13 * refer to ACPI Specification version 4.0, section 17.3.2.6 13 * refer to ACPI Specification version 4.0, section 17.3.2.6
14 * 14 *
15 * Copyright 2010 Intel Corp. 15 * Copyright 2010,2011 Intel Corp.
16 * Author: Huang Ying <ying.huang@intel.com> 16 * Author: Huang Ying <ying.huang@intel.com>
17 * 17 *
18 * This program is free software; you can redistribute it and/or 18 * This program is free software; you can redistribute it and/or
@@ -42,17 +42,45 @@
42#include <linux/mutex.h> 42#include <linux/mutex.h>
43#include <linux/ratelimit.h> 43#include <linux/ratelimit.h>
44#include <linux/vmalloc.h> 44#include <linux/vmalloc.h>
45#include <linux/irq_work.h>
46#include <linux/llist.h>
47#include <linux/genalloc.h>
45#include <acpi/apei.h> 48#include <acpi/apei.h>
46#include <acpi/atomicio.h> 49#include <acpi/atomicio.h>
47#include <acpi/hed.h> 50#include <acpi/hed.h>
48#include <asm/mce.h> 51#include <asm/mce.h>
49#include <asm/tlbflush.h> 52#include <asm/tlbflush.h>
53#include <asm/nmi.h>
50 54
51#include "apei-internal.h" 55#include "apei-internal.h"
52 56
53#define GHES_PFX "GHES: " 57#define GHES_PFX "GHES: "
54 58
55#define GHES_ESTATUS_MAX_SIZE 65536 59#define GHES_ESTATUS_MAX_SIZE 65536
60#define GHES_ESOURCE_PREALLOC_MAX_SIZE 65536
61
62#define GHES_ESTATUS_POOL_MIN_ALLOC_ORDER 3
63
64/* This is just an estimation for memory pool allocation */
65#define GHES_ESTATUS_CACHE_AVG_SIZE 512
66
67#define GHES_ESTATUS_CACHES_SIZE 4
68
69#define GHES_ESTATUS_IN_CACHE_MAX_NSEC 10000000000ULL
70/* Prevent too many caches are allocated because of RCU */
71#define GHES_ESTATUS_CACHE_ALLOCED_MAX (GHES_ESTATUS_CACHES_SIZE * 3 / 2)
72
73#define GHES_ESTATUS_CACHE_LEN(estatus_len) \
74 (sizeof(struct ghes_estatus_cache) + (estatus_len))
75#define GHES_ESTATUS_FROM_CACHE(estatus_cache) \
76 ((struct acpi_hest_generic_status *) \
77 ((struct ghes_estatus_cache *)(estatus_cache) + 1))
78
79#define GHES_ESTATUS_NODE_LEN(estatus_len) \
80 (sizeof(struct ghes_estatus_node) + (estatus_len))
81#define GHES_ESTATUS_FROM_NODE(estatus_node) \
82 ((struct acpi_hest_generic_status *) \
83 ((struct ghes_estatus_node *)(estatus_node) + 1))
56 84
57/* 85/*
58 * One struct ghes is created for each generic hardware error source. 86 * One struct ghes is created for each generic hardware error source.
@@ -77,6 +105,22 @@ struct ghes {
77 }; 105 };
78}; 106};
79 107
108struct ghes_estatus_node {
109 struct llist_node llnode;
110 struct acpi_hest_generic *generic;
111};
112
113struct ghes_estatus_cache {
114 u32 estatus_len;
115 atomic_t count;
116 struct acpi_hest_generic *generic;
117 unsigned long long time_in;
118 struct rcu_head rcu;
119};
120
121int ghes_disable;
122module_param_named(disable, ghes_disable, bool, 0);
123
80static int ghes_panic_timeout __read_mostly = 30; 124static int ghes_panic_timeout __read_mostly = 30;
81 125
82/* 126/*
@@ -121,6 +165,22 @@ static struct vm_struct *ghes_ioremap_area;
121static DEFINE_RAW_SPINLOCK(ghes_ioremap_lock_nmi); 165static DEFINE_RAW_SPINLOCK(ghes_ioremap_lock_nmi);
122static DEFINE_SPINLOCK(ghes_ioremap_lock_irq); 166static DEFINE_SPINLOCK(ghes_ioremap_lock_irq);
123 167
168/*
169 * printk is not safe in NMI context. So in NMI handler, we allocate
170 * required memory from lock-less memory allocator
171 * (ghes_estatus_pool), save estatus into it, put them into lock-less
172 * list (ghes_estatus_llist), then delay printk into IRQ context via
173 * irq_work (ghes_proc_irq_work). ghes_estatus_size_request record
174 * required pool size by all NMI error source.
175 */
176static struct gen_pool *ghes_estatus_pool;
177static unsigned long ghes_estatus_pool_size_request;
178static struct llist_head ghes_estatus_llist;
179static struct irq_work ghes_proc_irq_work;
180
181struct ghes_estatus_cache *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE];
182static atomic_t ghes_estatus_cache_alloced;
183
124static int ghes_ioremap_init(void) 184static int ghes_ioremap_init(void)
125{ 185{
126 ghes_ioremap_area = __get_vm_area(PAGE_SIZE * GHES_IOREMAP_PAGES, 186 ghes_ioremap_area = __get_vm_area(PAGE_SIZE * GHES_IOREMAP_PAGES,
@@ -180,6 +240,55 @@ static void ghes_iounmap_irq(void __iomem *vaddr_ptr)
180 __flush_tlb_one(vaddr); 240 __flush_tlb_one(vaddr);
181} 241}
182 242
243static int ghes_estatus_pool_init(void)
244{
245 ghes_estatus_pool = gen_pool_create(GHES_ESTATUS_POOL_MIN_ALLOC_ORDER, -1);
246 if (!ghes_estatus_pool)
247 return -ENOMEM;
248 return 0;
249}
250
251static void ghes_estatus_pool_free_chunk_page(struct gen_pool *pool,
252 struct gen_pool_chunk *chunk,
253 void *data)
254{
255 free_page(chunk->start_addr);
256}
257
258static void ghes_estatus_pool_exit(void)
259{
260 gen_pool_for_each_chunk(ghes_estatus_pool,
261 ghes_estatus_pool_free_chunk_page, NULL);
262 gen_pool_destroy(ghes_estatus_pool);
263}
264
265static int ghes_estatus_pool_expand(unsigned long len)
266{
267 unsigned long i, pages, size, addr;
268 int ret;
269
270 ghes_estatus_pool_size_request += PAGE_ALIGN(len);
271 size = gen_pool_size(ghes_estatus_pool);
272 if (size >= ghes_estatus_pool_size_request)
273 return 0;
274 pages = (ghes_estatus_pool_size_request - size) / PAGE_SIZE;
275 for (i = 0; i < pages; i++) {
276 addr = __get_free_page(GFP_KERNEL);
277 if (!addr)
278 return -ENOMEM;
279 ret = gen_pool_add(ghes_estatus_pool, addr, PAGE_SIZE, -1);
280 if (ret)
281 return ret;
282 }
283
284 return 0;
285}
286
287static void ghes_estatus_pool_shrink(unsigned long len)
288{
289 ghes_estatus_pool_size_request -= PAGE_ALIGN(len);
290}
291
183static struct ghes *ghes_new(struct acpi_hest_generic *generic) 292static struct ghes *ghes_new(struct acpi_hest_generic *generic)
184{ 293{
185 struct ghes *ghes; 294 struct ghes *ghes;
@@ -341,43 +450,196 @@ static void ghes_clear_estatus(struct ghes *ghes)
341 ghes->flags &= ~GHES_TO_CLEAR; 450 ghes->flags &= ~GHES_TO_CLEAR;
342} 451}
343 452
344static void ghes_do_proc(struct ghes *ghes) 453static void ghes_do_proc(const struct acpi_hest_generic_status *estatus)
345{ 454{
346 int sev, processed = 0; 455 int sev, sec_sev;
347 struct acpi_hest_generic_data *gdata; 456 struct acpi_hest_generic_data *gdata;
348 457
349 sev = ghes_severity(ghes->estatus->error_severity); 458 sev = ghes_severity(estatus->error_severity);
350 apei_estatus_for_each_section(ghes->estatus, gdata) { 459 apei_estatus_for_each_section(estatus, gdata) {
351#ifdef CONFIG_X86_MCE 460 sec_sev = ghes_severity(gdata->error_severity);
352 if (!uuid_le_cmp(*(uuid_le *)gdata->section_type, 461 if (!uuid_le_cmp(*(uuid_le *)gdata->section_type,
353 CPER_SEC_PLATFORM_MEM)) { 462 CPER_SEC_PLATFORM_MEM)) {
354 apei_mce_report_mem_error( 463 struct cper_sec_mem_err *mem_err;
355 sev == GHES_SEV_CORRECTED, 464 mem_err = (struct cper_sec_mem_err *)(gdata+1);
356 (struct cper_sec_mem_err *)(gdata+1)); 465#ifdef CONFIG_X86_MCE
357 processed = 1; 466 apei_mce_report_mem_error(sev == GHES_SEV_CORRECTED,
358 } 467 mem_err);
359#endif 468#endif
469#ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE
470 if (sev == GHES_SEV_RECOVERABLE &&
471 sec_sev == GHES_SEV_RECOVERABLE &&
472 mem_err->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS) {
473 unsigned long pfn;
474 pfn = mem_err->physical_addr >> PAGE_SHIFT;
475 memory_failure_queue(pfn, 0, 0);
476 }
477#endif
478 }
360 } 479 }
361} 480}
362 481
363static void ghes_print_estatus(const char *pfx, struct ghes *ghes) 482static void __ghes_print_estatus(const char *pfx,
483 const struct acpi_hest_generic *generic,
484 const struct acpi_hest_generic_status *estatus)
364{ 485{
365 /* Not more than 2 messages every 5 seconds */
366 static DEFINE_RATELIMIT_STATE(ratelimit, 5*HZ, 2);
367
368 if (pfx == NULL) { 486 if (pfx == NULL) {
369 if (ghes_severity(ghes->estatus->error_severity) <= 487 if (ghes_severity(estatus->error_severity) <=
370 GHES_SEV_CORRECTED) 488 GHES_SEV_CORRECTED)
371 pfx = KERN_WARNING HW_ERR; 489 pfx = KERN_WARNING HW_ERR;
372 else 490 else
373 pfx = KERN_ERR HW_ERR; 491 pfx = KERN_ERR HW_ERR;
374 } 492 }
375 if (__ratelimit(&ratelimit)) { 493 printk("%s""Hardware error from APEI Generic Hardware Error Source: %d\n",
376 printk( 494 pfx, generic->header.source_id);
377 "%s""Hardware error from APEI Generic Hardware Error Source: %d\n", 495 apei_estatus_print(pfx, estatus);
378 pfx, ghes->generic->header.source_id); 496}
379 apei_estatus_print(pfx, ghes->estatus); 497
498static int ghes_print_estatus(const char *pfx,
499 const struct acpi_hest_generic *generic,
500 const struct acpi_hest_generic_status *estatus)
501{
502 /* Not more than 2 messages every 5 seconds */
503 static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2);
504 static DEFINE_RATELIMIT_STATE(ratelimit_uncorrected, 5*HZ, 2);
505 struct ratelimit_state *ratelimit;
506
507 if (ghes_severity(estatus->error_severity) <= GHES_SEV_CORRECTED)
508 ratelimit = &ratelimit_corrected;
509 else
510 ratelimit = &ratelimit_uncorrected;
511 if (__ratelimit(ratelimit)) {
512 __ghes_print_estatus(pfx, generic, estatus);
513 return 1;
380 } 514 }
515 return 0;
516}
517
518/*
519 * GHES error status reporting throttle, to report more kinds of
520 * errors, instead of just most frequently occurred errors.
521 */
522static int ghes_estatus_cached(struct acpi_hest_generic_status *estatus)
523{
524 u32 len;
525 int i, cached = 0;
526 unsigned long long now;
527 struct ghes_estatus_cache *cache;
528 struct acpi_hest_generic_status *cache_estatus;
529
530 len = apei_estatus_len(estatus);
531 rcu_read_lock();
532 for (i = 0; i < GHES_ESTATUS_CACHES_SIZE; i++) {
533 cache = rcu_dereference(ghes_estatus_caches[i]);
534 if (cache == NULL)
535 continue;
536 if (len != cache->estatus_len)
537 continue;
538 cache_estatus = GHES_ESTATUS_FROM_CACHE(cache);
539 if (memcmp(estatus, cache_estatus, len))
540 continue;
541 atomic_inc(&cache->count);
542 now = sched_clock();
543 if (now - cache->time_in < GHES_ESTATUS_IN_CACHE_MAX_NSEC)
544 cached = 1;
545 break;
546 }
547 rcu_read_unlock();
548 return cached;
549}
550
551static struct ghes_estatus_cache *ghes_estatus_cache_alloc(
552 struct acpi_hest_generic *generic,
553 struct acpi_hest_generic_status *estatus)
554{
555 int alloced;
556 u32 len, cache_len;
557 struct ghes_estatus_cache *cache;
558 struct acpi_hest_generic_status *cache_estatus;
559
560 alloced = atomic_add_return(1, &ghes_estatus_cache_alloced);
561 if (alloced > GHES_ESTATUS_CACHE_ALLOCED_MAX) {
562 atomic_dec(&ghes_estatus_cache_alloced);
563 return NULL;
564 }
565 len = apei_estatus_len(estatus);
566 cache_len = GHES_ESTATUS_CACHE_LEN(len);
567 cache = (void *)gen_pool_alloc(ghes_estatus_pool, cache_len);
568 if (!cache) {
569 atomic_dec(&ghes_estatus_cache_alloced);
570 return NULL;
571 }
572 cache_estatus = GHES_ESTATUS_FROM_CACHE(cache);
573 memcpy(cache_estatus, estatus, len);
574 cache->estatus_len = len;
575 atomic_set(&cache->count, 0);
576 cache->generic = generic;
577 cache->time_in = sched_clock();
578 return cache;
579}
580
581static void ghes_estatus_cache_free(struct ghes_estatus_cache *cache)
582{
583 u32 len;
584
585 len = apei_estatus_len(GHES_ESTATUS_FROM_CACHE(cache));
586 len = GHES_ESTATUS_CACHE_LEN(len);
587 gen_pool_free(ghes_estatus_pool, (unsigned long)cache, len);
588 atomic_dec(&ghes_estatus_cache_alloced);
589}
590
591static void ghes_estatus_cache_rcu_free(struct rcu_head *head)
592{
593 struct ghes_estatus_cache *cache;
594
595 cache = container_of(head, struct ghes_estatus_cache, rcu);
596 ghes_estatus_cache_free(cache);
597}
598
599static void ghes_estatus_cache_add(
600 struct acpi_hest_generic *generic,
601 struct acpi_hest_generic_status *estatus)
602{
603 int i, slot = -1, count;
604 unsigned long long now, duration, period, max_period = 0;
605 struct ghes_estatus_cache *cache, *slot_cache = NULL, *new_cache;
606
607 new_cache = ghes_estatus_cache_alloc(generic, estatus);
608 if (new_cache == NULL)
609 return;
610 rcu_read_lock();
611 now = sched_clock();
612 for (i = 0; i < GHES_ESTATUS_CACHES_SIZE; i++) {
613 cache = rcu_dereference(ghes_estatus_caches[i]);
614 if (cache == NULL) {
615 slot = i;
616 slot_cache = NULL;
617 break;
618 }
619 duration = now - cache->time_in;
620 if (duration >= GHES_ESTATUS_IN_CACHE_MAX_NSEC) {
621 slot = i;
622 slot_cache = cache;
623 break;
624 }
625 count = atomic_read(&cache->count);
626 period = duration;
627 do_div(period, (count + 1));
628 if (period > max_period) {
629 max_period = period;
630 slot = i;
631 slot_cache = cache;
632 }
633 }
634 /* new_cache must be put into array after its contents are written */
635 smp_wmb();
636 if (slot != -1 && cmpxchg(ghes_estatus_caches + slot,
637 slot_cache, new_cache) == slot_cache) {
638 if (slot_cache)
639 call_rcu(&slot_cache->rcu, ghes_estatus_cache_rcu_free);
640 } else
641 ghes_estatus_cache_free(new_cache);
642 rcu_read_unlock();
381} 643}
382 644
383static int ghes_proc(struct ghes *ghes) 645static int ghes_proc(struct ghes *ghes)
@@ -387,9 +649,11 @@ static int ghes_proc(struct ghes *ghes)
387 rc = ghes_read_estatus(ghes, 0); 649 rc = ghes_read_estatus(ghes, 0);
388 if (rc) 650 if (rc)
389 goto out; 651 goto out;
390 ghes_print_estatus(NULL, ghes); 652 if (!ghes_estatus_cached(ghes->estatus)) {
391 ghes_do_proc(ghes); 653 if (ghes_print_estatus(NULL, ghes->generic, ghes->estatus))
392 654 ghes_estatus_cache_add(ghes->generic, ghes->estatus);
655 }
656 ghes_do_proc(ghes->estatus);
393out: 657out:
394 ghes_clear_estatus(ghes); 658 ghes_clear_estatus(ghes);
395 return 0; 659 return 0;
@@ -447,15 +711,50 @@ static int ghes_notify_sci(struct notifier_block *this,
447 return ret; 711 return ret;
448} 712}
449 713
450static int ghes_notify_nmi(struct notifier_block *this, 714static void ghes_proc_in_irq(struct irq_work *irq_work)
451 unsigned long cmd, void *data) 715{
716 struct llist_node *llnode, *next, *tail = NULL;
717 struct ghes_estatus_node *estatus_node;
718 struct acpi_hest_generic *generic;
719 struct acpi_hest_generic_status *estatus;
720 u32 len, node_len;
721
722 /*
723 * Because the time order of estatus in list is reversed,
724 * revert it back to proper order.
725 */
726 llnode = llist_del_all(&ghes_estatus_llist);
727 while (llnode) {
728 next = llnode->next;
729 llnode->next = tail;
730 tail = llnode;
731 llnode = next;
732 }
733 llnode = tail;
734 while (llnode) {
735 next = llnode->next;
736 estatus_node = llist_entry(llnode, struct ghes_estatus_node,
737 llnode);
738 estatus = GHES_ESTATUS_FROM_NODE(estatus_node);
739 len = apei_estatus_len(estatus);
740 node_len = GHES_ESTATUS_NODE_LEN(len);
741 ghes_do_proc(estatus);
742 if (!ghes_estatus_cached(estatus)) {
743 generic = estatus_node->generic;
744 if (ghes_print_estatus(NULL, generic, estatus))
745 ghes_estatus_cache_add(generic, estatus);
746 }
747 gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node,
748 node_len);
749 llnode = next;
750 }
751}
752
753static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
452{ 754{
453 struct ghes *ghes, *ghes_global = NULL; 755 struct ghes *ghes, *ghes_global = NULL;
454 int sev, sev_global = -1; 756 int sev, sev_global = -1;
455 int ret = NOTIFY_DONE; 757 int ret = NMI_DONE;
456
457 if (cmd != DIE_NMI)
458 return ret;
459 758
460 raw_spin_lock(&ghes_nmi_lock); 759 raw_spin_lock(&ghes_nmi_lock);
461 list_for_each_entry_rcu(ghes, &ghes_nmi, list) { 760 list_for_each_entry_rcu(ghes, &ghes_nmi, list) {
@@ -468,15 +767,16 @@ static int ghes_notify_nmi(struct notifier_block *this,
468 sev_global = sev; 767 sev_global = sev;
469 ghes_global = ghes; 768 ghes_global = ghes;
470 } 769 }
471 ret = NOTIFY_STOP; 770 ret = NMI_HANDLED;
472 } 771 }
473 772
474 if (ret == NOTIFY_DONE) 773 if (ret == NMI_DONE)
475 goto out; 774 goto out;
476 775
477 if (sev_global >= GHES_SEV_PANIC) { 776 if (sev_global >= GHES_SEV_PANIC) {
478 oops_begin(); 777 oops_begin();
479 ghes_print_estatus(KERN_EMERG HW_ERR, ghes_global); 778 __ghes_print_estatus(KERN_EMERG HW_ERR, ghes_global->generic,
779 ghes_global->estatus);
480 /* reboot to log the error! */ 780 /* reboot to log the error! */
481 if (panic_timeout == 0) 781 if (panic_timeout == 0)
482 panic_timeout = ghes_panic_timeout; 782 panic_timeout = ghes_panic_timeout;
@@ -484,12 +784,34 @@ static int ghes_notify_nmi(struct notifier_block *this,
484 } 784 }
485 785
486 list_for_each_entry_rcu(ghes, &ghes_nmi, list) { 786 list_for_each_entry_rcu(ghes, &ghes_nmi, list) {
787#ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG
788 u32 len, node_len;
789 struct ghes_estatus_node *estatus_node;
790 struct acpi_hest_generic_status *estatus;
791#endif
487 if (!(ghes->flags & GHES_TO_CLEAR)) 792 if (!(ghes->flags & GHES_TO_CLEAR))
488 continue; 793 continue;
489 /* Do not print estatus because printk is not NMI safe */ 794#ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG
490 ghes_do_proc(ghes); 795 if (ghes_estatus_cached(ghes->estatus))
796 goto next;
797 /* Save estatus for further processing in IRQ context */
798 len = apei_estatus_len(ghes->estatus);
799 node_len = GHES_ESTATUS_NODE_LEN(len);
800 estatus_node = (void *)gen_pool_alloc(ghes_estatus_pool,
801 node_len);
802 if (estatus_node) {
803 estatus_node->generic = ghes->generic;
804 estatus = GHES_ESTATUS_FROM_NODE(estatus_node);
805 memcpy(estatus, ghes->estatus, len);
806 llist_add(&estatus_node->llnode, &ghes_estatus_llist);
807 }
808next:
809#endif
491 ghes_clear_estatus(ghes); 810 ghes_clear_estatus(ghes);
492 } 811 }
812#ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG
813 irq_work_queue(&ghes_proc_irq_work);
814#endif
493 815
494out: 816out:
495 raw_spin_unlock(&ghes_nmi_lock); 817 raw_spin_unlock(&ghes_nmi_lock);
@@ -500,14 +822,26 @@ static struct notifier_block ghes_notifier_sci = {
500 .notifier_call = ghes_notify_sci, 822 .notifier_call = ghes_notify_sci,
501}; 823};
502 824
503static struct notifier_block ghes_notifier_nmi = { 825static unsigned long ghes_esource_prealloc_size(
504 .notifier_call = ghes_notify_nmi, 826 const struct acpi_hest_generic *generic)
505}; 827{
828 unsigned long block_length, prealloc_records, prealloc_size;
829
830 block_length = min_t(unsigned long, generic->error_block_length,
831 GHES_ESTATUS_MAX_SIZE);
832 prealloc_records = max_t(unsigned long,
833 generic->records_to_preallocate, 1);
834 prealloc_size = min_t(unsigned long, block_length * prealloc_records,
835 GHES_ESOURCE_PREALLOC_MAX_SIZE);
836
837 return prealloc_size;
838}
506 839
507static int __devinit ghes_probe(struct platform_device *ghes_dev) 840static int __devinit ghes_probe(struct platform_device *ghes_dev)
508{ 841{
509 struct acpi_hest_generic *generic; 842 struct acpi_hest_generic *generic;
510 struct ghes *ghes = NULL; 843 struct ghes *ghes = NULL;
844 unsigned long len;
511 int rc = -EINVAL; 845 int rc = -EINVAL;
512 846
513 generic = *(struct acpi_hest_generic **)ghes_dev->dev.platform_data; 847 generic = *(struct acpi_hest_generic **)ghes_dev->dev.platform_data;
@@ -573,9 +907,12 @@ static int __devinit ghes_probe(struct platform_device *ghes_dev)
573 mutex_unlock(&ghes_list_mutex); 907 mutex_unlock(&ghes_list_mutex);
574 break; 908 break;
575 case ACPI_HEST_NOTIFY_NMI: 909 case ACPI_HEST_NOTIFY_NMI:
910 len = ghes_esource_prealloc_size(generic);
911 ghes_estatus_pool_expand(len);
576 mutex_lock(&ghes_list_mutex); 912 mutex_lock(&ghes_list_mutex);
577 if (list_empty(&ghes_nmi)) 913 if (list_empty(&ghes_nmi))
578 register_die_notifier(&ghes_notifier_nmi); 914 register_nmi_handler(NMI_LOCAL, ghes_notify_nmi, 0,
915 "ghes");
579 list_add_rcu(&ghes->list, &ghes_nmi); 916 list_add_rcu(&ghes->list, &ghes_nmi);
580 mutex_unlock(&ghes_list_mutex); 917 mutex_unlock(&ghes_list_mutex);
581 break; 918 break;
@@ -597,6 +934,7 @@ static int __devexit ghes_remove(struct platform_device *ghes_dev)
597{ 934{
598 struct ghes *ghes; 935 struct ghes *ghes;
599 struct acpi_hest_generic *generic; 936 struct acpi_hest_generic *generic;
937 unsigned long len;
600 938
601 ghes = platform_get_drvdata(ghes_dev); 939 ghes = platform_get_drvdata(ghes_dev);
602 generic = ghes->generic; 940 generic = ghes->generic;
@@ -620,13 +958,15 @@ static int __devexit ghes_remove(struct platform_device *ghes_dev)
620 mutex_lock(&ghes_list_mutex); 958 mutex_lock(&ghes_list_mutex);
621 list_del_rcu(&ghes->list); 959 list_del_rcu(&ghes->list);
622 if (list_empty(&ghes_nmi)) 960 if (list_empty(&ghes_nmi))
623 unregister_die_notifier(&ghes_notifier_nmi); 961 unregister_nmi_handler(NMI_LOCAL, "ghes");
624 mutex_unlock(&ghes_list_mutex); 962 mutex_unlock(&ghes_list_mutex);
625 /* 963 /*
626 * To synchronize with NMI handler, ghes can only be 964 * To synchronize with NMI handler, ghes can only be
627 * freed after NMI handler finishes. 965 * freed after NMI handler finishes.
628 */ 966 */
629 synchronize_rcu(); 967 synchronize_rcu();
968 len = ghes_esource_prealloc_size(generic);
969 ghes_estatus_pool_shrink(len);
630 break; 970 break;
631 default: 971 default:
632 BUG(); 972 BUG();
@@ -662,15 +1002,43 @@ static int __init ghes_init(void)
662 return -EINVAL; 1002 return -EINVAL;
663 } 1003 }
664 1004
1005 if (ghes_disable) {
1006 pr_info(GHES_PFX "GHES is not enabled!\n");
1007 return -EINVAL;
1008 }
1009
1010 init_irq_work(&ghes_proc_irq_work, ghes_proc_in_irq);
1011
665 rc = ghes_ioremap_init(); 1012 rc = ghes_ioremap_init();
666 if (rc) 1013 if (rc)
667 goto err; 1014 goto err;
668 1015
669 rc = platform_driver_register(&ghes_platform_driver); 1016 rc = ghes_estatus_pool_init();
670 if (rc) 1017 if (rc)
671 goto err_ioremap_exit; 1018 goto err_ioremap_exit;
672 1019
1020 rc = ghes_estatus_pool_expand(GHES_ESTATUS_CACHE_AVG_SIZE *
1021 GHES_ESTATUS_CACHE_ALLOCED_MAX);
1022 if (rc)
1023 goto err_pool_exit;
1024
1025 rc = platform_driver_register(&ghes_platform_driver);
1026 if (rc)
1027 goto err_pool_exit;
1028
1029 rc = apei_osc_setup();
1030 if (rc == 0 && osc_sb_apei_support_acked)
1031 pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit and WHEA _OSC.\n");
1032 else if (rc == 0 && !osc_sb_apei_support_acked)
1033 pr_info(GHES_PFX "APEI firmware first mode is enabled by WHEA _OSC.\n");
1034 else if (rc && osc_sb_apei_support_acked)
1035 pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit.\n");
1036 else
1037 pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n");
1038
673 return 0; 1039 return 0;
1040err_pool_exit:
1041 ghes_estatus_pool_exit();
674err_ioremap_exit: 1042err_ioremap_exit:
675 ghes_ioremap_exit(); 1043 ghes_ioremap_exit();
676err: 1044err:
@@ -680,6 +1048,7 @@ err:
680static void __exit ghes_exit(void) 1048static void __exit ghes_exit(void)
681{ 1049{
682 platform_driver_unregister(&ghes_platform_driver); 1050 platform_driver_unregister(&ghes_platform_driver);
1051 ghes_estatus_pool_exit();
683 ghes_ioremap_exit(); 1052 ghes_ioremap_exit();
684} 1053}
685 1054
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c
index 181bc2f7bb74..05fee06f4d6e 100644
--- a/drivers/acpi/apei/hest.c
+++ b/drivers/acpi/apei/hest.c
@@ -231,16 +231,17 @@ void __init acpi_hest_init(void)
231 goto err; 231 goto err;
232 } 232 }
233 233
234 rc = apei_hest_parse(hest_parse_ghes_count, &ghes_count); 234 if (!ghes_disable) {
235 if (rc) 235 rc = apei_hest_parse(hest_parse_ghes_count, &ghes_count);
236 goto err; 236 if (rc)
237 237 goto err;
238 rc = hest_ghes_dev_register(ghes_count); 238 rc = hest_ghes_dev_register(ghes_count);
239 if (!rc) { 239 if (rc)
240 pr_info(HEST_PFX "Table parsing has been initialized.\n"); 240 goto err;
241 return;
242 } 241 }
243 242
243 pr_info(HEST_PFX "Table parsing has been initialized.\n");
244 return;
244err: 245err:
245 hest_disable = 1; 246 hest_disable = 1;
246} 247}
diff --git a/drivers/acpi/atomicio.c b/drivers/acpi/atomicio.c
index 7489b89c300f..04ae1c88c03c 100644
--- a/drivers/acpi/atomicio.c
+++ b/drivers/acpi/atomicio.c
@@ -24,7 +24,7 @@
24 */ 24 */
25 25
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/module.h> 27#include <linux/export.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/acpi.h> 29#include <linux/acpi.h>
30#include <linux/io.h> 30#include <linux/io.h>
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index fcc13ac0aa18..7711d94a0409 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -55,6 +55,9 @@
55#define ACPI_BATTERY_NOTIFY_INFO 0x81 55#define ACPI_BATTERY_NOTIFY_INFO 0x81
56#define ACPI_BATTERY_NOTIFY_THRESHOLD 0x82 56#define ACPI_BATTERY_NOTIFY_THRESHOLD 0x82
57 57
58/* Battery power unit: 0 means mW, 1 means mA */
59#define ACPI_BATTERY_POWER_UNIT_MA 1
60
58#define _COMPONENT ACPI_BATTERY_COMPONENT 61#define _COMPONENT ACPI_BATTERY_COMPONENT
59 62
60ACPI_MODULE_NAME("battery"); 63ACPI_MODULE_NAME("battery");
@@ -91,16 +94,12 @@ MODULE_DEVICE_TABLE(acpi, battery_device_ids);
91enum { 94enum {
92 ACPI_BATTERY_ALARM_PRESENT, 95 ACPI_BATTERY_ALARM_PRESENT,
93 ACPI_BATTERY_XINFO_PRESENT, 96 ACPI_BATTERY_XINFO_PRESENT,
94 /* For buggy DSDTs that report negative 16-bit values for either
95 * charging or discharging current and/or report 0 as 65536
96 * due to bad math.
97 */
98 ACPI_BATTERY_QUIRK_SIGNED16_CURRENT,
99 ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, 97 ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
100}; 98};
101 99
102struct acpi_battery { 100struct acpi_battery {
103 struct mutex lock; 101 struct mutex lock;
102 struct mutex sysfs_lock;
104 struct power_supply bat; 103 struct power_supply bat;
105 struct acpi_device *device; 104 struct acpi_device *device;
106 struct notifier_block pm_nb; 105 struct notifier_block pm_nb;
@@ -132,7 +131,7 @@ struct acpi_battery {
132 unsigned long flags; 131 unsigned long flags;
133}; 132};
134 133
135#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); 134#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat)
136 135
137inline int acpi_battery_present(struct acpi_battery *battery) 136inline int acpi_battery_present(struct acpi_battery *battery)
138{ 137{
@@ -301,7 +300,8 @@ static enum power_supply_property energy_battery_props[] = {
301#ifdef CONFIG_ACPI_PROCFS_POWER 300#ifdef CONFIG_ACPI_PROCFS_POWER
302inline char *acpi_battery_units(struct acpi_battery *battery) 301inline char *acpi_battery_units(struct acpi_battery *battery)
303{ 302{
304 return (battery->power_unit)?"mA":"mW"; 303 return (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) ?
304 "mA" : "mW";
305} 305}
306#endif 306#endif
307 307
@@ -461,9 +461,17 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
461 battery->update_time = jiffies; 461 battery->update_time = jiffies;
462 kfree(buffer.pointer); 462 kfree(buffer.pointer);
463 463
464 if (test_bit(ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, &battery->flags) && 464 /* For buggy DSDTs that report negative 16-bit values for either
465 battery->rate_now != -1) 465 * charging or discharging current and/or report 0 as 65536
466 * due to bad math.
467 */
468 if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA &&
469 battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN &&
470 (s16)(battery->rate_now) < 0) {
466 battery->rate_now = abs((s16)battery->rate_now); 471 battery->rate_now = abs((s16)battery->rate_now);
472 printk_once(KERN_WARNING FW_BUG "battery: (dis)charge rate"
473 " invalid.\n");
474 }
467 475
468 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags) 476 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
469 && battery->capacity_now >= 0 && battery->capacity_now <= 100) 477 && battery->capacity_now >= 0 && battery->capacity_now <= 100)
@@ -544,7 +552,7 @@ static int sysfs_add_battery(struct acpi_battery *battery)
544{ 552{
545 int result; 553 int result;
546 554
547 if (battery->power_unit) { 555 if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) {
548 battery->bat.properties = charge_battery_props; 556 battery->bat.properties = charge_battery_props;
549 battery->bat.num_properties = 557 battery->bat.num_properties =
550 ARRAY_SIZE(charge_battery_props); 558 ARRAY_SIZE(charge_battery_props);
@@ -566,18 +574,16 @@ static int sysfs_add_battery(struct acpi_battery *battery)
566 574
567static void sysfs_remove_battery(struct acpi_battery *battery) 575static void sysfs_remove_battery(struct acpi_battery *battery)
568{ 576{
569 if (!battery->bat.dev) 577 mutex_lock(&battery->sysfs_lock);
578 if (!battery->bat.dev) {
579 mutex_unlock(&battery->sysfs_lock);
570 return; 580 return;
581 }
582
571 device_remove_file(battery->bat.dev, &alarm_attr); 583 device_remove_file(battery->bat.dev, &alarm_attr);
572 power_supply_unregister(&battery->bat); 584 power_supply_unregister(&battery->bat);
573 battery->bat.dev = NULL; 585 battery->bat.dev = NULL;
574} 586 mutex_unlock(&battery->sysfs_lock);
575
576static void acpi_battery_quirks(struct acpi_battery *battery)
577{
578 if (dmi_name_in_vendors("Acer") && battery->power_unit) {
579 set_bit(ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, &battery->flags);
580 }
581} 587}
582 588
583/* 589/*
@@ -592,7 +598,7 @@ static void acpi_battery_quirks(struct acpi_battery *battery)
592 * 598 *
593 * Handle this correctly so that they won't break userspace. 599 * Handle this correctly so that they won't break userspace.
594 */ 600 */
595static void acpi_battery_quirks2(struct acpi_battery *battery) 601static void acpi_battery_quirks(struct acpi_battery *battery)
596{ 602{
597 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)) 603 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
598 return ; 604 return ;
@@ -623,13 +629,15 @@ static int acpi_battery_update(struct acpi_battery *battery)
623 result = acpi_battery_get_info(battery); 629 result = acpi_battery_get_info(battery);
624 if (result) 630 if (result)
625 return result; 631 return result;
626 acpi_battery_quirks(battery);
627 acpi_battery_init_alarm(battery); 632 acpi_battery_init_alarm(battery);
628 } 633 }
629 if (!battery->bat.dev) 634 if (!battery->bat.dev) {
630 sysfs_add_battery(battery); 635 result = sysfs_add_battery(battery);
636 if (result)
637 return result;
638 }
631 result = acpi_battery_get_state(battery); 639 result = acpi_battery_get_state(battery);
632 acpi_battery_quirks2(battery); 640 acpi_battery_quirks(battery);
633 return result; 641 return result;
634} 642}
635 643
@@ -863,7 +871,7 @@ DECLARE_FILE_FUNCTIONS(alarm);
863 }, \ 871 }, \
864 } 872 }
865 873
866static struct battery_file { 874static const struct battery_file {
867 struct file_operations ops; 875 struct file_operations ops;
868 mode_t mode; 876 mode_t mode;
869 const char *name; 877 const char *name;
@@ -948,9 +956,12 @@ static int battery_notify(struct notifier_block *nb,
948 struct acpi_battery *battery = container_of(nb, struct acpi_battery, 956 struct acpi_battery *battery = container_of(nb, struct acpi_battery,
949 pm_nb); 957 pm_nb);
950 switch (mode) { 958 switch (mode) {
959 case PM_POST_HIBERNATION:
951 case PM_POST_SUSPEND: 960 case PM_POST_SUSPEND:
952 sysfs_remove_battery(battery); 961 if (battery->bat.dev) {
953 sysfs_add_battery(battery); 962 sysfs_remove_battery(battery);
963 sysfs_add_battery(battery);
964 }
954 break; 965 break;
955 } 966 }
956 967
@@ -972,28 +983,38 @@ static int acpi_battery_add(struct acpi_device *device)
972 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); 983 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
973 device->driver_data = battery; 984 device->driver_data = battery;
974 mutex_init(&battery->lock); 985 mutex_init(&battery->lock);
986 mutex_init(&battery->sysfs_lock);
975 if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle, 987 if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle,
976 "_BIX", &handle))) 988 "_BIX", &handle)))
977 set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); 989 set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
978 acpi_battery_update(battery); 990 result = acpi_battery_update(battery);
991 if (result)
992 goto fail;
979#ifdef CONFIG_ACPI_PROCFS_POWER 993#ifdef CONFIG_ACPI_PROCFS_POWER
980 result = acpi_battery_add_fs(device); 994 result = acpi_battery_add_fs(device);
981#endif 995#endif
982 if (!result) { 996 if (result) {
983 printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
984 ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
985 device->status.battery_present ? "present" : "absent");
986 } else {
987#ifdef CONFIG_ACPI_PROCFS_POWER 997#ifdef CONFIG_ACPI_PROCFS_POWER
988 acpi_battery_remove_fs(device); 998 acpi_battery_remove_fs(device);
989#endif 999#endif
990 kfree(battery); 1000 goto fail;
991 } 1001 }
992 1002
1003 printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
1004 ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
1005 device->status.battery_present ? "present" : "absent");
1006
993 battery->pm_nb.notifier_call = battery_notify; 1007 battery->pm_nb.notifier_call = battery_notify;
994 register_pm_notifier(&battery->pm_nb); 1008 register_pm_notifier(&battery->pm_nb);
995 1009
996 return result; 1010 return result;
1011
1012fail:
1013 sysfs_remove_battery(battery);
1014 mutex_destroy(&battery->lock);
1015 mutex_destroy(&battery->sysfs_lock);
1016 kfree(battery);
1017 return result;
997} 1018}
998 1019
999static int acpi_battery_remove(struct acpi_device *device, int type) 1020static int acpi_battery_remove(struct acpi_device *device, int type)
@@ -1009,6 +1030,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
1009#endif 1030#endif
1010 sysfs_remove_battery(battery); 1031 sysfs_remove_battery(battery);
1011 mutex_destroy(&battery->lock); 1032 mutex_destroy(&battery->lock);
1033 mutex_destroy(&battery->sysfs_lock);
1012 kfree(battery); 1034 kfree(battery);
1013 return 0; 1035 return 0;
1014} 1036}
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c
index af308d03f492..cb9629638def 100644
--- a/drivers/acpi/blacklist.c
+++ b/drivers/acpi/blacklist.c
@@ -28,7 +28,6 @@
28 */ 28 */
29 29
30#include <linux/kernel.h> 30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/init.h> 31#include <linux/init.h>
33#include <linux/acpi.h> 32#include <linux/acpi.h>
34#include <acpi/acpi_bus.h> 33#include <acpi/acpi_bus.h>
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index d1e06c182cdb..437ddbf0c49a 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -39,6 +39,7 @@
39#include <linux/pci.h> 39#include <linux/pci.h>
40#include <acpi/acpi_bus.h> 40#include <acpi/acpi_bus.h>
41#include <acpi/acpi_drivers.h> 41#include <acpi/acpi_drivers.h>
42#include <acpi/apei.h>
42#include <linux/dmi.h> 43#include <linux/dmi.h>
43#include <linux/suspend.h> 44#include <linux/suspend.h>
44 45
@@ -519,6 +520,7 @@ out_kfree:
519} 520}
520EXPORT_SYMBOL(acpi_run_osc); 521EXPORT_SYMBOL(acpi_run_osc);
521 522
523bool osc_sb_apei_support_acked;
522static u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48"; 524static u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48";
523static void acpi_bus_osc_support(void) 525static void acpi_bus_osc_support(void)
524{ 526{
@@ -541,11 +543,19 @@ static void acpi_bus_osc_support(void)
541#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE) 543#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
542 capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_PPC_OST_SUPPORT; 544 capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_PPC_OST_SUPPORT;
543#endif 545#endif
546
547 if (!ghes_disable)
548 capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_APEI_SUPPORT;
544 if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))) 549 if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)))
545 return; 550 return;
546 if (ACPI_SUCCESS(acpi_run_osc(handle, &context))) 551 if (ACPI_SUCCESS(acpi_run_osc(handle, &context))) {
552 u32 *capbuf_ret = context.ret.pointer;
553 if (context.ret.length > OSC_SUPPORT_TYPE)
554 osc_sb_apei_support_acked =
555 capbuf_ret[OSC_SUPPORT_TYPE] & OSC_SB_APEI_SUPPORT;
547 kfree(context.ret.pointer); 556 kfree(context.ret.pointer);
548 /* do we need to check the returned cap? Sounds no */ 557 }
558 /* do we need to check other returned cap? Sounds no */
549} 559}
550 560
551/* -------------------------------------------------------------------------- 561/* --------------------------------------------------------------------------
diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c
index 182a9fc36355..b55d6a20dc0e 100644
--- a/drivers/acpi/debugfs.c
+++ b/drivers/acpi/debugfs.c
@@ -2,6 +2,7 @@
2 * debugfs.c - ACPI debugfs interface to userspace. 2 * debugfs.c - ACPI debugfs interface to userspace.
3 */ 3 */
4 4
5#include <linux/export.h>
5#include <linux/init.h> 6#include <linux/init.h>
6#include <linux/debugfs.h> 7#include <linux/debugfs.h>
7#include <acpi/acpi_drivers.h> 8#include <acpi/acpi_drivers.h>
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 1864ad3cf895..19a61136d848 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -77,7 +77,7 @@ struct dock_dependent_device {
77 struct list_head list; 77 struct list_head list;
78 struct list_head hotplug_list; 78 struct list_head hotplug_list;
79 acpi_handle handle; 79 acpi_handle handle;
80 struct acpi_dock_ops *ops; 80 const struct acpi_dock_ops *ops;
81 void *context; 81 void *context;
82}; 82};
83 83
@@ -589,7 +589,7 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifier);
589 * the dock driver after _DCK is executed. 589 * the dock driver after _DCK is executed.
590 */ 590 */
591int 591int
592register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops, 592register_hotplug_dock_device(acpi_handle handle, const struct acpi_dock_ops *ops,
593 void *context) 593 void *context)
594{ 594{
595 struct dock_dependent_device *dd; 595 struct dock_dependent_device *dd;
diff --git a/drivers/acpi/ec_sys.c b/drivers/acpi/ec_sys.c
index 05b44201a614..6c47ae9793a7 100644
--- a/drivers/acpi/ec_sys.c
+++ b/drivers/acpi/ec_sys.c
@@ -11,6 +11,7 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/acpi.h> 12#include <linux/acpi.h>
13#include <linux/debugfs.h> 13#include <linux/debugfs.h>
14#include <linux/module.h>
14#include "internal.h" 15#include "internal.h"
15 16
16MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>"); 17MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>");
@@ -92,7 +93,7 @@ static ssize_t acpi_ec_write_io(struct file *f, const char __user *buf,
92 return count; 93 return count;
93} 94}
94 95
95static struct file_operations acpi_ec_io_ops = { 96static const struct file_operations acpi_ec_io_ops = {
96 .owner = THIS_MODULE, 97 .owner = THIS_MODULE,
97 .open = acpi_ec_open_io, 98 .open = acpi_ec_open_io,
98 .read = acpi_ec_read_io, 99 .read = acpi_ec_read_io,
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c
index 85d908993809..1442737cedec 100644
--- a/drivers/acpi/event.c
+++ b/drivers/acpi/event.c
@@ -7,6 +7,7 @@
7 */ 7 */
8 8
9#include <linux/spinlock.h> 9#include <linux/spinlock.h>
10#include <linux/export.h>
10#include <linux/proc_fs.h> 11#include <linux/proc_fs.h>
11#include <linux/init.h> 12#include <linux/init.h>
12#include <linux/poll.h> 13#include <linux/poll.h>
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index 467479f07c1f..0f0356ca1a9e 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -110,7 +110,7 @@ fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
110 return result; 110 return result;
111} 111}
112 112
113static struct thermal_cooling_device_ops fan_cooling_ops = { 113static const struct thermal_cooling_device_ops fan_cooling_ops = {
114 .get_max_state = fan_get_max_state, 114 .get_max_state = fan_get_max_state,
115 .get_cur_state = fan_get_cur_state, 115 .get_cur_state = fan_get_cur_state,
116 .set_cur_state = fan_set_cur_state, 116 .set_cur_state = fan_set_cur_state,
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 7c47ed55e528..29a4a5c8ee00 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -6,6 +6,7 @@
6 * 6 *
7 * This file is released under the GPLv2. 7 * This file is released under the GPLv2.
8 */ 8 */
9#include <linux/export.h>
9#include <linux/init.h> 10#include <linux/init.h>
10#include <linux/list.h> 11#include <linux/list.h>
11#include <linux/device.h> 12#include <linux/device.h>
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 372f9b70f7f4..f31c5c5f1b7e 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -80,7 +80,8 @@ static acpi_osd_handler acpi_irq_handler;
80static void *acpi_irq_context; 80static void *acpi_irq_context;
81static struct workqueue_struct *kacpid_wq; 81static struct workqueue_struct *kacpid_wq;
82static struct workqueue_struct *kacpi_notify_wq; 82static struct workqueue_struct *kacpi_notify_wq;
83static struct workqueue_struct *kacpi_hotplug_wq; 83struct workqueue_struct *kacpi_hotplug_wq;
84EXPORT_SYMBOL(kacpi_hotplug_wq);
84 85
85struct acpi_res_list { 86struct acpi_res_list {
86 resource_size_t start; 87 resource_size_t start;
@@ -155,7 +156,7 @@ static u32 acpi_osi_handler(acpi_string interface, u32 supported)
155{ 156{
156 if (!strcmp("Linux", interface)) { 157 if (!strcmp("Linux", interface)) {
157 158
158 printk(KERN_NOTICE FW_BUG PREFIX 159 printk_once(KERN_NOTICE FW_BUG PREFIX
159 "BIOS _OSI(Linux) query %s%s\n", 160 "BIOS _OSI(Linux) query %s%s\n",
160 osi_linux.enable ? "honored" : "ignored", 161 osi_linux.enable ? "honored" : "ignored",
161 osi_linux.cmdline ? " via cmdline" : 162 osi_linux.cmdline ? " via cmdline" :
@@ -237,8 +238,23 @@ void acpi_os_vprintf(const char *fmt, va_list args)
237#endif 238#endif
238} 239}
239 240
241#ifdef CONFIG_KEXEC
242static unsigned long acpi_rsdp;
243static int __init setup_acpi_rsdp(char *arg)
244{
245 acpi_rsdp = simple_strtoul(arg, NULL, 16);
246 return 0;
247}
248early_param("acpi_rsdp", setup_acpi_rsdp);
249#endif
250
240acpi_physical_address __init acpi_os_get_root_pointer(void) 251acpi_physical_address __init acpi_os_get_root_pointer(void)
241{ 252{
253#ifdef CONFIG_KEXEC
254 if (acpi_rsdp)
255 return acpi_rsdp;
256#endif
257
242 if (efi_enabled) { 258 if (efi_enabled) {
243 if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) 259 if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
244 return efi.acpi20; 260 return efi.acpi20;
@@ -1083,7 +1099,13 @@ struct osi_setup_entry {
1083 bool enable; 1099 bool enable;
1084}; 1100};
1085 1101
1086static struct osi_setup_entry __initdata osi_setup_entries[OSI_STRING_ENTRIES_MAX]; 1102static struct osi_setup_entry __initdata
1103 osi_setup_entries[OSI_STRING_ENTRIES_MAX] = {
1104 {"Module Device", true},
1105 {"Processor Device", true},
1106 {"3.0 _SCP Extensions", true},
1107 {"Processor Aggregator Device", true},
1108};
1087 1109
1088void __init acpi_osi_setup(char *str) 1110void __init acpi_osi_setup(char *str)
1089{ 1111{
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index f907cfbfa13c..7f9eba9a0b02 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -303,6 +303,61 @@ void acpi_pci_irq_del_prt(struct pci_bus *bus)
303/* -------------------------------------------------------------------------- 303/* --------------------------------------------------------------------------
304 PCI Interrupt Routing Support 304 PCI Interrupt Routing Support
305 -------------------------------------------------------------------------- */ 305 -------------------------------------------------------------------------- */
306#ifdef CONFIG_X86_IO_APIC
307extern int noioapicquirk;
308extern int noioapicreroute;
309
310static int bridge_has_boot_interrupt_variant(struct pci_bus *bus)
311{
312 struct pci_bus *bus_it;
313
314 for (bus_it = bus ; bus_it ; bus_it = bus_it->parent) {
315 if (!bus_it->self)
316 return 0;
317 if (bus_it->self->irq_reroute_variant)
318 return bus_it->self->irq_reroute_variant;
319 }
320 return 0;
321}
322
323/*
324 * Some chipsets (e.g. Intel 6700PXH) generate a legacy INTx when the IRQ
325 * entry in the chipset's IO-APIC is masked (as, e.g. the RT kernel does
326 * during interrupt handling). When this INTx generation cannot be disabled,
327 * we reroute these interrupts to their legacy equivalent to get rid of
328 * spurious interrupts.
329 */
330static int acpi_reroute_boot_interrupt(struct pci_dev *dev,
331 struct acpi_prt_entry *entry)
332{
333 if (noioapicquirk || noioapicreroute) {
334 return 0;
335 } else {
336 switch (bridge_has_boot_interrupt_variant(dev->bus)) {
337 case 0:
338 /* no rerouting necessary */
339 return 0;
340 case INTEL_IRQ_REROUTE_VARIANT:
341 /*
342 * Remap according to INTx routing table in 6700PXH
343 * specs, intel order number 302628-002, section
344 * 2.15.2. Other chipsets (80332, ...) have the same
345 * mapping and are handled here as well.
346 */
347 dev_info(&dev->dev, "PCI IRQ %d -> rerouted to legacy "
348 "IRQ %d\n", entry->index,
349 (entry->index % 4) + 16);
350 entry->index = (entry->index % 4) + 16;
351 return 1;
352 default:
353 dev_warn(&dev->dev, "Cannot reroute IRQ %d to legacy "
354 "IRQ: unknown mapping\n", entry->index);
355 return -1;
356 }
357 }
358}
359#endif /* CONFIG_X86_IO_APIC */
360
306static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin) 361static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin)
307{ 362{
308 struct acpi_prt_entry *entry; 363 struct acpi_prt_entry *entry;
@@ -311,6 +366,9 @@ static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin)
311 366
312 entry = acpi_pci_irq_find_prt_entry(dev, pin); 367 entry = acpi_pci_irq_find_prt_entry(dev, pin);
313 if (entry) { 368 if (entry) {
369#ifdef CONFIG_X86_IO_APIC
370 acpi_reroute_boot_interrupt(dev, entry);
371#endif /* CONFIG_X86_IO_APIC */
314 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %s[%c] _PRT entry\n", 372 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %s[%c] _PRT entry\n",
315 pci_name(dev), pin_name(pin))); 373 pci_name(dev), pin_name(pin)));
316 return entry; 374 return entry;
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index d06078d660ad..2672c798272f 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -485,7 +485,8 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
485 root->secondary.end = 0xFF; 485 root->secondary.end = 0xFF;
486 printk(KERN_WARNING FW_BUG PREFIX 486 printk(KERN_WARNING FW_BUG PREFIX
487 "no secondary bus range in _CRS\n"); 487 "no secondary bus range in _CRS\n");
488 status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, &bus); 488 status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN,
489 NULL, &bus);
489 if (ACPI_SUCCESS(status)) 490 if (ACPI_SUCCESS(status))
490 root->secondary.start = bus; 491 root->secondary.start = bus;
491 else if (status == AE_NOT_FOUND) 492 else if (status == AE_NOT_FOUND)
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c
index f5f986991b52..251c7b6273a9 100644
--- a/drivers/acpi/proc.c
+++ b/drivers/acpi/proc.c
@@ -1,5 +1,6 @@
1#include <linux/proc_fs.h> 1#include <linux/proc_fs.h>
2#include <linux/seq_file.h> 2#include <linux/seq_file.h>
3#include <linux/export.h>
3#include <linux/suspend.h> 4#include <linux/suspend.h>
4#include <linux/bcd.h> 5#include <linux/bcd.h>
5#include <asm/uaccess.h> 6#include <asm/uaccess.h>
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 02d2a4c9084d..3a0428e8435c 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -7,6 +7,7 @@
7 * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> 7 * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
8 * - Added _PDC for platforms with Intel CPUs 8 * - Added _PDC for platforms with Intel CPUs
9 */ 9 */
10#include <linux/export.h>
10#include <linux/dmi.h> 11#include <linux/dmi.h>
11#include <linux/slab.h> 12#include <linux/slab.h>
12 13
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 431ab11c8c1b..9b88f9828d8c 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -37,7 +37,7 @@
37#include <linux/dmi.h> 37#include <linux/dmi.h>
38#include <linux/moduleparam.h> 38#include <linux/moduleparam.h>
39#include <linux/sched.h> /* need_resched() */ 39#include <linux/sched.h> /* need_resched() */
40#include <linux/pm_qos_params.h> 40#include <linux/pm_qos.h>
41#include <linux/clockchips.h> 41#include <linux/clockchips.h>
42#include <linux/cpuidle.h> 42#include <linux/cpuidle.h>
43#include <linux/irqflags.h> 43#include <linux/irqflags.h>
@@ -852,7 +852,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
852} 852}
853 853
854static int c3_cpu_count; 854static int c3_cpu_count;
855static DEFINE_SPINLOCK(c3_lock); 855static DEFINE_RAW_SPINLOCK(c3_lock);
856 856
857/** 857/**
858 * acpi_idle_enter_bm - enters C3 with proper BM handling 858 * acpi_idle_enter_bm - enters C3 with proper BM handling
@@ -930,12 +930,12 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
930 * without doing anything. 930 * without doing anything.
931 */ 931 */
932 if (pr->flags.bm_check && pr->flags.bm_control) { 932 if (pr->flags.bm_check && pr->flags.bm_control) {
933 spin_lock(&c3_lock); 933 raw_spin_lock(&c3_lock);
934 c3_cpu_count++; 934 c3_cpu_count++;
935 /* Disable bus master arbitration when all CPUs are in C3 */ 935 /* Disable bus master arbitration when all CPUs are in C3 */
936 if (c3_cpu_count == num_online_cpus()) 936 if (c3_cpu_count == num_online_cpus())
937 acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1); 937 acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
938 spin_unlock(&c3_lock); 938 raw_spin_unlock(&c3_lock);
939 } else if (!pr->flags.bm_check) { 939 } else if (!pr->flags.bm_check) {
940 ACPI_FLUSH_CPU_CACHE(); 940 ACPI_FLUSH_CPU_CACHE();
941 } 941 }
@@ -944,10 +944,10 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
944 944
945 /* Re-enable bus master arbitration */ 945 /* Re-enable bus master arbitration */
946 if (pr->flags.bm_check && pr->flags.bm_control) { 946 if (pr->flags.bm_check && pr->flags.bm_control) {
947 spin_lock(&c3_lock); 947 raw_spin_lock(&c3_lock);
948 acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0); 948 acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
949 c3_cpu_count--; 949 c3_cpu_count--;
950 spin_unlock(&c3_lock); 950 raw_spin_unlock(&c3_lock);
951 } 951 }
952 kt2 = ktime_get_real(); 952 kt2 = ktime_get_real();
953 idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1)); 953 idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1));
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index 79cb65332894..870550d6a4bf 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -244,7 +244,7 @@ processor_set_cur_state(struct thermal_cooling_device *cdev,
244 return result; 244 return result;
245} 245}
246 246
247struct thermal_cooling_device_ops processor_cooling_ops = { 247const struct thermal_cooling_device_ops processor_cooling_ops = {
248 .get_max_state = processor_get_max_state, 248 .get_max_state = processor_get_max_state,
249 .get_cur_state = processor_get_cur_state, 249 .get_cur_state = processor_get_cur_state,
250 .set_cur_state = processor_set_cur_state, 250 .set_cur_state = processor_set_cur_state,
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 51ae3794ec7f..6e36d0c0057c 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -112,7 +112,7 @@ struct acpi_battery {
112 u8 have_sysfs_alarm:1; 112 u8 have_sysfs_alarm:1;
113}; 113};
114 114
115#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); 115#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat)
116 116
117struct acpi_sbs { 117struct acpi_sbs {
118 struct power_supply charger; 118 struct power_supply charger;
@@ -130,6 +130,9 @@ struct acpi_sbs {
130 130
131#define to_acpi_sbs(x) container_of(x, struct acpi_sbs, charger) 131#define to_acpi_sbs(x) container_of(x, struct acpi_sbs, charger)
132 132
133static int acpi_sbs_remove(struct acpi_device *device, int type);
134static int acpi_battery_get_state(struct acpi_battery *battery);
135
133static inline int battery_scale(int log) 136static inline int battery_scale(int log)
134{ 137{
135 int scale = 1; 138 int scale = 1;
@@ -195,6 +198,8 @@ static int acpi_sbs_battery_get_property(struct power_supply *psy,
195 198
196 if ((!battery->present) && psp != POWER_SUPPLY_PROP_PRESENT) 199 if ((!battery->present) && psp != POWER_SUPPLY_PROP_PRESENT)
197 return -ENODEV; 200 return -ENODEV;
201
202 acpi_battery_get_state(battery);
198 switch (psp) { 203 switch (psp) {
199 case POWER_SUPPLY_PROP_STATUS: 204 case POWER_SUPPLY_PROP_STATUS:
200 if (battery->rate_now < 0) 205 if (battery->rate_now < 0)
@@ -225,11 +230,17 @@ static int acpi_sbs_battery_get_property(struct power_supply *psy,
225 case POWER_SUPPLY_PROP_POWER_NOW: 230 case POWER_SUPPLY_PROP_POWER_NOW:
226 val->intval = abs(battery->rate_now) * 231 val->intval = abs(battery->rate_now) *
227 acpi_battery_ipscale(battery) * 1000; 232 acpi_battery_ipscale(battery) * 1000;
233 val->intval *= (acpi_battery_mode(battery)) ?
234 (battery->voltage_now *
235 acpi_battery_vscale(battery) / 1000) : 1;
228 break; 236 break;
229 case POWER_SUPPLY_PROP_CURRENT_AVG: 237 case POWER_SUPPLY_PROP_CURRENT_AVG:
230 case POWER_SUPPLY_PROP_POWER_AVG: 238 case POWER_SUPPLY_PROP_POWER_AVG:
231 val->intval = abs(battery->rate_avg) * 239 val->intval = abs(battery->rate_avg) *
232 acpi_battery_ipscale(battery) * 1000; 240 acpi_battery_ipscale(battery) * 1000;
241 val->intval *= (acpi_battery_mode(battery)) ?
242 (battery->voltage_now *
243 acpi_battery_vscale(battery) / 1000) : 1;
233 break; 244 break;
234 case POWER_SUPPLY_PROP_CAPACITY: 245 case POWER_SUPPLY_PROP_CAPACITY:
235 val->intval = battery->state_of_charge; 246 val->intval = battery->state_of_charge;
@@ -903,8 +914,6 @@ static void acpi_sbs_callback(void *context)
903 } 914 }
904} 915}
905 916
906static int acpi_sbs_remove(struct acpi_device *device, int type);
907
908static int acpi_sbs_add(struct acpi_device *device) 917static int acpi_sbs_add(struct acpi_device *device)
909{ 918{
910 struct acpi_sbs *sbs; 919 struct acpi_sbs *sbs;
diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c
index f8be23b6c129..f8d2a472795c 100644
--- a/drivers/acpi/sbshc.c
+++ b/drivers/acpi/sbshc.c
@@ -13,6 +13,7 @@
13#include <linux/wait.h> 13#include <linux/wait.h>
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/module.h>
16#include <linux/interrupt.h> 17#include <linux/interrupt.h>
17#include "sbshc.h" 18#include "sbshc.h"
18 19
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 6c949602cbd1..6d9a3ab58db2 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -390,6 +390,22 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
390 }, 390 },
391 { 391 {
392 .callback = init_nvs_nosave, 392 .callback = init_nvs_nosave,
393 .ident = "Sony Vaio VGN-FW21E",
394 .matches = {
395 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
396 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW21E"),
397 },
398 },
399 {
400 .callback = init_nvs_nosave,
401 .ident = "Sony Vaio VPCEB17FX",
402 .matches = {
403 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
404 DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB17FX"),
405 },
406 },
407 {
408 .callback = init_nvs_nosave,
393 .ident = "Sony Vaio VGN-SR11M", 409 .ident = "Sony Vaio VGN-SR11M",
394 .matches = { 410 .matches = {
395 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 411 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
@@ -428,6 +444,38 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
428 DMI_MATCH(DMI_PRODUCT_NAME, "1000 Series"), 444 DMI_MATCH(DMI_PRODUCT_NAME, "1000 Series"),
429 }, 445 },
430 }, 446 },
447 {
448 .callback = init_old_suspend_ordering,
449 .ident = "Asus A8N-SLI DELUXE",
450 .matches = {
451 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
452 DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI DELUXE"),
453 },
454 },
455 {
456 .callback = init_old_suspend_ordering,
457 .ident = "Asus A8N-SLI Premium",
458 .matches = {
459 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
460 DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI Premium"),
461 },
462 },
463 {
464 .callback = init_nvs_nosave,
465 .ident = "Sony Vaio VGN-SR26GN_P",
466 .matches = {
467 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
468 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR26GN_P"),
469 },
470 },
471 {
472 .callback = init_nvs_nosave,
473 .ident = "Sony Vaio VGN-FW520F",
474 .matches = {
475 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
476 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW520F"),
477 },
478 },
431 {}, 479 {},
432}; 480};
433#endif /* CONFIG_SUSPEND */ 481#endif /* CONFIG_SUSPEND */
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
index 77255f250dbb..c538d0ef10ff 100644
--- a/drivers/acpi/sysfs.c
+++ b/drivers/acpi/sysfs.c
@@ -149,12 +149,12 @@ static int param_get_debug_level(char *buffer, const struct kernel_param *kp)
149 return result; 149 return result;
150} 150}
151 151
152static struct kernel_param_ops param_ops_debug_layer = { 152static const struct kernel_param_ops param_ops_debug_layer = {
153 .set = param_set_uint, 153 .set = param_set_uint,
154 .get = param_get_debug_layer, 154 .get = param_get_debug_layer,
155}; 155};
156 156
157static struct kernel_param_ops param_ops_debug_level = { 157static const struct kernel_param_ops param_ops_debug_level = {
158 .set = param_set_uint, 158 .set = param_set_uint,
159 .get = param_get_debug_level, 159 .get = param_get_debug_level,
160}; 160};
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 2607e17b520f..48fbc647b178 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -812,7 +812,7 @@ acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal,
812 thermal_zone_unbind_cooling_device); 812 thermal_zone_unbind_cooling_device);
813} 813}
814 814
815static struct thermal_zone_device_ops acpi_thermal_zone_ops = { 815static const struct thermal_zone_device_ops acpi_thermal_zone_ops = {
816 .bind = acpi_thermal_bind_cooling_device, 816 .bind = acpi_thermal_bind_cooling_device,
817 .unbind = acpi_thermal_unbind_cooling_device, 817 .unbind = acpi_thermal_unbind_cooling_device,
818 .get_temp = thermal_get_temp, 818 .get_temp = thermal_get_temp,
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index db39e9e607d8..08a44b532f7c 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -46,7 +46,6 @@
46 46
47#define PREFIX "ACPI: " 47#define PREFIX "ACPI: "
48 48
49#define ACPI_VIDEO_CLASS "video"
50#define ACPI_VIDEO_BUS_NAME "Video Bus" 49#define ACPI_VIDEO_BUS_NAME "Video Bus"
51#define ACPI_VIDEO_DEVICE_NAME "Video Device" 50#define ACPI_VIDEO_DEVICE_NAME "Video Device"
52#define ACPI_VIDEO_NOTIFY_SWITCH 0x80 51#define ACPI_VIDEO_NOTIFY_SWITCH 0x80
@@ -308,7 +307,7 @@ video_set_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long st
308 return acpi_video_device_lcd_set_level(video, level); 307 return acpi_video_device_lcd_set_level(video, level);
309} 308}
310 309
311static struct thermal_cooling_device_ops video_cooling_ops = { 310static const struct thermal_cooling_device_ops video_cooling_ops = {
312 .get_max_state = video_get_max_state, 311 .get_max_state = video_get_max_state,
313 .get_cur_state = video_get_cur_state, 312 .get_cur_state = video_get_cur_state,
314 .set_cur_state = video_set_cur_state, 313 .set_cur_state = video_set_cur_state,
@@ -1445,7 +1444,8 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
1445 case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch, 1444 case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch,
1446 * most likely via hotkey. */ 1445 * most likely via hotkey. */
1447 acpi_bus_generate_proc_event(device, event, 0); 1446 acpi_bus_generate_proc_event(device, event, 0);
1448 keycode = KEY_SWITCHVIDEOMODE; 1447 if (!acpi_notifier_call_chain(device, event, 0))
1448 keycode = KEY_SWITCHVIDEOMODE;
1449 break; 1449 break;
1450 1450
1451 case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video 1451 case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video
@@ -1475,7 +1475,8 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
1475 break; 1475 break;
1476 } 1476 }
1477 1477
1478 acpi_notifier_call_chain(device, event, 0); 1478 if (event != ACPI_VIDEO_NOTIFY_SWITCH)
1479 acpi_notifier_call_chain(device, event, 0);
1479 1480
1480 if (keycode) { 1481 if (keycode) {
1481 input_report_key(input, keycode, 1); 1482 input_report_key(input, keycode, 1);
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 5af3479714f6..f3f0fe7e255a 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -33,6 +33,7 @@
33 * 33 *
34 */ 34 */
35 35
36#include <linux/export.h>
36#include <linux/acpi.h> 37#include <linux/acpi.h>
37#include <linux/dmi.h> 38#include <linux/dmi.h>
38#include <linux/pci.h> 39#include <linux/pci.h>