aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/Kconfig9
-rw-r--r--drivers/acpi/Makefile9
-rw-r--r--drivers/acpi/ac.c1
-rw-r--r--drivers/acpi/acpi_memhotplug.c1
-rw-r--r--drivers/acpi/acpi_pad.c16
-rw-r--r--drivers/acpi/acpica/evgpe.c19
-rw-r--r--drivers/acpi/acpica/evxfevnt.c33
-rw-r--r--drivers/acpi/acpica/exmutex.c3
-rw-r--r--drivers/acpi/acpica/exprep.c17
-rw-r--r--drivers/acpi/acpica/hwacpi.c20
-rw-r--r--drivers/acpi/apei/Kconfig30
-rw-r--r--drivers/acpi/apei/Makefile5
-rw-r--r--drivers/acpi/apei/apei-base.c593
-rw-r--r--drivers/acpi/apei/apei-internal.h114
-rw-r--r--drivers/acpi/apei/cper.c84
-rw-r--r--drivers/acpi/apei/einj.c548
-rw-r--r--drivers/acpi/apei/erst.c855
-rw-r--r--drivers/acpi/apei/ghes.c427
-rw-r--r--drivers/acpi/apei/hest.c173
-rw-r--r--drivers/acpi/atomicio.c360
-rw-r--r--drivers/acpi/battery.c93
-rw-r--r--drivers/acpi/bus.c13
-rw-r--r--drivers/acpi/button.c1
-rw-r--r--drivers/acpi/container.c1
-rw-r--r--drivers/acpi/debug.c1
-rw-r--r--drivers/acpi/dock.c8
-rw-r--r--drivers/acpi/ec.c72
-rw-r--r--drivers/acpi/event.c1
-rw-r--r--drivers/acpi/glue.c1
-rw-r--r--drivers/acpi/hed.c112
-rw-r--r--drivers/acpi/hest.c135
-rw-r--r--drivers/acpi/internal.h2
-rw-r--r--drivers/acpi/numa.c6
-rw-r--r--drivers/acpi/osl.c23
-rw-r--r--drivers/acpi/pci_irq.c1
-rw-r--r--drivers/acpi/pci_link.c1
-rw-r--r--drivers/acpi/pci_root.c68
-rw-r--r--drivers/acpi/pci_slot.c1
-rw-r--r--drivers/acpi/power.c1
-rw-r--r--drivers/acpi/power_meter.c3
-rw-r--r--drivers/acpi/processor_core.c1119
-rw-r--r--drivers/acpi/processor_driver.c979
-rw-r--r--drivers/acpi/processor_idle.c29
-rw-r--r--drivers/acpi/processor_pdc.c209
-rw-r--r--drivers/acpi/processor_perflib.c1
-rw-r--r--drivers/acpi/processor_throttling.c4
-rw-r--r--drivers/acpi/sbs.c6
-rw-r--r--drivers/acpi/sbshc.c3
-rw-r--r--drivers/acpi/scan.c51
-rw-r--r--drivers/acpi/sleep.c120
-rw-r--r--drivers/acpi/sleep.h2
-rw-r--r--drivers/acpi/system.c1
-rw-r--r--drivers/acpi/thermal.c37
-rw-r--r--drivers/acpi/utils.c46
-rw-r--r--drivers/acpi/video.c223
-rw-r--r--drivers/acpi/video_detect.c2
56 files changed, 5010 insertions, 1683 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 93d2c7971df6..746411518802 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -360,4 +360,13 @@ config ACPI_SBS
360 To compile this driver as a module, choose M here: 360 To compile this driver as a module, choose M here:
361 the modules will be called sbs and sbshc. 361 the modules will be called sbs and sbshc.
362 362
363config ACPI_HED
364 tristate "Hardware Error Device"
365 help
366 This driver supports the Hardware Error Device (PNP0C33),
367 which is used to report some hardware errors notified via
368 SCI, mainly the corrected errors.
369
370source "drivers/acpi/apei/Kconfig"
371
363endif # ACPI 372endif # ACPI
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 66cc3f36a954..6ee33169e1dc 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -19,7 +19,7 @@ obj-y += acpi.o \
19 19
20# All the builtin files are in the "acpi." module_param namespace. 20# All the builtin files are in the "acpi." module_param namespace.
21acpi-y += osl.o utils.o reboot.o 21acpi-y += osl.o utils.o reboot.o
22acpi-y += hest.o 22acpi-y += atomicio.o
23 23
24# sleep related files 24# sleep related files
25acpi-y += wakeup.o 25acpi-y += wakeup.o
@@ -32,7 +32,7 @@ acpi-$(CONFIG_ACPI_SLEEP) += proc.o
32# 32#
33acpi-y += bus.o glue.o 33acpi-y += bus.o glue.o
34acpi-y += scan.o 34acpi-y += scan.o
35acpi-y += processor_pdc.o 35acpi-y += processor_core.o
36acpi-y += ec.o 36acpi-y += ec.o
37acpi-$(CONFIG_ACPI_DOCK) += dock.o 37acpi-$(CONFIG_ACPI_DOCK) += dock.o
38acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o 38acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
@@ -59,10 +59,13 @@ obj-$(CONFIG_ACPI_BATTERY) += battery.o
59obj-$(CONFIG_ACPI_SBS) += sbshc.o 59obj-$(CONFIG_ACPI_SBS) += sbshc.o
60obj-$(CONFIG_ACPI_SBS) += sbs.o 60obj-$(CONFIG_ACPI_SBS) += sbs.o
61obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o 61obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o
62obj-$(CONFIG_ACPI_HED) += hed.o
62 63
63# processor has its own "processor." module_param namespace 64# processor has its own "processor." module_param namespace
64processor-y := processor_core.o processor_throttling.o 65processor-y := processor_driver.o processor_throttling.o
65processor-y += processor_idle.o processor_thermal.o 66processor-y += processor_idle.o processor_thermal.o
66processor-$(CONFIG_CPU_FREQ) += processor_perflib.o 67processor-$(CONFIG_CPU_FREQ) += processor_perflib.o
67 68
68obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o 69obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o
70
71obj-$(CONFIG_ACPI_APEI) += apei/
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index b6ed60b57b0d..56205a0b85df 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -25,6 +25,7 @@
25 25
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/slab.h>
28#include <linux/init.h> 29#include <linux/init.h>
29#include <linux/types.h> 30#include <linux/types.h>
30#ifdef CONFIG_ACPI_PROCFS_POWER 31#ifdef CONFIG_ACPI_PROCFS_POWER
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index 3597d73f28f6..d98571385656 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -30,6 +30,7 @@
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/types.h> 31#include <linux/types.h>
32#include <linux/memory_hotplug.h> 32#include <linux/memory_hotplug.h>
33#include <linux/slab.h>
33#include <acpi/acpi_drivers.h> 34#include <acpi/acpi_drivers.h>
34 35
35#define ACPI_MEMORY_DEVICE_CLASS "memory" 36#define ACPI_MEMORY_DEVICE_CLASS "memory"
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c
index 7e52295f1ecc..f169e516a1af 100644
--- a/drivers/acpi/acpi_pad.c
+++ b/drivers/acpi/acpi_pad.c
@@ -27,10 +27,11 @@
27#include <linux/freezer.h> 27#include <linux/freezer.h>
28#include <linux/cpu.h> 28#include <linux/cpu.h>
29#include <linux/clockchips.h> 29#include <linux/clockchips.h>
30#include <linux/slab.h>
30#include <acpi/acpi_bus.h> 31#include <acpi/acpi_bus.h>
31#include <acpi/acpi_drivers.h> 32#include <acpi/acpi_drivers.h>
32 33
33#define ACPI_PROCESSOR_AGGREGATOR_CLASS "processor_aggregator" 34#define ACPI_PROCESSOR_AGGREGATOR_CLASS "acpi_pad"
34#define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator" 35#define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator"
35#define ACPI_PROCESSOR_AGGREGATOR_NOTIFY 0x80 36#define ACPI_PROCESSOR_AGGREGATOR_NOTIFY 0x80
36static DEFINE_MUTEX(isolated_cpus_lock); 37static DEFINE_MUTEX(isolated_cpus_lock);
@@ -42,6 +43,10 @@ static DEFINE_MUTEX(isolated_cpus_lock);
42#define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1) 43#define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1)
43#define CPUID5_ECX_INTERRUPT_BREAK (0x2) 44#define CPUID5_ECX_INTERRUPT_BREAK (0x2)
44static unsigned long power_saving_mwait_eax; 45static unsigned long power_saving_mwait_eax;
46
47static unsigned char tsc_detected_unstable;
48static unsigned char tsc_marked_unstable;
49
45static void power_saving_mwait_init(void) 50static void power_saving_mwait_init(void)
46{ 51{
47 unsigned int eax, ebx, ecx, edx; 52 unsigned int eax, ebx, ecx, edx;
@@ -86,8 +91,8 @@ static void power_saving_mwait_init(void)
86 91
87 /*FALL THROUGH*/ 92 /*FALL THROUGH*/
88 default: 93 default:
89 /* TSC could halt in idle, so notify users */ 94 /* TSC could halt in idle */
90 mark_tsc_unstable("TSC halts in idle"); 95 tsc_detected_unstable = 1;
91 } 96 }
92#endif 97#endif
93} 98}
@@ -177,6 +182,11 @@ static int power_saving_thread(void *data)
177 expire_time = jiffies + HZ * (100 - idle_pct) / 100; 182 expire_time = jiffies + HZ * (100 - idle_pct) / 100;
178 183
179 while (!need_resched()) { 184 while (!need_resched()) {
185 if (tsc_detected_unstable && !tsc_marked_unstable) {
186 /* TSC could halt in idle, so notify users */
187 mark_tsc_unstable("TSC halts in idle");
188 tsc_marked_unstable = 1;
189 }
180 local_irq_disable(); 190 local_irq_disable();
181 cpu = smp_processor_id(); 191 cpu = smp_processor_id();
182 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, 192 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
index 837de669743a..78c55508aff5 100644
--- a/drivers/acpi/acpica/evgpe.c
+++ b/drivers/acpi/acpica/evgpe.c
@@ -117,19 +117,14 @@ acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
117 if (ACPI_FAILURE(status)) 117 if (ACPI_FAILURE(status))
118 return_ACPI_STATUS(status); 118 return_ACPI_STATUS(status);
119 119
120 /* Mark wake-enabled or HW enable, or both */ 120 /* Clear the GPE (of stale events), then enable it */
121 121 status = acpi_hw_clear_gpe(gpe_event_info);
122 if (gpe_event_info->runtime_count) { 122 if (ACPI_FAILURE(status))
123 /* Clear the GPE (of stale events), then enable it */ 123 return_ACPI_STATUS(status);
124 status = acpi_hw_clear_gpe(gpe_event_info);
125 if (ACPI_FAILURE(status))
126 return_ACPI_STATUS(status);
127
128 /* Enable the requested runtime GPE */
129 status = acpi_hw_write_gpe_enable_reg(gpe_event_info);
130 }
131 124
132 return_ACPI_STATUS(AE_OK); 125 /* Enable the requested GPE */
126 status = acpi_hw_write_gpe_enable_reg(gpe_event_info);
127 return_ACPI_STATUS(status);
133} 128}
134 129
135/******************************************************************************* 130/*******************************************************************************
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index 5ff32c78ea2d..bfbe291d572e 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -69,7 +69,7 @@ acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
69 69
70acpi_status acpi_enable(void) 70acpi_status acpi_enable(void)
71{ 71{
72 acpi_status status = AE_OK; 72 acpi_status status;
73 73
74 ACPI_FUNCTION_TRACE(acpi_enable); 74 ACPI_FUNCTION_TRACE(acpi_enable);
75 75
@@ -84,21 +84,30 @@ acpi_status acpi_enable(void)
84 if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { 84 if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
85 ACPI_DEBUG_PRINT((ACPI_DB_INIT, 85 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
86 "System is already in ACPI mode\n")); 86 "System is already in ACPI mode\n"));
87 } else { 87 return_ACPI_STATUS(AE_OK);
88 /* Transition to ACPI mode */ 88 }
89 89
90 status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI); 90 /* Transition to ACPI mode */
91 if (ACPI_FAILURE(status)) {
92 ACPI_ERROR((AE_INFO,
93 "Could not transition to ACPI mode"));
94 return_ACPI_STATUS(status);
95 }
96 91
97 ACPI_DEBUG_PRINT((ACPI_DB_INIT, 92 status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI);
98 "Transition to ACPI mode successful\n")); 93 if (ACPI_FAILURE(status)) {
94 ACPI_ERROR((AE_INFO,
95 "Could not transition to ACPI mode"));
96 return_ACPI_STATUS(status);
99 } 97 }
100 98
101 return_ACPI_STATUS(status); 99 /* Sanity check that transition succeeded */
100
101 if (acpi_hw_get_mode() != ACPI_SYS_MODE_ACPI) {
102 ACPI_ERROR((AE_INFO,
103 "Hardware did not enter ACPI mode"));
104 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
105 }
106
107 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
108 "Transition to ACPI mode successful\n"));
109
110 return_ACPI_STATUS(AE_OK);
102} 111}
103 112
104ACPI_EXPORT_SYMBOL(acpi_enable) 113ACPI_EXPORT_SYMBOL(acpi_enable)
diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c
index cc8a10268f68..7116bc86494d 100644
--- a/drivers/acpi/acpica/exmutex.c
+++ b/drivers/acpi/acpica/exmutex.c
@@ -375,8 +375,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
375 return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED); 375 return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED);
376 } 376 }
377 377
378 /* Must have a valid thread ID */ 378 /* Must have a valid thread. */
379
380 if (!walk_state->thread) { 379 if (!walk_state->thread) {
381 ACPI_ERROR((AE_INFO, 380 ACPI_ERROR((AE_INFO,
382 "Cannot release Mutex [%4.4s], null thread info", 381 "Cannot release Mutex [%4.4s], null thread info",
diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c
index edf62bf5b266..2fbfe51fb141 100644
--- a/drivers/acpi/acpica/exprep.c
+++ b/drivers/acpi/acpica/exprep.c
@@ -468,6 +468,23 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
468 468
469 acpi_ut_add_reference(obj_desc->field.region_obj); 469 acpi_ut_add_reference(obj_desc->field.region_obj);
470 470
471 /* allow full data read from EC address space */
472 if (obj_desc->field.region_obj->region.space_id ==
473 ACPI_ADR_SPACE_EC) {
474 if (obj_desc->common_field.bit_length > 8) {
475 unsigned width =
476 ACPI_ROUND_BITS_UP_TO_BYTES(
477 obj_desc->common_field.bit_length);
478 // access_bit_width is u8, don't overflow it
479 if (width > 8)
480 width = 8;
481 obj_desc->common_field.access_byte_width =
482 width;
483 obj_desc->common_field.access_bit_width =
484 8 * width;
485 }
486 }
487
471 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, 488 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
472 "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n", 489 "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n",
473 obj_desc->field.start_field_bit_offset, 490 obj_desc->field.start_field_bit_offset,
diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c
index 679a112a7d26..b44274a0b62c 100644
--- a/drivers/acpi/acpica/hwacpi.c
+++ b/drivers/acpi/acpica/hwacpi.c
@@ -63,7 +63,6 @@ acpi_status acpi_hw_set_mode(u32 mode)
63{ 63{
64 64
65 acpi_status status; 65 acpi_status status;
66 u32 retry;
67 66
68 ACPI_FUNCTION_TRACE(hw_set_mode); 67 ACPI_FUNCTION_TRACE(hw_set_mode);
69 68
@@ -125,24 +124,7 @@ acpi_status acpi_hw_set_mode(u32 mode)
125 return_ACPI_STATUS(status); 124 return_ACPI_STATUS(status);
126 } 125 }
127 126
128 /* 127 return_ACPI_STATUS(AE_OK);
129 * Some hardware takes a LONG time to switch modes. Give them 3 sec to
130 * do so, but allow faster systems to proceed more quickly.
131 */
132 retry = 3000;
133 while (retry) {
134 if (acpi_hw_get_mode() == mode) {
135 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
136 "Mode %X successfully enabled\n",
137 mode));
138 return_ACPI_STATUS(AE_OK);
139 }
140 acpi_os_stall(1000);
141 retry--;
142 }
143
144 ACPI_ERROR((AE_INFO, "Hardware did not change modes"));
145 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
146} 128}
147 129
148/******************************************************************************* 130/*******************************************************************************
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig
new file mode 100644
index 000000000000..f8c668f27b5a
--- /dev/null
+++ b/drivers/acpi/apei/Kconfig
@@ -0,0 +1,30 @@
1config ACPI_APEI
2 bool "ACPI Platform Error Interface (APEI)"
3 depends on X86
4 help
5 APEI allows to report errors (for example from the chipset)
6 to the operating system. This improves NMI handling
7 especially. In addition it supports error serialization and
8 error injection.
9
10config ACPI_APEI_GHES
11 tristate "APEI Generic Hardware Error Source"
12 depends on ACPI_APEI && X86
13 select ACPI_HED
14 help
15 Generic Hardware Error Source provides a way to report
16 platform hardware errors (such as that from chipset). It
17 works in so called "Firmware First" mode, that is, hardware
18 errors are reported to firmware firstly, then reported to
19 Linux by firmware. This way, some non-standard hardware
20 error registers or non-standard hardware link can be checked
21 by firmware to produce more valuable hardware error
22 information for Linux.
23
24config ACPI_APEI_EINJ
25 tristate "APEI Error INJection (EINJ)"
26 depends on ACPI_APEI && DEBUG_FS
27 help
28 EINJ provides a hardware error injection mechanism, it is
29 mainly used for debugging and testing the other parts of
30 APEI and some other RAS features.
diff --git a/drivers/acpi/apei/Makefile b/drivers/acpi/apei/Makefile
new file mode 100644
index 000000000000..b13b03a17789
--- /dev/null
+++ b/drivers/acpi/apei/Makefile
@@ -0,0 +1,5 @@
1obj-$(CONFIG_ACPI_APEI) += apei.o
2obj-$(CONFIG_ACPI_APEI_GHES) += ghes.o
3obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o
4
5apei-y := apei-base.o hest.o cper.o erst.o
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c
new file mode 100644
index 000000000000..db3946e9c66b
--- /dev/null
+++ b/drivers/acpi/apei/apei-base.c
@@ -0,0 +1,593 @@
1/*
2 * apei-base.c - ACPI Platform Error Interface (APEI) supporting
3 * infrastructure
4 *
5 * APEI allows to report errors (for example from the chipset) to the
6 * the operating system. This improves NMI handling especially. In
7 * addition it supports error serialization and error injection.
8 *
9 * For more information about APEI, please refer to ACPI Specification
10 * version 4.0, chapter 17.
11 *
12 * This file has Common functions used by more than one APEI table,
13 * including framework of interpreter for ERST and EINJ; resource
14 * management for APEI registers.
15 *
16 * Copyright (C) 2009, Intel Corp.
17 * Author: Huang Ying <ying.huang@intel.com>
18 *
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License version
21 * 2 as published by the Free Software Foundation.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 */
32
33#include <linux/kernel.h>
34#include <linux/module.h>
35#include <linux/init.h>
36#include <linux/acpi.h>
37#include <linux/io.h>
38#include <linux/kref.h>
39#include <linux/rculist.h>
40#include <linux/interrupt.h>
41#include <linux/debugfs.h>
42#include <acpi/atomicio.h>
43
44#include "apei-internal.h"
45
46#define APEI_PFX "APEI: "
47
48/*
49 * APEI ERST (Error Record Serialization Table) and EINJ (Error
50 * INJection) interpreter framework.
51 */
52
53#define APEI_EXEC_PRESERVE_REGISTER 0x1
54
55void apei_exec_ctx_init(struct apei_exec_context *ctx,
56 struct apei_exec_ins_type *ins_table,
57 u32 instructions,
58 struct acpi_whea_header *action_table,
59 u32 entries)
60{
61 ctx->ins_table = ins_table;
62 ctx->instructions = instructions;
63 ctx->action_table = action_table;
64 ctx->entries = entries;
65}
66EXPORT_SYMBOL_GPL(apei_exec_ctx_init);
67
68int __apei_exec_read_register(struct acpi_whea_header *entry, u64 *val)
69{
70 int rc;
71
72 rc = acpi_atomic_read(val, &entry->register_region);
73 if (rc)
74 return rc;
75 *val >>= entry->register_region.bit_offset;
76 *val &= entry->mask;
77
78 return 0;
79}
80
81int apei_exec_read_register(struct apei_exec_context *ctx,
82 struct acpi_whea_header *entry)
83{
84 int rc;
85 u64 val = 0;
86
87 rc = __apei_exec_read_register(entry, &val);
88 if (rc)
89 return rc;
90 ctx->value = val;
91
92 return 0;
93}
94EXPORT_SYMBOL_GPL(apei_exec_read_register);
95
96int apei_exec_read_register_value(struct apei_exec_context *ctx,
97 struct acpi_whea_header *entry)
98{
99 int rc;
100
101 rc = apei_exec_read_register(ctx, entry);
102 if (rc)
103 return rc;
104 ctx->value = (ctx->value == entry->value);
105
106 return 0;
107}
108EXPORT_SYMBOL_GPL(apei_exec_read_register_value);
109
110int __apei_exec_write_register(struct acpi_whea_header *entry, u64 val)
111{
112 int rc;
113
114 val &= entry->mask;
115 val <<= entry->register_region.bit_offset;
116 if (entry->flags & APEI_EXEC_PRESERVE_REGISTER) {
117 u64 valr = 0;
118 rc = acpi_atomic_read(&valr, &entry->register_region);
119 if (rc)
120 return rc;
121 valr &= ~(entry->mask << entry->register_region.bit_offset);
122 val |= valr;
123 }
124 rc = acpi_atomic_write(val, &entry->register_region);
125
126 return rc;
127}
128
129int apei_exec_write_register(struct apei_exec_context *ctx,
130 struct acpi_whea_header *entry)
131{
132 return __apei_exec_write_register(entry, ctx->value);
133}
134EXPORT_SYMBOL_GPL(apei_exec_write_register);
135
136int apei_exec_write_register_value(struct apei_exec_context *ctx,
137 struct acpi_whea_header *entry)
138{
139 int rc;
140
141 ctx->value = entry->value;
142 rc = apei_exec_write_register(ctx, entry);
143
144 return rc;
145}
146EXPORT_SYMBOL_GPL(apei_exec_write_register_value);
147
148int apei_exec_noop(struct apei_exec_context *ctx,
149 struct acpi_whea_header *entry)
150{
151 return 0;
152}
153EXPORT_SYMBOL_GPL(apei_exec_noop);
154
155/*
156 * Interpret the specified action. Go through whole action table,
157 * execute all instructions belong to the action.
158 */
159int apei_exec_run(struct apei_exec_context *ctx, u8 action)
160{
161 int rc;
162 u32 i, ip;
163 struct acpi_whea_header *entry;
164 apei_exec_ins_func_t run;
165
166 ctx->ip = 0;
167
168 /*
169 * "ip" is the instruction pointer of current instruction,
170 * "ctx->ip" specifies the next instruction to executed,
171 * instruction "run" function may change the "ctx->ip" to
172 * implement "goto" semantics.
173 */
174rewind:
175 ip = 0;
176 for (i = 0; i < ctx->entries; i++) {
177 entry = &ctx->action_table[i];
178 if (entry->action != action)
179 continue;
180 if (ip == ctx->ip) {
181 if (entry->instruction >= ctx->instructions ||
182 !ctx->ins_table[entry->instruction].run) {
183 pr_warning(FW_WARN APEI_PFX
184 "Invalid action table, unknown instruction type: %d\n",
185 entry->instruction);
186 return -EINVAL;
187 }
188 run = ctx->ins_table[entry->instruction].run;
189 rc = run(ctx, entry);
190 if (rc < 0)
191 return rc;
192 else if (rc != APEI_EXEC_SET_IP)
193 ctx->ip++;
194 }
195 ip++;
196 if (ctx->ip < ip)
197 goto rewind;
198 }
199
200 return 0;
201}
202EXPORT_SYMBOL_GPL(apei_exec_run);
203
204typedef int (*apei_exec_entry_func_t)(struct apei_exec_context *ctx,
205 struct acpi_whea_header *entry,
206 void *data);
207
208static int apei_exec_for_each_entry(struct apei_exec_context *ctx,
209 apei_exec_entry_func_t func,
210 void *data,
211 int *end)
212{
213 u8 ins;
214 int i, rc;
215 struct acpi_whea_header *entry;
216 struct apei_exec_ins_type *ins_table = ctx->ins_table;
217
218 for (i = 0; i < ctx->entries; i++) {
219 entry = ctx->action_table + i;
220 ins = entry->instruction;
221 if (end)
222 *end = i;
223 if (ins >= ctx->instructions || !ins_table[ins].run) {
224 pr_warning(FW_WARN APEI_PFX
225 "Invalid action table, unknown instruction type: %d\n",
226 ins);
227 return -EINVAL;
228 }
229 rc = func(ctx, entry, data);
230 if (rc)
231 return rc;
232 }
233
234 return 0;
235}
236
237static int pre_map_gar_callback(struct apei_exec_context *ctx,
238 struct acpi_whea_header *entry,
239 void *data)
240{
241 u8 ins = entry->instruction;
242
243 if (ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER)
244 return acpi_pre_map_gar(&entry->register_region);
245
246 return 0;
247}
248
249/*
250 * Pre-map all GARs in action table to make it possible to access them
251 * in NMI handler.
252 */
253int apei_exec_pre_map_gars(struct apei_exec_context *ctx)
254{
255 int rc, end;
256
257 rc = apei_exec_for_each_entry(ctx, pre_map_gar_callback,
258 NULL, &end);
259 if (rc) {
260 struct apei_exec_context ctx_unmap;
261 memcpy(&ctx_unmap, ctx, sizeof(*ctx));
262 ctx_unmap.entries = end;
263 apei_exec_post_unmap_gars(&ctx_unmap);
264 }
265
266 return rc;
267}
268EXPORT_SYMBOL_GPL(apei_exec_pre_map_gars);
269
270static int post_unmap_gar_callback(struct apei_exec_context *ctx,
271 struct acpi_whea_header *entry,
272 void *data)
273{
274 u8 ins = entry->instruction;
275
276 if (ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER)
277 acpi_post_unmap_gar(&entry->register_region);
278
279 return 0;
280}
281
282/* Post-unmap all GAR in action table. */
283int apei_exec_post_unmap_gars(struct apei_exec_context *ctx)
284{
285 return apei_exec_for_each_entry(ctx, post_unmap_gar_callback,
286 NULL, NULL);
287}
288EXPORT_SYMBOL_GPL(apei_exec_post_unmap_gars);
289
290/*
291 * Resource management for GARs in APEI
292 */
293struct apei_res {
294 struct list_head list;
295 unsigned long start;
296 unsigned long end;
297};
298
299/* Collect all resources requested, to avoid conflict */
300struct apei_resources apei_resources_all = {
301 .iomem = LIST_HEAD_INIT(apei_resources_all.iomem),
302 .ioport = LIST_HEAD_INIT(apei_resources_all.ioport),
303};
304
305static int apei_res_add(struct list_head *res_list,
306 unsigned long start, unsigned long size)
307{
308 struct apei_res *res, *resn, *res_ins = NULL;
309 unsigned long end = start + size;
310
311 if (end <= start)
312 return 0;
313repeat:
314 list_for_each_entry_safe(res, resn, res_list, list) {
315 if (res->start > end || res->end < start)
316 continue;
317 else if (end <= res->end && start >= res->start) {
318 kfree(res_ins);
319 return 0;
320 }
321 list_del(&res->list);
322 res->start = start = min(res->start, start);
323 res->end = end = max(res->end, end);
324 kfree(res_ins);
325 res_ins = res;
326 goto repeat;
327 }
328
329 if (res_ins)
330 list_add(&res_ins->list, res_list);
331 else {
332 res_ins = kmalloc(sizeof(*res), GFP_KERNEL);
333 if (!res_ins)
334 return -ENOMEM;
335 res_ins->start = start;
336 res_ins->end = end;
337 list_add(&res_ins->list, res_list);
338 }
339
340 return 0;
341}
342
343static int apei_res_sub(struct list_head *res_list1,
344 struct list_head *res_list2)
345{
346 struct apei_res *res1, *resn1, *res2, *res;
347 res1 = list_entry(res_list1->next, struct apei_res, list);
348 resn1 = list_entry(res1->list.next, struct apei_res, list);
349 while (&res1->list != res_list1) {
350 list_for_each_entry(res2, res_list2, list) {
351 if (res1->start >= res2->end ||
352 res1->end <= res2->start)
353 continue;
354 else if (res1->end <= res2->end &&
355 res1->start >= res2->start) {
356 list_del(&res1->list);
357 kfree(res1);
358 break;
359 } else if (res1->end > res2->end &&
360 res1->start < res2->start) {
361 res = kmalloc(sizeof(*res), GFP_KERNEL);
362 if (!res)
363 return -ENOMEM;
364 res->start = res2->end;
365 res->end = res1->end;
366 res1->end = res2->start;
367 list_add(&res->list, &res1->list);
368 resn1 = res;
369 } else {
370 if (res1->start < res2->start)
371 res1->end = res2->start;
372 else
373 res1->start = res2->end;
374 }
375 }
376 res1 = resn1;
377 resn1 = list_entry(resn1->list.next, struct apei_res, list);
378 }
379
380 return 0;
381}
382
383static void apei_res_clean(struct list_head *res_list)
384{
385 struct apei_res *res, *resn;
386
387 list_for_each_entry_safe(res, resn, res_list, list) {
388 list_del(&res->list);
389 kfree(res);
390 }
391}
392
393void apei_resources_fini(struct apei_resources *resources)
394{
395 apei_res_clean(&resources->iomem);
396 apei_res_clean(&resources->ioport);
397}
398EXPORT_SYMBOL_GPL(apei_resources_fini);
399
400static int apei_resources_merge(struct apei_resources *resources1,
401 struct apei_resources *resources2)
402{
403 int rc;
404 struct apei_res *res;
405
406 list_for_each_entry(res, &resources2->iomem, list) {
407 rc = apei_res_add(&resources1->iomem, res->start,
408 res->end - res->start);
409 if (rc)
410 return rc;
411 }
412 list_for_each_entry(res, &resources2->ioport, list) {
413 rc = apei_res_add(&resources1->ioport, res->start,
414 res->end - res->start);
415 if (rc)
416 return rc;
417 }
418
419 return 0;
420}
421
422/*
423 * EINJ has two groups of GARs (EINJ table entry and trigger table
424 * entry), so common resources are subtracted from the trigger table
425 * resources before the second requesting.
426 */
427int apei_resources_sub(struct apei_resources *resources1,
428 struct apei_resources *resources2)
429{
430 int rc;
431
432 rc = apei_res_sub(&resources1->iomem, &resources2->iomem);
433 if (rc)
434 return rc;
435 return apei_res_sub(&resources1->ioport, &resources2->ioport);
436}
437EXPORT_SYMBOL_GPL(apei_resources_sub);
438
439/*
440 * IO memory/port rersource management mechanism is used to check
441 * whether memory/port area used by GARs conflicts with normal memory
442 * or IO memory/port of devices.
443 */
444int apei_resources_request(struct apei_resources *resources,
445 const char *desc)
446{
447 struct apei_res *res, *res_bak;
448 struct resource *r;
449
450 apei_resources_sub(resources, &apei_resources_all);
451
452 list_for_each_entry(res, &resources->iomem, list) {
453 r = request_mem_region(res->start, res->end - res->start,
454 desc);
455 if (!r) {
456 pr_err(APEI_PFX
457 "Can not request iomem region <%016llx-%016llx> for GARs.\n",
458 (unsigned long long)res->start,
459 (unsigned long long)res->end);
460 res_bak = res;
461 goto err_unmap_iomem;
462 }
463 }
464
465 list_for_each_entry(res, &resources->ioport, list) {
466 r = request_region(res->start, res->end - res->start, desc);
467 if (!r) {
468 pr_err(APEI_PFX
469 "Can not request ioport region <%016llx-%016llx> for GARs.\n",
470 (unsigned long long)res->start,
471 (unsigned long long)res->end);
472 res_bak = res;
473 goto err_unmap_ioport;
474 }
475 }
476
477 apei_resources_merge(&apei_resources_all, resources);
478
479 return 0;
480err_unmap_ioport:
481 list_for_each_entry(res, &resources->ioport, list) {
482 if (res == res_bak)
483 break;
484 release_mem_region(res->start, res->end - res->start);
485 }
486 res_bak = NULL;
487err_unmap_iomem:
488 list_for_each_entry(res, &resources->iomem, list) {
489 if (res == res_bak)
490 break;
491 release_region(res->start, res->end - res->start);
492 }
493 return -EINVAL;
494}
495EXPORT_SYMBOL_GPL(apei_resources_request);
496
497void apei_resources_release(struct apei_resources *resources)
498{
499 struct apei_res *res;
500
501 list_for_each_entry(res, &resources->iomem, list)
502 release_mem_region(res->start, res->end - res->start);
503 list_for_each_entry(res, &resources->ioport, list)
504 release_region(res->start, res->end - res->start);
505
506 apei_resources_sub(&apei_resources_all, resources);
507}
508EXPORT_SYMBOL_GPL(apei_resources_release);
509
510static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr)
511{
512 u32 width, space_id;
513
514 width = reg->bit_width;
515 space_id = reg->space_id;
516 /* Handle possible alignment issues */
517 memcpy(paddr, &reg->address, sizeof(*paddr));
518 if (!*paddr) {
519 pr_warning(FW_BUG APEI_PFX
520 "Invalid physical address in GAR [0x%llx/%u/%u]\n",
521 *paddr, width, space_id);
522 return -EINVAL;
523 }
524
525 if ((width != 8) && (width != 16) && (width != 32) && (width != 64)) {
526 pr_warning(FW_BUG APEI_PFX
527 "Invalid bit width in GAR [0x%llx/%u/%u]\n",
528 *paddr, width, space_id);
529 return -EINVAL;
530 }
531
532 if (space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY &&
533 space_id != ACPI_ADR_SPACE_SYSTEM_IO) {
534 pr_warning(FW_BUG APEI_PFX
535 "Invalid address space type in GAR [0x%llx/%u/%u]\n",
536 *paddr, width, space_id);
537 return -EINVAL;
538 }
539
540 return 0;
541}
542
543static int collect_res_callback(struct apei_exec_context *ctx,
544 struct acpi_whea_header *entry,
545 void *data)
546{
547 struct apei_resources *resources = data;
548 struct acpi_generic_address *reg = &entry->register_region;
549 u8 ins = entry->instruction;
550 u64 paddr;
551 int rc;
552
553 if (!(ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER))
554 return 0;
555
556 rc = apei_check_gar(reg, &paddr);
557 if (rc)
558 return rc;
559
560 switch (reg->space_id) {
561 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
562 return apei_res_add(&resources->iomem, paddr,
563 reg->bit_width / 8);
564 case ACPI_ADR_SPACE_SYSTEM_IO:
565 return apei_res_add(&resources->ioport, paddr,
566 reg->bit_width / 8);
567 default:
568 return -EINVAL;
569 }
570}
571
572/*
573 * Same register may be used by multiple instructions in GARs, so
574 * resources are collected before requesting.
575 */
576int apei_exec_collect_resources(struct apei_exec_context *ctx,
577 struct apei_resources *resources)
578{
579 return apei_exec_for_each_entry(ctx, collect_res_callback,
580 resources, NULL);
581}
582EXPORT_SYMBOL_GPL(apei_exec_collect_resources);
583
584struct dentry *apei_get_debugfs_dir(void)
585{
586 static struct dentry *dapei;
587
588 if (!dapei)
589 dapei = debugfs_create_dir("apei", NULL);
590
591 return dapei;
592}
593EXPORT_SYMBOL_GPL(apei_get_debugfs_dir);
diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h
new file mode 100644
index 000000000000..18df1e940276
--- /dev/null
+++ b/drivers/acpi/apei/apei-internal.h
@@ -0,0 +1,114 @@
1/*
2 * apei-internal.h - ACPI Platform Error Interface internal
3 * definations.
4 */
5
6#ifndef APEI_INTERNAL_H
7#define APEI_INTERNAL_H
8
9#include <linux/cper.h>
10
11struct apei_exec_context;
12
13typedef int (*apei_exec_ins_func_t)(struct apei_exec_context *ctx,
14 struct acpi_whea_header *entry);
15
16#define APEI_EXEC_INS_ACCESS_REGISTER 0x0001
17
18struct apei_exec_ins_type {
19 u32 flags;
20 apei_exec_ins_func_t run;
21};
22
23struct apei_exec_context {
24 u32 ip;
25 u64 value;
26 u64 var1;
27 u64 var2;
28 u64 src_base;
29 u64 dst_base;
30 struct apei_exec_ins_type *ins_table;
31 u32 instructions;
32 struct acpi_whea_header *action_table;
33 u32 entries;
34};
35
36void apei_exec_ctx_init(struct apei_exec_context *ctx,
37 struct apei_exec_ins_type *ins_table,
38 u32 instructions,
39 struct acpi_whea_header *action_table,
40 u32 entries);
41
42static inline void apei_exec_ctx_set_input(struct apei_exec_context *ctx,
43 u64 input)
44{
45 ctx->value = input;
46}
47
48static inline u64 apei_exec_ctx_get_output(struct apei_exec_context *ctx)
49{
50 return ctx->value;
51}
52
53int apei_exec_run(struct apei_exec_context *ctx, u8 action);
54
55/* Common instruction implementation */
56
57/* IP has been set in instruction function */
58#define APEI_EXEC_SET_IP 1
59
60int __apei_exec_read_register(struct acpi_whea_header *entry, u64 *val);
61int __apei_exec_write_register(struct acpi_whea_header *entry, u64 val);
62int apei_exec_read_register(struct apei_exec_context *ctx,
63 struct acpi_whea_header *entry);
64int apei_exec_read_register_value(struct apei_exec_context *ctx,
65 struct acpi_whea_header *entry);
66int apei_exec_write_register(struct apei_exec_context *ctx,
67 struct acpi_whea_header *entry);
68int apei_exec_write_register_value(struct apei_exec_context *ctx,
69 struct acpi_whea_header *entry);
70int apei_exec_noop(struct apei_exec_context *ctx,
71 struct acpi_whea_header *entry);
72int apei_exec_pre_map_gars(struct apei_exec_context *ctx);
73int apei_exec_post_unmap_gars(struct apei_exec_context *ctx);
74
75struct apei_resources {
76 struct list_head iomem;
77 struct list_head ioport;
78};
79
80static inline void apei_resources_init(struct apei_resources *resources)
81{
82 INIT_LIST_HEAD(&resources->iomem);
83 INIT_LIST_HEAD(&resources->ioport);
84}
85
86void apei_resources_fini(struct apei_resources *resources);
87int apei_resources_sub(struct apei_resources *resources1,
88 struct apei_resources *resources2);
89int apei_resources_request(struct apei_resources *resources,
90 const char *desc);
91void apei_resources_release(struct apei_resources *resources);
92int apei_exec_collect_resources(struct apei_exec_context *ctx,
93 struct apei_resources *resources);
94
95struct dentry;
96struct dentry *apei_get_debugfs_dir(void);
97
98#define apei_estatus_for_each_section(estatus, section) \
99 for (section = (struct acpi_hest_generic_data *)(estatus + 1); \
100 (void *)section - (void *)estatus < estatus->data_length; \
101 section = (void *)(section+1) + section->error_data_length)
102
103static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus)
104{
105 if (estatus->raw_data_length)
106 return estatus->raw_data_offset + \
107 estatus->raw_data_length;
108 else
109 return sizeof(*estatus) + estatus->data_length;
110}
111
112int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus);
113int apei_estatus_check(const struct acpi_hest_generic_status *estatus);
114#endif
diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c
new file mode 100644
index 000000000000..f4cf2fc4c8c1
--- /dev/null
+++ b/drivers/acpi/apei/cper.c
@@ -0,0 +1,84 @@
1/*
2 * UEFI Common Platform Error Record (CPER) support
3 *
4 * Copyright (C) 2010, Intel Corp.
5 * Author: Huang Ying <ying.huang@intel.com>
6 *
7 * CPER is the format used to describe platform hardware error by
8 * various APEI tables, such as ERST, BERT and HEST etc.
9 *
10 * For more information about CPER, please refer to Appendix N of UEFI
11 * Specification version 2.3.
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License version
15 * 2 as published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/time.h>
30#include <linux/cper.h>
31#include <linux/acpi.h>
32
33/*
34 * CPER record ID need to be unique even after reboot, because record
35 * ID is used as index for ERST storage, while CPER records from
36 * multiple boot may co-exist in ERST.
37 */
38u64 cper_next_record_id(void)
39{
40 static atomic64_t seq;
41
42 if (!atomic64_read(&seq))
43 atomic64_set(&seq, ((u64)get_seconds()) << 32);
44
45 return atomic64_inc_return(&seq);
46}
47EXPORT_SYMBOL_GPL(cper_next_record_id);
48
49int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus)
50{
51 if (estatus->data_length &&
52 estatus->data_length < sizeof(struct acpi_hest_generic_data))
53 return -EINVAL;
54 if (estatus->raw_data_length &&
55 estatus->raw_data_offset < sizeof(*estatus) + estatus->data_length)
56 return -EINVAL;
57
58 return 0;
59}
60EXPORT_SYMBOL_GPL(apei_estatus_check_header);
61
62int apei_estatus_check(const struct acpi_hest_generic_status *estatus)
63{
64 struct acpi_hest_generic_data *gdata;
65 unsigned int data_len, gedata_len;
66 int rc;
67
68 rc = apei_estatus_check_header(estatus);
69 if (rc)
70 return rc;
71 data_len = estatus->data_length;
72 gdata = (struct acpi_hest_generic_data *)(estatus + 1);
73 while (data_len > sizeof(*gdata)) {
74 gedata_len = gdata->error_data_length;
75 if (gedata_len > data_len - sizeof(*gdata))
76 return -EINVAL;
77 data_len -= gedata_len + sizeof(*gdata);
78 }
79 if (data_len)
80 return -EINVAL;
81
82 return 0;
83}
84EXPORT_SYMBOL_GPL(apei_estatus_check);
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
new file mode 100644
index 000000000000..465c885938ee
--- /dev/null
+++ b/drivers/acpi/apei/einj.c
@@ -0,0 +1,548 @@
1/*
2 * APEI Error INJection support
3 *
4 * EINJ provides a hardware error injection mechanism, this is useful
5 * for debugging and testing of other APEI and RAS features.
6 *
7 * For more information about EINJ, please refer to ACPI Specification
8 * version 4.0, section 17.5.
9 *
10 * Copyright 2009-2010 Intel Corp.
11 * Author: Huang Ying <ying.huang@intel.com>
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License version
15 * 2 as published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/io.h>
31#include <linux/debugfs.h>
32#include <linux/seq_file.h>
33#include <linux/nmi.h>
34#include <linux/delay.h>
35#include <acpi/acpi.h>
36
37#include "apei-internal.h"
38
39#define EINJ_PFX "EINJ: "
40
41#define SPIN_UNIT 100 /* 100ns */
42/* Firmware should respond within 1 miliseconds */
43#define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC)
44
45/*
46 * Some BIOSes allow parameters to the SET_ERROR_TYPE entries in the
47 * EINJ table through an unpublished extension. Use with caution as
48 * most will ignore the parameter and make their own choice of address
49 * for error injection.
50 */
51struct einj_parameter {
52 u64 type;
53 u64 reserved1;
54 u64 reserved2;
55 u64 param1;
56 u64 param2;
57};
58
59#define EINJ_OP_BUSY 0x1
60#define EINJ_STATUS_SUCCESS 0x0
61#define EINJ_STATUS_FAIL 0x1
62#define EINJ_STATUS_INVAL 0x2
63
64#define EINJ_TAB_ENTRY(tab) \
65 ((struct acpi_whea_header *)((char *)(tab) + \
66 sizeof(struct acpi_table_einj)))
67
68static struct acpi_table_einj *einj_tab;
69
70static struct apei_resources einj_resources;
71
72static struct apei_exec_ins_type einj_ins_type[] = {
73 [ACPI_EINJ_READ_REGISTER] = {
74 .flags = APEI_EXEC_INS_ACCESS_REGISTER,
75 .run = apei_exec_read_register,
76 },
77 [ACPI_EINJ_READ_REGISTER_VALUE] = {
78 .flags = APEI_EXEC_INS_ACCESS_REGISTER,
79 .run = apei_exec_read_register_value,
80 },
81 [ACPI_EINJ_WRITE_REGISTER] = {
82 .flags = APEI_EXEC_INS_ACCESS_REGISTER,
83 .run = apei_exec_write_register,
84 },
85 [ACPI_EINJ_WRITE_REGISTER_VALUE] = {
86 .flags = APEI_EXEC_INS_ACCESS_REGISTER,
87 .run = apei_exec_write_register_value,
88 },
89 [ACPI_EINJ_NOOP] = {
90 .flags = 0,
91 .run = apei_exec_noop,
92 },
93};
94
95/*
96 * Prevent EINJ interpreter to run simultaneously, because the
97 * corresponding firmware implementation may not work properly when
98 * invoked simultaneously.
99 */
100static DEFINE_MUTEX(einj_mutex);
101
102static struct einj_parameter *einj_param;
103
104static void einj_exec_ctx_init(struct apei_exec_context *ctx)
105{
106 apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type),
107 EINJ_TAB_ENTRY(einj_tab), einj_tab->entries);
108}
109
110static int __einj_get_available_error_type(u32 *type)
111{
112 struct apei_exec_context ctx;
113 int rc;
114
115 einj_exec_ctx_init(&ctx);
116 rc = apei_exec_run(&ctx, ACPI_EINJ_GET_ERROR_TYPE);
117 if (rc)
118 return rc;
119 *type = apei_exec_ctx_get_output(&ctx);
120
121 return 0;
122}
123
124/* Get error injection capabilities of the platform */
125static int einj_get_available_error_type(u32 *type)
126{
127 int rc;
128
129 mutex_lock(&einj_mutex);
130 rc = __einj_get_available_error_type(type);
131 mutex_unlock(&einj_mutex);
132
133 return rc;
134}
135
136static int einj_timedout(u64 *t)
137{
138 if ((s64)*t < SPIN_UNIT) {
139 pr_warning(FW_WARN EINJ_PFX
140 "Firmware does not respond in time\n");
141 return 1;
142 }
143 *t -= SPIN_UNIT;
144 ndelay(SPIN_UNIT);
145 touch_nmi_watchdog();
146 return 0;
147}
148
149static u64 einj_get_parameter_address(void)
150{
151 int i;
152 u64 paddr = 0;
153 struct acpi_whea_header *entry;
154
155 entry = EINJ_TAB_ENTRY(einj_tab);
156 for (i = 0; i < einj_tab->entries; i++) {
157 if (entry->action == ACPI_EINJ_SET_ERROR_TYPE &&
158 entry->instruction == ACPI_EINJ_WRITE_REGISTER &&
159 entry->register_region.space_id ==
160 ACPI_ADR_SPACE_SYSTEM_MEMORY)
161 memcpy(&paddr, &entry->register_region.address,
162 sizeof(paddr));
163 entry++;
164 }
165
166 return paddr;
167}
168
169/* do sanity check to trigger table */
170static int einj_check_trigger_header(struct acpi_einj_trigger *trigger_tab)
171{
172 if (trigger_tab->header_size != sizeof(struct acpi_einj_trigger))
173 return -EINVAL;
174 if (trigger_tab->table_size > PAGE_SIZE ||
175 trigger_tab->table_size <= trigger_tab->header_size)
176 return -EINVAL;
177 if (trigger_tab->entry_count !=
178 (trigger_tab->table_size - trigger_tab->header_size) /
179 sizeof(struct acpi_einj_entry))
180 return -EINVAL;
181
182 return 0;
183}
184
185/* Execute instructions in trigger error action table */
186static int __einj_error_trigger(u64 trigger_paddr)
187{
188 struct acpi_einj_trigger *trigger_tab = NULL;
189 struct apei_exec_context trigger_ctx;
190 struct apei_resources trigger_resources;
191 struct acpi_whea_header *trigger_entry;
192 struct resource *r;
193 u32 table_size;
194 int rc = -EIO;
195
196 r = request_mem_region(trigger_paddr, sizeof(*trigger_tab),
197 "APEI EINJ Trigger Table");
198 if (!r) {
199 pr_err(EINJ_PFX
200 "Can not request iomem region <%016llx-%016llx> for Trigger table.\n",
201 (unsigned long long)trigger_paddr,
202 (unsigned long long)trigger_paddr+sizeof(*trigger_tab));
203 goto out;
204 }
205 trigger_tab = ioremap_cache(trigger_paddr, sizeof(*trigger_tab));
206 if (!trigger_tab) {
207 pr_err(EINJ_PFX "Failed to map trigger table!\n");
208 goto out_rel_header;
209 }
210 rc = einj_check_trigger_header(trigger_tab);
211 if (rc) {
212 pr_warning(FW_BUG EINJ_PFX
213 "The trigger error action table is invalid\n");
214 goto out_rel_header;
215 }
216 rc = -EIO;
217 table_size = trigger_tab->table_size;
218 r = request_mem_region(trigger_paddr + sizeof(*trigger_tab),
219 table_size - sizeof(*trigger_tab),
220 "APEI EINJ Trigger Table");
221 if (!r) {
222 pr_err(EINJ_PFX
223"Can not request iomem region <%016llx-%016llx> for Trigger Table Entry.\n",
224 (unsigned long long)trigger_paddr+sizeof(*trigger_tab),
225 (unsigned long long)trigger_paddr + table_size);
226 goto out_rel_header;
227 }
228 iounmap(trigger_tab);
229 trigger_tab = ioremap_cache(trigger_paddr, table_size);
230 if (!trigger_tab) {
231 pr_err(EINJ_PFX "Failed to map trigger table!\n");
232 goto out_rel_entry;
233 }
234 trigger_entry = (struct acpi_whea_header *)
235 ((char *)trigger_tab + sizeof(struct acpi_einj_trigger));
236 apei_resources_init(&trigger_resources);
237 apei_exec_ctx_init(&trigger_ctx, einj_ins_type,
238 ARRAY_SIZE(einj_ins_type),
239 trigger_entry, trigger_tab->entry_count);
240 rc = apei_exec_collect_resources(&trigger_ctx, &trigger_resources);
241 if (rc)
242 goto out_fini;
243 rc = apei_resources_sub(&trigger_resources, &einj_resources);
244 if (rc)
245 goto out_fini;
246 rc = apei_resources_request(&trigger_resources, "APEI EINJ Trigger");
247 if (rc)
248 goto out_fini;
249 rc = apei_exec_pre_map_gars(&trigger_ctx);
250 if (rc)
251 goto out_release;
252
253 rc = apei_exec_run(&trigger_ctx, ACPI_EINJ_TRIGGER_ERROR);
254
255 apei_exec_post_unmap_gars(&trigger_ctx);
256out_release:
257 apei_resources_release(&trigger_resources);
258out_fini:
259 apei_resources_fini(&trigger_resources);
260out_rel_entry:
261 release_mem_region(trigger_paddr + sizeof(*trigger_tab),
262 table_size - sizeof(*trigger_tab));
263out_rel_header:
264 release_mem_region(trigger_paddr, sizeof(*trigger_tab));
265out:
266 if (trigger_tab)
267 iounmap(trigger_tab);
268
269 return rc;
270}
271
272static int __einj_error_inject(u32 type, u64 param1, u64 param2)
273{
274 struct apei_exec_context ctx;
275 u64 val, trigger_paddr, timeout = FIRMWARE_TIMEOUT;
276 int rc;
277
278 einj_exec_ctx_init(&ctx);
279
280 rc = apei_exec_run(&ctx, ACPI_EINJ_BEGIN_OPERATION);
281 if (rc)
282 return rc;
283 apei_exec_ctx_set_input(&ctx, type);
284 rc = apei_exec_run(&ctx, ACPI_EINJ_SET_ERROR_TYPE);
285 if (rc)
286 return rc;
287 if (einj_param) {
288 writeq(param1, &einj_param->param1);
289 writeq(param2, &einj_param->param2);
290 }
291 rc = apei_exec_run(&ctx, ACPI_EINJ_EXECUTE_OPERATION);
292 if (rc)
293 return rc;
294 for (;;) {
295 rc = apei_exec_run(&ctx, ACPI_EINJ_CHECK_BUSY_STATUS);
296 if (rc)
297 return rc;
298 val = apei_exec_ctx_get_output(&ctx);
299 if (!(val & EINJ_OP_BUSY))
300 break;
301 if (einj_timedout(&timeout))
302 return -EIO;
303 }
304 rc = apei_exec_run(&ctx, ACPI_EINJ_GET_COMMAND_STATUS);
305 if (rc)
306 return rc;
307 val = apei_exec_ctx_get_output(&ctx);
308 if (val != EINJ_STATUS_SUCCESS)
309 return -EBUSY;
310
311 rc = apei_exec_run(&ctx, ACPI_EINJ_GET_TRIGGER_TABLE);
312 if (rc)
313 return rc;
314 trigger_paddr = apei_exec_ctx_get_output(&ctx);
315 rc = __einj_error_trigger(trigger_paddr);
316 if (rc)
317 return rc;
318 rc = apei_exec_run(&ctx, ACPI_EINJ_END_OPERATION);
319
320 return rc;
321}
322
323/* Inject the specified hardware error */
324static int einj_error_inject(u32 type, u64 param1, u64 param2)
325{
326 int rc;
327
328 mutex_lock(&einj_mutex);
329 rc = __einj_error_inject(type, param1, param2);
330 mutex_unlock(&einj_mutex);
331
332 return rc;
333}
334
335static u32 error_type;
336static u64 error_param1;
337static u64 error_param2;
338static struct dentry *einj_debug_dir;
339
340static int available_error_type_show(struct seq_file *m, void *v)
341{
342 int rc;
343 u32 available_error_type = 0;
344
345 rc = einj_get_available_error_type(&available_error_type);
346 if (rc)
347 return rc;
348 if (available_error_type & 0x0001)
349 seq_printf(m, "0x00000001\tProcessor Correctable\n");
350 if (available_error_type & 0x0002)
351 seq_printf(m, "0x00000002\tProcessor Uncorrectable non-fatal\n");
352 if (available_error_type & 0x0004)
353 seq_printf(m, "0x00000004\tProcessor Uncorrectable fatal\n");
354 if (available_error_type & 0x0008)
355 seq_printf(m, "0x00000008\tMemory Correctable\n");
356 if (available_error_type & 0x0010)
357 seq_printf(m, "0x00000010\tMemory Uncorrectable non-fatal\n");
358 if (available_error_type & 0x0020)
359 seq_printf(m, "0x00000020\tMemory Uncorrectable fatal\n");
360 if (available_error_type & 0x0040)
361 seq_printf(m, "0x00000040\tPCI Express Correctable\n");
362 if (available_error_type & 0x0080)
363 seq_printf(m, "0x00000080\tPCI Express Uncorrectable non-fatal\n");
364 if (available_error_type & 0x0100)
365 seq_printf(m, "0x00000100\tPCI Express Uncorrectable fatal\n");
366 if (available_error_type & 0x0200)
367 seq_printf(m, "0x00000200\tPlatform Correctable\n");
368 if (available_error_type & 0x0400)
369 seq_printf(m, "0x00000400\tPlatform Uncorrectable non-fatal\n");
370 if (available_error_type & 0x0800)
371 seq_printf(m, "0x00000800\tPlatform Uncorrectable fatal\n");
372
373 return 0;
374}
375
376static int available_error_type_open(struct inode *inode, struct file *file)
377{
378 return single_open(file, available_error_type_show, NULL);
379}
380
381static const struct file_operations available_error_type_fops = {
382 .open = available_error_type_open,
383 .read = seq_read,
384 .llseek = seq_lseek,
385 .release = single_release,
386};
387
388static int error_type_get(void *data, u64 *val)
389{
390 *val = error_type;
391
392 return 0;
393}
394
395static int error_type_set(void *data, u64 val)
396{
397 int rc;
398 u32 available_error_type = 0;
399
400 /* Only one error type can be specified */
401 if (val & (val - 1))
402 return -EINVAL;
403 rc = einj_get_available_error_type(&available_error_type);
404 if (rc)
405 return rc;
406 if (!(val & available_error_type))
407 return -EINVAL;
408 error_type = val;
409
410 return 0;
411}
412
413DEFINE_SIMPLE_ATTRIBUTE(error_type_fops, error_type_get,
414 error_type_set, "0x%llx\n");
415
416static int error_inject_set(void *data, u64 val)
417{
418 if (!error_type)
419 return -EINVAL;
420
421 return einj_error_inject(error_type, error_param1, error_param2);
422}
423
424DEFINE_SIMPLE_ATTRIBUTE(error_inject_fops, NULL,
425 error_inject_set, "%llu\n");
426
427static int einj_check_table(struct acpi_table_einj *einj_tab)
428{
429 if (einj_tab->header_length != sizeof(struct acpi_table_einj))
430 return -EINVAL;
431 if (einj_tab->header.length < sizeof(struct acpi_table_einj))
432 return -EINVAL;
433 if (einj_tab->entries !=
434 (einj_tab->header.length - sizeof(struct acpi_table_einj)) /
435 sizeof(struct acpi_einj_entry))
436 return -EINVAL;
437
438 return 0;
439}
440
441static int __init einj_init(void)
442{
443 int rc;
444 u64 param_paddr;
445 acpi_status status;
446 struct dentry *fentry;
447 struct apei_exec_context ctx;
448
449 if (acpi_disabled)
450 return -ENODEV;
451
452 status = acpi_get_table(ACPI_SIG_EINJ, 0,
453 (struct acpi_table_header **)&einj_tab);
454 if (status == AE_NOT_FOUND) {
455 pr_info(EINJ_PFX "Table is not found!\n");
456 return -ENODEV;
457 } else if (ACPI_FAILURE(status)) {
458 const char *msg = acpi_format_exception(status);
459 pr_err(EINJ_PFX "Failed to get table, %s\n", msg);
460 return -EINVAL;
461 }
462
463 rc = einj_check_table(einj_tab);
464 if (rc) {
465 pr_warning(FW_BUG EINJ_PFX "EINJ table is invalid\n");
466 return -EINVAL;
467 }
468
469 rc = -ENOMEM;
470 einj_debug_dir = debugfs_create_dir("einj", apei_get_debugfs_dir());
471 if (!einj_debug_dir)
472 goto err_cleanup;
473 fentry = debugfs_create_file("available_error_type", S_IRUSR,
474 einj_debug_dir, NULL,
475 &available_error_type_fops);
476 if (!fentry)
477 goto err_cleanup;
478 fentry = debugfs_create_file("error_type", S_IRUSR | S_IWUSR,
479 einj_debug_dir, NULL, &error_type_fops);
480 if (!fentry)
481 goto err_cleanup;
482 fentry = debugfs_create_x64("param1", S_IRUSR | S_IWUSR,
483 einj_debug_dir, &error_param1);
484 if (!fentry)
485 goto err_cleanup;
486 fentry = debugfs_create_x64("param2", S_IRUSR | S_IWUSR,
487 einj_debug_dir, &error_param2);
488 if (!fentry)
489 goto err_cleanup;
490 fentry = debugfs_create_file("error_inject", S_IWUSR,
491 einj_debug_dir, NULL, &error_inject_fops);
492 if (!fentry)
493 goto err_cleanup;
494
495 apei_resources_init(&einj_resources);
496 einj_exec_ctx_init(&ctx);
497 rc = apei_exec_collect_resources(&ctx, &einj_resources);
498 if (rc)
499 goto err_fini;
500 rc = apei_resources_request(&einj_resources, "APEI EINJ");
501 if (rc)
502 goto err_fini;
503 rc = apei_exec_pre_map_gars(&ctx);
504 if (rc)
505 goto err_release;
506 param_paddr = einj_get_parameter_address();
507 if (param_paddr) {
508 einj_param = ioremap(param_paddr, sizeof(*einj_param));
509 rc = -ENOMEM;
510 if (!einj_param)
511 goto err_unmap;
512 }
513
514 pr_info(EINJ_PFX "Error INJection is initialized.\n");
515
516 return 0;
517
518err_unmap:
519 apei_exec_post_unmap_gars(&ctx);
520err_release:
521 apei_resources_release(&einj_resources);
522err_fini:
523 apei_resources_fini(&einj_resources);
524err_cleanup:
525 debugfs_remove_recursive(einj_debug_dir);
526
527 return rc;
528}
529
530static void __exit einj_exit(void)
531{
532 struct apei_exec_context ctx;
533
534 if (einj_param)
535 iounmap(einj_param);
536 einj_exec_ctx_init(&ctx);
537 apei_exec_post_unmap_gars(&ctx);
538 apei_resources_release(&einj_resources);
539 apei_resources_fini(&einj_resources);
540 debugfs_remove_recursive(einj_debug_dir);
541}
542
543module_init(einj_init);
544module_exit(einj_exit);
545
546MODULE_AUTHOR("Huang Ying");
547MODULE_DESCRIPTION("APEI Error INJection support");
548MODULE_LICENSE("GPL");
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c
new file mode 100644
index 000000000000..2ebc39115507
--- /dev/null
+++ b/drivers/acpi/apei/erst.c
@@ -0,0 +1,855 @@
1/*
2 * APEI Error Record Serialization Table support
3 *
4 * ERST is a way provided by APEI to save and retrieve hardware error
5 * infomation to and from a persistent store.
6 *
7 * For more information about ERST, please refer to ACPI Specification
8 * version 4.0, section 17.4.
9 *
10 * Copyright 2010 Intel Corp.
11 * Author: Huang Ying <ying.huang@intel.com>
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License version
15 * 2 as published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/delay.h>
31#include <linux/io.h>
32#include <linux/acpi.h>
33#include <linux/uaccess.h>
34#include <linux/cper.h>
35#include <linux/nmi.h>
36#include <acpi/apei.h>
37
38#include "apei-internal.h"
39
40#define ERST_PFX "ERST: "
41
42/* ERST command status */
43#define ERST_STATUS_SUCCESS 0x0
44#define ERST_STATUS_NOT_ENOUGH_SPACE 0x1
45#define ERST_STATUS_HARDWARE_NOT_AVAILABLE 0x2
46#define ERST_STATUS_FAILED 0x3
47#define ERST_STATUS_RECORD_STORE_EMPTY 0x4
48#define ERST_STATUS_RECORD_NOT_FOUND 0x5
49
50#define ERST_TAB_ENTRY(tab) \
51 ((struct acpi_whea_header *)((char *)(tab) + \
52 sizeof(struct acpi_table_erst)))
53
54#define SPIN_UNIT 100 /* 100ns */
55/* Firmware should respond within 1 miliseconds */
56#define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC)
57#define FIRMWARE_MAX_STALL 50 /* 50us */
58
59int erst_disable;
60EXPORT_SYMBOL_GPL(erst_disable);
61
62static struct acpi_table_erst *erst_tab;
63
64/* ERST Error Log Address Range atrributes */
65#define ERST_RANGE_RESERVED 0x0001
66#define ERST_RANGE_NVRAM 0x0002
67#define ERST_RANGE_SLOW 0x0004
68
69/*
70 * ERST Error Log Address Range, used as buffer for reading/writing
71 * error records.
72 */
73static struct erst_erange {
74 u64 base;
75 u64 size;
76 void __iomem *vaddr;
77 u32 attr;
78} erst_erange;
79
80/*
81 * Prevent ERST interpreter to run simultaneously, because the
82 * corresponding firmware implementation may not work properly when
83 * invoked simultaneously.
84 *
85 * It is used to provide exclusive accessing for ERST Error Log
86 * Address Range too.
87 */
88static DEFINE_SPINLOCK(erst_lock);
89
90static inline int erst_errno(int command_status)
91{
92 switch (command_status) {
93 case ERST_STATUS_SUCCESS:
94 return 0;
95 case ERST_STATUS_HARDWARE_NOT_AVAILABLE:
96 return -ENODEV;
97 case ERST_STATUS_NOT_ENOUGH_SPACE:
98 return -ENOSPC;
99 case ERST_STATUS_RECORD_STORE_EMPTY:
100 case ERST_STATUS_RECORD_NOT_FOUND:
101 return -ENOENT;
102 default:
103 return -EINVAL;
104 }
105}
106
107static int erst_timedout(u64 *t, u64 spin_unit)
108{
109 if ((s64)*t < spin_unit) {
110 pr_warning(FW_WARN ERST_PFX
111 "Firmware does not respond in time\n");
112 return 1;
113 }
114 *t -= spin_unit;
115 ndelay(spin_unit);
116 touch_nmi_watchdog();
117 return 0;
118}
119
120static int erst_exec_load_var1(struct apei_exec_context *ctx,
121 struct acpi_whea_header *entry)
122{
123 return __apei_exec_read_register(entry, &ctx->var1);
124}
125
126static int erst_exec_load_var2(struct apei_exec_context *ctx,
127 struct acpi_whea_header *entry)
128{
129 return __apei_exec_read_register(entry, &ctx->var2);
130}
131
132static int erst_exec_store_var1(struct apei_exec_context *ctx,
133 struct acpi_whea_header *entry)
134{
135 return __apei_exec_write_register(entry, ctx->var1);
136}
137
138static int erst_exec_add(struct apei_exec_context *ctx,
139 struct acpi_whea_header *entry)
140{
141 ctx->var1 += ctx->var2;
142 return 0;
143}
144
145static int erst_exec_subtract(struct apei_exec_context *ctx,
146 struct acpi_whea_header *entry)
147{
148 ctx->var1 -= ctx->var2;
149 return 0;
150}
151
152static int erst_exec_add_value(struct apei_exec_context *ctx,
153 struct acpi_whea_header *entry)
154{
155 int rc;
156 u64 val;
157
158 rc = __apei_exec_read_register(entry, &val);
159 if (rc)
160 return rc;
161 val += ctx->value;
162 rc = __apei_exec_write_register(entry, val);
163 return rc;
164}
165
166static int erst_exec_subtract_value(struct apei_exec_context *ctx,
167 struct acpi_whea_header *entry)
168{
169 int rc;
170 u64 val;
171
172 rc = __apei_exec_read_register(entry, &val);
173 if (rc)
174 return rc;
175 val -= ctx->value;
176 rc = __apei_exec_write_register(entry, val);
177 return rc;
178}
179
180static int erst_exec_stall(struct apei_exec_context *ctx,
181 struct acpi_whea_header *entry)
182{
183 u64 stall_time;
184
185 if (ctx->value > FIRMWARE_MAX_STALL) {
186 if (!in_nmi())
187 pr_warning(FW_WARN ERST_PFX
188 "Too long stall time for stall instruction: %llx.\n",
189 ctx->value);
190 stall_time = FIRMWARE_MAX_STALL;
191 } else
192 stall_time = ctx->value;
193 udelay(stall_time);
194 return 0;
195}
196
197static int erst_exec_stall_while_true(struct apei_exec_context *ctx,
198 struct acpi_whea_header *entry)
199{
200 int rc;
201 u64 val;
202 u64 timeout = FIRMWARE_TIMEOUT;
203 u64 stall_time;
204
205 if (ctx->var1 > FIRMWARE_MAX_STALL) {
206 if (!in_nmi())
207 pr_warning(FW_WARN ERST_PFX
208 "Too long stall time for stall while true instruction: %llx.\n",
209 ctx->var1);
210 stall_time = FIRMWARE_MAX_STALL;
211 } else
212 stall_time = ctx->var1;
213
214 for (;;) {
215 rc = __apei_exec_read_register(entry, &val);
216 if (rc)
217 return rc;
218 if (val != ctx->value)
219 break;
220 if (erst_timedout(&timeout, stall_time * NSEC_PER_USEC))
221 return -EIO;
222 }
223 return 0;
224}
225
226static int erst_exec_skip_next_instruction_if_true(
227 struct apei_exec_context *ctx,
228 struct acpi_whea_header *entry)
229{
230 int rc;
231 u64 val;
232
233 rc = __apei_exec_read_register(entry, &val);
234 if (rc)
235 return rc;
236 if (val == ctx->value) {
237 ctx->ip += 2;
238 return APEI_EXEC_SET_IP;
239 }
240
241 return 0;
242}
243
244static int erst_exec_goto(struct apei_exec_context *ctx,
245 struct acpi_whea_header *entry)
246{
247 ctx->ip = ctx->value;
248 return APEI_EXEC_SET_IP;
249}
250
251static int erst_exec_set_src_address_base(struct apei_exec_context *ctx,
252 struct acpi_whea_header *entry)
253{
254 return __apei_exec_read_register(entry, &ctx->src_base);
255}
256
257static int erst_exec_set_dst_address_base(struct apei_exec_context *ctx,
258 struct acpi_whea_header *entry)
259{
260 return __apei_exec_read_register(entry, &ctx->dst_base);
261}
262
263static int erst_exec_move_data(struct apei_exec_context *ctx,
264 struct acpi_whea_header *entry)
265{
266 int rc;
267 u64 offset;
268
269 rc = __apei_exec_read_register(entry, &offset);
270 if (rc)
271 return rc;
272 memmove((void *)ctx->dst_base + offset,
273 (void *)ctx->src_base + offset,
274 ctx->var2);
275
276 return 0;
277}
278
279static struct apei_exec_ins_type erst_ins_type[] = {
280 [ACPI_ERST_READ_REGISTER] = {
281 .flags = APEI_EXEC_INS_ACCESS_REGISTER,
282 .run = apei_exec_read_register,
283 },
284 [ACPI_ERST_READ_REGISTER_VALUE] = {
285 .flags = APEI_EXEC_INS_ACCESS_REGISTER,
286 .run = apei_exec_read_register_value,
287 },
288 [ACPI_ERST_WRITE_REGISTER] = {
289 .flags = APEI_EXEC_INS_ACCESS_REGISTER,
290 .run = apei_exec_write_register,
291 },
292 [ACPI_ERST_WRITE_REGISTER_VALUE] = {
293 .flags = APEI_EXEC_INS_ACCESS_REGISTER,
294 .run = apei_exec_write_register_value,
295 },
296 [ACPI_ERST_NOOP] = {
297 .flags = 0,
298 .run = apei_exec_noop,
299 },
300 [ACPI_ERST_LOAD_VAR1] = {
301 .flags = APEI_EXEC_INS_ACCESS_REGISTER,
302 .run = erst_exec_load_var1,
303 },
304 [ACPI_ERST_LOAD_VAR2] = {
305 .flags = APEI_EXEC_INS_ACCESS_REGISTER,
306 .run = erst_exec_load_var2,
307 },
308 [ACPI_ERST_STORE_VAR1] = {
309 .flags = APEI_EXEC_INS_ACCESS_REGISTER,
310 .run = erst_exec_store_var1,
311 },
312 [ACPI_ERST_ADD] = {
313 .flags = 0,
314 .run = erst_exec_add,
315 },
316 [ACPI_ERST_SUBTRACT] = {
317 .flags = 0,
318 .run = erst_exec_subtract,
319 },
320 [ACPI_ERST_ADD_VALUE] = {
321 .flags = APEI_EXEC_INS_ACCESS_REGISTER,
322 .run = erst_exec_add_value,
323 },
324 [ACPI_ERST_SUBTRACT_VALUE] = {
325 .flags = APEI_EXEC_INS_ACCESS_REGISTER,
326 .run = erst_exec_subtract_value,
327 },
328 [ACPI_ERST_STALL] = {
329 .flags = 0,
330 .run = erst_exec_stall,
331 },
332 [ACPI_ERST_STALL_WHILE_TRUE] = {
333 .flags = APEI_EXEC_INS_ACCESS_REGISTER,
334 .run = erst_exec_stall_while_true,
335 },
336 [ACPI_ERST_SKIP_NEXT_IF_TRUE] = {
337 .flags = APEI_EXEC_INS_ACCESS_REGISTER,
338 .run = erst_exec_skip_next_instruction_if_true,
339 },
340 [ACPI_ERST_GOTO] = {
341 .flags = 0,
342 .run = erst_exec_goto,
343 },
344 [ACPI_ERST_SET_SRC_ADDRESS_BASE] = {
345 .flags = APEI_EXEC_INS_ACCESS_REGISTER,
346 .run = erst_exec_set_src_address_base,
347 },
348 [ACPI_ERST_SET_DST_ADDRESS_BASE] = {
349 .flags = APEI_EXEC_INS_ACCESS_REGISTER,
350 .run = erst_exec_set_dst_address_base,
351 },
352 [ACPI_ERST_MOVE_DATA] = {
353 .flags = APEI_EXEC_INS_ACCESS_REGISTER,
354 .run = erst_exec_move_data,
355 },
356};
357
358static inline void erst_exec_ctx_init(struct apei_exec_context *ctx)
359{
360 apei_exec_ctx_init(ctx, erst_ins_type, ARRAY_SIZE(erst_ins_type),
361 ERST_TAB_ENTRY(erst_tab), erst_tab->entries);
362}
363
364static int erst_get_erange(struct erst_erange *range)
365{
366 struct apei_exec_context ctx;
367 int rc;
368
369 erst_exec_ctx_init(&ctx);
370 rc = apei_exec_run(&ctx, ACPI_ERST_GET_ERROR_RANGE);
371 if (rc)
372 return rc;
373 range->base = apei_exec_ctx_get_output(&ctx);
374 rc = apei_exec_run(&ctx, ACPI_ERST_GET_ERROR_LENGTH);
375 if (rc)
376 return rc;
377 range->size = apei_exec_ctx_get_output(&ctx);
378 rc = apei_exec_run(&ctx, ACPI_ERST_GET_ERROR_ATTRIBUTES);
379 if (rc)
380 return rc;
381 range->attr = apei_exec_ctx_get_output(&ctx);
382
383 return 0;
384}
385
386static ssize_t __erst_get_record_count(void)
387{
388 struct apei_exec_context ctx;
389 int rc;
390
391 erst_exec_ctx_init(&ctx);
392 rc = apei_exec_run(&ctx, ACPI_ERST_GET_RECORD_COUNT);
393 if (rc)
394 return rc;
395 return apei_exec_ctx_get_output(&ctx);
396}
397
398ssize_t erst_get_record_count(void)
399{
400 ssize_t count;
401 unsigned long flags;
402
403 if (erst_disable)
404 return -ENODEV;
405
406 spin_lock_irqsave(&erst_lock, flags);
407 count = __erst_get_record_count();
408 spin_unlock_irqrestore(&erst_lock, flags);
409
410 return count;
411}
412EXPORT_SYMBOL_GPL(erst_get_record_count);
413
414static int __erst_get_next_record_id(u64 *record_id)
415{
416 struct apei_exec_context ctx;
417 int rc;
418
419 erst_exec_ctx_init(&ctx);
420 rc = apei_exec_run(&ctx, ACPI_ERST_GET_RECORD_ID);
421 if (rc)
422 return rc;
423 *record_id = apei_exec_ctx_get_output(&ctx);
424
425 return 0;
426}
427
428/*
429 * Get the record ID of an existing error record on the persistent
430 * storage. If there is no error record on the persistent storage, the
431 * returned record_id is APEI_ERST_INVALID_RECORD_ID.
432 */
433int erst_get_next_record_id(u64 *record_id)
434{
435 int rc;
436 unsigned long flags;
437
438 if (erst_disable)
439 return -ENODEV;
440
441 spin_lock_irqsave(&erst_lock, flags);
442 rc = __erst_get_next_record_id(record_id);
443 spin_unlock_irqrestore(&erst_lock, flags);
444
445 return rc;
446}
447EXPORT_SYMBOL_GPL(erst_get_next_record_id);
448
449static int __erst_write_to_storage(u64 offset)
450{
451 struct apei_exec_context ctx;
452 u64 timeout = FIRMWARE_TIMEOUT;
453 u64 val;
454 int rc;
455
456 erst_exec_ctx_init(&ctx);
457 rc = apei_exec_run(&ctx, ACPI_ERST_BEGIN_WRITE);
458 if (rc)
459 return rc;
460 apei_exec_ctx_set_input(&ctx, offset);
461 rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_OFFSET);
462 if (rc)
463 return rc;
464 rc = apei_exec_run(&ctx, ACPI_ERST_EXECUTE_OPERATION);
465 if (rc)
466 return rc;
467 for (;;) {
468 rc = apei_exec_run(&ctx, ACPI_ERST_CHECK_BUSY_STATUS);
469 if (rc)
470 return rc;
471 val = apei_exec_ctx_get_output(&ctx);
472 if (!val)
473 break;
474 if (erst_timedout(&timeout, SPIN_UNIT))
475 return -EIO;
476 }
477 rc = apei_exec_run(&ctx, ACPI_ERST_GET_COMMAND_STATUS);
478 if (rc)
479 return rc;
480 val = apei_exec_ctx_get_output(&ctx);
481 rc = apei_exec_run(&ctx, ACPI_ERST_END);
482 if (rc)
483 return rc;
484
485 return erst_errno(val);
486}
487
488static int __erst_read_from_storage(u64 record_id, u64 offset)
489{
490 struct apei_exec_context ctx;
491 u64 timeout = FIRMWARE_TIMEOUT;
492 u64 val;
493 int rc;
494
495 erst_exec_ctx_init(&ctx);
496 rc = apei_exec_run(&ctx, ACPI_ERST_BEGIN_READ);
497 if (rc)
498 return rc;
499 apei_exec_ctx_set_input(&ctx, offset);
500 rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_OFFSET);
501 if (rc)
502 return rc;
503 apei_exec_ctx_set_input(&ctx, record_id);
504 rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_ID);
505 if (rc)
506 return rc;
507 rc = apei_exec_run(&ctx, ACPI_ERST_EXECUTE_OPERATION);
508 if (rc)
509 return rc;
510 for (;;) {
511 rc = apei_exec_run(&ctx, ACPI_ERST_CHECK_BUSY_STATUS);
512 if (rc)
513 return rc;
514 val = apei_exec_ctx_get_output(&ctx);
515 if (!val)
516 break;
517 if (erst_timedout(&timeout, SPIN_UNIT))
518 return -EIO;
519 };
520 rc = apei_exec_run(&ctx, ACPI_ERST_GET_COMMAND_STATUS);
521 if (rc)
522 return rc;
523 val = apei_exec_ctx_get_output(&ctx);
524 rc = apei_exec_run(&ctx, ACPI_ERST_END);
525 if (rc)
526 return rc;
527
528 return erst_errno(val);
529}
530
531static int __erst_clear_from_storage(u64 record_id)
532{
533 struct apei_exec_context ctx;
534 u64 timeout = FIRMWARE_TIMEOUT;
535 u64 val;
536 int rc;
537
538 erst_exec_ctx_init(&ctx);
539 rc = apei_exec_run(&ctx, ACPI_ERST_BEGIN_CLEAR);
540 if (rc)
541 return rc;
542 apei_exec_ctx_set_input(&ctx, record_id);
543 rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_ID);
544 if (rc)
545 return rc;
546 rc = apei_exec_run(&ctx, ACPI_ERST_EXECUTE_OPERATION);
547 if (rc)
548 return rc;
549 for (;;) {
550 rc = apei_exec_run(&ctx, ACPI_ERST_CHECK_BUSY_STATUS);
551 if (rc)
552 return rc;
553 val = apei_exec_ctx_get_output(&ctx);
554 if (!val)
555 break;
556 if (erst_timedout(&timeout, SPIN_UNIT))
557 return -EIO;
558 }
559 rc = apei_exec_run(&ctx, ACPI_ERST_GET_COMMAND_STATUS);
560 if (rc)
561 return rc;
562 val = apei_exec_ctx_get_output(&ctx);
563 rc = apei_exec_run(&ctx, ACPI_ERST_END);
564 if (rc)
565 return rc;
566
567 return erst_errno(val);
568}
569
570/* NVRAM ERST Error Log Address Range is not supported yet */
571static void pr_unimpl_nvram(void)
572{
573 if (printk_ratelimit())
574 pr_warning(ERST_PFX
575 "NVRAM ERST Log Address Range is not implemented yet\n");
576}
577
578static int __erst_write_to_nvram(const struct cper_record_header *record)
579{
580 /* do not print message, because printk is not safe for NMI */
581 return -ENOSYS;
582}
583
584static int __erst_read_to_erange_from_nvram(u64 record_id, u64 *offset)
585{
586 pr_unimpl_nvram();
587 return -ENOSYS;
588}
589
590static int __erst_clear_from_nvram(u64 record_id)
591{
592 pr_unimpl_nvram();
593 return -ENOSYS;
594}
595
596int erst_write(const struct cper_record_header *record)
597{
598 int rc;
599 unsigned long flags;
600 struct cper_record_header *rcd_erange;
601
602 if (erst_disable)
603 return -ENODEV;
604
605 if (memcmp(record->signature, CPER_SIG_RECORD, CPER_SIG_SIZE))
606 return -EINVAL;
607
608 if (erst_erange.attr & ERST_RANGE_NVRAM) {
609 if (!spin_trylock_irqsave(&erst_lock, flags))
610 return -EBUSY;
611 rc = __erst_write_to_nvram(record);
612 spin_unlock_irqrestore(&erst_lock, flags);
613 return rc;
614 }
615
616 if (record->record_length > erst_erange.size)
617 return -EINVAL;
618
619 if (!spin_trylock_irqsave(&erst_lock, flags))
620 return -EBUSY;
621 memcpy(erst_erange.vaddr, record, record->record_length);
622 rcd_erange = erst_erange.vaddr;
623 /* signature for serialization system */
624 memcpy(&rcd_erange->persistence_information, "ER", 2);
625
626 rc = __erst_write_to_storage(0);
627 spin_unlock_irqrestore(&erst_lock, flags);
628
629 return rc;
630}
631EXPORT_SYMBOL_GPL(erst_write);
632
633static int __erst_read_to_erange(u64 record_id, u64 *offset)
634{
635 int rc;
636
637 if (erst_erange.attr & ERST_RANGE_NVRAM)
638 return __erst_read_to_erange_from_nvram(
639 record_id, offset);
640
641 rc = __erst_read_from_storage(record_id, 0);
642 if (rc)
643 return rc;
644 *offset = 0;
645
646 return 0;
647}
648
649static ssize_t __erst_read(u64 record_id, struct cper_record_header *record,
650 size_t buflen)
651{
652 int rc;
653 u64 offset, len = 0;
654 struct cper_record_header *rcd_tmp;
655
656 rc = __erst_read_to_erange(record_id, &offset);
657 if (rc)
658 return rc;
659 rcd_tmp = erst_erange.vaddr + offset;
660 len = rcd_tmp->record_length;
661 if (len <= buflen)
662 memcpy(record, rcd_tmp, len);
663
664 return len;
665}
666
667/*
668 * If return value > buflen, the buffer size is not big enough,
669 * else if return value < 0, something goes wrong,
670 * else everything is OK, and return value is record length
671 */
672ssize_t erst_read(u64 record_id, struct cper_record_header *record,
673 size_t buflen)
674{
675 ssize_t len;
676 unsigned long flags;
677
678 if (erst_disable)
679 return -ENODEV;
680
681 spin_lock_irqsave(&erst_lock, flags);
682 len = __erst_read(record_id, record, buflen);
683 spin_unlock_irqrestore(&erst_lock, flags);
684 return len;
685}
686EXPORT_SYMBOL_GPL(erst_read);
687
688/*
689 * If return value > buflen, the buffer size is not big enough,
690 * else if return value = 0, there is no more record to read,
691 * else if return value < 0, something goes wrong,
692 * else everything is OK, and return value is record length
693 */
694ssize_t erst_read_next(struct cper_record_header *record, size_t buflen)
695{
696 int rc;
697 ssize_t len;
698 unsigned long flags;
699 u64 record_id;
700
701 if (erst_disable)
702 return -ENODEV;
703
704 spin_lock_irqsave(&erst_lock, flags);
705 rc = __erst_get_next_record_id(&record_id);
706 if (rc) {
707 spin_unlock_irqrestore(&erst_lock, flags);
708 return rc;
709 }
710 /* no more record */
711 if (record_id == APEI_ERST_INVALID_RECORD_ID) {
712 spin_unlock_irqrestore(&erst_lock, flags);
713 return 0;
714 }
715
716 len = __erst_read(record_id, record, buflen);
717 spin_unlock_irqrestore(&erst_lock, flags);
718
719 return len;
720}
721EXPORT_SYMBOL_GPL(erst_read_next);
722
723int erst_clear(u64 record_id)
724{
725 int rc;
726 unsigned long flags;
727
728 if (erst_disable)
729 return -ENODEV;
730
731 spin_lock_irqsave(&erst_lock, flags);
732 if (erst_erange.attr & ERST_RANGE_NVRAM)
733 rc = __erst_clear_from_nvram(record_id);
734 else
735 rc = __erst_clear_from_storage(record_id);
736 spin_unlock_irqrestore(&erst_lock, flags);
737
738 return rc;
739}
740EXPORT_SYMBOL_GPL(erst_clear);
741
742static int __init setup_erst_disable(char *str)
743{
744 erst_disable = 1;
745 return 0;
746}
747
748__setup("erst_disable", setup_erst_disable);
749
750static int erst_check_table(struct acpi_table_erst *erst_tab)
751{
752 if (erst_tab->header_length != sizeof(struct acpi_table_erst))
753 return -EINVAL;
754 if (erst_tab->header.length < sizeof(struct acpi_table_erst))
755 return -EINVAL;
756 if (erst_tab->entries !=
757 (erst_tab->header.length - sizeof(struct acpi_table_erst)) /
758 sizeof(struct acpi_erst_entry))
759 return -EINVAL;
760
761 return 0;
762}
763
764static int __init erst_init(void)
765{
766 int rc = 0;
767 acpi_status status;
768 struct apei_exec_context ctx;
769 struct apei_resources erst_resources;
770 struct resource *r;
771
772 if (acpi_disabled)
773 goto err;
774
775 if (erst_disable) {
776 pr_info(ERST_PFX
777 "Error Record Serialization Table (ERST) support is disabled.\n");
778 goto err;
779 }
780
781 status = acpi_get_table(ACPI_SIG_ERST, 0,
782 (struct acpi_table_header **)&erst_tab);
783 if (status == AE_NOT_FOUND) {
784 pr_err(ERST_PFX "Table is not found!\n");
785 goto err;
786 } else if (ACPI_FAILURE(status)) {
787 const char *msg = acpi_format_exception(status);
788 pr_err(ERST_PFX "Failed to get table, %s\n", msg);
789 rc = -EINVAL;
790 goto err;
791 }
792
793 rc = erst_check_table(erst_tab);
794 if (rc) {
795 pr_err(FW_BUG ERST_PFX "ERST table is invalid\n");
796 goto err;
797 }
798
799 apei_resources_init(&erst_resources);
800 erst_exec_ctx_init(&ctx);
801 rc = apei_exec_collect_resources(&ctx, &erst_resources);
802 if (rc)
803 goto err_fini;
804 rc = apei_resources_request(&erst_resources, "APEI ERST");
805 if (rc)
806 goto err_fini;
807 rc = apei_exec_pre_map_gars(&ctx);
808 if (rc)
809 goto err_release;
810 rc = erst_get_erange(&erst_erange);
811 if (rc) {
812 if (rc == -ENODEV)
813 pr_info(ERST_PFX
814 "The corresponding hardware device or firmware implementation "
815 "is not available.\n");
816 else
817 pr_err(ERST_PFX
818 "Failed to get Error Log Address Range.\n");
819 goto err_unmap_reg;
820 }
821
822 r = request_mem_region(erst_erange.base, erst_erange.size, "APEI ERST");
823 if (!r) {
824 pr_err(ERST_PFX
825 "Can not request iomem region <0x%16llx-0x%16llx> for ERST.\n",
826 (unsigned long long)erst_erange.base,
827 (unsigned long long)erst_erange.base + erst_erange.size);
828 rc = -EIO;
829 goto err_unmap_reg;
830 }
831 rc = -ENOMEM;
832 erst_erange.vaddr = ioremap_cache(erst_erange.base,
833 erst_erange.size);
834 if (!erst_erange.vaddr)
835 goto err_release_erange;
836
837 pr_info(ERST_PFX
838 "Error Record Serialization Table (ERST) support is initialized.\n");
839
840 return 0;
841
842err_release_erange:
843 release_mem_region(erst_erange.base, erst_erange.size);
844err_unmap_reg:
845 apei_exec_post_unmap_gars(&ctx);
846err_release:
847 apei_resources_release(&erst_resources);
848err_fini:
849 apei_resources_fini(&erst_resources);
850err:
851 erst_disable = 1;
852 return rc;
853}
854
855device_initcall(erst_init);
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
new file mode 100644
index 000000000000..fd0cc016a099
--- /dev/null
+++ b/drivers/acpi/apei/ghes.c
@@ -0,0 +1,427 @@
1/*
2 * APEI Generic Hardware Error Source support
3 *
4 * Generic Hardware Error Source provides a way to report platform
5 * hardware errors (such as that from chipset). It works in so called
6 * "Firmware First" mode, that is, hardware errors are reported to
7 * firmware firstly, then reported to Linux by firmware. This way,
8 * some non-standard hardware error registers or non-standard hardware
9 * link can be checked by firmware to produce more hardware error
10 * information for Linux.
11 *
12 * For more information about Generic Hardware Error Source, please
13 * refer to ACPI Specification version 4.0, section 17.3.2.6
14 *
15 * Now, only SCI notification type and memory errors are
16 * supported. More notification type and hardware error type will be
17 * added later.
18 *
19 * Copyright 2010 Intel Corp.
20 * Author: Huang Ying <ying.huang@intel.com>
21 *
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License version
24 * 2 as published by the Free Software Foundation;
25 *
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
30 *
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 */
35
36#include <linux/kernel.h>
37#include <linux/module.h>
38#include <linux/init.h>
39#include <linux/acpi.h>
40#include <linux/io.h>
41#include <linux/interrupt.h>
42#include <linux/cper.h>
43#include <linux/kdebug.h>
44#include <acpi/apei.h>
45#include <acpi/atomicio.h>
46#include <acpi/hed.h>
47#include <asm/mce.h>
48
49#include "apei-internal.h"
50
51#define GHES_PFX "GHES: "
52
53#define GHES_ESTATUS_MAX_SIZE 65536
54
55/*
56 * One struct ghes is created for each generic hardware error
57 * source.
58 *
59 * It provides the context for APEI hardware error timer/IRQ/SCI/NMI
60 * handler. Handler for one generic hardware error source is only
61 * triggered after the previous one is done. So handler can uses
62 * struct ghes without locking.
63 *
64 * estatus: memory buffer for error status block, allocated during
65 * HEST parsing.
66 */
67#define GHES_TO_CLEAR 0x0001
68
69struct ghes {
70 struct acpi_hest_generic *generic;
71 struct acpi_hest_generic_status *estatus;
72 struct list_head list;
73 u64 buffer_paddr;
74 unsigned long flags;
75};
76
77/*
78 * Error source lists, one list for each notification method. The
79 * members in lists are struct ghes.
80 *
81 * The list members are only added in HEST parsing and deleted during
82 * module_exit, that is, single-threaded. So no lock is needed for
83 * that.
84 *
85 * But the mutual exclusion is needed between members adding/deleting
86 * and timer/IRQ/SCI/NMI handler, which may traverse the list. RCU is
87 * used for that.
88 */
89static LIST_HEAD(ghes_sci);
90
91static struct ghes *ghes_new(struct acpi_hest_generic *generic)
92{
93 struct ghes *ghes;
94 unsigned int error_block_length;
95 int rc;
96
97 ghes = kzalloc(sizeof(*ghes), GFP_KERNEL);
98 if (!ghes)
99 return ERR_PTR(-ENOMEM);
100 ghes->generic = generic;
101 INIT_LIST_HEAD(&ghes->list);
102 rc = acpi_pre_map_gar(&generic->error_status_address);
103 if (rc)
104 goto err_free;
105 error_block_length = generic->error_block_length;
106 if (error_block_length > GHES_ESTATUS_MAX_SIZE) {
107 pr_warning(FW_WARN GHES_PFX
108 "Error status block length is too long: %u for "
109 "generic hardware error source: %d.\n",
110 error_block_length, generic->header.source_id);
111 error_block_length = GHES_ESTATUS_MAX_SIZE;
112 }
113 ghes->estatus = kmalloc(error_block_length, GFP_KERNEL);
114 if (!ghes->estatus) {
115 rc = -ENOMEM;
116 goto err_unmap;
117 }
118
119 return ghes;
120
121err_unmap:
122 acpi_post_unmap_gar(&generic->error_status_address);
123err_free:
124 kfree(ghes);
125 return ERR_PTR(rc);
126}
127
128static void ghes_fini(struct ghes *ghes)
129{
130 kfree(ghes->estatus);
131 acpi_post_unmap_gar(&ghes->generic->error_status_address);
132}
133
134enum {
135 GHES_SER_NO = 0x0,
136 GHES_SER_CORRECTED = 0x1,
137 GHES_SER_RECOVERABLE = 0x2,
138 GHES_SER_PANIC = 0x3,
139};
140
141static inline int ghes_severity(int severity)
142{
143 switch (severity) {
144 case CPER_SER_INFORMATIONAL:
145 return GHES_SER_NO;
146 case CPER_SER_CORRECTED:
147 return GHES_SER_CORRECTED;
148 case CPER_SER_RECOVERABLE:
149 return GHES_SER_RECOVERABLE;
150 case CPER_SER_FATAL:
151 return GHES_SER_PANIC;
152 default:
153 /* Unkown, go panic */
154 return GHES_SER_PANIC;
155 }
156}
157
158/* SCI handler run in work queue, so ioremap can be used here */
159static int ghes_copy_tofrom_phys(void *buffer, u64 paddr, u32 len,
160 int from_phys)
161{
162 void *vaddr;
163
164 vaddr = ioremap_cache(paddr, len);
165 if (!vaddr)
166 return -ENOMEM;
167 if (from_phys)
168 memcpy(buffer, vaddr, len);
169 else
170 memcpy(vaddr, buffer, len);
171 iounmap(vaddr);
172
173 return 0;
174}
175
176static int ghes_read_estatus(struct ghes *ghes, int silent)
177{
178 struct acpi_hest_generic *g = ghes->generic;
179 u64 buf_paddr;
180 u32 len;
181 int rc;
182
183 rc = acpi_atomic_read(&buf_paddr, &g->error_status_address);
184 if (rc) {
185 if (!silent && printk_ratelimit())
186 pr_warning(FW_WARN GHES_PFX
187"Failed to read error status block address for hardware error source: %d.\n",
188 g->header.source_id);
189 return -EIO;
190 }
191 if (!buf_paddr)
192 return -ENOENT;
193
194 rc = ghes_copy_tofrom_phys(ghes->estatus, buf_paddr,
195 sizeof(*ghes->estatus), 1);
196 if (rc)
197 return rc;
198 if (!ghes->estatus->block_status)
199 return -ENOENT;
200
201 ghes->buffer_paddr = buf_paddr;
202 ghes->flags |= GHES_TO_CLEAR;
203
204 rc = -EIO;
205 len = apei_estatus_len(ghes->estatus);
206 if (len < sizeof(*ghes->estatus))
207 goto err_read_block;
208 if (len > ghes->generic->error_block_length)
209 goto err_read_block;
210 if (apei_estatus_check_header(ghes->estatus))
211 goto err_read_block;
212 rc = ghes_copy_tofrom_phys(ghes->estatus + 1,
213 buf_paddr + sizeof(*ghes->estatus),
214 len - sizeof(*ghes->estatus), 1);
215 if (rc)
216 return rc;
217 if (apei_estatus_check(ghes->estatus))
218 goto err_read_block;
219 rc = 0;
220
221err_read_block:
222 if (rc && !silent)
223 pr_warning(FW_WARN GHES_PFX
224 "Failed to read error status block!\n");
225 return rc;
226}
227
228static void ghes_clear_estatus(struct ghes *ghes)
229{
230 ghes->estatus->block_status = 0;
231 if (!(ghes->flags & GHES_TO_CLEAR))
232 return;
233 ghes_copy_tofrom_phys(ghes->estatus, ghes->buffer_paddr,
234 sizeof(ghes->estatus->block_status), 0);
235 ghes->flags &= ~GHES_TO_CLEAR;
236}
237
238static void ghes_do_proc(struct ghes *ghes)
239{
240 int ser, processed = 0;
241 struct acpi_hest_generic_data *gdata;
242
243 ser = ghes_severity(ghes->estatus->error_severity);
244 apei_estatus_for_each_section(ghes->estatus, gdata) {
245#ifdef CONFIG_X86_MCE
246 if (!uuid_le_cmp(*(uuid_le *)gdata->section_type,
247 CPER_SEC_PLATFORM_MEM)) {
248 apei_mce_report_mem_error(
249 ser == GHES_SER_CORRECTED,
250 (struct cper_sec_mem_err *)(gdata+1));
251 processed = 1;
252 }
253#endif
254 }
255
256 if (!processed && printk_ratelimit())
257 pr_warning(GHES_PFX
258 "Unknown error record from generic hardware error source: %d\n",
259 ghes->generic->header.source_id);
260}
261
262static int ghes_proc(struct ghes *ghes)
263{
264 int rc;
265
266 rc = ghes_read_estatus(ghes, 0);
267 if (rc)
268 goto out;
269 ghes_do_proc(ghes);
270
271out:
272 ghes_clear_estatus(ghes);
273 return 0;
274}
275
276static int ghes_notify_sci(struct notifier_block *this,
277 unsigned long event, void *data)
278{
279 struct ghes *ghes;
280 int ret = NOTIFY_DONE;
281
282 rcu_read_lock();
283 list_for_each_entry_rcu(ghes, &ghes_sci, list) {
284 if (!ghes_proc(ghes))
285 ret = NOTIFY_OK;
286 }
287 rcu_read_unlock();
288
289 return ret;
290}
291
292static struct notifier_block ghes_notifier_sci = {
293 .notifier_call = ghes_notify_sci,
294};
295
296static int hest_ghes_parse(struct acpi_hest_header *hest_hdr, void *data)
297{
298 struct acpi_hest_generic *generic;
299 struct ghes *ghes = NULL;
300 int rc = 0;
301
302 if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR)
303 return 0;
304
305 generic = (struct acpi_hest_generic *)hest_hdr;
306 if (!generic->enabled)
307 return 0;
308
309 if (generic->error_block_length <
310 sizeof(struct acpi_hest_generic_status)) {
311 pr_warning(FW_BUG GHES_PFX
312"Invalid error block length: %u for generic hardware error source: %d\n",
313 generic->error_block_length,
314 generic->header.source_id);
315 goto err;
316 }
317 if (generic->records_to_preallocate == 0) {
318 pr_warning(FW_BUG GHES_PFX
319"Invalid records to preallocate: %u for generic hardware error source: %d\n",
320 generic->records_to_preallocate,
321 generic->header.source_id);
322 goto err;
323 }
324 ghes = ghes_new(generic);
325 if (IS_ERR(ghes)) {
326 rc = PTR_ERR(ghes);
327 ghes = NULL;
328 goto err;
329 }
330 switch (generic->notify.type) {
331 case ACPI_HEST_NOTIFY_POLLED:
332 pr_warning(GHES_PFX
333"Generic hardware error source: %d notified via POLL is not supported!\n",
334 generic->header.source_id);
335 break;
336 case ACPI_HEST_NOTIFY_EXTERNAL:
337 case ACPI_HEST_NOTIFY_LOCAL:
338 pr_warning(GHES_PFX
339"Generic hardware error source: %d notified via IRQ is not supported!\n",
340 generic->header.source_id);
341 break;
342 case ACPI_HEST_NOTIFY_SCI:
343 if (list_empty(&ghes_sci))
344 register_acpi_hed_notifier(&ghes_notifier_sci);
345 list_add_rcu(&ghes->list, &ghes_sci);
346 break;
347 case ACPI_HEST_NOTIFY_NMI:
348 pr_warning(GHES_PFX
349"Generic hardware error source: %d notified via NMI is not supported!\n",
350 generic->header.source_id);
351 break;
352 default:
353 pr_warning(FW_WARN GHES_PFX
354 "Unknown notification type: %u for generic hardware error source: %d\n",
355 generic->notify.type, generic->header.source_id);
356 break;
357 }
358
359 return 0;
360err:
361 if (ghes)
362 ghes_fini(ghes);
363 return rc;
364}
365
366static void ghes_cleanup(void)
367{
368 struct ghes *ghes, *nghes;
369
370 if (!list_empty(&ghes_sci))
371 unregister_acpi_hed_notifier(&ghes_notifier_sci);
372
373 synchronize_rcu();
374
375 list_for_each_entry_safe(ghes, nghes, &ghes_sci, list) {
376 list_del(&ghes->list);
377 ghes_fini(ghes);
378 kfree(ghes);
379 }
380}
381
382static int __init ghes_init(void)
383{
384 int rc;
385
386 if (acpi_disabled)
387 return -ENODEV;
388
389 if (hest_disable) {
390 pr_info(GHES_PFX "HEST is not enabled!\n");
391 return -EINVAL;
392 }
393
394 rc = apei_hest_parse(hest_ghes_parse, NULL);
395 if (rc) {
396 pr_err(GHES_PFX
397 "Error during parsing HEST generic hardware error sources.\n");
398 goto err_cleanup;
399 }
400
401 if (list_empty(&ghes_sci)) {
402 pr_info(GHES_PFX
403 "No functional generic hardware error sources.\n");
404 rc = -ENODEV;
405 goto err_cleanup;
406 }
407
408 pr_info(GHES_PFX
409 "Generic Hardware Error Source support is initialized.\n");
410
411 return 0;
412err_cleanup:
413 ghes_cleanup();
414 return rc;
415}
416
417static void __exit ghes_exit(void)
418{
419 ghes_cleanup();
420}
421
422module_init(ghes_init);
423module_exit(ghes_exit);
424
425MODULE_AUTHOR("Huang Ying");
426MODULE_DESCRIPTION("APEI Generic Hardware Error Source support");
427MODULE_LICENSE("GPL");
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c
new file mode 100644
index 000000000000..e7f40d362cb3
--- /dev/null
+++ b/drivers/acpi/apei/hest.c
@@ -0,0 +1,173 @@
1/*
2 * APEI Hardware Error Souce Table support
3 *
4 * HEST describes error sources in detail; communicates operational
5 * parameters (i.e. severity levels, masking bits, and threshold
6 * values) to Linux as necessary. It also allows the BIOS to report
7 * non-standard error sources to Linux (for example, chipset-specific
8 * error registers).
9 *
10 * For more information about HEST, please refer to ACPI Specification
11 * version 4.0, section 17.3.2.
12 *
13 * Copyright 2009 Intel Corp.
14 * Author: Huang Ying <ying.huang@intel.com>
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License version
18 * 2 as published by the Free Software Foundation;
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 */
29
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/acpi.h>
34#include <linux/kdebug.h>
35#include <linux/highmem.h>
36#include <linux/io.h>
37#include <acpi/apei.h>
38
39#include "apei-internal.h"
40
41#define HEST_PFX "HEST: "
42
43int hest_disable;
44EXPORT_SYMBOL_GPL(hest_disable);
45
46/* HEST table parsing */
47
48static struct acpi_table_hest *hest_tab;
49
50static int hest_void_parse(struct acpi_hest_header *hest_hdr, void *data)
51{
52 return 0;
53}
54
55static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = {
56 [ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */
57 [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1,
58 [ACPI_HEST_TYPE_IA32_NMI] = sizeof(struct acpi_hest_ia_nmi),
59 [ACPI_HEST_TYPE_AER_ROOT_PORT] = sizeof(struct acpi_hest_aer_root),
60 [ACPI_HEST_TYPE_AER_ENDPOINT] = sizeof(struct acpi_hest_aer),
61 [ACPI_HEST_TYPE_AER_BRIDGE] = sizeof(struct acpi_hest_aer_bridge),
62 [ACPI_HEST_TYPE_GENERIC_ERROR] = sizeof(struct acpi_hest_generic),
63};
64
65static int hest_esrc_len(struct acpi_hest_header *hest_hdr)
66{
67 u16 hest_type = hest_hdr->type;
68 int len;
69
70 if (hest_type >= ACPI_HEST_TYPE_RESERVED)
71 return 0;
72
73 len = hest_esrc_len_tab[hest_type];
74
75 if (hest_type == ACPI_HEST_TYPE_IA32_CORRECTED_CHECK) {
76 struct acpi_hest_ia_corrected *cmc;
77 cmc = (struct acpi_hest_ia_corrected *)hest_hdr;
78 len = sizeof(*cmc) + cmc->num_hardware_banks *
79 sizeof(struct acpi_hest_ia_error_bank);
80 } else if (hest_type == ACPI_HEST_TYPE_IA32_CHECK) {
81 struct acpi_hest_ia_machine_check *mc;
82 mc = (struct acpi_hest_ia_machine_check *)hest_hdr;
83 len = sizeof(*mc) + mc->num_hardware_banks *
84 sizeof(struct acpi_hest_ia_error_bank);
85 }
86 BUG_ON(len == -1);
87
88 return len;
89};
90
91int apei_hest_parse(apei_hest_func_t func, void *data)
92{
93 struct acpi_hest_header *hest_hdr;
94 int i, rc, len;
95
96 if (hest_disable)
97 return -EINVAL;
98
99 hest_hdr = (struct acpi_hest_header *)(hest_tab + 1);
100 for (i = 0; i < hest_tab->error_source_count; i++) {
101 len = hest_esrc_len(hest_hdr);
102 if (!len) {
103 pr_warning(FW_WARN HEST_PFX
104 "Unknown or unused hardware error source "
105 "type: %d for hardware error source: %d.\n",
106 hest_hdr->type, hest_hdr->source_id);
107 return -EINVAL;
108 }
109 if ((void *)hest_hdr + len >
110 (void *)hest_tab + hest_tab->header.length) {
111 pr_warning(FW_BUG HEST_PFX
112 "Table contents overflow for hardware error source: %d.\n",
113 hest_hdr->source_id);
114 return -EINVAL;
115 }
116
117 rc = func(hest_hdr, data);
118 if (rc)
119 return rc;
120
121 hest_hdr = (void *)hest_hdr + len;
122 }
123
124 return 0;
125}
126EXPORT_SYMBOL_GPL(apei_hest_parse);
127
128static int __init setup_hest_disable(char *str)
129{
130 hest_disable = 1;
131 return 0;
132}
133
134__setup("hest_disable", setup_hest_disable);
135
136static int __init hest_init(void)
137{
138 acpi_status status;
139 int rc = -ENODEV;
140
141 if (acpi_disabled)
142 goto err;
143
144 if (hest_disable) {
145 pr_info(HEST_PFX "HEST tabling parsing is disabled.\n");
146 goto err;
147 }
148
149 status = acpi_get_table(ACPI_SIG_HEST, 0,
150 (struct acpi_table_header **)&hest_tab);
151 if (status == AE_NOT_FOUND) {
152 pr_info(HEST_PFX "Table is not found!\n");
153 goto err;
154 } else if (ACPI_FAILURE(status)) {
155 const char *msg = acpi_format_exception(status);
156 pr_err(HEST_PFX "Failed to get table, %s\n", msg);
157 rc = -EINVAL;
158 goto err;
159 }
160
161 rc = apei_hest_parse(hest_void_parse, NULL);
162 if (rc)
163 goto err;
164
165 pr_info(HEST_PFX "HEST table parsing is initialized.\n");
166
167 return 0;
168err:
169 hest_disable = 1;
170 return rc;
171}
172
173subsys_initcall(hest_init);
diff --git a/drivers/acpi/atomicio.c b/drivers/acpi/atomicio.c
new file mode 100644
index 000000000000..814b19249616
--- /dev/null
+++ b/drivers/acpi/atomicio.c
@@ -0,0 +1,360 @@
1/*
2 * atomicio.c - ACPI IO memory pre-mapping/post-unmapping, then
3 * accessing in atomic context.
4 *
5 * This is used for NMI handler to access IO memory area, because
6 * ioremap/iounmap can not be used in NMI handler. The IO memory area
7 * is pre-mapped in process context and accessed in NMI handler.
8 *
9 * Copyright (C) 2009-2010, Intel Corp.
10 * Author: Huang Ying <ying.huang@intel.com>
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License version
14 * 2 as published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/init.h>
29#include <linux/acpi.h>
30#include <linux/io.h>
31#include <linux/kref.h>
32#include <linux/rculist.h>
33#include <linux/interrupt.h>
34#include <acpi/atomicio.h>
35
36#define ACPI_PFX "ACPI: "
37
38static LIST_HEAD(acpi_iomaps);
39/*
40 * Used for mutual exclusion between writers of acpi_iomaps list, for
41 * synchronization between readers and writer, RCU is used.
42 */
43static DEFINE_SPINLOCK(acpi_iomaps_lock);
44
45struct acpi_iomap {
46 struct list_head list;
47 void __iomem *vaddr;
48 unsigned long size;
49 phys_addr_t paddr;
50 struct kref ref;
51};
52
53/* acpi_iomaps_lock or RCU read lock must be held before calling */
54static struct acpi_iomap *__acpi_find_iomap(phys_addr_t paddr,
55 unsigned long size)
56{
57 struct acpi_iomap *map;
58
59 list_for_each_entry_rcu(map, &acpi_iomaps, list) {
60 if (map->paddr + map->size >= paddr + size &&
61 map->paddr <= paddr)
62 return map;
63 }
64 return NULL;
65}
66
67/*
68 * Atomic "ioremap" used by NMI handler, if the specified IO memory
69 * area is not pre-mapped, NULL will be returned.
70 *
71 * acpi_iomaps_lock or RCU read lock must be held before calling
72 */
73static void __iomem *__acpi_ioremap_fast(phys_addr_t paddr,
74 unsigned long size)
75{
76 struct acpi_iomap *map;
77
78 map = __acpi_find_iomap(paddr, size);
79 if (map)
80 return map->vaddr + (paddr - map->paddr);
81 else
82 return NULL;
83}
84
85/* acpi_iomaps_lock must be held before calling */
86static void __iomem *__acpi_try_ioremap(phys_addr_t paddr,
87 unsigned long size)
88{
89 struct acpi_iomap *map;
90
91 map = __acpi_find_iomap(paddr, size);
92 if (map) {
93 kref_get(&map->ref);
94 return map->vaddr + (paddr - map->paddr);
95 } else
96 return NULL;
97}
98
99/*
100 * Used to pre-map the specified IO memory area. First try to find
101 * whether the area is already pre-mapped, if it is, increase the
102 * reference count (in __acpi_try_ioremap) and return; otherwise, do
103 * the real ioremap, and add the mapping into acpi_iomaps list.
104 */
105static void __iomem *acpi_pre_map(phys_addr_t paddr,
106 unsigned long size)
107{
108 void __iomem *vaddr;
109 struct acpi_iomap *map;
110 unsigned long pg_sz, flags;
111 phys_addr_t pg_off;
112
113 spin_lock_irqsave(&acpi_iomaps_lock, flags);
114 vaddr = __acpi_try_ioremap(paddr, size);
115 spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
116 if (vaddr)
117 return vaddr;
118
119 pg_off = paddr & PAGE_MASK;
120 pg_sz = ((paddr + size + PAGE_SIZE - 1) & PAGE_MASK) - pg_off;
121 vaddr = ioremap(pg_off, pg_sz);
122 if (!vaddr)
123 return NULL;
124 map = kmalloc(sizeof(*map), GFP_KERNEL);
125 if (!map)
126 goto err_unmap;
127 INIT_LIST_HEAD(&map->list);
128 map->paddr = pg_off;
129 map->size = pg_sz;
130 map->vaddr = vaddr;
131 kref_init(&map->ref);
132
133 spin_lock_irqsave(&acpi_iomaps_lock, flags);
134 vaddr = __acpi_try_ioremap(paddr, size);
135 if (vaddr) {
136 spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
137 iounmap(map->vaddr);
138 kfree(map);
139 return vaddr;
140 }
141 list_add_tail_rcu(&map->list, &acpi_iomaps);
142 spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
143
144 return vaddr + (paddr - pg_off);
145err_unmap:
146 iounmap(vaddr);
147 return NULL;
148}
149
150/* acpi_iomaps_lock must be held before calling */
151static void __acpi_kref_del_iomap(struct kref *ref)
152{
153 struct acpi_iomap *map;
154
155 map = container_of(ref, struct acpi_iomap, ref);
156 list_del_rcu(&map->list);
157}
158
159/*
160 * Used to post-unmap the specified IO memory area. The iounmap is
161 * done only if the reference count goes zero.
162 */
163static void acpi_post_unmap(phys_addr_t paddr, unsigned long size)
164{
165 struct acpi_iomap *map;
166 unsigned long flags;
167 int del;
168
169 spin_lock_irqsave(&acpi_iomaps_lock, flags);
170 map = __acpi_find_iomap(paddr, size);
171 BUG_ON(!map);
172 del = kref_put(&map->ref, __acpi_kref_del_iomap);
173 spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
174
175 if (!del)
176 return;
177
178 synchronize_rcu();
179 iounmap(map->vaddr);
180 kfree(map);
181}
182
183/* In NMI handler, should set silent = 1 */
184static int acpi_check_gar(struct acpi_generic_address *reg,
185 u64 *paddr, int silent)
186{
187 u32 width, space_id;
188
189 width = reg->bit_width;
190 space_id = reg->space_id;
191 /* Handle possible alignment issues */
192 memcpy(paddr, &reg->address, sizeof(*paddr));
193 if (!*paddr) {
194 if (!silent)
195 pr_warning(FW_BUG ACPI_PFX
196 "Invalid physical address in GAR [0x%llx/%u/%u]\n",
197 *paddr, width, space_id);
198 return -EINVAL;
199 }
200
201 if ((width != 8) && (width != 16) && (width != 32) && (width != 64)) {
202 if (!silent)
203 pr_warning(FW_BUG ACPI_PFX
204 "Invalid bit width in GAR [0x%llx/%u/%u]\n",
205 *paddr, width, space_id);
206 return -EINVAL;
207 }
208
209 if (space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY &&
210 space_id != ACPI_ADR_SPACE_SYSTEM_IO) {
211 if (!silent)
212 pr_warning(FW_BUG ACPI_PFX
213 "Invalid address space type in GAR [0x%llx/%u/%u]\n",
214 *paddr, width, space_id);
215 return -EINVAL;
216 }
217
218 return 0;
219}
220
221/* Pre-map, working on GAR */
222int acpi_pre_map_gar(struct acpi_generic_address *reg)
223{
224 u64 paddr;
225 void __iomem *vaddr;
226 int rc;
227
228 if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
229 return 0;
230
231 rc = acpi_check_gar(reg, &paddr, 0);
232 if (rc)
233 return rc;
234
235 vaddr = acpi_pre_map(paddr, reg->bit_width / 8);
236 if (!vaddr)
237 return -EIO;
238
239 return 0;
240}
241EXPORT_SYMBOL_GPL(acpi_pre_map_gar);
242
243/* Post-unmap, working on GAR */
244int acpi_post_unmap_gar(struct acpi_generic_address *reg)
245{
246 u64 paddr;
247 int rc;
248
249 if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
250 return 0;
251
252 rc = acpi_check_gar(reg, &paddr, 0);
253 if (rc)
254 return rc;
255
256 acpi_post_unmap(paddr, reg->bit_width / 8);
257
258 return 0;
259}
260EXPORT_SYMBOL_GPL(acpi_post_unmap_gar);
261
262/*
263 * Can be used in atomic (including NMI) or process context. RCU read
264 * lock can only be released after the IO memory area accessing.
265 */
266static int acpi_atomic_read_mem(u64 paddr, u64 *val, u32 width)
267{
268 void __iomem *addr;
269
270 rcu_read_lock();
271 addr = __acpi_ioremap_fast(paddr, width);
272 switch (width) {
273 case 8:
274 *val = readb(addr);
275 break;
276 case 16:
277 *val = readw(addr);
278 break;
279 case 32:
280 *val = readl(addr);
281 break;
282 case 64:
283 *val = readq(addr);
284 break;
285 default:
286 return -EINVAL;
287 }
288 rcu_read_unlock();
289
290 return 0;
291}
292
293static int acpi_atomic_write_mem(u64 paddr, u64 val, u32 width)
294{
295 void __iomem *addr;
296
297 rcu_read_lock();
298 addr = __acpi_ioremap_fast(paddr, width);
299 switch (width) {
300 case 8:
301 writeb(val, addr);
302 break;
303 case 16:
304 writew(val, addr);
305 break;
306 case 32:
307 writel(val, addr);
308 break;
309 case 64:
310 writeq(val, addr);
311 break;
312 default:
313 return -EINVAL;
314 }
315 rcu_read_unlock();
316
317 return 0;
318}
319
320/* GAR accessing in atomic (including NMI) or process context */
321int acpi_atomic_read(u64 *val, struct acpi_generic_address *reg)
322{
323 u64 paddr;
324 int rc;
325
326 rc = acpi_check_gar(reg, &paddr, 1);
327 if (rc)
328 return rc;
329
330 *val = 0;
331 switch (reg->space_id) {
332 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
333 return acpi_atomic_read_mem(paddr, val, reg->bit_width);
334 case ACPI_ADR_SPACE_SYSTEM_IO:
335 return acpi_os_read_port(paddr, (u32 *)val, reg->bit_width);
336 default:
337 return -EINVAL;
338 }
339}
340EXPORT_SYMBOL_GPL(acpi_atomic_read);
341
342int acpi_atomic_write(u64 val, struct acpi_generic_address *reg)
343{
344 u64 paddr;
345 int rc;
346
347 rc = acpi_check_gar(reg, &paddr, 1);
348 if (rc)
349 return rc;
350
351 switch (reg->space_id) {
352 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
353 return acpi_atomic_write_mem(paddr, val, reg->bit_width);
354 case ACPI_ADR_SPACE_SYSTEM_IO:
355 return acpi_os_write_port(paddr, val, reg->bit_width);
356 default:
357 return -EINVAL;
358 }
359}
360EXPORT_SYMBOL_GPL(acpi_atomic_write);
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 58d2c91ba62b..3026e3fa83ef 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -32,6 +32,7 @@
32#include <linux/jiffies.h> 32#include <linux/jiffies.h>
33#include <linux/async.h> 33#include <linux/async.h>
34#include <linux/dmi.h> 34#include <linux/dmi.h>
35#include <linux/slab.h>
35 36
36#ifdef CONFIG_ACPI_PROCFS_POWER 37#ifdef CONFIG_ACPI_PROCFS_POWER
37#include <linux/proc_fs.h> 38#include <linux/proc_fs.h>
@@ -54,6 +55,7 @@
54#define ACPI_BATTERY_DEVICE_NAME "Battery" 55#define ACPI_BATTERY_DEVICE_NAME "Battery"
55#define ACPI_BATTERY_NOTIFY_STATUS 0x80 56#define ACPI_BATTERY_NOTIFY_STATUS 0x80
56#define ACPI_BATTERY_NOTIFY_INFO 0x81 57#define ACPI_BATTERY_NOTIFY_INFO 0x81
58#define ACPI_BATTERY_NOTIFY_THRESHOLD 0x82
57 59
58#define _COMPONENT ACPI_BATTERY_COMPONENT 60#define _COMPONENT ACPI_BATTERY_COMPONENT
59 61
@@ -88,10 +90,15 @@ static const struct acpi_device_id battery_device_ids[] = {
88 90
89MODULE_DEVICE_TABLE(acpi, battery_device_ids); 91MODULE_DEVICE_TABLE(acpi, battery_device_ids);
90 92
91/* For buggy DSDTs that report negative 16-bit values for either charging 93enum {
92 * or discharging current and/or report 0 as 65536 due to bad math. 94 ACPI_BATTERY_ALARM_PRESENT,
93 */ 95 ACPI_BATTERY_XINFO_PRESENT,
94#define QUIRK_SIGNED16_CURRENT 0x0001 96 /* For buggy DSDTs that report negative 16-bit values for either
97 * charging or discharging current and/or report 0 as 65536
98 * due to bad math.
99 */
100 ACPI_BATTERY_QUIRK_SIGNED16_CURRENT,
101};
95 102
96struct acpi_battery { 103struct acpi_battery {
97 struct mutex lock; 104 struct mutex lock;
@@ -109,6 +116,12 @@ struct acpi_battery {
109 int design_voltage; 116 int design_voltage;
110 int design_capacity_warning; 117 int design_capacity_warning;
111 int design_capacity_low; 118 int design_capacity_low;
119 int cycle_count;
120 int measurement_accuracy;
121 int max_sampling_time;
122 int min_sampling_time;
123 int max_averaging_interval;
124 int min_averaging_interval;
112 int capacity_granularity_1; 125 int capacity_granularity_1;
113 int capacity_granularity_2; 126 int capacity_granularity_2;
114 int alarm; 127 int alarm;
@@ -118,8 +131,7 @@ struct acpi_battery {
118 char oem_info[32]; 131 char oem_info[32];
119 int state; 132 int state;
120 int power_unit; 133 int power_unit;
121 u8 alarm_present; 134 unsigned long flags;
122 long quirks;
123}; 135};
124 136
125#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); 137#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
@@ -198,6 +210,9 @@ static int acpi_battery_get_property(struct power_supply *psy,
198 case POWER_SUPPLY_PROP_TECHNOLOGY: 210 case POWER_SUPPLY_PROP_TECHNOLOGY:
199 val->intval = acpi_battery_technology(battery); 211 val->intval = acpi_battery_technology(battery);
200 break; 212 break;
213 case POWER_SUPPLY_PROP_CYCLE_COUNT:
214 val->intval = battery->cycle_count;
215 break;
201 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 216 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
202 val->intval = battery->design_voltage * 1000; 217 val->intval = battery->design_voltage * 1000;
203 break; 218 break;
@@ -239,6 +254,7 @@ static enum power_supply_property charge_battery_props[] = {
239 POWER_SUPPLY_PROP_STATUS, 254 POWER_SUPPLY_PROP_STATUS,
240 POWER_SUPPLY_PROP_PRESENT, 255 POWER_SUPPLY_PROP_PRESENT,
241 POWER_SUPPLY_PROP_TECHNOLOGY, 256 POWER_SUPPLY_PROP_TECHNOLOGY,
257 POWER_SUPPLY_PROP_CYCLE_COUNT,
242 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 258 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
243 POWER_SUPPLY_PROP_VOLTAGE_NOW, 259 POWER_SUPPLY_PROP_VOLTAGE_NOW,
244 POWER_SUPPLY_PROP_CURRENT_NOW, 260 POWER_SUPPLY_PROP_CURRENT_NOW,
@@ -254,6 +270,7 @@ static enum power_supply_property energy_battery_props[] = {
254 POWER_SUPPLY_PROP_STATUS, 270 POWER_SUPPLY_PROP_STATUS,
255 POWER_SUPPLY_PROP_PRESENT, 271 POWER_SUPPLY_PROP_PRESENT,
256 POWER_SUPPLY_PROP_TECHNOLOGY, 272 POWER_SUPPLY_PROP_TECHNOLOGY,
273 POWER_SUPPLY_PROP_CYCLE_COUNT,
257 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 274 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
258 POWER_SUPPLY_PROP_VOLTAGE_NOW, 275 POWER_SUPPLY_PROP_VOLTAGE_NOW,
259 POWER_SUPPLY_PROP_CURRENT_NOW, 276 POWER_SUPPLY_PROP_CURRENT_NOW,
@@ -305,6 +322,28 @@ static struct acpi_offsets info_offsets[] = {
305 {offsetof(struct acpi_battery, oem_info), 1}, 322 {offsetof(struct acpi_battery, oem_info), 1},
306}; 323};
307 324
325static struct acpi_offsets extended_info_offsets[] = {
326 {offsetof(struct acpi_battery, power_unit), 0},
327 {offsetof(struct acpi_battery, design_capacity), 0},
328 {offsetof(struct acpi_battery, full_charge_capacity), 0},
329 {offsetof(struct acpi_battery, technology), 0},
330 {offsetof(struct acpi_battery, design_voltage), 0},
331 {offsetof(struct acpi_battery, design_capacity_warning), 0},
332 {offsetof(struct acpi_battery, design_capacity_low), 0},
333 {offsetof(struct acpi_battery, cycle_count), 0},
334 {offsetof(struct acpi_battery, measurement_accuracy), 0},
335 {offsetof(struct acpi_battery, max_sampling_time), 0},
336 {offsetof(struct acpi_battery, min_sampling_time), 0},
337 {offsetof(struct acpi_battery, max_averaging_interval), 0},
338 {offsetof(struct acpi_battery, min_averaging_interval), 0},
339 {offsetof(struct acpi_battery, capacity_granularity_1), 0},
340 {offsetof(struct acpi_battery, capacity_granularity_2), 0},
341 {offsetof(struct acpi_battery, model_number), 1},
342 {offsetof(struct acpi_battery, serial_number), 1},
343 {offsetof(struct acpi_battery, type), 1},
344 {offsetof(struct acpi_battery, oem_info), 1},
345};
346
308static int extract_package(struct acpi_battery *battery, 347static int extract_package(struct acpi_battery *battery,
309 union acpi_object *package, 348 union acpi_object *package,
310 struct acpi_offsets *offsets, int num) 349 struct acpi_offsets *offsets, int num)
@@ -350,22 +389,29 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
350{ 389{
351 int result = -EFAULT; 390 int result = -EFAULT;
352 acpi_status status = 0; 391 acpi_status status = 0;
392 char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags)?
393 "_BIX" : "_BIF";
394
353 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 395 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
354 396
355 if (!acpi_battery_present(battery)) 397 if (!acpi_battery_present(battery))
356 return 0; 398 return 0;
357 mutex_lock(&battery->lock); 399 mutex_lock(&battery->lock);
358 status = acpi_evaluate_object(battery->device->handle, "_BIF", 400 status = acpi_evaluate_object(battery->device->handle, name,
359 NULL, &buffer); 401 NULL, &buffer);
360 mutex_unlock(&battery->lock); 402 mutex_unlock(&battery->lock);
361 403
362 if (ACPI_FAILURE(status)) { 404 if (ACPI_FAILURE(status)) {
363 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); 405 ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s", name));
364 return -ENODEV; 406 return -ENODEV;
365 } 407 }
366 408 if (test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags))
367 result = extract_package(battery, buffer.pointer, 409 result = extract_package(battery, buffer.pointer,
368 info_offsets, ARRAY_SIZE(info_offsets)); 410 extended_info_offsets,
411 ARRAY_SIZE(extended_info_offsets));
412 else
413 result = extract_package(battery, buffer.pointer,
414 info_offsets, ARRAY_SIZE(info_offsets));
369 kfree(buffer.pointer); 415 kfree(buffer.pointer);
370 return result; 416 return result;
371} 417}
@@ -399,7 +445,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
399 battery->update_time = jiffies; 445 battery->update_time = jiffies;
400 kfree(buffer.pointer); 446 kfree(buffer.pointer);
401 447
402 if ((battery->quirks & QUIRK_SIGNED16_CURRENT) && 448 if (test_bit(ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, &battery->flags) &&
403 battery->rate_now != -1) 449 battery->rate_now != -1)
404 battery->rate_now = abs((s16)battery->rate_now); 450 battery->rate_now = abs((s16)battery->rate_now);
405 451
@@ -412,7 +458,8 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery)
412 union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER }; 458 union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER };
413 struct acpi_object_list arg_list = { 1, &arg0 }; 459 struct acpi_object_list arg_list = { 1, &arg0 };
414 460
415 if (!acpi_battery_present(battery)|| !battery->alarm_present) 461 if (!acpi_battery_present(battery) ||
462 !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags))
416 return -ENODEV; 463 return -ENODEV;
417 464
418 arg0.integer.value = battery->alarm; 465 arg0.integer.value = battery->alarm;
@@ -437,10 +484,10 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery)
437 /* See if alarms are supported, and if so, set default */ 484 /* See if alarms are supported, and if so, set default */
438 status = acpi_get_handle(battery->device->handle, "_BTP", &handle); 485 status = acpi_get_handle(battery->device->handle, "_BTP", &handle);
439 if (ACPI_FAILURE(status)) { 486 if (ACPI_FAILURE(status)) {
440 battery->alarm_present = 0; 487 clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
441 return 0; 488 return 0;
442 } 489 }
443 battery->alarm_present = 1; 490 set_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
444 if (!battery->alarm) 491 if (!battery->alarm)
445 battery->alarm = battery->design_capacity_warning; 492 battery->alarm = battery->design_capacity_warning;
446 return acpi_battery_set_alarm(battery); 493 return acpi_battery_set_alarm(battery);
@@ -510,9 +557,8 @@ static void sysfs_remove_battery(struct acpi_battery *battery)
510 557
511static void acpi_battery_quirks(struct acpi_battery *battery) 558static void acpi_battery_quirks(struct acpi_battery *battery)
512{ 559{
513 battery->quirks = 0;
514 if (dmi_name_in_vendors("Acer") && battery->power_unit) { 560 if (dmi_name_in_vendors("Acer") && battery->power_unit) {
515 battery->quirks |= QUIRK_SIGNED16_CURRENT; 561 set_bit(ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, &battery->flags);
516 } 562 }
517} 563}
518 564
@@ -522,13 +568,13 @@ static int acpi_battery_update(struct acpi_battery *battery)
522 result = acpi_battery_get_status(battery); 568 result = acpi_battery_get_status(battery);
523 if (result) 569 if (result)
524 return result; 570 return result;
525#ifdef CONFIG_ACPI_SYSFS_POWER
526 if (!acpi_battery_present(battery)) { 571 if (!acpi_battery_present(battery)) {
572#ifdef CONFIG_ACPI_SYSFS_POWER
527 sysfs_remove_battery(battery); 573 sysfs_remove_battery(battery);
574#endif
528 battery->update_time = 0; 575 battery->update_time = 0;
529 return 0; 576 return 0;
530 } 577 }
531#endif
532 if (!battery->update_time || 578 if (!battery->update_time ||
533 old_present != acpi_battery_present(battery)) { 579 old_present != acpi_battery_present(battery)) {
534 result = acpi_battery_get_info(battery); 580 result = acpi_battery_get_info(battery);
@@ -590,6 +636,7 @@ static int acpi_battery_print_info(struct seq_file *seq, int result)
590 seq_printf(seq, "design capacity low: %d %sh\n", 636 seq_printf(seq, "design capacity low: %d %sh\n",
591 battery->design_capacity_low, 637 battery->design_capacity_low,
592 acpi_battery_units(battery)); 638 acpi_battery_units(battery));
639 seq_printf(seq, "cycle count: %i\n", battery->cycle_count);
593 seq_printf(seq, "capacity granularity 1: %d %sh\n", 640 seq_printf(seq, "capacity granularity 1: %d %sh\n",
594 battery->capacity_granularity_1, 641 battery->capacity_granularity_1,
595 acpi_battery_units(battery)); 642 acpi_battery_units(battery));
@@ -833,7 +880,7 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event)
833#ifdef CONFIG_ACPI_SYSFS_POWER 880#ifdef CONFIG_ACPI_SYSFS_POWER
834 /* acpi_battery_update could remove power_supply object */ 881 /* acpi_battery_update could remove power_supply object */
835 if (battery->bat.dev) 882 if (battery->bat.dev)
836 kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE); 883 power_supply_changed(&battery->bat);
837#endif 884#endif
838} 885}
839 886
@@ -841,6 +888,7 @@ static int acpi_battery_add(struct acpi_device *device)
841{ 888{
842 int result = 0; 889 int result = 0;
843 struct acpi_battery *battery = NULL; 890 struct acpi_battery *battery = NULL;
891 acpi_handle handle;
844 if (!device) 892 if (!device)
845 return -EINVAL; 893 return -EINVAL;
846 battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); 894 battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
@@ -851,6 +899,9 @@ static int acpi_battery_add(struct acpi_device *device)
851 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); 899 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
852 device->driver_data = battery; 900 device->driver_data = battery;
853 mutex_init(&battery->lock); 901 mutex_init(&battery->lock);
902 if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle,
903 "_BIX", &handle)))
904 set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
854 acpi_battery_update(battery); 905 acpi_battery_update(battery);
855#ifdef CONFIG_ACPI_PROCFS_POWER 906#ifdef CONFIG_ACPI_PROCFS_POWER
856 result = acpi_battery_add_fs(device); 907 result = acpi_battery_add_fs(device);
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index a52126e46307..743576bf1bd7 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -32,6 +32,7 @@
32#include <linux/device.h> 32#include <linux/device.h>
33#include <linux/proc_fs.h> 33#include <linux/proc_fs.h>
34#include <linux/acpi.h> 34#include <linux/acpi.h>
35#include <linux/slab.h>
35#ifdef CONFIG_X86 36#ifdef CONFIG_X86
36#include <asm/mpspec.h> 37#include <asm/mpspec.h>
37#endif 38#endif
@@ -190,16 +191,16 @@ int acpi_bus_get_power(acpi_handle handle, int *state)
190 * Get the device's power state either directly (via _PSC) or 191 * Get the device's power state either directly (via _PSC) or
191 * indirectly (via power resources). 192 * indirectly (via power resources).
192 */ 193 */
193 if (device->power.flags.explicit_get) { 194 if (device->power.flags.power_resources) {
195 result = acpi_power_get_inferred_state(device);
196 if (result)
197 return result;
198 } else if (device->power.flags.explicit_get) {
194 status = acpi_evaluate_integer(device->handle, "_PSC", 199 status = acpi_evaluate_integer(device->handle, "_PSC",
195 NULL, &psc); 200 NULL, &psc);
196 if (ACPI_FAILURE(status)) 201 if (ACPI_FAILURE(status))
197 return -ENODEV; 202 return -ENODEV;
198 device->power.state = (int)psc; 203 device->power.state = (int)psc;
199 } else if (device->power.flags.power_resources) {
200 result = acpi_power_get_inferred_state(device);
201 if (result)
202 return result;
203 } 204 }
204 205
205 *state = device->power.state; 206 *state = device->power.state;
@@ -526,7 +527,7 @@ int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id,
526 if (!event_is_open) 527 if (!event_is_open)
527 return 0; 528 return 0;
528 529
529 event = kmalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC); 530 event = kzalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC);
530 if (!event) 531 if (!event)
531 return -ENOMEM; 532 return -ENOMEM;
532 533
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index f53fbe307c9d..fd51c4ab4829 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -30,6 +30,7 @@
30#include <linux/proc_fs.h> 30#include <linux/proc_fs.h>
31#include <linux/seq_file.h> 31#include <linux/seq_file.h>
32#include <linux/input.h> 32#include <linux/input.h>
33#include <linux/slab.h>
33#include <acpi/acpi_bus.h> 34#include <acpi/acpi_bus.h>
34#include <acpi/acpi_drivers.h> 35#include <acpi/acpi_drivers.h>
35 36
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 5faf6c21257d..45cd03b4630e 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -29,6 +29,7 @@
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/slab.h>
32#include <linux/types.h> 33#include <linux/types.h>
33#include <linux/acpi.h> 34#include <linux/acpi.h>
34#include <acpi/acpi_bus.h> 35#include <acpi/acpi_bus.h>
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c
index cc421b7ae166..146135e7a6a1 100644
--- a/drivers/acpi/debug.c
+++ b/drivers/acpi/debug.c
@@ -9,6 +9,7 @@
9#include <linux/kernel.h> 9#include <linux/kernel.h>
10#include <linux/moduleparam.h> 10#include <linux/moduleparam.h>
11#include <linux/debugfs.h> 11#include <linux/debugfs.h>
12#include <linux/slab.h>
12#include <asm/uaccess.h> 13#include <asm/uaccess.h>
13#include <acpi/acpi_drivers.h> 14#include <acpi/acpi_drivers.h>
14 15
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index d9a85f1ddde6..3fe29e992be8 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -24,6 +24,7 @@
24 24
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/slab.h>
27#include <linux/init.h> 28#include <linux/init.h>
28#include <linux/types.h> 29#include <linux/types.h>
29#include <linux/notifier.h> 30#include <linux/notifier.h>
@@ -1025,13 +1026,10 @@ static int dock_remove(struct dock_station *ds)
1025static acpi_status 1026static acpi_status
1026find_dock(acpi_handle handle, u32 lvl, void *context, void **rv) 1027find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
1027{ 1028{
1028 acpi_status status = AE_OK;
1029
1030 if (is_dock(handle)) 1029 if (is_dock(handle))
1031 if (dock_add(handle) >= 0) 1030 dock_add(handle);
1032 status = AE_CTRL_TERMINATE;
1033 1031
1034 return status; 1032 return AE_OK;
1035} 1033}
1036 1034
1037static acpi_status 1035static acpi_status
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index d7a6bbbb834c..e61d4f8e62a5 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -39,6 +39,7 @@
39#include <linux/interrupt.h> 39#include <linux/interrupt.h>
40#include <linux/list.h> 40#include <linux/list.h>
41#include <linux/spinlock.h> 41#include <linux/spinlock.h>
42#include <linux/slab.h>
42#include <asm/io.h> 43#include <asm/io.h>
43#include <acpi/acpi_bus.h> 44#include <acpi/acpi_bus.h>
44#include <acpi/acpi_drivers.h> 45#include <acpi/acpi_drivers.h>
@@ -76,8 +77,9 @@ enum ec_command {
76enum { 77enum {
77 EC_FLAGS_QUERY_PENDING, /* Query is pending */ 78 EC_FLAGS_QUERY_PENDING, /* Query is pending */
78 EC_FLAGS_GPE_STORM, /* GPE storm detected */ 79 EC_FLAGS_GPE_STORM, /* GPE storm detected */
79 EC_FLAGS_HANDLERS_INSTALLED /* Handlers for GPE and 80 EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and
80 * OpReg are installed */ 81 * OpReg are installed */
82 EC_FLAGS_FROZEN, /* Transactions are suspended */
81}; 83};
82 84
83/* If we find an EC via the ECDT, we need to keep a ptr to its context */ 85/* If we find an EC via the ECDT, we need to keep a ptr to its context */
@@ -291,6 +293,10 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
291 if (t->rdata) 293 if (t->rdata)
292 memset(t->rdata, 0, t->rlen); 294 memset(t->rdata, 0, t->rlen);
293 mutex_lock(&ec->lock); 295 mutex_lock(&ec->lock);
296 if (test_bit(EC_FLAGS_FROZEN, &ec->flags)) {
297 status = -EINVAL;
298 goto unlock;
299 }
294 if (ec->global_lock) { 300 if (ec->global_lock) {
295 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); 301 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
296 if (ACPI_FAILURE(status)) { 302 if (ACPI_FAILURE(status)) {
@@ -453,6 +459,32 @@ int ec_transaction(u8 command,
453 459
454EXPORT_SYMBOL(ec_transaction); 460EXPORT_SYMBOL(ec_transaction);
455 461
462void acpi_ec_suspend_transactions(void)
463{
464 struct acpi_ec *ec = first_ec;
465
466 if (!ec)
467 return;
468
469 mutex_lock(&ec->lock);
470 /* Prevent transactions from being carried out */
471 set_bit(EC_FLAGS_FROZEN, &ec->flags);
472 mutex_unlock(&ec->lock);
473}
474
475void acpi_ec_resume_transactions(void)
476{
477 struct acpi_ec *ec = first_ec;
478
479 if (!ec)
480 return;
481
482 mutex_lock(&ec->lock);
483 /* Allow transactions to be carried out again */
484 clear_bit(EC_FLAGS_FROZEN, &ec->flags);
485 mutex_unlock(&ec->lock);
486}
487
456static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data) 488static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data)
457{ 489{
458 int result; 490 int result;
@@ -597,12 +629,12 @@ static u32 acpi_ec_gpe_handler(void *data)
597 629
598static acpi_status 630static acpi_status
599acpi_ec_space_handler(u32 function, acpi_physical_address address, 631acpi_ec_space_handler(u32 function, acpi_physical_address address,
600 u32 bits, u64 *value, 632 u32 bits, u64 *value64,
601 void *handler_context, void *region_context) 633 void *handler_context, void *region_context)
602{ 634{
603 struct acpi_ec *ec = handler_context; 635 struct acpi_ec *ec = handler_context;
604 int result = 0, i; 636 int result = 0, i, bytes = bits / 8;
605 u8 temp = 0; 637 u8 *value = (u8 *)value64;
606 638
607 if ((address > 0xFF) || !value || !handler_context) 639 if ((address > 0xFF) || !value || !handler_context)
608 return AE_BAD_PARAMETER; 640 return AE_BAD_PARAMETER;
@@ -610,32 +642,15 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
610 if (function != ACPI_READ && function != ACPI_WRITE) 642 if (function != ACPI_READ && function != ACPI_WRITE)
611 return AE_BAD_PARAMETER; 643 return AE_BAD_PARAMETER;
612 644
613 if (bits != 8 && acpi_strict) 645 if (EC_FLAGS_MSI || bits > 8)
614 return AE_BAD_PARAMETER;
615
616 if (EC_FLAGS_MSI)
617 acpi_ec_burst_enable(ec); 646 acpi_ec_burst_enable(ec);
618 647
619 if (function == ACPI_READ) { 648 for (i = 0; i < bytes; ++i, ++address, ++value)
620 result = acpi_ec_read(ec, address, &temp); 649 result = (function == ACPI_READ) ?
621 *value = temp; 650 acpi_ec_read(ec, address, value) :
622 } else { 651 acpi_ec_write(ec, address, *value);
623 temp = 0xff & (*value);
624 result = acpi_ec_write(ec, address, temp);
625 }
626 652
627 for (i = 8; unlikely(bits - i > 0); i += 8) { 653 if (EC_FLAGS_MSI || bits > 8)
628 ++address;
629 if (function == ACPI_READ) {
630 result = acpi_ec_read(ec, address, &temp);
631 (*value) |= ((u64)temp) << i;
632 } else {
633 temp = 0xff & ((*value) >> i);
634 result = acpi_ec_write(ec, address, temp);
635 }
636 }
637
638 if (EC_FLAGS_MSI)
639 acpi_ec_burst_disable(ec); 654 acpi_ec_burst_disable(ec);
640 655
641 switch (result) { 656 switch (result) {
@@ -1012,10 +1027,9 @@ int __init acpi_ec_ecdt_probe(void)
1012 /* Don't trust ECDT, which comes from ASUSTek */ 1027 /* Don't trust ECDT, which comes from ASUSTek */
1013 if (!EC_FLAGS_VALIDATE_ECDT) 1028 if (!EC_FLAGS_VALIDATE_ECDT)
1014 goto install; 1029 goto install;
1015 saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); 1030 saved_ec = kmemdup(boot_ec, sizeof(struct acpi_ec), GFP_KERNEL);
1016 if (!saved_ec) 1031 if (!saved_ec)
1017 return -ENOMEM; 1032 return -ENOMEM;
1018 memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec));
1019 /* fall through */ 1033 /* fall through */
1020 } 1034 }
1021 1035
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c
index c511071bfd79..d439314a75d8 100644
--- a/drivers/acpi/event.c
+++ b/drivers/acpi/event.c
@@ -10,6 +10,7 @@
10#include <linux/proc_fs.h> 10#include <linux/proc_fs.h>
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/poll.h> 12#include <linux/poll.h>
13#include <linux/gfp.h>
13#include <acpi/acpi_drivers.h> 14#include <acpi/acpi_drivers.h>
14#include <net/netlink.h> 15#include <net/netlink.h>
15#include <net/genetlink.h> 16#include <net/genetlink.h>
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 6d5b64b7d526..4af6301601e7 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -9,6 +9,7 @@
9#include <linux/init.h> 9#include <linux/init.h>
10#include <linux/list.h> 10#include <linux/list.h>
11#include <linux/device.h> 11#include <linux/device.h>
12#include <linux/slab.h>
12#include <linux/rwsem.h> 13#include <linux/rwsem.h>
13#include <linux/acpi.h> 14#include <linux/acpi.h>
14 15
diff --git a/drivers/acpi/hed.c b/drivers/acpi/hed.c
new file mode 100644
index 000000000000..d0c1967f7597
--- /dev/null
+++ b/drivers/acpi/hed.c
@@ -0,0 +1,112 @@
1/*
2 * ACPI Hardware Error Device (PNP0C33) Driver
3 *
4 * Copyright (C) 2010, Intel Corp.
5 * Author: Huang Ying <ying.huang@intel.com>
6 *
7 * ACPI Hardware Error Device is used to report some hardware errors
8 * notified via SCI, mainly the corrected errors.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License version
12 * 2 as published by the Free Software Foundation;
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/acpi.h>
28#include <acpi/acpi_bus.h>
29#include <acpi/acpi_drivers.h>
30#include <acpi/hed.h>
31
32static struct acpi_device_id acpi_hed_ids[] = {
33 {"PNP0C33", 0},
34 {"", 0},
35};
36MODULE_DEVICE_TABLE(acpi, acpi_hed_ids);
37
38static acpi_handle hed_handle;
39
40static BLOCKING_NOTIFIER_HEAD(acpi_hed_notify_list);
41
42int register_acpi_hed_notifier(struct notifier_block *nb)
43{
44 return blocking_notifier_chain_register(&acpi_hed_notify_list, nb);
45}
46EXPORT_SYMBOL_GPL(register_acpi_hed_notifier);
47
48void unregister_acpi_hed_notifier(struct notifier_block *nb)
49{
50 blocking_notifier_chain_unregister(&acpi_hed_notify_list, nb);
51}
52EXPORT_SYMBOL_GPL(unregister_acpi_hed_notifier);
53
54/*
55 * SCI to report hardware error is forwarded to the listeners of HED,
56 * it is used by HEST Generic Hardware Error Source with notify type
57 * SCI.
58 */
59static void acpi_hed_notify(struct acpi_device *device, u32 event)
60{
61 blocking_notifier_call_chain(&acpi_hed_notify_list, 0, NULL);
62}
63
64static int __devinit acpi_hed_add(struct acpi_device *device)
65{
66 /* Only one hardware error device */
67 if (hed_handle)
68 return -EINVAL;
69 hed_handle = device->handle;
70 return 0;
71}
72
73static int __devexit acpi_hed_remove(struct acpi_device *device, int type)
74{
75 hed_handle = NULL;
76 return 0;
77}
78
79static struct acpi_driver acpi_hed_driver = {
80 .name = "hardware_error_device",
81 .class = "hardware_error",
82 .ids = acpi_hed_ids,
83 .ops = {
84 .add = acpi_hed_add,
85 .remove = acpi_hed_remove,
86 .notify = acpi_hed_notify,
87 },
88};
89
90static int __init acpi_hed_init(void)
91{
92 if (acpi_disabled)
93 return -ENODEV;
94
95 if (acpi_bus_register_driver(&acpi_hed_driver) < 0)
96 return -ENODEV;
97
98 return 0;
99}
100
101static void __exit acpi_hed_exit(void)
102{
103 acpi_bus_unregister_driver(&acpi_hed_driver);
104}
105
106module_init(acpi_hed_init);
107module_exit(acpi_hed_exit);
108
109ACPI_MODULE_NAME("hed");
110MODULE_AUTHOR("Huang Ying");
111MODULE_DESCRIPTION("ACPI Hardware Error Device Driver");
112MODULE_LICENSE("GPL");
diff --git a/drivers/acpi/hest.c b/drivers/acpi/hest.c
deleted file mode 100644
index 4bb18c980ac6..000000000000
--- a/drivers/acpi/hest.c
+++ /dev/null
@@ -1,135 +0,0 @@
1#include <linux/acpi.h>
2#include <linux/pci.h>
3
4#define PREFIX "ACPI: "
5
6static inline unsigned long parse_acpi_hest_ia_machine_check(struct acpi_hest_ia_machine_check *p)
7{
8 return sizeof(*p) +
9 (sizeof(struct acpi_hest_ia_error_bank) * p->num_hardware_banks);
10}
11
12static inline unsigned long parse_acpi_hest_ia_corrected(struct acpi_hest_ia_corrected *p)
13{
14 return sizeof(*p) +
15 (sizeof(struct acpi_hest_ia_error_bank) * p->num_hardware_banks);
16}
17
18static inline unsigned long parse_acpi_hest_ia_nmi(struct acpi_hest_ia_nmi *p)
19{
20 return sizeof(*p);
21}
22
23static inline unsigned long parse_acpi_hest_generic(struct acpi_hest_generic *p)
24{
25 return sizeof(*p);
26}
27
28static inline unsigned int hest_match_pci(struct acpi_hest_aer_common *p, struct pci_dev *pci)
29{
30 return (0 == pci_domain_nr(pci->bus) &&
31 p->bus == pci->bus->number &&
32 p->device == PCI_SLOT(pci->devfn) &&
33 p->function == PCI_FUNC(pci->devfn));
34}
35
36static unsigned long parse_acpi_hest_aer(void *hdr, int type, struct pci_dev *pci, int *firmware_first)
37{
38 struct acpi_hest_aer_common *p = hdr + sizeof(struct acpi_hest_header);
39 unsigned long rc=0;
40 u8 pcie_type = 0;
41 u8 bridge = 0;
42 switch (type) {
43 case ACPI_HEST_TYPE_AER_ROOT_PORT:
44 rc = sizeof(struct acpi_hest_aer_root);
45 pcie_type = PCI_EXP_TYPE_ROOT_PORT;
46 break;
47 case ACPI_HEST_TYPE_AER_ENDPOINT:
48 rc = sizeof(struct acpi_hest_aer);
49 pcie_type = PCI_EXP_TYPE_ENDPOINT;
50 break;
51 case ACPI_HEST_TYPE_AER_BRIDGE:
52 rc = sizeof(struct acpi_hest_aer_bridge);
53 if ((pci->class >> 16) == PCI_BASE_CLASS_BRIDGE)
54 bridge = 1;
55 break;
56 }
57
58 if (p->flags & ACPI_HEST_GLOBAL) {
59 if ((pci->is_pcie && (pci->pcie_type == pcie_type)) || bridge)
60 *firmware_first = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST);
61 }
62 else
63 if (hest_match_pci(p, pci))
64 *firmware_first = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST);
65 return rc;
66}
67
68static int acpi_hest_firmware_first(struct acpi_table_header *stdheader, struct pci_dev *pci)
69{
70 struct acpi_table_hest *hest = (struct acpi_table_hest *)stdheader;
71 void *p = (void *)hest + sizeof(*hest); /* defined by the ACPI 4.0 spec */
72 struct acpi_hest_header *hdr = p;
73
74 int i;
75 int firmware_first = 0;
76 static unsigned char printed_unused = 0;
77 static unsigned char printed_reserved = 0;
78
79 for (i=0, hdr=p; p < (((void *)hest) + hest->header.length) && i < hest->error_source_count; i++) {
80 switch (hdr->type) {
81 case ACPI_HEST_TYPE_IA32_CHECK:
82 p += parse_acpi_hest_ia_machine_check(p);
83 break;
84 case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
85 p += parse_acpi_hest_ia_corrected(p);
86 break;
87 case ACPI_HEST_TYPE_IA32_NMI:
88 p += parse_acpi_hest_ia_nmi(p);
89 break;
90 /* These three should never appear */
91 case ACPI_HEST_TYPE_NOT_USED3:
92 case ACPI_HEST_TYPE_NOT_USED4:
93 case ACPI_HEST_TYPE_NOT_USED5:
94 if (!printed_unused) {
95 printk(KERN_DEBUG PREFIX
96 "HEST Error Source list contains an obsolete type (%d).\n", hdr->type);
97 printed_unused = 1;
98 }
99 break;
100 case ACPI_HEST_TYPE_AER_ROOT_PORT:
101 case ACPI_HEST_TYPE_AER_ENDPOINT:
102 case ACPI_HEST_TYPE_AER_BRIDGE:
103 p += parse_acpi_hest_aer(p, hdr->type, pci, &firmware_first);
104 break;
105 case ACPI_HEST_TYPE_GENERIC_ERROR:
106 p += parse_acpi_hest_generic(p);
107 break;
108 /* These should never appear either */
109 case ACPI_HEST_TYPE_RESERVED:
110 default:
111 if (!printed_reserved) {
112 printk(KERN_DEBUG PREFIX
113 "HEST Error Source list contains a reserved type (%d).\n", hdr->type);
114 printed_reserved = 1;
115 }
116 break;
117 }
118 }
119 return firmware_first;
120}
121
122int acpi_hest_firmware_first_pci(struct pci_dev *pci)
123{
124 acpi_status status = AE_NOT_FOUND;
125 struct acpi_table_header *hest = NULL;
126 status = acpi_get_table(ACPI_SIG_HEST, 1, &hest);
127
128 if (ACPI_SUCCESS(status)) {
129 if (acpi_hest_firmware_first(hest, pci)) {
130 return 1;
131 }
132 }
133 return 0;
134}
135EXPORT_SYMBOL_GPL(acpi_hest_firmware_first_pci);
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 9c4c962e46e3..e28411367239 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -49,6 +49,8 @@ void acpi_early_processor_set_pdc(void);
49int acpi_ec_init(void); 49int acpi_ec_init(void);
50int acpi_ec_ecdt_probe(void); 50int acpi_ec_ecdt_probe(void);
51int acpi_boot_ec_enable(void); 51int acpi_boot_ec_enable(void);
52void acpi_ec_suspend_transactions(void);
53void acpi_ec_resume_transactions(void);
52 54
53/*-------------------------------------------------------------------------- 55/*--------------------------------------------------------------------------
54 Suspend/Resume 56 Suspend/Resume
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index b8725461d887..b0337d314604 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -61,8 +61,10 @@ int node_to_pxm(int node)
61 61
62void __acpi_map_pxm_to_node(int pxm, int node) 62void __acpi_map_pxm_to_node(int pxm, int node)
63{ 63{
64 pxm_to_node_map[pxm] = node; 64 if (pxm_to_node_map[pxm] == NUMA_NO_NODE || node < pxm_to_node_map[pxm])
65 node_to_pxm_map[node] = pxm; 65 pxm_to_node_map[pxm] = node;
66 if (node_to_pxm_map[node] == PXM_INVAL || pxm < node_to_pxm_map[node])
67 node_to_pxm_map[node] = pxm;
66} 68}
67 69
68int acpi_map_pxm_to_node(int pxm) 70int acpi_map_pxm_to_node(int pxm)
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 8e6d8665f0ae..7594f65800cf 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -758,7 +758,14 @@ static acpi_status __acpi_os_execute(acpi_execute_type type,
758 queue = hp ? kacpi_hotplug_wq : 758 queue = hp ? kacpi_hotplug_wq :
759 (type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq); 759 (type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq);
760 dpc->wait = hp ? 1 : 0; 760 dpc->wait = hp ? 1 : 0;
761 INIT_WORK(&dpc->work, acpi_os_execute_deferred); 761
762 if (queue == kacpi_hotplug_wq)
763 INIT_WORK(&dpc->work, acpi_os_execute_deferred);
764 else if (queue == kacpi_notify_wq)
765 INIT_WORK(&dpc->work, acpi_os_execute_deferred);
766 else
767 INIT_WORK(&dpc->work, acpi_os_execute_deferred);
768
762 ret = queue_work(queue, &dpc->work); 769 ret = queue_work(queue, &dpc->work);
763 770
764 if (!ret) { 771 if (!ret) {
@@ -1151,16 +1158,10 @@ int acpi_check_resource_conflict(const struct resource *res)
1151 1158
1152 if (clash) { 1159 if (clash) {
1153 if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) { 1160 if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) {
1154 printk("%sACPI: %s resource %s [0x%llx-0x%llx]" 1161 printk(KERN_WARNING "ACPI: resource %s %pR"
1155 " conflicts with ACPI region %s" 1162 " conflicts with ACPI region %s %pR\n",
1156 " [0x%llx-0x%llx]\n", 1163 res->name, res, res_list_elem->name,
1157 acpi_enforce_resources == ENFORCE_RESOURCES_LAX 1164 res_list_elem);
1158 ? KERN_WARNING : KERN_ERR,
1159 ioport ? "I/O" : "Memory", res->name,
1160 (long long) res->start, (long long) res->end,
1161 res_list_elem->name,
1162 (long long) res_list_elem->start,
1163 (long long) res_list_elem->end);
1164 if (acpi_enforce_resources == ENFORCE_RESOURCES_LAX) 1165 if (acpi_enforce_resources == ENFORCE_RESOURCES_LAX)
1165 printk(KERN_NOTICE "ACPI: This conflict may" 1166 printk(KERN_NOTICE "ACPI: This conflict may"
1166 " cause random problems and system" 1167 " cause random problems and system"
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 843699ed93f2..b0a71ecee682 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -37,6 +37,7 @@
37#include <linux/pm.h> 37#include <linux/pm.h>
38#include <linux/pci.h> 38#include <linux/pci.h>
39#include <linux/acpi.h> 39#include <linux/acpi.h>
40#include <linux/slab.h>
40#include <acpi/acpi_bus.h> 41#include <acpi/acpi_bus.h>
41#include <acpi/acpi_drivers.h> 42#include <acpi/acpi_drivers.h>
42 43
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 04b0f007c9b7..8d47a5846aeb 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -39,6 +39,7 @@
39#include <linux/pm.h> 39#include <linux/pm.h>
40#include <linux/pci.h> 40#include <linux/pci.h>
41#include <linux/mutex.h> 41#include <linux/mutex.h>
42#include <linux/slab.h>
42 43
43#include <acpi/acpi_bus.h> 44#include <acpi/acpi_bus.h>
44#include <acpi/acpi_drivers.h> 45#include <acpi/acpi_drivers.h>
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index d724736d56c8..4eac59393edc 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -34,6 +34,7 @@
34#include <linux/pci.h> 34#include <linux/pci.h>
35#include <linux/pci-acpi.h> 35#include <linux/pci-acpi.h>
36#include <linux/acpi.h> 36#include <linux/acpi.h>
37#include <linux/slab.h>
37#include <acpi/acpi_bus.h> 38#include <acpi/acpi_bus.h>
38#include <acpi/acpi_drivers.h> 39#include <acpi/acpi_drivers.h>
39 40
@@ -119,7 +120,8 @@ acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
119 struct acpi_pci_root *root; 120 struct acpi_pci_root *root;
120 121
121 list_for_each_entry(root, &acpi_pci_roots, node) 122 list_for_each_entry(root, &acpi_pci_roots, node)
122 if ((root->segment == (u16) seg) && (root->bus_nr == (u16) bus)) 123 if ((root->segment == (u16) seg) &&
124 (root->secondary.start == (u16) bus))
123 return root->device->handle; 125 return root->device->handle;
124 return NULL; 126 return NULL;
125} 127}
@@ -153,7 +155,7 @@ EXPORT_SYMBOL_GPL(acpi_is_root_bridge);
153static acpi_status 155static acpi_status
154get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) 156get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
155{ 157{
156 int *busnr = data; 158 struct resource *res = data;
157 struct acpi_resource_address64 address; 159 struct acpi_resource_address64 address;
158 160
159 if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 && 161 if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
@@ -163,28 +165,27 @@ get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
163 165
164 acpi_resource_to_address64(resource, &address); 166 acpi_resource_to_address64(resource, &address);
165 if ((address.address_length > 0) && 167 if ((address.address_length > 0) &&
166 (address.resource_type == ACPI_BUS_NUMBER_RANGE)) 168 (address.resource_type == ACPI_BUS_NUMBER_RANGE)) {
167 *busnr = address.minimum; 169 res->start = address.minimum;
170 res->end = address.minimum + address.address_length - 1;
171 }
168 172
169 return AE_OK; 173 return AE_OK;
170} 174}
171 175
172static acpi_status try_get_root_bridge_busnr(acpi_handle handle, 176static acpi_status try_get_root_bridge_busnr(acpi_handle handle,
173 unsigned long long *bus) 177 struct resource *res)
174{ 178{
175 acpi_status status; 179 acpi_status status;
176 int busnum;
177 180
178 busnum = -1; 181 res->start = -1;
179 status = 182 status =
180 acpi_walk_resources(handle, METHOD_NAME__CRS, 183 acpi_walk_resources(handle, METHOD_NAME__CRS,
181 get_root_bridge_busnr_callback, &busnum); 184 get_root_bridge_busnr_callback, res);
182 if (ACPI_FAILURE(status)) 185 if (ACPI_FAILURE(status))
183 return status; 186 return status;
184 /* Check if we really get a bus number from _CRS */ 187 if (res->start == -1)
185 if (busnum == -1)
186 return AE_ERROR; 188 return AE_ERROR;
187 *bus = busnum;
188 return AE_OK; 189 return AE_OK;
189} 190}
190 191
@@ -428,34 +429,47 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
428 struct acpi_device *child; 429 struct acpi_device *child;
429 u32 flags, base_flags; 430 u32 flags, base_flags;
430 431
432 root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
433 if (!root)
434 return -ENOMEM;
435
431 segment = 0; 436 segment = 0;
432 status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL, 437 status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL,
433 &segment); 438 &segment);
434 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { 439 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
435 printk(KERN_ERR PREFIX "can't evaluate _SEG\n"); 440 printk(KERN_ERR PREFIX "can't evaluate _SEG\n");
436 return -ENODEV; 441 result = -ENODEV;
442 goto end;
437 } 443 }
438 444
439 /* Check _CRS first, then _BBN. If no _BBN, default to zero. */ 445 /* Check _CRS first, then _BBN. If no _BBN, default to zero. */
440 bus = 0; 446 root->secondary.flags = IORESOURCE_BUS;
441 status = try_get_root_bridge_busnr(device->handle, &bus); 447 status = try_get_root_bridge_busnr(device->handle, &root->secondary);
442 if (ACPI_FAILURE(status)) { 448 if (ACPI_FAILURE(status)) {
449 /*
450 * We need both the start and end of the downstream bus range
451 * to interpret _CBA (MMCONFIG base address), so it really is
452 * supposed to be in _CRS. If we don't find it there, all we
453 * can do is assume [_BBN-0xFF] or [0-0xFF].
454 */
455 root->secondary.end = 0xFF;
456 printk(KERN_WARNING FW_BUG PREFIX
457 "no secondary bus range in _CRS\n");
443 status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, &bus); 458 status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, &bus);
444 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { 459 if (ACPI_SUCCESS(status))
445 printk(KERN_ERR PREFIX 460 root->secondary.start = bus;
446 "no bus number in _CRS and can't evaluate _BBN\n"); 461 else if (status == AE_NOT_FOUND)
447 return -ENODEV; 462 root->secondary.start = 0;
463 else {
464 printk(KERN_ERR PREFIX "can't evaluate _BBN\n");
465 result = -ENODEV;
466 goto end;
448 } 467 }
449 } 468 }
450 469
451 root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
452 if (!root)
453 return -ENOMEM;
454
455 INIT_LIST_HEAD(&root->node); 470 INIT_LIST_HEAD(&root->node);
456 root->device = device; 471 root->device = device;
457 root->segment = segment & 0xFFFF; 472 root->segment = segment & 0xFFFF;
458 root->bus_nr = bus & 0xFF;
459 strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); 473 strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
460 strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); 474 strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
461 device->driver_data = root; 475 device->driver_data = root;
@@ -474,9 +488,9 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
474 /* TBD: Locking */ 488 /* TBD: Locking */
475 list_add_tail(&root->node, &acpi_pci_roots); 489 list_add_tail(&root->node, &acpi_pci_roots);
476 490
477 printk(KERN_INFO PREFIX "%s [%s] (%04x:%02x)\n", 491 printk(KERN_INFO PREFIX "%s [%s] (domain %04x %pR)\n",
478 acpi_device_name(device), acpi_device_bid(device), 492 acpi_device_name(device), acpi_device_bid(device),
479 root->segment, root->bus_nr); 493 root->segment, &root->secondary);
480 494
481 /* 495 /*
482 * Scan the Root Bridge 496 * Scan the Root Bridge
@@ -485,11 +499,11 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
485 * PCI namespace does not get created until this call is made (and 499 * PCI namespace does not get created until this call is made (and
486 * thus the root bridge's pci_dev does not exist). 500 * thus the root bridge's pci_dev does not exist).
487 */ 501 */
488 root->bus = pci_acpi_scan_root(device, segment, bus); 502 root->bus = pci_acpi_scan_root(root);
489 if (!root->bus) { 503 if (!root->bus) {
490 printk(KERN_ERR PREFIX 504 printk(KERN_ERR PREFIX
491 "Bus %04x:%02x not present in PCI namespace\n", 505 "Bus %04x:%02x not present in PCI namespace\n",
492 root->segment, root->bus_nr); 506 root->segment, (unsigned int)root->secondary.start);
493 result = -ENODEV; 507 result = -ENODEV;
494 goto end; 508 goto end;
495 } 509 }
diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c
index 11f219743204..07f7fea8a4e2 100644
--- a/drivers/acpi/pci_slot.c
+++ b/drivers/acpi/pci_slot.c
@@ -26,6 +26,7 @@
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/slab.h>
29#include <linux/types.h> 30#include <linux/types.h>
30#include <linux/pci.h> 31#include <linux/pci.h>
31#include <linux/acpi.h> 32#include <linux/acpi.h>
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 0f30c3c1eea4..ddc76787b842 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -39,6 +39,7 @@
39#include <linux/module.h> 39#include <linux/module.h>
40#include <linux/init.h> 40#include <linux/init.h>
41#include <linux/types.h> 41#include <linux/types.h>
42#include <linux/slab.h>
42#include <linux/proc_fs.h> 43#include <linux/proc_fs.h>
43#include <linux/seq_file.h> 44#include <linux/seq_file.h>
44#include <acpi/acpi_bus.h> 45#include <acpi/acpi_bus.h>
diff --git a/drivers/acpi/power_meter.c b/drivers/acpi/power_meter.c
index 834c5af0de4b..66f67293341e 100644
--- a/drivers/acpi/power_meter.c
+++ b/drivers/acpi/power_meter.c
@@ -25,6 +25,7 @@
25#include <linux/jiffies.h> 25#include <linux/jiffies.h>
26#include <linux/mutex.h> 26#include <linux/mutex.h>
27#include <linux/dmi.h> 27#include <linux/dmi.h>
28#include <linux/slab.h>
28#include <linux/kdev_t.h> 29#include <linux/kdev_t.h>
29#include <linux/sched.h> 30#include <linux/sched.h>
30#include <linux/time.h> 31#include <linux/time.h>
@@ -34,7 +35,7 @@
34#define ACPI_POWER_METER_NAME "power_meter" 35#define ACPI_POWER_METER_NAME "power_meter"
35ACPI_MODULE_NAME(ACPI_POWER_METER_NAME); 36ACPI_MODULE_NAME(ACPI_POWER_METER_NAME);
36#define ACPI_POWER_METER_DEVICE_NAME "Power Meter" 37#define ACPI_POWER_METER_DEVICE_NAME "Power Meter"
37#define ACPI_POWER_METER_CLASS "power_meter_resource" 38#define ACPI_POWER_METER_CLASS "pwr_meter_resource"
38 39
39#define NUM_SENSORS 17 40#define NUM_SENSORS 17
40 41
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index e9b7b402dbfb..51284351418f 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -1,383 +1,63 @@
1/* 1/*
2 * acpi_processor.c - ACPI Processor Driver ($Revision: 71 $) 2 * Copyright (C) 2005 Intel Corporation
3 * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
3 * 4 *
4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 5 * Alex Chiang <achiang@hp.com>
5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 6 * - Unified x86/ia64 implementations
6 * Copyright (C) 2004 Dominik Brodowski <linux@brodo.de> 7 * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
7 * Copyright (C) 2004 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> 8 * - Added _PDC for platforms with Intel CPUs
8 * - Added processor hotplug support
9 *
10 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or (at
15 * your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 *
26 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27 * TBD:
28 * 1. Make # power states dynamic.
29 * 2. Support duty_cycle values that span bit 4.
30 * 3. Optimize by having scheduler determine business instead of
31 * having us try to calculate it here.
32 * 4. Need C1 timing -- must modify kernel (IRQ handler) to get this.
33 */ 9 */
34
35#include <linux/kernel.h>
36#include <linux/module.h>
37#include <linux/init.h>
38#include <linux/types.h>
39#include <linux/pci.h>
40#include <linux/pm.h>
41#include <linux/cpufreq.h>
42#include <linux/cpu.h>
43#include <linux/proc_fs.h>
44#include <linux/seq_file.h>
45#include <linux/dmi.h> 10#include <linux/dmi.h>
46#include <linux/moduleparam.h> 11#include <linux/slab.h>
47#include <linux/cpuidle.h>
48 12
49#include <asm/io.h>
50#include <asm/system.h>
51#include <asm/cpu.h>
52#include <asm/delay.h>
53#include <asm/uaccess.h>
54#include <asm/processor.h>
55#include <asm/smp.h>
56#include <asm/acpi.h>
57
58#include <acpi/acpi_bus.h>
59#include <acpi/acpi_drivers.h> 13#include <acpi/acpi_drivers.h>
60#include <acpi/processor.h> 14#include <acpi/processor.h>
61 15
62#define PREFIX "ACPI: " 16#include "internal.h"
63
64#define ACPI_PROCESSOR_CLASS "processor"
65#define ACPI_PROCESSOR_DEVICE_NAME "Processor"
66#define ACPI_PROCESSOR_FILE_INFO "info"
67#define ACPI_PROCESSOR_FILE_THROTTLING "throttling"
68#define ACPI_PROCESSOR_FILE_LIMIT "limit"
69#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
70#define ACPI_PROCESSOR_NOTIFY_POWER 0x81
71#define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82
72
73#define ACPI_PROCESSOR_LIMIT_USER 0
74#define ACPI_PROCESSOR_LIMIT_THERMAL 1
75 17
18#define PREFIX "ACPI: "
76#define _COMPONENT ACPI_PROCESSOR_COMPONENT 19#define _COMPONENT ACPI_PROCESSOR_COMPONENT
77ACPI_MODULE_NAME("processor_core"); 20ACPI_MODULE_NAME("processor_core");
78 21
79MODULE_AUTHOR("Paul Diefenbaugh"); 22static int set_no_mwait(const struct dmi_system_id *id)
80MODULE_DESCRIPTION("ACPI Processor Driver");
81MODULE_LICENSE("GPL");
82
83static int acpi_processor_add(struct acpi_device *device);
84static int acpi_processor_remove(struct acpi_device *device, int type);
85#ifdef CONFIG_ACPI_PROCFS
86static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
87#endif
88static void acpi_processor_notify(struct acpi_device *device, u32 event);
89static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
90static int acpi_processor_handle_eject(struct acpi_processor *pr);
91
92
93static const struct acpi_device_id processor_device_ids[] = {
94 {ACPI_PROCESSOR_OBJECT_HID, 0},
95 {"ACPI0007", 0},
96 {"", 0},
97};
98MODULE_DEVICE_TABLE(acpi, processor_device_ids);
99
100static struct acpi_driver acpi_processor_driver = {
101 .name = "processor",
102 .class = ACPI_PROCESSOR_CLASS,
103 .ids = processor_device_ids,
104 .ops = {
105 .add = acpi_processor_add,
106 .remove = acpi_processor_remove,
107 .suspend = acpi_processor_suspend,
108 .resume = acpi_processor_resume,
109 .notify = acpi_processor_notify,
110 },
111};
112
113#define INSTALL_NOTIFY_HANDLER 1
114#define UNINSTALL_NOTIFY_HANDLER 2
115#ifdef CONFIG_ACPI_PROCFS
116static const struct file_operations acpi_processor_info_fops = {
117 .owner = THIS_MODULE,
118 .open = acpi_processor_info_open_fs,
119 .read = seq_read,
120 .llseek = seq_lseek,
121 .release = single_release,
122};
123#endif
124
125DEFINE_PER_CPU(struct acpi_processor *, processors);
126EXPORT_PER_CPU_SYMBOL(processors);
127
128struct acpi_processor_errata errata __read_mostly;
129
130/* --------------------------------------------------------------------------
131 Errata Handling
132 -------------------------------------------------------------------------- */
133
134static int acpi_processor_errata_piix4(struct pci_dev *dev)
135{ 23{
136 u8 value1 = 0; 24 printk(KERN_NOTICE PREFIX "%s detected - "
137 u8 value2 = 0; 25 "disabling mwait for CPU C-states\n", id->ident);
138 26 idle_nomwait = 1;
139
140 if (!dev)
141 return -EINVAL;
142
143 /*
144 * Note that 'dev' references the PIIX4 ACPI Controller.
145 */
146
147 switch (dev->revision) {
148 case 0:
149 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step\n"));
150 break;
151 case 1:
152 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 B-step\n"));
153 break;
154 case 2:
155 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4E\n"));
156 break;
157 case 3:
158 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4M\n"));
159 break;
160 default:
161 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unknown PIIX4\n"));
162 break;
163 }
164
165 switch (dev->revision) {
166
167 case 0: /* PIIX4 A-step */
168 case 1: /* PIIX4 B-step */
169 /*
170 * See specification changes #13 ("Manual Throttle Duty Cycle")
171 * and #14 ("Enabling and Disabling Manual Throttle"), plus
172 * erratum #5 ("STPCLK# Deassertion Time") from the January
173 * 2002 PIIX4 specification update. Applies to only older
174 * PIIX4 models.
175 */
176 errata.piix4.throttle = 1;
177
178 case 2: /* PIIX4E */
179 case 3: /* PIIX4M */
180 /*
181 * See erratum #18 ("C3 Power State/BMIDE and Type-F DMA
182 * Livelock") from the January 2002 PIIX4 specification update.
183 * Applies to all PIIX4 models.
184 */
185
186 /*
187 * BM-IDE
188 * ------
189 * Find the PIIX4 IDE Controller and get the Bus Master IDE
190 * Status register address. We'll use this later to read
191 * each IDE controller's DMA status to make sure we catch all
192 * DMA activity.
193 */
194 dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
195 PCI_DEVICE_ID_INTEL_82371AB,
196 PCI_ANY_ID, PCI_ANY_ID, NULL);
197 if (dev) {
198 errata.piix4.bmisx = pci_resource_start(dev, 4);
199 pci_dev_put(dev);
200 }
201
202 /*
203 * Type-F DMA
204 * ----------
205 * Find the PIIX4 ISA Controller and read the Motherboard
206 * DMA controller's status to see if Type-F (Fast) DMA mode
207 * is enabled (bit 7) on either channel. Note that we'll
208 * disable C3 support if this is enabled, as some legacy
209 * devices won't operate well if fast DMA is disabled.
210 */
211 dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
212 PCI_DEVICE_ID_INTEL_82371AB_0,
213 PCI_ANY_ID, PCI_ANY_ID, NULL);
214 if (dev) {
215 pci_read_config_byte(dev, 0x76, &value1);
216 pci_read_config_byte(dev, 0x77, &value2);
217 if ((value1 & 0x80) || (value2 & 0x80))
218 errata.piix4.fdma = 1;
219 pci_dev_put(dev);
220 }
221
222 break;
223 }
224
225 if (errata.piix4.bmisx)
226 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
227 "Bus master activity detection (BM-IDE) erratum enabled\n"));
228 if (errata.piix4.fdma)
229 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
230 "Type-F DMA livelock erratum (C3 disabled)\n"));
231
232 return 0; 27 return 0;
233} 28}
234 29
235static int acpi_processor_errata(struct acpi_processor *pr) 30static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = {
236{ 31 {
237 int result = 0; 32 set_no_mwait, "IFL91 board", {
238 struct pci_dev *dev = NULL; 33 DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
239 34 DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"),
240 35 DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"),
241 if (!pr) 36 DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL},
242 return -EINVAL; 37 {
243 38 set_no_mwait, "Extensa 5220", {
244 /* 39 DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
245 * PIIX4 40 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
246 */ 41 DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
247 dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, 42 DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL},
248 PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID, 43 {},
249 PCI_ANY_ID, NULL); 44};
250 if (dev) {
251 result = acpi_processor_errata_piix4(dev);
252 pci_dev_put(dev);
253 }
254
255 return result;
256}
257
258/* --------------------------------------------------------------------------
259 FS Interface (/proc)
260 -------------------------------------------------------------------------- */
261
262#ifdef CONFIG_ACPI_PROCFS
263static struct proc_dir_entry *acpi_processor_dir = NULL;
264
265static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset)
266{
267 struct acpi_processor *pr = seq->private;
268
269
270 if (!pr)
271 goto end;
272
273 seq_printf(seq, "processor id: %d\n"
274 "acpi id: %d\n"
275 "bus mastering control: %s\n"
276 "power management: %s\n"
277 "throttling control: %s\n"
278 "limit interface: %s\n",
279 pr->id,
280 pr->acpi_id,
281 pr->flags.bm_control ? "yes" : "no",
282 pr->flags.power ? "yes" : "no",
283 pr->flags.throttling ? "yes" : "no",
284 pr->flags.limit ? "yes" : "no");
285
286 end:
287 return 0;
288}
289
290static int acpi_processor_info_open_fs(struct inode *inode, struct file *file)
291{
292 return single_open(file, acpi_processor_info_seq_show,
293 PDE(inode)->data);
294}
295
296static int __cpuinit acpi_processor_add_fs(struct acpi_device *device)
297{
298 struct proc_dir_entry *entry = NULL;
299
300
301 if (!acpi_device_dir(device)) {
302 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
303 acpi_processor_dir);
304 if (!acpi_device_dir(device))
305 return -ENODEV;
306 }
307
308 /* 'info' [R] */
309 entry = proc_create_data(ACPI_PROCESSOR_FILE_INFO,
310 S_IRUGO, acpi_device_dir(device),
311 &acpi_processor_info_fops,
312 acpi_driver_data(device));
313 if (!entry)
314 return -EIO;
315
316 /* 'throttling' [R/W] */
317 entry = proc_create_data(ACPI_PROCESSOR_FILE_THROTTLING,
318 S_IFREG | S_IRUGO | S_IWUSR,
319 acpi_device_dir(device),
320 &acpi_processor_throttling_fops,
321 acpi_driver_data(device));
322 if (!entry)
323 return -EIO;
324
325 /* 'limit' [R/W] */
326 entry = proc_create_data(ACPI_PROCESSOR_FILE_LIMIT,
327 S_IFREG | S_IRUGO | S_IWUSR,
328 acpi_device_dir(device),
329 &acpi_processor_limit_fops,
330 acpi_driver_data(device));
331 if (!entry)
332 return -EIO;
333 return 0;
334}
335static int acpi_processor_remove_fs(struct acpi_device *device)
336{
337
338 if (acpi_device_dir(device)) {
339 remove_proc_entry(ACPI_PROCESSOR_FILE_INFO,
340 acpi_device_dir(device));
341 remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
342 acpi_device_dir(device));
343 remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,
344 acpi_device_dir(device));
345 remove_proc_entry(acpi_device_bid(device), acpi_processor_dir);
346 acpi_device_dir(device) = NULL;
347 }
348
349 return 0;
350}
351#else
352static inline int acpi_processor_add_fs(struct acpi_device *device)
353{
354 return 0;
355}
356static inline int acpi_processor_remove_fs(struct acpi_device *device)
357{
358 return 0;
359}
360#endif
361
362/* Use the acpiid in MADT to map cpus in case of SMP */
363
364#ifndef CONFIG_SMP
365static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) { return -1; }
366#else
367
368static struct acpi_table_madt *madt;
369 45
46#ifdef CONFIG_SMP
370static int map_lapic_id(struct acpi_subtable_header *entry, 47static int map_lapic_id(struct acpi_subtable_header *entry,
371 u32 acpi_id, int *apic_id) 48 u32 acpi_id, int *apic_id)
372{ 49{
373 struct acpi_madt_local_apic *lapic = 50 struct acpi_madt_local_apic *lapic =
374 (struct acpi_madt_local_apic *)entry; 51 (struct acpi_madt_local_apic *)entry;
375 if ((lapic->lapic_flags & ACPI_MADT_ENABLED) && 52
376 lapic->processor_id == acpi_id) { 53 if (!(lapic->lapic_flags & ACPI_MADT_ENABLED))
377 *apic_id = lapic->id; 54 return 0;
378 return 1; 55
379 } 56 if (lapic->processor_id != acpi_id)
380 return 0; 57 return 0;
58
59 *apic_id = lapic->id;
60 return 1;
381} 61}
382 62
383static int map_x2apic_id(struct acpi_subtable_header *entry, 63static int map_x2apic_id(struct acpi_subtable_header *entry,
@@ -385,22 +65,16 @@ static int map_x2apic_id(struct acpi_subtable_header *entry,
385{ 65{
386 struct acpi_madt_local_x2apic *apic = 66 struct acpi_madt_local_x2apic *apic =
387 (struct acpi_madt_local_x2apic *)entry; 67 (struct acpi_madt_local_x2apic *)entry;
388 u32 tmp = apic->local_apic_id;
389 68
390 /* Only check enabled APICs*/
391 if (!(apic->lapic_flags & ACPI_MADT_ENABLED)) 69 if (!(apic->lapic_flags & ACPI_MADT_ENABLED))
392 return 0; 70 return 0;
393 71
394 /* Device statement declaration type */ 72 if (device_declaration && (apic->uid == acpi_id)) {
395 if (device_declaration) { 73 *apic_id = apic->local_apic_id;
396 if (apic->uid == acpi_id) 74 return 1;
397 goto found;
398 } 75 }
399 76
400 return 0; 77 return 0;
401found:
402 *apic_id = tmp;
403 return 1;
404} 78}
405 79
406static int map_lsapic_id(struct acpi_subtable_header *entry, 80static int map_lsapic_id(struct acpi_subtable_header *entry,
@@ -408,35 +82,34 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
408{ 82{
409 struct acpi_madt_local_sapic *lsapic = 83 struct acpi_madt_local_sapic *lsapic =
410 (struct acpi_madt_local_sapic *)entry; 84 (struct acpi_madt_local_sapic *)entry;
411 u32 tmp = (lsapic->id << 8) | lsapic->eid;
412 85
413 /* Only check enabled APICs*/
414 if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED)) 86 if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED))
415 return 0; 87 return 0;
416 88
417 /* Device statement declaration type */
418 if (device_declaration) { 89 if (device_declaration) {
419 if (entry->length < 16) 90 if ((entry->length < 16) || (lsapic->uid != acpi_id))
420 printk(KERN_ERR PREFIX 91 return 0;
421 "Invalid LSAPIC with Device type processor (SAPIC ID %#x)\n", 92 } else if (lsapic->processor_id != acpi_id)
422 tmp); 93 return 0;
423 else if (lsapic->uid == acpi_id)
424 goto found;
425 /* Processor statement declaration type */
426 } else if (lsapic->processor_id == acpi_id)
427 goto found;
428 94
429 return 0; 95 *apic_id = (lsapic->id << 8) | lsapic->eid;
430found:
431 *apic_id = tmp;
432 return 1; 96 return 1;
433} 97}
434 98
435static int map_madt_entry(int type, u32 acpi_id) 99static int map_madt_entry(int type, u32 acpi_id)
436{ 100{
437 unsigned long madt_end, entry; 101 unsigned long madt_end, entry;
102 static struct acpi_table_madt *madt;
103 static int read_madt;
438 int apic_id = -1; 104 int apic_id = -1;
439 105
106 if (!read_madt) {
107 if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0,
108 (struct acpi_table_header **)&madt)))
109 madt = NULL;
110 read_madt++;
111 }
112
440 if (!madt) 113 if (!madt)
441 return apic_id; 114 return apic_id;
442 115
@@ -496,7 +169,7 @@ exit:
496 return apic_id; 169 return apic_id;
497} 170}
498 171
499static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) 172int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
500{ 173{
501 int i; 174 int i;
502 int apic_id = -1; 175 int apic_id = -1;
@@ -513,630 +186,170 @@ static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id)
513 } 186 }
514 return -1; 187 return -1;
515} 188}
189EXPORT_SYMBOL_GPL(acpi_get_cpuid);
516#endif 190#endif
517 191
518/* -------------------------------------------------------------------------- 192static bool processor_physically_present(acpi_handle handle)
519 Driver Interface
520 -------------------------------------------------------------------------- */
521
522static int acpi_processor_get_info(struct acpi_device *device)
523{ 193{
524 acpi_status status = 0; 194 int cpuid, type;
195 u32 acpi_id;
196 acpi_status status;
197 acpi_object_type acpi_type;
198 unsigned long long tmp;
525 union acpi_object object = { 0 }; 199 union acpi_object object = { 0 };
526 struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; 200 struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
527 struct acpi_processor *pr;
528 int cpu_index, device_declaration = 0;
529 static int cpu0_initialized;
530
531 pr = acpi_driver_data(device);
532 if (!pr)
533 return -EINVAL;
534
535 if (num_online_cpus() > 1)
536 errata.smp = TRUE;
537
538 acpi_processor_errata(pr);
539
540 /*
541 * Check to see if we have bus mastering arbitration control. This
542 * is required for proper C3 usage (to maintain cache coherency).
543 */
544 if (acpi_gbl_FADT.pm2_control_block && acpi_gbl_FADT.pm2_control_length) {
545 pr->flags.bm_control = 1;
546 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
547 "Bus mastering arbitration control present\n"));
548 } else
549 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
550 "No bus mastering arbitration control\n"));
551
552 if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_OBJECT_HID)) {
553 /* Declared with "Processor" statement; match ProcessorID */
554 status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
555 if (ACPI_FAILURE(status)) {
556 printk(KERN_ERR PREFIX "Evaluating processor object\n");
557 return -ENODEV;
558 }
559
560 /*
561 * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
562 * >>> 'acpi_get_processor_id(acpi_id, &id)' in
563 * arch/xxx/acpi.c
564 */
565 pr->acpi_id = object.processor.proc_id;
566 } else {
567 /*
568 * Declared with "Device" statement; match _UID.
569 * Note that we don't handle string _UIDs yet.
570 */
571 unsigned long long value;
572 status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
573 NULL, &value);
574 if (ACPI_FAILURE(status)) {
575 printk(KERN_ERR PREFIX
576 "Evaluating processor _UID [%#x]\n", status);
577 return -ENODEV;
578 }
579 device_declaration = 1;
580 pr->acpi_id = value;
581 }
582 cpu_index = get_cpu_id(pr->handle, device_declaration, pr->acpi_id);
583
584 /* Handle UP system running SMP kernel, with no LAPIC in MADT */
585 if (!cpu0_initialized && (cpu_index == -1) &&
586 (num_online_cpus() == 1)) {
587 cpu_index = 0;
588 }
589
590 cpu0_initialized = 1;
591
592 pr->id = cpu_index;
593
594 /*
595 * Extra Processor objects may be enumerated on MP systems with
596 * less than the max # of CPUs. They should be ignored _iff
597 * they are physically not present.
598 */
599 if (pr->id == -1) {
600 if (ACPI_FAILURE
601 (acpi_processor_hotadd_init(pr->handle, &pr->id))) {
602 return -ENODEV;
603 }
604 }
605 /*
606 * On some boxes several processors use the same processor bus id.
607 * But they are located in different scope. For example:
608 * \_SB.SCK0.CPU0
609 * \_SB.SCK1.CPU0
610 * Rename the processor device bus id. And the new bus id will be
611 * generated as the following format:
612 * CPU+CPU ID.
613 */
614 sprintf(acpi_device_bid(device), "CPU%X", pr->id);
615 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id,
616 pr->acpi_id));
617
618 if (!object.processor.pblk_address)
619 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n"));
620 else if (object.processor.pblk_length != 6)
621 printk(KERN_ERR PREFIX "Invalid PBLK length [%d]\n",
622 object.processor.pblk_length);
623 else {
624 pr->throttling.address = object.processor.pblk_address;
625 pr->throttling.duty_offset = acpi_gbl_FADT.duty_offset;
626 pr->throttling.duty_width = acpi_gbl_FADT.duty_width;
627
628 pr->pblk = object.processor.pblk_address;
629
630 /*
631 * We don't care about error returns - we just try to mark
632 * these reserved so that nobody else is confused into thinking
633 * that this region might be unused..
634 *
635 * (In particular, allocating the IO range for Cardbus)
636 */
637 request_region(pr->throttling.address, 6, "ACPI CPU throttle");
638 }
639
640 /*
641 * If ACPI describes a slot number for this CPU, we can use it
642 * ensure we get the right value in the "physical id" field
643 * of /proc/cpuinfo
644 */
645 status = acpi_evaluate_object(pr->handle, "_SUN", NULL, &buffer);
646 if (ACPI_SUCCESS(status))
647 arch_fix_phys_package_id(pr->id, object.integer.value);
648
649 return 0;
650}
651
652static DEFINE_PER_CPU(void *, processor_device_array);
653
654static void acpi_processor_notify(struct acpi_device *device, u32 event)
655{
656 struct acpi_processor *pr = acpi_driver_data(device);
657 int saved;
658
659 if (!pr)
660 return;
661 201
662 switch (event) { 202 status = acpi_get_type(handle, &acpi_type);
663 case ACPI_PROCESSOR_NOTIFY_PERFORMANCE: 203 if (ACPI_FAILURE(status))
664 saved = pr->performance_platform_limit; 204 return false;
665 acpi_processor_ppc_has_changed(pr, 1); 205
666 if (saved == pr->performance_platform_limit) 206 switch (acpi_type) {
667 break; 207 case ACPI_TYPE_PROCESSOR:
668 acpi_bus_generate_proc_event(device, event, 208 status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
669 pr->performance_platform_limit); 209 if (ACPI_FAILURE(status))
670 acpi_bus_generate_netlink_event(device->pnp.device_class, 210 return false;
671 dev_name(&device->dev), event, 211 acpi_id = object.processor.proc_id;
672 pr->performance_platform_limit);
673 break; 212 break;
674 case ACPI_PROCESSOR_NOTIFY_POWER: 213 case ACPI_TYPE_DEVICE:
675 acpi_processor_cst_has_changed(pr); 214 status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp);
676 acpi_bus_generate_proc_event(device, event, 0); 215 if (ACPI_FAILURE(status))
677 acpi_bus_generate_netlink_event(device->pnp.device_class, 216 return false;
678 dev_name(&device->dev), event, 0); 217 acpi_id = tmp;
679 break; 218 break;
680 case ACPI_PROCESSOR_NOTIFY_THROTTLING:
681 acpi_processor_tstate_has_changed(pr);
682 acpi_bus_generate_proc_event(device, event, 0);
683 acpi_bus_generate_netlink_event(device->pnp.device_class,
684 dev_name(&device->dev), event, 0);
685 default: 219 default:
686 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 220 return false;
687 "Unsupported event [0x%x]\n", event));
688 break;
689 } 221 }
690 222
691 return; 223 type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
692} 224 cpuid = acpi_get_cpuid(handle, type, acpi_id);
693 225
694static int acpi_cpu_soft_notify(struct notifier_block *nfb, 226 if (cpuid == -1)
695 unsigned long action, void *hcpu) 227 return false;
696{
697 unsigned int cpu = (unsigned long)hcpu;
698 struct acpi_processor *pr = per_cpu(processors, cpu);
699 228
700 if (action == CPU_ONLINE && pr) { 229 return true;
701 acpi_processor_ppc_has_changed(pr, 0);
702 acpi_processor_cst_has_changed(pr);
703 acpi_processor_tstate_has_changed(pr);
704 }
705 return NOTIFY_OK;
706} 230}
707 231
708static struct notifier_block acpi_cpu_notifier = 232static void acpi_set_pdc_bits(u32 *buf)
709{ 233{
710 .notifier_call = acpi_cpu_soft_notify, 234 buf[0] = ACPI_PDC_REVISION_ID;
711}; 235 buf[1] = 1;
712
713static int __cpuinit acpi_processor_add(struct acpi_device *device)
714{
715 struct acpi_processor *pr = NULL;
716 int result = 0;
717 struct sys_device *sysdev;
718
719 pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
720 if (!pr)
721 return -ENOMEM;
722
723 if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) {
724 kfree(pr);
725 return -ENOMEM;
726 }
727
728 pr->handle = device->handle;
729 strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
730 strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
731 device->driver_data = pr;
732
733 result = acpi_processor_get_info(device);
734 if (result) {
735 /* Processor is physically not present */
736 return 0;
737 }
738
739 BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
740
741 /*
742 * Buggy BIOS check
743 * ACPI id of processors can be reported wrongly by the BIOS.
744 * Don't trust it blindly
745 */
746 if (per_cpu(processor_device_array, pr->id) != NULL &&
747 per_cpu(processor_device_array, pr->id) != device) {
748 printk(KERN_WARNING "BIOS reported wrong ACPI id "
749 "for the processor\n");
750 result = -ENODEV;
751 goto err_free_cpumask;
752 }
753 per_cpu(processor_device_array, pr->id) = device;
754 236
755 per_cpu(processors, pr->id) = pr; 237 /* Enable coordination with firmware's _TSD info */
238 buf[2] = ACPI_PDC_SMP_T_SWCOORD;
756 239
757 result = acpi_processor_add_fs(device); 240 /* Twiddle arch-specific bits needed for _PDC */
758 if (result) 241 arch_acpi_set_pdc_bits(buf);
759 goto err_free_cpumask;
760
761 sysdev = get_cpu_sysdev(pr->id);
762 if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) {
763 result = -EFAULT;
764 goto err_remove_fs;
765 }
766
767 /* _PDC call should be done before doing anything else (if reqd.). */
768 acpi_processor_set_pdc(pr->handle);
769
770#ifdef CONFIG_CPU_FREQ
771 acpi_processor_ppc_has_changed(pr, 0);
772#endif
773 acpi_processor_get_throttling_info(pr);
774 acpi_processor_get_limit_info(pr);
775
776
777 acpi_processor_power_init(pr, device);
778
779 pr->cdev = thermal_cooling_device_register("Processor", device,
780 &processor_cooling_ops);
781 if (IS_ERR(pr->cdev)) {
782 result = PTR_ERR(pr->cdev);
783 goto err_power_exit;
784 }
785
786 dev_dbg(&device->dev, "registered as cooling_device%d\n",
787 pr->cdev->id);
788
789 result = sysfs_create_link(&device->dev.kobj,
790 &pr->cdev->device.kobj,
791 "thermal_cooling");
792 if (result) {
793 printk(KERN_ERR PREFIX "Create sysfs link\n");
794 goto err_thermal_unregister;
795 }
796 result = sysfs_create_link(&pr->cdev->device.kobj,
797 &device->dev.kobj,
798 "device");
799 if (result) {
800 printk(KERN_ERR PREFIX "Create sysfs link\n");
801 goto err_remove_sysfs;
802 }
803
804 return 0;
805
806err_remove_sysfs:
807 sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
808err_thermal_unregister:
809 thermal_cooling_device_unregister(pr->cdev);
810err_power_exit:
811 acpi_processor_power_exit(pr, device);
812err_remove_fs:
813 acpi_processor_remove_fs(device);
814err_free_cpumask:
815 free_cpumask_var(pr->throttling.shared_cpu_map);
816
817 return result;
818} 242}
819 243
820static int acpi_processor_remove(struct acpi_device *device, int type) 244static struct acpi_object_list *acpi_processor_alloc_pdc(void)
821{ 245{
822 struct acpi_processor *pr = NULL; 246 struct acpi_object_list *obj_list;
823 247 union acpi_object *obj;
824 248 u32 *buf;
825 if (!device || !acpi_driver_data(device))
826 return -EINVAL;
827
828 pr = acpi_driver_data(device);
829
830 if (pr->id >= nr_cpu_ids)
831 goto free;
832 249
833 if (type == ACPI_BUS_REMOVAL_EJECT) { 250 /* allocate and initialize pdc. It will be used later. */
834 if (acpi_processor_handle_eject(pr)) 251 obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
835 return -EINVAL; 252 if (!obj_list) {
253 printk(KERN_ERR "Memory allocation error\n");
254 return NULL;
836 } 255 }
837 256
838 acpi_processor_power_exit(pr, device); 257 obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
839 258 if (!obj) {
840 sysfs_remove_link(&device->dev.kobj, "sysdev"); 259 printk(KERN_ERR "Memory allocation error\n");
841 260 kfree(obj_list);
842 acpi_processor_remove_fs(device); 261 return NULL;
843
844 if (pr->cdev) {
845 sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
846 sysfs_remove_link(&pr->cdev->device.kobj, "device");
847 thermal_cooling_device_unregister(pr->cdev);
848 pr->cdev = NULL;
849 } 262 }
850 263
851 per_cpu(processors, pr->id) = NULL; 264 buf = kmalloc(12, GFP_KERNEL);
852 per_cpu(processor_device_array, pr->id) = NULL; 265 if (!buf) {
853 266 printk(KERN_ERR "Memory allocation error\n");
854free: 267 kfree(obj);
855 free_cpumask_var(pr->throttling.shared_cpu_map); 268 kfree(obj_list);
856 kfree(pr); 269 return NULL;
857
858 return 0;
859}
860
861#ifdef CONFIG_ACPI_HOTPLUG_CPU
862/****************************************************************************
863 * Acpi processor hotplug support *
864 ****************************************************************************/
865
866static int is_processor_present(acpi_handle handle)
867{
868 acpi_status status;
869 unsigned long long sta = 0;
870
871
872 status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
873
874 if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT))
875 return 1;
876
877 /*
878 * _STA is mandatory for a processor that supports hot plug
879 */
880 if (status == AE_NOT_FOUND)
881 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
882 "Processor does not support hot plug\n"));
883 else
884 ACPI_EXCEPTION((AE_INFO, status,
885 "Processor Device is not present"));
886 return 0;
887}
888
889static
890int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
891{
892 acpi_handle phandle;
893 struct acpi_device *pdev;
894
895
896 if (acpi_get_parent(handle, &phandle)) {
897 return -ENODEV;
898 } 270 }
899 271
900 if (acpi_bus_get_device(phandle, &pdev)) { 272 acpi_set_pdc_bits(buf);
901 return -ENODEV;
902 }
903 273
904 if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_PROCESSOR)) { 274 obj->type = ACPI_TYPE_BUFFER;
905 return -ENODEV; 275 obj->buffer.length = 12;
906 } 276 obj->buffer.pointer = (u8 *) buf;
277 obj_list->count = 1;
278 obj_list->pointer = obj;
907 279
908 return 0; 280 return obj_list;
909} 281}
910 282
911static void __ref acpi_processor_hotplug_notify(acpi_handle handle, 283/*
912 u32 event, void *data) 284 * _PDC is required for a BIOS-OS handshake for most of the newer
285 * ACPI processor features.
286 */
287static int
288acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
913{ 289{
914 struct acpi_processor *pr; 290 acpi_status status = AE_OK;
915 struct acpi_device *device = NULL;
916 int result;
917
918 291
919 switch (event) { 292 if (idle_nomwait) {
920 case ACPI_NOTIFY_BUS_CHECK: 293 /*
921 case ACPI_NOTIFY_DEVICE_CHECK: 294 * If mwait is disabled for CPU C-states, the C2C3_FFH access
922 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 295 * mode will be disabled in the parameter of _PDC object.
923 "Processor driver received %s event\n", 296 * Of course C1_FFH access mode will also be disabled.
924 (event == ACPI_NOTIFY_BUS_CHECK) ? 297 */
925 "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK")); 298 union acpi_object *obj;
926 299 u32 *buffer = NULL;
927 if (!is_processor_present(handle))
928 break;
929 300
930 if (acpi_bus_get_device(handle, &device)) { 301 obj = pdc_in->pointer;
931 result = acpi_processor_device_add(handle, &device); 302 buffer = (u32 *)(obj->buffer.pointer);
932 if (result) 303 buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH);
933 printk(KERN_ERR PREFIX
934 "Unable to add the device\n");
935 break;
936 }
937 break;
938 case ACPI_NOTIFY_EJECT_REQUEST:
939 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
940 "received ACPI_NOTIFY_EJECT_REQUEST\n"));
941 304
942 if (acpi_bus_get_device(handle, &device)) {
943 printk(KERN_ERR PREFIX
944 "Device don't exist, dropping EJECT\n");
945 break;
946 }
947 pr = acpi_driver_data(device);
948 if (!pr) {
949 printk(KERN_ERR PREFIX
950 "Driver data is NULL, dropping EJECT\n");
951 return;
952 }
953 break;
954 default:
955 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
956 "Unsupported event [0x%x]\n", event));
957 break;
958 } 305 }
306 status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL);
959 307
960 return;
961}
962
963static acpi_status
964processor_walk_namespace_cb(acpi_handle handle,
965 u32 lvl, void *context, void **rv)
966{
967 acpi_status status;
968 int *action = context;
969 acpi_object_type type = 0;
970
971 status = acpi_get_type(handle, &type);
972 if (ACPI_FAILURE(status)) 308 if (ACPI_FAILURE(status))
973 return (AE_OK); 309 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
974 310 "Could not evaluate _PDC, using legacy perf. control.\n"));
975 if (type != ACPI_TYPE_PROCESSOR)
976 return (AE_OK);
977
978 switch (*action) {
979 case INSTALL_NOTIFY_HANDLER:
980 acpi_install_notify_handler(handle,
981 ACPI_SYSTEM_NOTIFY,
982 acpi_processor_hotplug_notify,
983 NULL);
984 break;
985 case UNINSTALL_NOTIFY_HANDLER:
986 acpi_remove_notify_handler(handle,
987 ACPI_SYSTEM_NOTIFY,
988 acpi_processor_hotplug_notify);
989 break;
990 default:
991 break;
992 }
993 311
994 return (AE_OK); 312 return status;
995} 313}
996 314
997static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu) 315void acpi_processor_set_pdc(acpi_handle handle)
998{ 316{
317 struct acpi_object_list *obj_list;
999 318
1000 if (!is_processor_present(handle)) { 319 if (arch_has_acpi_pdc() == false)
1001 return AE_ERROR; 320 return;
1002 }
1003 321
1004 if (acpi_map_lsapic(handle, p_cpu)) 322 obj_list = acpi_processor_alloc_pdc();
1005 return AE_ERROR; 323 if (!obj_list)
324 return;
1006 325
1007 if (arch_register_cpu(*p_cpu)) { 326 acpi_processor_eval_pdc(handle, obj_list);
1008 acpi_unmap_lsapic(*p_cpu);
1009 return AE_ERROR;
1010 }
1011 327
1012 return AE_OK; 328 kfree(obj_list->pointer->buffer.pointer);
329 kfree(obj_list->pointer);
330 kfree(obj_list);
1013} 331}
332EXPORT_SYMBOL_GPL(acpi_processor_set_pdc);
1014 333
1015static int acpi_processor_handle_eject(struct acpi_processor *pr) 334static acpi_status
335early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)
1016{ 336{
1017 if (cpu_online(pr->id)) 337 if (processor_physically_present(handle) == false)
1018 cpu_down(pr->id); 338 return AE_OK;
1019 339
1020 arch_unregister_cpu(pr->id); 340 acpi_processor_set_pdc(handle);
1021 acpi_unmap_lsapic(pr->id); 341 return AE_OK;
1022 return (0);
1023}
1024#else
1025static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu)
1026{
1027 return AE_ERROR;
1028}
1029static int acpi_processor_handle_eject(struct acpi_processor *pr)
1030{
1031 return (-EINVAL);
1032} 342}
1033#endif
1034 343
1035static 344void __init acpi_early_processor_set_pdc(void)
1036void acpi_processor_install_hotplug_notify(void)
1037{ 345{
1038#ifdef CONFIG_ACPI_HOTPLUG_CPU 346 /*
1039 int action = INSTALL_NOTIFY_HANDLER; 347 * Check whether the system is DMI table. If yes, OSPM
1040 acpi_walk_namespace(ACPI_TYPE_PROCESSOR, 348 * should not use mwait for CPU-states.
1041 ACPI_ROOT_OBJECT, 349 */
1042 ACPI_UINT32_MAX, 350 dmi_check_system(processor_idle_dmi_table);
1043 processor_walk_namespace_cb, NULL, &action, NULL);
1044#endif
1045 register_hotcpu_notifier(&acpi_cpu_notifier);
1046}
1047 351
1048static 352 acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
1049void acpi_processor_uninstall_hotplug_notify(void)
1050{
1051#ifdef CONFIG_ACPI_HOTPLUG_CPU
1052 int action = UNINSTALL_NOTIFY_HANDLER;
1053 acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
1054 ACPI_ROOT_OBJECT,
1055 ACPI_UINT32_MAX, 353 ACPI_UINT32_MAX,
1056 processor_walk_namespace_cb, NULL, &action, NULL); 354 early_init_pdc, NULL, NULL, NULL);
1057#endif
1058 unregister_hotcpu_notifier(&acpi_cpu_notifier);
1059} 355}
1060
1061/*
1062 * We keep the driver loaded even when ACPI is not running.
1063 * This is needed for the powernow-k8 driver, that works even without
1064 * ACPI, but needs symbols from this driver
1065 */
1066
1067static int __init acpi_processor_init(void)
1068{
1069 int result = 0;
1070
1071 if (acpi_disabled)
1072 return 0;
1073
1074 memset(&errata, 0, sizeof(errata));
1075
1076#ifdef CONFIG_SMP
1077 if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0,
1078 (struct acpi_table_header **)&madt)))
1079 madt = NULL;
1080#endif
1081#ifdef CONFIG_ACPI_PROCFS
1082 acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
1083 if (!acpi_processor_dir)
1084 return -ENOMEM;
1085#endif
1086 result = cpuidle_register_driver(&acpi_idle_driver);
1087 if (result < 0)
1088 goto out_proc;
1089
1090 result = acpi_bus_register_driver(&acpi_processor_driver);
1091 if (result < 0)
1092 goto out_cpuidle;
1093
1094 acpi_processor_install_hotplug_notify();
1095
1096 acpi_thermal_cpufreq_init();
1097
1098 acpi_processor_ppc_init();
1099
1100 acpi_processor_throttling_init();
1101
1102 return 0;
1103
1104out_cpuidle:
1105 cpuidle_unregister_driver(&acpi_idle_driver);
1106
1107out_proc:
1108#ifdef CONFIG_ACPI_PROCFS
1109 remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
1110#endif
1111
1112 return result;
1113}
1114
1115static void __exit acpi_processor_exit(void)
1116{
1117 if (acpi_disabled)
1118 return;
1119
1120 acpi_processor_ppc_exit();
1121
1122 acpi_thermal_cpufreq_exit();
1123
1124 acpi_processor_uninstall_hotplug_notify();
1125
1126 acpi_bus_unregister_driver(&acpi_processor_driver);
1127
1128 cpuidle_unregister_driver(&acpi_idle_driver);
1129
1130#ifdef CONFIG_ACPI_PROCFS
1131 remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
1132#endif
1133
1134 return;
1135}
1136
1137module_init(acpi_processor_init);
1138module_exit(acpi_processor_exit);
1139
1140EXPORT_SYMBOL(acpi_processor_set_thermal_limit);
1141
1142MODULE_ALIAS("processor");
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
new file mode 100644
index 000000000000..5675d9747e87
--- /dev/null
+++ b/drivers/acpi/processor_driver.c
@@ -0,0 +1,979 @@
1/*
2 * acpi_processor.c - ACPI Processor Driver ($Revision: 71 $)
3 *
4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6 * Copyright (C) 2004 Dominik Brodowski <linux@brodo.de>
7 * Copyright (C) 2004 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
8 * - Added processor hotplug support
9 *
10 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or (at
15 * your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 *
26 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27 * TBD:
28 * 1. Make # power states dynamic.
29 * 2. Support duty_cycle values that span bit 4.
30 * 3. Optimize by having scheduler determine business instead of
31 * having us try to calculate it here.
32 * 4. Need C1 timing -- must modify kernel (IRQ handler) to get this.
33 */
34
35#include <linux/kernel.h>
36#include <linux/module.h>
37#include <linux/init.h>
38#include <linux/types.h>
39#include <linux/pci.h>
40#include <linux/pm.h>
41#include <linux/cpufreq.h>
42#include <linux/cpu.h>
43#include <linux/proc_fs.h>
44#include <linux/seq_file.h>
45#include <linux/dmi.h>
46#include <linux/moduleparam.h>
47#include <linux/cpuidle.h>
48#include <linux/slab.h>
49
50#include <asm/io.h>
51#include <asm/system.h>
52#include <asm/cpu.h>
53#include <asm/delay.h>
54#include <asm/uaccess.h>
55#include <asm/processor.h>
56#include <asm/smp.h>
57#include <asm/acpi.h>
58
59#include <acpi/acpi_bus.h>
60#include <acpi/acpi_drivers.h>
61#include <acpi/processor.h>
62
63#define PREFIX "ACPI: "
64
65#define ACPI_PROCESSOR_CLASS "processor"
66#define ACPI_PROCESSOR_DEVICE_NAME "Processor"
67#define ACPI_PROCESSOR_FILE_INFO "info"
68#define ACPI_PROCESSOR_FILE_THROTTLING "throttling"
69#define ACPI_PROCESSOR_FILE_LIMIT "limit"
70#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
71#define ACPI_PROCESSOR_NOTIFY_POWER 0x81
72#define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82
73
74#define ACPI_PROCESSOR_LIMIT_USER 0
75#define ACPI_PROCESSOR_LIMIT_THERMAL 1
76
77#define _COMPONENT ACPI_PROCESSOR_COMPONENT
78ACPI_MODULE_NAME("processor_driver");
79
80MODULE_AUTHOR("Paul Diefenbaugh");
81MODULE_DESCRIPTION("ACPI Processor Driver");
82MODULE_LICENSE("GPL");
83
84static int acpi_processor_add(struct acpi_device *device);
85static int acpi_processor_remove(struct acpi_device *device, int type);
86#ifdef CONFIG_ACPI_PROCFS
87static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
88#endif
89static void acpi_processor_notify(struct acpi_device *device, u32 event);
90static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
91static int acpi_processor_handle_eject(struct acpi_processor *pr);
92
93
94static const struct acpi_device_id processor_device_ids[] = {
95 {ACPI_PROCESSOR_OBJECT_HID, 0},
96 {"ACPI0007", 0},
97 {"", 0},
98};
99MODULE_DEVICE_TABLE(acpi, processor_device_ids);
100
101static struct acpi_driver acpi_processor_driver = {
102 .name = "processor",
103 .class = ACPI_PROCESSOR_CLASS,
104 .ids = processor_device_ids,
105 .ops = {
106 .add = acpi_processor_add,
107 .remove = acpi_processor_remove,
108 .suspend = acpi_processor_suspend,
109 .resume = acpi_processor_resume,
110 .notify = acpi_processor_notify,
111 },
112};
113
114#define INSTALL_NOTIFY_HANDLER 1
115#define UNINSTALL_NOTIFY_HANDLER 2
116#ifdef CONFIG_ACPI_PROCFS
117static const struct file_operations acpi_processor_info_fops = {
118 .owner = THIS_MODULE,
119 .open = acpi_processor_info_open_fs,
120 .read = seq_read,
121 .llseek = seq_lseek,
122 .release = single_release,
123};
124#endif
125
126DEFINE_PER_CPU(struct acpi_processor *, processors);
127EXPORT_PER_CPU_SYMBOL(processors);
128
129struct acpi_processor_errata errata __read_mostly;
130
131/* --------------------------------------------------------------------------
132 Errata Handling
133 -------------------------------------------------------------------------- */
134
135static int acpi_processor_errata_piix4(struct pci_dev *dev)
136{
137 u8 value1 = 0;
138 u8 value2 = 0;
139
140
141 if (!dev)
142 return -EINVAL;
143
144 /*
145 * Note that 'dev' references the PIIX4 ACPI Controller.
146 */
147
148 switch (dev->revision) {
149 case 0:
150 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step\n"));
151 break;
152 case 1:
153 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 B-step\n"));
154 break;
155 case 2:
156 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4E\n"));
157 break;
158 case 3:
159 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4M\n"));
160 break;
161 default:
162 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unknown PIIX4\n"));
163 break;
164 }
165
166 switch (dev->revision) {
167
168 case 0: /* PIIX4 A-step */
169 case 1: /* PIIX4 B-step */
170 /*
171 * See specification changes #13 ("Manual Throttle Duty Cycle")
172 * and #14 ("Enabling and Disabling Manual Throttle"), plus
173 * erratum #5 ("STPCLK# Deassertion Time") from the January
174 * 2002 PIIX4 specification update. Applies to only older
175 * PIIX4 models.
176 */
177 errata.piix4.throttle = 1;
178
179 case 2: /* PIIX4E */
180 case 3: /* PIIX4M */
181 /*
182 * See erratum #18 ("C3 Power State/BMIDE and Type-F DMA
183 * Livelock") from the January 2002 PIIX4 specification update.
184 * Applies to all PIIX4 models.
185 */
186
187 /*
188 * BM-IDE
189 * ------
190 * Find the PIIX4 IDE Controller and get the Bus Master IDE
191 * Status register address. We'll use this later to read
192 * each IDE controller's DMA status to make sure we catch all
193 * DMA activity.
194 */
195 dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
196 PCI_DEVICE_ID_INTEL_82371AB,
197 PCI_ANY_ID, PCI_ANY_ID, NULL);
198 if (dev) {
199 errata.piix4.bmisx = pci_resource_start(dev, 4);
200 pci_dev_put(dev);
201 }
202
203 /*
204 * Type-F DMA
205 * ----------
206 * Find the PIIX4 ISA Controller and read the Motherboard
207 * DMA controller's status to see if Type-F (Fast) DMA mode
208 * is enabled (bit 7) on either channel. Note that we'll
209 * disable C3 support if this is enabled, as some legacy
210 * devices won't operate well if fast DMA is disabled.
211 */
212 dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
213 PCI_DEVICE_ID_INTEL_82371AB_0,
214 PCI_ANY_ID, PCI_ANY_ID, NULL);
215 if (dev) {
216 pci_read_config_byte(dev, 0x76, &value1);
217 pci_read_config_byte(dev, 0x77, &value2);
218 if ((value1 & 0x80) || (value2 & 0x80))
219 errata.piix4.fdma = 1;
220 pci_dev_put(dev);
221 }
222
223 break;
224 }
225
226 if (errata.piix4.bmisx)
227 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
228 "Bus master activity detection (BM-IDE) erratum enabled\n"));
229 if (errata.piix4.fdma)
230 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
231 "Type-F DMA livelock erratum (C3 disabled)\n"));
232
233 return 0;
234}
235
236static int acpi_processor_errata(struct acpi_processor *pr)
237{
238 int result = 0;
239 struct pci_dev *dev = NULL;
240
241
242 if (!pr)
243 return -EINVAL;
244
245 /*
246 * PIIX4
247 */
248 dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
249 PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID,
250 PCI_ANY_ID, NULL);
251 if (dev) {
252 result = acpi_processor_errata_piix4(dev);
253 pci_dev_put(dev);
254 }
255
256 return result;
257}
258
259/* --------------------------------------------------------------------------
260 FS Interface (/proc)
261 -------------------------------------------------------------------------- */
262
263#ifdef CONFIG_ACPI_PROCFS
264static struct proc_dir_entry *acpi_processor_dir = NULL;
265
266static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset)
267{
268 struct acpi_processor *pr = seq->private;
269
270
271 if (!pr)
272 goto end;
273
274 seq_printf(seq, "processor id: %d\n"
275 "acpi id: %d\n"
276 "bus mastering control: %s\n"
277 "power management: %s\n"
278 "throttling control: %s\n"
279 "limit interface: %s\n",
280 pr->id,
281 pr->acpi_id,
282 pr->flags.bm_control ? "yes" : "no",
283 pr->flags.power ? "yes" : "no",
284 pr->flags.throttling ? "yes" : "no",
285 pr->flags.limit ? "yes" : "no");
286
287 end:
288 return 0;
289}
290
291static int acpi_processor_info_open_fs(struct inode *inode, struct file *file)
292{
293 return single_open(file, acpi_processor_info_seq_show,
294 PDE(inode)->data);
295}
296
297static int __cpuinit acpi_processor_add_fs(struct acpi_device *device)
298{
299 struct proc_dir_entry *entry = NULL;
300
301
302 if (!acpi_device_dir(device)) {
303 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
304 acpi_processor_dir);
305 if (!acpi_device_dir(device))
306 return -ENODEV;
307 }
308
309 /* 'info' [R] */
310 entry = proc_create_data(ACPI_PROCESSOR_FILE_INFO,
311 S_IRUGO, acpi_device_dir(device),
312 &acpi_processor_info_fops,
313 acpi_driver_data(device));
314 if (!entry)
315 return -EIO;
316
317 /* 'throttling' [R/W] */
318 entry = proc_create_data(ACPI_PROCESSOR_FILE_THROTTLING,
319 S_IFREG | S_IRUGO | S_IWUSR,
320 acpi_device_dir(device),
321 &acpi_processor_throttling_fops,
322 acpi_driver_data(device));
323 if (!entry)
324 return -EIO;
325
326 /* 'limit' [R/W] */
327 entry = proc_create_data(ACPI_PROCESSOR_FILE_LIMIT,
328 S_IFREG | S_IRUGO | S_IWUSR,
329 acpi_device_dir(device),
330 &acpi_processor_limit_fops,
331 acpi_driver_data(device));
332 if (!entry)
333 return -EIO;
334 return 0;
335}
336static int acpi_processor_remove_fs(struct acpi_device *device)
337{
338
339 if (acpi_device_dir(device)) {
340 remove_proc_entry(ACPI_PROCESSOR_FILE_INFO,
341 acpi_device_dir(device));
342 remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
343 acpi_device_dir(device));
344 remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,
345 acpi_device_dir(device));
346 remove_proc_entry(acpi_device_bid(device), acpi_processor_dir);
347 acpi_device_dir(device) = NULL;
348 }
349
350 return 0;
351}
352#else
353static inline int acpi_processor_add_fs(struct acpi_device *device)
354{
355 return 0;
356}
357static inline int acpi_processor_remove_fs(struct acpi_device *device)
358{
359 return 0;
360}
361#endif
362
363/* --------------------------------------------------------------------------
364 Driver Interface
365 -------------------------------------------------------------------------- */
366
367static int acpi_processor_get_info(struct acpi_device *device)
368{
369 acpi_status status = 0;
370 union acpi_object object = { 0 };
371 struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
372 struct acpi_processor *pr;
373 int cpu_index, device_declaration = 0;
374 static int cpu0_initialized;
375
376 pr = acpi_driver_data(device);
377 if (!pr)
378 return -EINVAL;
379
380 if (num_online_cpus() > 1)
381 errata.smp = TRUE;
382
383 acpi_processor_errata(pr);
384
385 /*
386 * Check to see if we have bus mastering arbitration control. This
387 * is required for proper C3 usage (to maintain cache coherency).
388 */
389 if (acpi_gbl_FADT.pm2_control_block && acpi_gbl_FADT.pm2_control_length) {
390 pr->flags.bm_control = 1;
391 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
392 "Bus mastering arbitration control present\n"));
393 } else
394 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
395 "No bus mastering arbitration control\n"));
396
397 if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_OBJECT_HID)) {
398 /* Declared with "Processor" statement; match ProcessorID */
399 status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
400 if (ACPI_FAILURE(status)) {
401 printk(KERN_ERR PREFIX "Evaluating processor object\n");
402 return -ENODEV;
403 }
404
405 /*
406 * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
407 * >>> 'acpi_get_processor_id(acpi_id, &id)' in
408 * arch/xxx/acpi.c
409 */
410 pr->acpi_id = object.processor.proc_id;
411 } else {
412 /*
413 * Declared with "Device" statement; match _UID.
414 * Note that we don't handle string _UIDs yet.
415 */
416 unsigned long long value;
417 status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
418 NULL, &value);
419 if (ACPI_FAILURE(status)) {
420 printk(KERN_ERR PREFIX
421 "Evaluating processor _UID [%#x]\n", status);
422 return -ENODEV;
423 }
424 device_declaration = 1;
425 pr->acpi_id = value;
426 }
427 cpu_index = acpi_get_cpuid(pr->handle, device_declaration, pr->acpi_id);
428
429 /* Handle UP system running SMP kernel, with no LAPIC in MADT */
430 if (!cpu0_initialized && (cpu_index == -1) &&
431 (num_online_cpus() == 1)) {
432 cpu_index = 0;
433 }
434
435 cpu0_initialized = 1;
436
437 pr->id = cpu_index;
438
439 /*
440 * Extra Processor objects may be enumerated on MP systems with
441 * less than the max # of CPUs. They should be ignored _iff
442 * they are physically not present.
443 */
444 if (pr->id == -1) {
445 if (ACPI_FAILURE
446 (acpi_processor_hotadd_init(pr->handle, &pr->id))) {
447 return -ENODEV;
448 }
449 }
450 /*
451 * On some boxes several processors use the same processor bus id.
452 * But they are located in different scope. For example:
453 * \_SB.SCK0.CPU0
454 * \_SB.SCK1.CPU0
455 * Rename the processor device bus id. And the new bus id will be
456 * generated as the following format:
457 * CPU+CPU ID.
458 */
459 sprintf(acpi_device_bid(device), "CPU%X", pr->id);
460 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id,
461 pr->acpi_id));
462
463 if (!object.processor.pblk_address)
464 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n"));
465 else if (object.processor.pblk_length != 6)
466 printk(KERN_ERR PREFIX "Invalid PBLK length [%d]\n",
467 object.processor.pblk_length);
468 else {
469 pr->throttling.address = object.processor.pblk_address;
470 pr->throttling.duty_offset = acpi_gbl_FADT.duty_offset;
471 pr->throttling.duty_width = acpi_gbl_FADT.duty_width;
472
473 pr->pblk = object.processor.pblk_address;
474
475 /*
476 * We don't care about error returns - we just try to mark
477 * these reserved so that nobody else is confused into thinking
478 * that this region might be unused..
479 *
480 * (In particular, allocating the IO range for Cardbus)
481 */
482 request_region(pr->throttling.address, 6, "ACPI CPU throttle");
483 }
484
485 /*
486 * If ACPI describes a slot number for this CPU, we can use it
487 * ensure we get the right value in the "physical id" field
488 * of /proc/cpuinfo
489 */
490 status = acpi_evaluate_object(pr->handle, "_SUN", NULL, &buffer);
491 if (ACPI_SUCCESS(status))
492 arch_fix_phys_package_id(pr->id, object.integer.value);
493
494 return 0;
495}
496
497static DEFINE_PER_CPU(void *, processor_device_array);
498
499static void acpi_processor_notify(struct acpi_device *device, u32 event)
500{
501 struct acpi_processor *pr = acpi_driver_data(device);
502 int saved;
503
504 if (!pr)
505 return;
506
507 switch (event) {
508 case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
509 saved = pr->performance_platform_limit;
510 acpi_processor_ppc_has_changed(pr, 1);
511 if (saved == pr->performance_platform_limit)
512 break;
513 acpi_bus_generate_proc_event(device, event,
514 pr->performance_platform_limit);
515 acpi_bus_generate_netlink_event(device->pnp.device_class,
516 dev_name(&device->dev), event,
517 pr->performance_platform_limit);
518 break;
519 case ACPI_PROCESSOR_NOTIFY_POWER:
520 acpi_processor_cst_has_changed(pr);
521 acpi_bus_generate_proc_event(device, event, 0);
522 acpi_bus_generate_netlink_event(device->pnp.device_class,
523 dev_name(&device->dev), event, 0);
524 break;
525 case ACPI_PROCESSOR_NOTIFY_THROTTLING:
526 acpi_processor_tstate_has_changed(pr);
527 acpi_bus_generate_proc_event(device, event, 0);
528 acpi_bus_generate_netlink_event(device->pnp.device_class,
529 dev_name(&device->dev), event, 0);
530 default:
531 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
532 "Unsupported event [0x%x]\n", event));
533 break;
534 }
535
536 return;
537}
538
539static int acpi_cpu_soft_notify(struct notifier_block *nfb,
540 unsigned long action, void *hcpu)
541{
542 unsigned int cpu = (unsigned long)hcpu;
543 struct acpi_processor *pr = per_cpu(processors, cpu);
544
545 if (action == CPU_ONLINE && pr) {
546 acpi_processor_ppc_has_changed(pr, 0);
547 acpi_processor_cst_has_changed(pr);
548 acpi_processor_tstate_has_changed(pr);
549 }
550 return NOTIFY_OK;
551}
552
553static struct notifier_block acpi_cpu_notifier =
554{
555 .notifier_call = acpi_cpu_soft_notify,
556};
557
558static int __cpuinit acpi_processor_add(struct acpi_device *device)
559{
560 struct acpi_processor *pr = NULL;
561 int result = 0;
562 struct sys_device *sysdev;
563
564 pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
565 if (!pr)
566 return -ENOMEM;
567
568 if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) {
569 kfree(pr);
570 return -ENOMEM;
571 }
572
573 pr->handle = device->handle;
574 strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
575 strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
576 device->driver_data = pr;
577
578 result = acpi_processor_get_info(device);
579 if (result) {
580 /* Processor is physically not present */
581 return 0;
582 }
583
584 BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
585
586 /*
587 * Buggy BIOS check
588 * ACPI id of processors can be reported wrongly by the BIOS.
589 * Don't trust it blindly
590 */
591 if (per_cpu(processor_device_array, pr->id) != NULL &&
592 per_cpu(processor_device_array, pr->id) != device) {
593 printk(KERN_WARNING "BIOS reported wrong ACPI id "
594 "for the processor\n");
595 result = -ENODEV;
596 goto err_free_cpumask;
597 }
598 per_cpu(processor_device_array, pr->id) = device;
599
600 per_cpu(processors, pr->id) = pr;
601
602 result = acpi_processor_add_fs(device);
603 if (result)
604 goto err_free_cpumask;
605
606 sysdev = get_cpu_sysdev(pr->id);
607 if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) {
608 result = -EFAULT;
609 goto err_remove_fs;
610 }
611
612#ifdef CONFIG_CPU_FREQ
613 acpi_processor_ppc_has_changed(pr, 0);
614#endif
615 acpi_processor_get_throttling_info(pr);
616 acpi_processor_get_limit_info(pr);
617
618
619 acpi_processor_power_init(pr, device);
620
621 pr->cdev = thermal_cooling_device_register("Processor", device,
622 &processor_cooling_ops);
623 if (IS_ERR(pr->cdev)) {
624 result = PTR_ERR(pr->cdev);
625 goto err_power_exit;
626 }
627
628 dev_dbg(&device->dev, "registered as cooling_device%d\n",
629 pr->cdev->id);
630
631 result = sysfs_create_link(&device->dev.kobj,
632 &pr->cdev->device.kobj,
633 "thermal_cooling");
634 if (result) {
635 printk(KERN_ERR PREFIX "Create sysfs link\n");
636 goto err_thermal_unregister;
637 }
638 result = sysfs_create_link(&pr->cdev->device.kobj,
639 &device->dev.kobj,
640 "device");
641 if (result) {
642 printk(KERN_ERR PREFIX "Create sysfs link\n");
643 goto err_remove_sysfs;
644 }
645
646 return 0;
647
648err_remove_sysfs:
649 sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
650err_thermal_unregister:
651 thermal_cooling_device_unregister(pr->cdev);
652err_power_exit:
653 acpi_processor_power_exit(pr, device);
654err_remove_fs:
655 acpi_processor_remove_fs(device);
656err_free_cpumask:
657 free_cpumask_var(pr->throttling.shared_cpu_map);
658
659 return result;
660}
661
662static int acpi_processor_remove(struct acpi_device *device, int type)
663{
664 struct acpi_processor *pr = NULL;
665
666
667 if (!device || !acpi_driver_data(device))
668 return -EINVAL;
669
670 pr = acpi_driver_data(device);
671
672 if (pr->id >= nr_cpu_ids)
673 goto free;
674
675 if (type == ACPI_BUS_REMOVAL_EJECT) {
676 if (acpi_processor_handle_eject(pr))
677 return -EINVAL;
678 }
679
680 acpi_processor_power_exit(pr, device);
681
682 sysfs_remove_link(&device->dev.kobj, "sysdev");
683
684 acpi_processor_remove_fs(device);
685
686 if (pr->cdev) {
687 sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
688 sysfs_remove_link(&pr->cdev->device.kobj, "device");
689 thermal_cooling_device_unregister(pr->cdev);
690 pr->cdev = NULL;
691 }
692
693 per_cpu(processors, pr->id) = NULL;
694 per_cpu(processor_device_array, pr->id) = NULL;
695
696free:
697 free_cpumask_var(pr->throttling.shared_cpu_map);
698 kfree(pr);
699
700 return 0;
701}
702
703#ifdef CONFIG_ACPI_HOTPLUG_CPU
704/****************************************************************************
705 * Acpi processor hotplug support *
706 ****************************************************************************/
707
708static int is_processor_present(acpi_handle handle)
709{
710 acpi_status status;
711 unsigned long long sta = 0;
712
713
714 status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
715
716 if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT))
717 return 1;
718
719 /*
720 * _STA is mandatory for a processor that supports hot plug
721 */
722 if (status == AE_NOT_FOUND)
723 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
724 "Processor does not support hot plug\n"));
725 else
726 ACPI_EXCEPTION((AE_INFO, status,
727 "Processor Device is not present"));
728 return 0;
729}
730
731static
732int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
733{
734 acpi_handle phandle;
735 struct acpi_device *pdev;
736
737
738 if (acpi_get_parent(handle, &phandle)) {
739 return -ENODEV;
740 }
741
742 if (acpi_bus_get_device(phandle, &pdev)) {
743 return -ENODEV;
744 }
745
746 if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_PROCESSOR)) {
747 return -ENODEV;
748 }
749
750 return 0;
751}
752
753static void __ref acpi_processor_hotplug_notify(acpi_handle handle,
754 u32 event, void *data)
755{
756 struct acpi_processor *pr;
757 struct acpi_device *device = NULL;
758 int result;
759
760
761 switch (event) {
762 case ACPI_NOTIFY_BUS_CHECK:
763 case ACPI_NOTIFY_DEVICE_CHECK:
764 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
765 "Processor driver received %s event\n",
766 (event == ACPI_NOTIFY_BUS_CHECK) ?
767 "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"));
768
769 if (!is_processor_present(handle))
770 break;
771
772 if (acpi_bus_get_device(handle, &device)) {
773 result = acpi_processor_device_add(handle, &device);
774 if (result)
775 printk(KERN_ERR PREFIX
776 "Unable to add the device\n");
777 break;
778 }
779 break;
780 case ACPI_NOTIFY_EJECT_REQUEST:
781 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
782 "received ACPI_NOTIFY_EJECT_REQUEST\n"));
783
784 if (acpi_bus_get_device(handle, &device)) {
785 printk(KERN_ERR PREFIX
786 "Device don't exist, dropping EJECT\n");
787 break;
788 }
789 pr = acpi_driver_data(device);
790 if (!pr) {
791 printk(KERN_ERR PREFIX
792 "Driver data is NULL, dropping EJECT\n");
793 return;
794 }
795 break;
796 default:
797 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
798 "Unsupported event [0x%x]\n", event));
799 break;
800 }
801
802 return;
803}
804
805static acpi_status
806processor_walk_namespace_cb(acpi_handle handle,
807 u32 lvl, void *context, void **rv)
808{
809 acpi_status status;
810 int *action = context;
811 acpi_object_type type = 0;
812
813 status = acpi_get_type(handle, &type);
814 if (ACPI_FAILURE(status))
815 return (AE_OK);
816
817 if (type != ACPI_TYPE_PROCESSOR)
818 return (AE_OK);
819
820 switch (*action) {
821 case INSTALL_NOTIFY_HANDLER:
822 acpi_install_notify_handler(handle,
823 ACPI_SYSTEM_NOTIFY,
824 acpi_processor_hotplug_notify,
825 NULL);
826 break;
827 case UNINSTALL_NOTIFY_HANDLER:
828 acpi_remove_notify_handler(handle,
829 ACPI_SYSTEM_NOTIFY,
830 acpi_processor_hotplug_notify);
831 break;
832 default:
833 break;
834 }
835
836 return (AE_OK);
837}
838
839static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu)
840{
841
842 if (!is_processor_present(handle)) {
843 return AE_ERROR;
844 }
845
846 if (acpi_map_lsapic(handle, p_cpu))
847 return AE_ERROR;
848
849 if (arch_register_cpu(*p_cpu)) {
850 acpi_unmap_lsapic(*p_cpu);
851 return AE_ERROR;
852 }
853
854 return AE_OK;
855}
856
857static int acpi_processor_handle_eject(struct acpi_processor *pr)
858{
859 if (cpu_online(pr->id))
860 cpu_down(pr->id);
861
862 arch_unregister_cpu(pr->id);
863 acpi_unmap_lsapic(pr->id);
864 return (0);
865}
866#else
867static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu)
868{
869 return AE_ERROR;
870}
871static int acpi_processor_handle_eject(struct acpi_processor *pr)
872{
873 return (-EINVAL);
874}
875#endif
876
877static
878void acpi_processor_install_hotplug_notify(void)
879{
880#ifdef CONFIG_ACPI_HOTPLUG_CPU
881 int action = INSTALL_NOTIFY_HANDLER;
882 acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
883 ACPI_ROOT_OBJECT,
884 ACPI_UINT32_MAX,
885 processor_walk_namespace_cb, NULL, &action, NULL);
886#endif
887 register_hotcpu_notifier(&acpi_cpu_notifier);
888}
889
890static
891void acpi_processor_uninstall_hotplug_notify(void)
892{
893#ifdef CONFIG_ACPI_HOTPLUG_CPU
894 int action = UNINSTALL_NOTIFY_HANDLER;
895 acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
896 ACPI_ROOT_OBJECT,
897 ACPI_UINT32_MAX,
898 processor_walk_namespace_cb, NULL, &action, NULL);
899#endif
900 unregister_hotcpu_notifier(&acpi_cpu_notifier);
901}
902
903/*
904 * We keep the driver loaded even when ACPI is not running.
905 * This is needed for the powernow-k8 driver, that works even without
906 * ACPI, but needs symbols from this driver
907 */
908
909static int __init acpi_processor_init(void)
910{
911 int result = 0;
912
913 if (acpi_disabled)
914 return 0;
915
916 memset(&errata, 0, sizeof(errata));
917
918#ifdef CONFIG_ACPI_PROCFS
919 acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
920 if (!acpi_processor_dir)
921 return -ENOMEM;
922#endif
923 result = cpuidle_register_driver(&acpi_idle_driver);
924 if (result < 0)
925 goto out_proc;
926
927 result = acpi_bus_register_driver(&acpi_processor_driver);
928 if (result < 0)
929 goto out_cpuidle;
930
931 acpi_processor_install_hotplug_notify();
932
933 acpi_thermal_cpufreq_init();
934
935 acpi_processor_ppc_init();
936
937 acpi_processor_throttling_init();
938
939 return 0;
940
941out_cpuidle:
942 cpuidle_unregister_driver(&acpi_idle_driver);
943
944out_proc:
945#ifdef CONFIG_ACPI_PROCFS
946 remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
947#endif
948
949 return result;
950}
951
952static void __exit acpi_processor_exit(void)
953{
954 if (acpi_disabled)
955 return;
956
957 acpi_processor_ppc_exit();
958
959 acpi_thermal_cpufreq_exit();
960
961 acpi_processor_uninstall_hotplug_notify();
962
963 acpi_bus_unregister_driver(&acpi_processor_driver);
964
965 cpuidle_unregister_driver(&acpi_idle_driver);
966
967#ifdef CONFIG_ACPI_PROCFS
968 remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
969#endif
970
971 return;
972}
973
974module_init(acpi_processor_init);
975module_exit(acpi_processor_exit);
976
977EXPORT_SYMBOL(acpi_processor_set_thermal_limit);
978
979MODULE_ALIAS("processor");
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 37dfce749398..43fe52f9834b 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -32,6 +32,7 @@
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/init.h> 33#include <linux/init.h>
34#include <linux/cpufreq.h> 34#include <linux/cpufreq.h>
35#include <linux/slab.h>
35#include <linux/proc_fs.h> 36#include <linux/proc_fs.h>
36#include <linux/seq_file.h> 37#include <linux/seq_file.h>
37#include <linux/acpi.h> 38#include <linux/acpi.h>
@@ -726,19 +727,9 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
726 break; 727 break;
727 } 728 }
728 729
729 if (pr->power.states[i].promotion.state) 730 seq_puts(seq, "promotion[--] ");
730 seq_printf(seq, "promotion[C%zd] ",
731 (pr->power.states[i].promotion.state -
732 pr->power.states));
733 else
734 seq_puts(seq, "promotion[--] ");
735 731
736 if (pr->power.states[i].demotion.state) 732 seq_puts(seq, "demotion[--] ");
737 seq_printf(seq, "demotion[C%zd] ",
738 (pr->power.states[i].demotion.state -
739 pr->power.states));
740 else
741 seq_puts(seq, "demotion[--] ");
742 733
743 seq_printf(seq, "latency[%03d] usage[%08d] duration[%020llu]\n", 734 seq_printf(seq, "latency[%03d] usage[%08d] duration[%020llu]\n",
744 pr->power.states[i].latency, 735 pr->power.states[i].latency,
@@ -868,6 +859,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
868 struct acpi_processor *pr; 859 struct acpi_processor *pr;
869 struct acpi_processor_cx *cx = cpuidle_get_statedata(state); 860 struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
870 ktime_t kt1, kt2; 861 ktime_t kt1, kt2;
862 s64 idle_time_ns;
871 s64 idle_time; 863 s64 idle_time;
872 s64 sleep_ticks = 0; 864 s64 sleep_ticks = 0;
873 865
@@ -909,12 +901,14 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
909 sched_clock_idle_sleep_event(); 901 sched_clock_idle_sleep_event();
910 acpi_idle_do_entry(cx); 902 acpi_idle_do_entry(cx);
911 kt2 = ktime_get_real(); 903 kt2 = ktime_get_real();
912 idle_time = ktime_to_us(ktime_sub(kt2, kt1)); 904 idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1));
905 idle_time = idle_time_ns;
906 do_div(idle_time, NSEC_PER_USEC);
913 907
914 sleep_ticks = us_to_pm_timer_ticks(idle_time); 908 sleep_ticks = us_to_pm_timer_ticks(idle_time);
915 909
916 /* Tell the scheduler how much we idled: */ 910 /* Tell the scheduler how much we idled: */
917 sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); 911 sched_clock_idle_wakeup_event(idle_time_ns);
918 912
919 local_irq_enable(); 913 local_irq_enable();
920 current_thread_info()->status |= TS_POLLING; 914 current_thread_info()->status |= TS_POLLING;
@@ -942,6 +936,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
942 struct acpi_processor *pr; 936 struct acpi_processor *pr;
943 struct acpi_processor_cx *cx = cpuidle_get_statedata(state); 937 struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
944 ktime_t kt1, kt2; 938 ktime_t kt1, kt2;
939 s64 idle_time_ns;
945 s64 idle_time; 940 s64 idle_time;
946 s64 sleep_ticks = 0; 941 s64 sleep_ticks = 0;
947 942
@@ -1024,11 +1019,13 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
1024 spin_unlock(&c3_lock); 1019 spin_unlock(&c3_lock);
1025 } 1020 }
1026 kt2 = ktime_get_real(); 1021 kt2 = ktime_get_real();
1027 idle_time = ktime_to_us(ktime_sub(kt2, kt1)); 1022 idle_time_ns = ktime_to_us(ktime_sub(kt2, kt1));
1023 idle_time = idle_time_ns;
1024 do_div(idle_time, NSEC_PER_USEC);
1028 1025
1029 sleep_ticks = us_to_pm_timer_ticks(idle_time); 1026 sleep_ticks = us_to_pm_timer_ticks(idle_time);
1030 /* Tell the scheduler how much we idled: */ 1027 /* Tell the scheduler how much we idled: */
1031 sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); 1028 sched_clock_idle_wakeup_event(idle_time_ns);
1032 1029
1033 local_irq_enable(); 1030 local_irq_enable();
1034 current_thread_info()->status |= TS_POLLING; 1031 current_thread_info()->status |= TS_POLLING;
diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c
deleted file mode 100644
index e306ba9aa34e..000000000000
--- a/drivers/acpi/processor_pdc.c
+++ /dev/null
@@ -1,209 +0,0 @@
1/*
2 * Copyright (C) 2005 Intel Corporation
3 * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
4 *
5 * Alex Chiang <achiang@hp.com>
6 * - Unified x86/ia64 implementations
7 * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
8 * - Added _PDC for platforms with Intel CPUs
9 */
10#include <linux/dmi.h>
11
12#include <acpi/acpi_drivers.h>
13#include <acpi/processor.h>
14
15#include "internal.h"
16
17#define PREFIX "ACPI: "
18#define _COMPONENT ACPI_PROCESSOR_COMPONENT
19ACPI_MODULE_NAME("processor_pdc");
20
21static int set_no_mwait(const struct dmi_system_id *id)
22{
23 printk(KERN_NOTICE PREFIX "%s detected - "
24 "disabling mwait for CPU C-states\n", id->ident);
25 idle_nomwait = 1;
26 return 0;
27}
28
29static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = {
30 {
31 set_no_mwait, "IFL91 board", {
32 DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
33 DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"),
34 DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"),
35 DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL},
36 {
37 set_no_mwait, "Extensa 5220", {
38 DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
39 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
40 DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
41 DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL},
42 {},
43};
44
45static void acpi_set_pdc_bits(u32 *buf)
46{
47 buf[0] = ACPI_PDC_REVISION_ID;
48 buf[1] = 1;
49
50 /* Enable coordination with firmware's _TSD info */
51 buf[2] = ACPI_PDC_SMP_T_SWCOORD;
52
53 /* Twiddle arch-specific bits needed for _PDC */
54 arch_acpi_set_pdc_bits(buf);
55}
56
57static struct acpi_object_list *acpi_processor_alloc_pdc(void)
58{
59 struct acpi_object_list *obj_list;
60 union acpi_object *obj;
61 u32 *buf;
62
63 /* allocate and initialize pdc. It will be used later. */
64 obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
65 if (!obj_list) {
66 printk(KERN_ERR "Memory allocation error\n");
67 return NULL;
68 }
69
70 obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
71 if (!obj) {
72 printk(KERN_ERR "Memory allocation error\n");
73 kfree(obj_list);
74 return NULL;
75 }
76
77 buf = kmalloc(12, GFP_KERNEL);
78 if (!buf) {
79 printk(KERN_ERR "Memory allocation error\n");
80 kfree(obj);
81 kfree(obj_list);
82 return NULL;
83 }
84
85 acpi_set_pdc_bits(buf);
86
87 obj->type = ACPI_TYPE_BUFFER;
88 obj->buffer.length = 12;
89 obj->buffer.pointer = (u8 *) buf;
90 obj_list->count = 1;
91 obj_list->pointer = obj;
92
93 return obj_list;
94}
95
96/*
97 * _PDC is required for a BIOS-OS handshake for most of the newer
98 * ACPI processor features.
99 */
100static int
101acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
102{
103 acpi_status status = AE_OK;
104
105 if (idle_nomwait) {
106 /*
107 * If mwait is disabled for CPU C-states, the C2C3_FFH access
108 * mode will be disabled in the parameter of _PDC object.
109 * Of course C1_FFH access mode will also be disabled.
110 */
111 union acpi_object *obj;
112 u32 *buffer = NULL;
113
114 obj = pdc_in->pointer;
115 buffer = (u32 *)(obj->buffer.pointer);
116 buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH);
117
118 }
119 status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL);
120
121 if (ACPI_FAILURE(status))
122 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
123 "Could not evaluate _PDC, using legacy perf. control.\n"));
124
125 return status;
126}
127
128static int early_pdc_done;
129
130void acpi_processor_set_pdc(acpi_handle handle)
131{
132 struct acpi_object_list *obj_list;
133
134 if (arch_has_acpi_pdc() == false)
135 return;
136
137 if (early_pdc_done)
138 return;
139
140 obj_list = acpi_processor_alloc_pdc();
141 if (!obj_list)
142 return;
143
144 acpi_processor_eval_pdc(handle, obj_list);
145
146 kfree(obj_list->pointer->buffer.pointer);
147 kfree(obj_list->pointer);
148 kfree(obj_list);
149}
150EXPORT_SYMBOL_GPL(acpi_processor_set_pdc);
151
152static int early_pdc_optin;
153static int set_early_pdc_optin(const struct dmi_system_id *id)
154{
155 early_pdc_optin = 1;
156 return 0;
157}
158
159static int param_early_pdc_optin(char *s)
160{
161 early_pdc_optin = 1;
162 return 1;
163}
164__setup("acpi_early_pdc_eval", param_early_pdc_optin);
165
166static struct dmi_system_id __cpuinitdata early_pdc_optin_table[] = {
167 {
168 set_early_pdc_optin, "HP Envy", {
169 DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"),
170 DMI_MATCH(DMI_PRODUCT_NAME, "HP Envy") }, NULL},
171 {
172 set_early_pdc_optin, "HP Pavilion dv6", {
173 DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"),
174 DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv6") }, NULL},
175 {
176 set_early_pdc_optin, "HP Pavilion dv7", {
177 DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"),
178 DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv7") }, NULL},
179 {},
180};
181
182static acpi_status
183early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)
184{
185 acpi_processor_set_pdc(handle);
186 return AE_OK;
187}
188
189void __init acpi_early_processor_set_pdc(void)
190{
191 /*
192 * Check whether the system is DMI table. If yes, OSPM
193 * should not use mwait for CPU-states.
194 */
195 dmi_check_system(processor_idle_dmi_table);
196
197 /*
198 * Allow systems to opt-in to early _PDC evaluation.
199 */
200 dmi_check_system(early_pdc_optin_table);
201 if (!early_pdc_optin)
202 return;
203
204 acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
205 ACPI_UINT32_MAX,
206 early_init_pdc, NULL, NULL, NULL);
207
208 early_pdc_done = 1;
209}
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index d648a9860b88..ba1bd263d903 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -30,6 +30,7 @@
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/cpufreq.h> 32#include <linux/cpufreq.h>
33#include <linux/slab.h>
33 34
34#ifdef CONFIG_X86 35#ifdef CONFIG_X86
35#include <asm/cpufeature.h> 36#include <asm/cpufeature.h>
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 7ded7542fc9d..9ade1a5b32ed 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -28,6 +28,7 @@
28 28
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/slab.h>
31#include <linux/init.h> 32#include <linux/init.h>
32#include <linux/sched.h> 33#include <linux/sched.h>
33#include <linux/cpufreq.h> 34#include <linux/cpufreq.h>
@@ -1133,9 +1134,6 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
1133 int result = 0; 1134 int result = 0;
1134 struct acpi_processor_throttling *pthrottling; 1135 struct acpi_processor_throttling *pthrottling;
1135 1136
1136 if (!pr)
1137 return -EINVAL;
1138
1139 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 1137 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1140 "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n", 1138 "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n",
1141 pr->throttling.address, 1139 pr->throttling.address,
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index b16ddbf23a9c..4ff76e8174eb 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -25,6 +25,7 @@
25 */ 25 */
26 26
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/slab.h>
28#include <linux/module.h> 29#include <linux/module.h>
29#include <linux/moduleparam.h> 30#include <linux/moduleparam.h>
30#include <linux/kernel.h> 31#include <linux/kernel.h>
@@ -217,6 +218,9 @@ static int acpi_sbs_battery_get_property(struct power_supply *psy,
217 case POWER_SUPPLY_PROP_TECHNOLOGY: 218 case POWER_SUPPLY_PROP_TECHNOLOGY:
218 val->intval = acpi_battery_technology(battery); 219 val->intval = acpi_battery_technology(battery);
219 break; 220 break;
221 case POWER_SUPPLY_PROP_CYCLE_COUNT:
222 val->intval = battery->cycle_count;
223 break;
220 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 224 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
221 val->intval = battery->design_voltage * 225 val->intval = battery->design_voltage *
222 acpi_battery_vscale(battery) * 1000; 226 acpi_battery_vscale(battery) * 1000;
@@ -276,6 +280,7 @@ static enum power_supply_property sbs_charge_battery_props[] = {
276 POWER_SUPPLY_PROP_STATUS, 280 POWER_SUPPLY_PROP_STATUS,
277 POWER_SUPPLY_PROP_PRESENT, 281 POWER_SUPPLY_PROP_PRESENT,
278 POWER_SUPPLY_PROP_TECHNOLOGY, 282 POWER_SUPPLY_PROP_TECHNOLOGY,
283 POWER_SUPPLY_PROP_CYCLE_COUNT,
279 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 284 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
280 POWER_SUPPLY_PROP_VOLTAGE_NOW, 285 POWER_SUPPLY_PROP_VOLTAGE_NOW,
281 POWER_SUPPLY_PROP_CURRENT_NOW, 286 POWER_SUPPLY_PROP_CURRENT_NOW,
@@ -560,6 +565,7 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
560 battery->design_voltage * acpi_battery_vscale(battery)); 565 battery->design_voltage * acpi_battery_vscale(battery));
561 seq_printf(seq, "design capacity warning: unknown\n"); 566 seq_printf(seq, "design capacity warning: unknown\n");
562 seq_printf(seq, "design capacity low: unknown\n"); 567 seq_printf(seq, "design capacity low: unknown\n");
568 seq_printf(seq, "cycle count: %i\n", battery->cycle_count);
563 seq_printf(seq, "capacity granularity 1: unknown\n"); 569 seq_printf(seq, "capacity granularity 1: unknown\n");
564 seq_printf(seq, "capacity granularity 2: unknown\n"); 570 seq_printf(seq, "capacity granularity 2: unknown\n");
565 seq_printf(seq, "model number: %s\n", battery->device_name); 571 seq_printf(seq, "model number: %s\n", battery->device_name);
diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c
index fd09229282ea..f8be23b6c129 100644
--- a/drivers/acpi/sbshc.c
+++ b/drivers/acpi/sbshc.c
@@ -11,13 +11,14 @@
11#include <acpi/acpi_bus.h> 11#include <acpi/acpi_bus.h>
12#include <acpi/acpi_drivers.h> 12#include <acpi/acpi_drivers.h>
13#include <linux/wait.h> 13#include <linux/wait.h>
14#include <linux/slab.h>
14#include <linux/delay.h> 15#include <linux/delay.h>
15#include <linux/interrupt.h> 16#include <linux/interrupt.h>
16#include "sbshc.h" 17#include "sbshc.h"
17 18
18#define PREFIX "ACPI: " 19#define PREFIX "ACPI: "
19 20
20#define ACPI_SMB_HC_CLASS "smbus_host_controller" 21#define ACPI_SMB_HC_CLASS "smbus_host_ctl"
21#define ACPI_SMB_HC_DEVICE_NAME "ACPI SMBus HC" 22#define ACPI_SMB_HC_DEVICE_NAME "ACPI SMBus HC"
22 23
23struct acpi_smb_hc { 24struct acpi_smb_hc {
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index fb7fc24fe727..0338f513a010 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -4,10 +4,12 @@
4 4
5#include <linux/module.h> 5#include <linux/module.h>
6#include <linux/init.h> 6#include <linux/init.h>
7#include <linux/slab.h>
7#include <linux/kernel.h> 8#include <linux/kernel.h>
8#include <linux/acpi.h> 9#include <linux/acpi.h>
9#include <linux/signal.h> 10#include <linux/signal.h>
10#include <linux/kthread.h> 11#include <linux/kthread.h>
12#include <linux/dmi.h>
11 13
12#include <acpi/acpi_drivers.h> 14#include <acpi/acpi_drivers.h>
13 15
@@ -1032,6 +1034,41 @@ static void acpi_add_id(struct acpi_device *device, const char *dev_id)
1032 list_add_tail(&id->list, &device->pnp.ids); 1034 list_add_tail(&id->list, &device->pnp.ids);
1033} 1035}
1034 1036
1037/*
1038 * Old IBM workstations have a DSDT bug wherein the SMBus object
1039 * lacks the SMBUS01 HID and the methods do not have the necessary "_"
1040 * prefix. Work around this.
1041 */
1042static int acpi_ibm_smbus_match(struct acpi_device *device)
1043{
1044 acpi_handle h_dummy;
1045 struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL};
1046 int result;
1047
1048 if (!dmi_name_in_vendors("IBM"))
1049 return -ENODEV;
1050
1051 /* Look for SMBS object */
1052 result = acpi_get_name(device->handle, ACPI_SINGLE_NAME, &path);
1053 if (result)
1054 return result;
1055
1056 if (strcmp("SMBS", path.pointer)) {
1057 result = -ENODEV;
1058 goto out;
1059 }
1060
1061 /* Does it have the necessary (but misnamed) methods? */
1062 result = -ENODEV;
1063 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "SBI", &h_dummy)) &&
1064 ACPI_SUCCESS(acpi_get_handle(device->handle, "SBR", &h_dummy)) &&
1065 ACPI_SUCCESS(acpi_get_handle(device->handle, "SBW", &h_dummy)))
1066 result = 0;
1067out:
1068 kfree(path.pointer);
1069 return result;
1070}
1071
1035static void acpi_device_set_id(struct acpi_device *device) 1072static void acpi_device_set_id(struct acpi_device *device)
1036{ 1073{
1037 acpi_status status; 1074 acpi_status status;
@@ -1044,12 +1081,6 @@ static void acpi_device_set_id(struct acpi_device *device)
1044 if (ACPI_IS_ROOT_DEVICE(device)) { 1081 if (ACPI_IS_ROOT_DEVICE(device)) {
1045 acpi_add_id(device, ACPI_SYSTEM_HID); 1082 acpi_add_id(device, ACPI_SYSTEM_HID);
1046 break; 1083 break;
1047 } else if (ACPI_IS_ROOT_DEVICE(device->parent)) {
1048 /* \_SB_, the only root-level namespace device */
1049 acpi_add_id(device, ACPI_BUS_HID);
1050 strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
1051 strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
1052 break;
1053 } 1084 }
1054 1085
1055 status = acpi_get_object_info(device->handle, &info); 1086 status = acpi_get_object_info(device->handle, &info);
@@ -1082,6 +1113,14 @@ static void acpi_device_set_id(struct acpi_device *device)
1082 acpi_add_id(device, ACPI_BAY_HID); 1113 acpi_add_id(device, ACPI_BAY_HID);
1083 else if (ACPI_SUCCESS(acpi_dock_match(device))) 1114 else if (ACPI_SUCCESS(acpi_dock_match(device)))
1084 acpi_add_id(device, ACPI_DOCK_HID); 1115 acpi_add_id(device, ACPI_DOCK_HID);
1116 else if (!acpi_ibm_smbus_match(device))
1117 acpi_add_id(device, ACPI_SMBUS_IBM_HID);
1118 else if (!acpi_device_hid(device) &&
1119 ACPI_IS_ROOT_DEVICE(device->parent)) {
1120 acpi_add_id(device, ACPI_BUS_HID); /* \_SB, LNXSYBUS */
1121 strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
1122 strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
1123 }
1085 1124
1086 break; 1125 break;
1087 case ACPI_BUS_TYPE_POWER: 1126 case ACPI_BUS_TYPE_POWER:
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 3bde594a9979..4ab2275b4461 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -80,22 +80,6 @@ static int acpi_sleep_prepare(u32 acpi_state)
80 80
81#ifdef CONFIG_ACPI_SLEEP 81#ifdef CONFIG_ACPI_SLEEP
82static u32 acpi_target_sleep_state = ACPI_STATE_S0; 82static u32 acpi_target_sleep_state = ACPI_STATE_S0;
83/*
84 * According to the ACPI specification the BIOS should make sure that ACPI is
85 * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still,
86 * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI
87 * on such systems during resume. Unfortunately that doesn't help in
88 * particularly pathological cases in which SCI_EN has to be set directly on
89 * resume, although the specification states very clearly that this flag is
90 * owned by the hardware. The set_sci_en_on_resume variable will be set in such
91 * cases.
92 */
93static bool set_sci_en_on_resume;
94
95void __init acpi_set_sci_en_on_resume(void)
96{
97 set_sci_en_on_resume = true;
98}
99 83
100/* 84/*
101 * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the 85 * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the
@@ -253,11 +237,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
253 break; 237 break;
254 } 238 }
255 239
256 /* If ACPI is not enabled by the BIOS, we need to enable it here. */ 240 /* This violates the spec but is required for bug compatibility. */
257 if (set_sci_en_on_resume) 241 acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1);
258 acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1);
259 else
260 acpi_enable();
261 242
262 /* Reprogram control registers and execute _BFS */ 243 /* Reprogram control registers and execute _BFS */
263 acpi_leave_sleep_state_prep(acpi_state); 244 acpi_leave_sleep_state_prep(acpi_state);
@@ -346,12 +327,6 @@ static int __init init_old_suspend_ordering(const struct dmi_system_id *d)
346 return 0; 327 return 0;
347} 328}
348 329
349static int __init init_set_sci_en_on_resume(const struct dmi_system_id *d)
350{
351 set_sci_en_on_resume = true;
352 return 0;
353}
354
355static struct dmi_system_id __initdata acpisleep_dmi_table[] = { 330static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
356 { 331 {
357 .callback = init_old_suspend_ordering, 332 .callback = init_old_suspend_ordering,
@@ -370,22 +345,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
370 }, 345 },
371 }, 346 },
372 { 347 {
373 .callback = init_set_sci_en_on_resume,
374 .ident = "Apple MacBook 1,1",
375 .matches = {
376 DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."),
377 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"),
378 },
379 },
380 {
381 .callback = init_set_sci_en_on_resume,
382 .ident = "Apple MacMini 1,1",
383 .matches = {
384 DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."),
385 DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"),
386 },
387 },
388 {
389 .callback = init_old_suspend_ordering, 348 .callback = init_old_suspend_ordering,
390 .ident = "Asus Pundit P1-AH2 (M2N8L motherboard)", 349 .ident = "Asus Pundit P1-AH2 (M2N8L motherboard)",
391 .matches = { 350 .matches = {
@@ -394,62 +353,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
394 }, 353 },
395 }, 354 },
396 { 355 {
397 .callback = init_set_sci_en_on_resume,
398 .ident = "Toshiba Satellite L300",
399 .matches = {
400 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
401 DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L300"),
402 },
403 },
404 {
405 .callback = init_set_sci_en_on_resume,
406 .ident = "Hewlett-Packard HP G7000 Notebook PC",
407 .matches = {
408 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
409 DMI_MATCH(DMI_PRODUCT_NAME, "HP G7000 Notebook PC"),
410 },
411 },
412 {
413 .callback = init_set_sci_en_on_resume,
414 .ident = "Hewlett-Packard HP Pavilion dv3 Notebook PC",
415 .matches = {
416 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
417 DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv3 Notebook PC"),
418 },
419 },
420 {
421 .callback = init_set_sci_en_on_resume,
422 .ident = "Hewlett-Packard Pavilion dv4",
423 .matches = {
424 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
425 DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4"),
426 },
427 },
428 {
429 .callback = init_set_sci_en_on_resume,
430 .ident = "Hewlett-Packard Pavilion dv7",
431 .matches = {
432 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
433 DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv7"),
434 },
435 },
436 {
437 .callback = init_set_sci_en_on_resume,
438 .ident = "Hewlett-Packard Compaq Presario C700 Notebook PC",
439 .matches = {
440 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
441 DMI_MATCH(DMI_PRODUCT_NAME, "Compaq Presario C700 Notebook PC"),
442 },
443 },
444 {
445 .callback = init_set_sci_en_on_resume,
446 .ident = "Hewlett-Packard Compaq Presario CQ40 Notebook PC",
447 .matches = {
448 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
449 DMI_MATCH(DMI_PRODUCT_NAME, "Compaq Presario CQ40 Notebook PC"),
450 },
451 },
452 {
453 .callback = init_old_suspend_ordering, 356 .callback = init_old_suspend_ordering,
454 .ident = "Panasonic CF51-2L", 357 .ident = "Panasonic CF51-2L",
455 .matches = { 358 .matches = {
@@ -552,8 +455,17 @@ static void acpi_hibernation_leave(void)
552 hibernate_nvs_restore(); 455 hibernate_nvs_restore();
553} 456}
554 457
555static void acpi_pm_enable_gpes(void) 458static int acpi_pm_pre_restore(void)
459{
460 acpi_disable_all_gpes();
461 acpi_os_wait_events_complete(NULL);
462 acpi_ec_suspend_transactions();
463 return 0;
464}
465
466static void acpi_pm_restore_cleanup(void)
556{ 467{
468 acpi_ec_resume_transactions();
557 acpi_enable_all_runtime_gpes(); 469 acpi_enable_all_runtime_gpes();
558} 470}
559 471
@@ -565,8 +477,8 @@ static struct platform_hibernation_ops acpi_hibernation_ops = {
565 .prepare = acpi_pm_prepare, 477 .prepare = acpi_pm_prepare,
566 .enter = acpi_hibernation_enter, 478 .enter = acpi_hibernation_enter,
567 .leave = acpi_hibernation_leave, 479 .leave = acpi_hibernation_leave,
568 .pre_restore = acpi_pm_disable_gpes, 480 .pre_restore = acpi_pm_pre_restore,
569 .restore_cleanup = acpi_pm_enable_gpes, 481 .restore_cleanup = acpi_pm_restore_cleanup,
570}; 482};
571 483
572/** 484/**
@@ -618,8 +530,8 @@ static struct platform_hibernation_ops acpi_hibernation_ops_old = {
618 .prepare = acpi_pm_disable_gpes, 530 .prepare = acpi_pm_disable_gpes,
619 .enter = acpi_hibernation_enter, 531 .enter = acpi_hibernation_enter,
620 .leave = acpi_hibernation_leave, 532 .leave = acpi_hibernation_leave,
621 .pre_restore = acpi_pm_disable_gpes, 533 .pre_restore = acpi_pm_pre_restore,
622 .restore_cleanup = acpi_pm_enable_gpes, 534 .restore_cleanup = acpi_pm_restore_cleanup,
623 .recover = acpi_pm_finish, 535 .recover = acpi_pm_finish,
624}; 536};
625#endif /* CONFIG_HIBERNATION */ 537#endif /* CONFIG_HIBERNATION */
diff --git a/drivers/acpi/sleep.h b/drivers/acpi/sleep.h
index 8a8f3b3382a6..25b8bd149284 100644
--- a/drivers/acpi/sleep.h
+++ b/drivers/acpi/sleep.h
@@ -1,6 +1,6 @@
1 1
2extern u8 sleep_states[]; 2extern u8 sleep_states[];
3extern int acpi_suspend (u32 state); 3extern int acpi_suspend(u32 state);
4 4
5extern void acpi_enable_wakeup_device_prep(u8 sleep_state); 5extern void acpi_enable_wakeup_device_prep(u8 sleep_state);
6extern void acpi_enable_wakeup_device(u8 sleep_state); 6extern void acpi_enable_wakeup_device(u8 sleep_state);
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 743f2445e2a1..4aaf24976138 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -25,6 +25,7 @@
25 25
26#include <linux/proc_fs.h> 26#include <linux/proc_fs.h>
27#include <linux/seq_file.h> 27#include <linux/seq_file.h>
28#include <linux/slab.h>
28#include <linux/init.h> 29#include <linux/init.h>
29#include <linux/string.h> 30#include <linux/string.h>
30#include <asm/uaccess.h> 31#include <asm/uaccess.h>
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 9073ada88835..efad1f33aeb5 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -35,6 +35,7 @@
35#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/dmi.h> 36#include <linux/dmi.h>
37#include <linux/init.h> 37#include <linux/init.h>
38#include <linux/slab.h>
38#include <linux/types.h> 39#include <linux/types.h>
39#include <linux/proc_fs.h> 40#include <linux/proc_fs.h>
40#include <linux/jiffies.h> 41#include <linux/jiffies.h>
@@ -368,7 +369,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
368 int valid = 0; 369 int valid = 0;
369 int i; 370 int i;
370 371
371 /* Critical Shutdown (required) */ 372 /* Critical Shutdown */
372 if (flag & ACPI_TRIPS_CRITICAL) { 373 if (flag & ACPI_TRIPS_CRITICAL) {
373 status = acpi_evaluate_integer(tz->device->handle, 374 status = acpi_evaluate_integer(tz->device->handle,
374 "_CRT", NULL, &tmp); 375 "_CRT", NULL, &tmp);
@@ -379,17 +380,19 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
379 * Below zero (Celsius) values clearly aren't right for sure.. 380 * Below zero (Celsius) values clearly aren't right for sure..
380 * ... so lets discard those as invalid. 381 * ... so lets discard those as invalid.
381 */ 382 */
382 if (ACPI_FAILURE(status) || 383 if (ACPI_FAILURE(status)) {
383 tz->trips.critical.temperature <= 2732) { 384 tz->trips.critical.flags.valid = 0;
385 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
386 "No critical threshold\n"));
387 } else if (tmp <= 2732) {
388 printk(KERN_WARNING FW_BUG "Invalid critical threshold "
389 "(%llu)\n", tmp);
384 tz->trips.critical.flags.valid = 0; 390 tz->trips.critical.flags.valid = 0;
385 ACPI_EXCEPTION((AE_INFO, status,
386 "No or invalid critical threshold"));
387 return -ENODEV;
388 } else { 391 } else {
389 tz->trips.critical.flags.valid = 1; 392 tz->trips.critical.flags.valid = 1;
390 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 393 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
391 "Found critical threshold [%lu]\n", 394 "Found critical threshold [%lu]\n",
392 tz->trips.critical.temperature)); 395 tz->trips.critical.temperature));
393 } 396 }
394 if (tz->trips.critical.flags.valid == 1) { 397 if (tz->trips.critical.flags.valid == 1) {
395 if (crt == -1) { 398 if (crt == -1) {
@@ -575,7 +578,23 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
575 578
576static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) 579static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
577{ 580{
578 return acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT); 581 int i, valid, ret = acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT);
582
583 if (ret)
584 return ret;
585
586 valid = tz->trips.critical.flags.valid |
587 tz->trips.hot.flags.valid |
588 tz->trips.passive.flags.valid;
589
590 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
591 valid |= tz->trips.active[i].flags.valid;
592
593 if (!valid) {
594 printk(KERN_WARNING FW_BUG "No valid trip found\n");
595 return -ENODEV;
596 }
597 return 0;
579} 598}
580 599
581static void acpi_thermal_check(void *data) 600static void acpi_thermal_check(void *data)
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index 11882dbe2094..b002a471c5d4 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -25,6 +25,7 @@
25 25
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/slab.h>
28#include <linux/init.h> 29#include <linux/init.h>
29#include <linux/types.h> 30#include <linux/types.h>
30#include <acpi/acpi_bus.h> 31#include <acpi/acpi_bus.h>
@@ -289,51 +290,6 @@ acpi_evaluate_integer(acpi_handle handle,
289 290
290EXPORT_SYMBOL(acpi_evaluate_integer); 291EXPORT_SYMBOL(acpi_evaluate_integer);
291 292
292#if 0
293acpi_status
294acpi_evaluate_string(acpi_handle handle,
295 acpi_string pathname,
296 acpi_object_list * arguments, acpi_string * data)
297{
298 acpi_status status = AE_OK;
299 acpi_object *element = NULL;
300 acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
301
302
303 if (!data)
304 return AE_BAD_PARAMETER;
305
306 status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
307 if (ACPI_FAILURE(status)) {
308 acpi_util_eval_error(handle, pathname, status);
309 return status;
310 }
311
312 element = (acpi_object *) buffer.pointer;
313
314 if ((element->type != ACPI_TYPE_STRING)
315 || (element->type != ACPI_TYPE_BUFFER)
316 || !element->string.length) {
317 acpi_util_eval_error(handle, pathname, AE_BAD_DATA);
318 return AE_BAD_DATA;
319 }
320
321 *data = kzalloc(element->string.length + 1, GFP_KERNEL);
322 if (!data) {
323 printk(KERN_ERR PREFIX "Memory allocation\n");
324 return -ENOMEM;
325 }
326
327 memcpy(*data, element->string.pointer, element->string.length);
328
329 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%s]\n", *data));
330
331 kfree(buffer.pointer);
332
333 return AE_OK;
334}
335#endif
336
337acpi_status 293acpi_status
338acpi_evaluate_reference(acpi_handle handle, 294acpi_evaluate_reference(acpi_handle handle,
339 acpi_string pathname, 295 acpi_string pathname,
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 6e9b49149fce..9865d46f49a8 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -39,10 +39,13 @@
39#include <linux/sort.h> 39#include <linux/sort.h>
40#include <linux/pci.h> 40#include <linux/pci.h>
41#include <linux/pci_ids.h> 41#include <linux/pci_ids.h>
42#include <linux/slab.h>
42#include <asm/uaccess.h> 43#include <asm/uaccess.h>
43#include <linux/dmi.h> 44#include <linux/dmi.h>
44#include <acpi/acpi_bus.h> 45#include <acpi/acpi_bus.h>
45#include <acpi/acpi_drivers.h> 46#include <acpi/acpi_drivers.h>
47#include <linux/suspend.h>
48#include <acpi/video.h>
46 49
47#define PREFIX "ACPI: " 50#define PREFIX "ACPI: "
48 51
@@ -63,11 +66,6 @@
63 66
64#define MAX_NAME_LEN 20 67#define MAX_NAME_LEN 20
65 68
66#define ACPI_VIDEO_DISPLAY_CRT 1
67#define ACPI_VIDEO_DISPLAY_TV 2
68#define ACPI_VIDEO_DISPLAY_DVI 3
69#define ACPI_VIDEO_DISPLAY_LCD 4
70
71#define _COMPONENT ACPI_VIDEO_COMPONENT 69#define _COMPONENT ACPI_VIDEO_COMPONENT
72ACPI_MODULE_NAME("video"); 70ACPI_MODULE_NAME("video");
73 71
@@ -88,7 +86,6 @@ module_param(allow_duplicates, bool, 0644);
88static int register_count = 0; 86static int register_count = 0;
89static int acpi_video_bus_add(struct acpi_device *device); 87static int acpi_video_bus_add(struct acpi_device *device);
90static int acpi_video_bus_remove(struct acpi_device *device, int type); 88static int acpi_video_bus_remove(struct acpi_device *device, int type);
91static int acpi_video_resume(struct acpi_device *device);
92static void acpi_video_bus_notify(struct acpi_device *device, u32 event); 89static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
93 90
94static const struct acpi_device_id video_device_ids[] = { 91static const struct acpi_device_id video_device_ids[] = {
@@ -104,7 +101,6 @@ static struct acpi_driver acpi_video_bus = {
104 .ops = { 101 .ops = {
105 .add = acpi_video_bus_add, 102 .add = acpi_video_bus_add,
106 .remove = acpi_video_bus_remove, 103 .remove = acpi_video_bus_remove,
107 .resume = acpi_video_resume,
108 .notify = acpi_video_bus_notify, 104 .notify = acpi_video_bus_notify,
109 }, 105 },
110}; 106};
@@ -159,6 +155,7 @@ struct acpi_video_bus {
159 struct proc_dir_entry *dir; 155 struct proc_dir_entry *dir;
160 struct input_dev *input; 156 struct input_dev *input;
161 char phys[32]; /* for input device */ 157 char phys[32]; /* for input device */
158 struct notifier_block pm_nb;
162}; 159};
163 160
164struct acpi_video_device_flags { 161struct acpi_video_device_flags {
@@ -327,7 +324,7 @@ static int acpi_video_device_lcd_set_level(struct acpi_video_device *device,
327 int level); 324 int level);
328static int acpi_video_device_lcd_get_level_current( 325static int acpi_video_device_lcd_get_level_current(
329 struct acpi_video_device *device, 326 struct acpi_video_device *device,
330 unsigned long long *level); 327 unsigned long long *level, int init);
331static int acpi_video_get_next_level(struct acpi_video_device *device, 328static int acpi_video_get_next_level(struct acpi_video_device *device,
332 u32 level_current, u32 event); 329 u32 level_current, u32 event);
333static int acpi_video_switch_brightness(struct acpi_video_device *device, 330static int acpi_video_switch_brightness(struct acpi_video_device *device,
@@ -345,7 +342,7 @@ static int acpi_video_get_brightness(struct backlight_device *bd)
345 struct acpi_video_device *vd = 342 struct acpi_video_device *vd =
346 (struct acpi_video_device *)bl_get_data(bd); 343 (struct acpi_video_device *)bl_get_data(bd);
347 344
348 if (acpi_video_device_lcd_get_level_current(vd, &cur_level)) 345 if (acpi_video_device_lcd_get_level_current(vd, &cur_level, 0))
349 return -EINVAL; 346 return -EINVAL;
350 for (i = 2; i < vd->brightness->count; i++) { 347 for (i = 2; i < vd->brightness->count; i++) {
351 if (vd->brightness->levels[i] == cur_level) 348 if (vd->brightness->levels[i] == cur_level)
@@ -414,7 +411,7 @@ static int video_get_cur_state(struct thermal_cooling_device *cooling_dev, unsig
414 unsigned long long level; 411 unsigned long long level;
415 int offset; 412 int offset;
416 413
417 if (acpi_video_device_lcd_get_level_current(video, &level)) 414 if (acpi_video_device_lcd_get_level_current(video, &level, 0))
418 return -EINVAL; 415 return -EINVAL;
419 for (offset = 2; offset < video->brightness->count; offset++) 416 for (offset = 2; offset < video->brightness->count; offset++)
420 if (level == video->brightness->levels[offset]) { 417 if (level == video->brightness->levels[offset]) {
@@ -609,7 +606,7 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
609 606
610static int 607static int
611acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, 608acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
612 unsigned long long *level) 609 unsigned long long *level, int init)
613{ 610{
614 acpi_status status = AE_OK; 611 acpi_status status = AE_OK;
615 int i; 612 int i;
@@ -633,10 +630,16 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
633 device->brightness->curr = *level; 630 device->brightness->curr = *level;
634 return 0; 631 return 0;
635 } 632 }
636 /* BQC returned an invalid level. Stop using it. */ 633 if (!init) {
637 ACPI_WARNING((AE_INFO, "%s returned an invalid level", 634 /*
638 buf)); 635 * BQC returned an invalid level.
639 device->cap._BQC = device->cap._BCQ = 0; 636 * Stop using it.
637 */
638 ACPI_WARNING((AE_INFO,
639 "%s returned an invalid level",
640 buf));
641 device->cap._BQC = device->cap._BCQ = 0;
642 }
640 } else { 643 } else {
641 /* Fixme: 644 /* Fixme:
642 * should we return an error or ignore this failure? 645 * should we return an error or ignore this failure?
@@ -892,7 +895,7 @@ acpi_video_init_brightness(struct acpi_video_device *device)
892 if (!device->cap._BQC) 895 if (!device->cap._BQC)
893 goto set_level; 896 goto set_level;
894 897
895 result = acpi_video_device_lcd_get_level_current(device, &level_old); 898 result = acpi_video_device_lcd_get_level_current(device, &level_old, 1);
896 if (result) 899 if (result)
897 goto out_free_levels; 900 goto out_free_levels;
898 901
@@ -903,7 +906,7 @@ acpi_video_init_brightness(struct acpi_video_device *device)
903 if (result) 906 if (result)
904 goto out_free_levels; 907 goto out_free_levels;
905 908
906 result = acpi_video_device_lcd_get_level_current(device, &level); 909 result = acpi_video_device_lcd_get_level_current(device, &level, 0);
907 if (result) 910 if (result)
908 goto out_free_levels; 911 goto out_free_levels;
909 912
@@ -992,6 +995,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
992 } 995 }
993 996
994 if (acpi_video_backlight_support()) { 997 if (acpi_video_backlight_support()) {
998 struct backlight_properties props;
995 int result; 999 int result;
996 static int count = 0; 1000 static int count = 0;
997 char *name; 1001 char *name;
@@ -999,17 +1003,26 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
999 result = acpi_video_init_brightness(device); 1003 result = acpi_video_init_brightness(device);
1000 if (result) 1004 if (result)
1001 return; 1005 return;
1002 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); 1006 name = kasprintf(GFP_KERNEL, "acpi_video%d", count);
1003 if (!name) 1007 if (!name)
1004 return; 1008 return;
1009 count++;
1005 1010
1006 sprintf(name, "acpi_video%d", count++); 1011 memset(&props, 0, sizeof(struct backlight_properties));
1007 device->backlight = backlight_device_register(name, 1012 props.max_brightness = device->brightness->count - 3;
1008 NULL, device, &acpi_backlight_ops); 1013 device->backlight = backlight_device_register(name, NULL, device,
1014 &acpi_backlight_ops,
1015 &props);
1009 kfree(name); 1016 kfree(name);
1010 if (IS_ERR(device->backlight)) 1017 if (IS_ERR(device->backlight))
1011 return; 1018 return;
1012 device->backlight->props.max_brightness = device->brightness->count-3; 1019
1020 /*
1021 * Save current brightness level in case we have to restore it
1022 * before acpi_video_device_lcd_set_level() is called next time.
1023 */
1024 device->backlight->props.brightness =
1025 acpi_video_get_brightness(device->backlight);
1013 1026
1014 result = sysfs_create_link(&device->backlight->dev.kobj, 1027 result = sysfs_create_link(&device->backlight->dev.kobj,
1015 &device->dev->dev.kobj, "device"); 1028 &device->dev->dev.kobj, "device");
@@ -1050,10 +1063,10 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
1050 if (device->cap._DCS && device->cap._DSS) { 1063 if (device->cap._DCS && device->cap._DSS) {
1051 static int count; 1064 static int count;
1052 char *name; 1065 char *name;
1053 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); 1066 name = kasprintf(GFP_KERNEL, "acpi_video%d", count);
1054 if (!name) 1067 if (!name)
1055 return; 1068 return;
1056 sprintf(name, "acpi_video%d", count++); 1069 count++;
1057 device->output_dev = video_output_register(name, 1070 device->output_dev = video_output_register(name,
1058 NULL, device, &acpi_output_properties); 1071 NULL, device, &acpi_output_properties);
1059 kfree(name); 1072 kfree(name);
@@ -1731,11 +1744,27 @@ acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id
1731} 1744}
1732 1745
1733static int 1746static int
1747acpi_video_get_device_type(struct acpi_video_bus *video,
1748 unsigned long device_id)
1749{
1750 struct acpi_video_enumerated_device *ids;
1751 int i;
1752
1753 for (i = 0; i < video->attached_count; i++) {
1754 ids = &video->attached_array[i];
1755 if ((ids->value.int_val & 0xffff) == device_id)
1756 return ids->value.int_val;
1757 }
1758
1759 return 0;
1760}
1761
1762static int
1734acpi_video_bus_get_one_device(struct acpi_device *device, 1763acpi_video_bus_get_one_device(struct acpi_device *device,
1735 struct acpi_video_bus *video) 1764 struct acpi_video_bus *video)
1736{ 1765{
1737 unsigned long long device_id; 1766 unsigned long long device_id;
1738 int status; 1767 int status, device_type;
1739 struct acpi_video_device *data; 1768 struct acpi_video_device *data;
1740 struct acpi_video_device_attrib* attribute; 1769 struct acpi_video_device_attrib* attribute;
1741 1770
@@ -1780,8 +1809,25 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
1780 } 1809 }
1781 if(attribute->bios_can_detect) 1810 if(attribute->bios_can_detect)
1782 data->flags.bios = 1; 1811 data->flags.bios = 1;
1783 } else 1812 } else {
1784 data->flags.unknown = 1; 1813 /* Check for legacy IDs */
1814 device_type = acpi_video_get_device_type(video,
1815 device_id);
1816 /* Ignore bits 16 and 18-20 */
1817 switch (device_type & 0xffe2ffff) {
1818 case ACPI_VIDEO_DISPLAY_LEGACY_MONITOR:
1819 data->flags.crt = 1;
1820 break;
1821 case ACPI_VIDEO_DISPLAY_LEGACY_PANEL:
1822 data->flags.lcd = 1;
1823 break;
1824 case ACPI_VIDEO_DISPLAY_LEGACY_TV:
1825 data->flags.tvout = 1;
1826 break;
1827 default:
1828 data->flags.unknown = 1;
1829 }
1830 }
1785 1831
1786 acpi_video_device_bind(video, data); 1832 acpi_video_device_bind(video, data);
1787 acpi_video_device_find_cap(data); 1833 acpi_video_device_find_cap(data);
@@ -1996,7 +2042,7 @@ acpi_video_switch_brightness(struct acpi_video_device *device, int event)
1996 goto out; 2042 goto out;
1997 2043
1998 result = acpi_video_device_lcd_get_level_current(device, 2044 result = acpi_video_device_lcd_get_level_current(device,
1999 &level_current); 2045 &level_current, 0);
2000 if (result) 2046 if (result)
2001 goto out; 2047 goto out;
2002 2048
@@ -2015,6 +2061,71 @@ out:
2015 return result; 2061 return result;
2016} 2062}
2017 2063
2064int acpi_video_get_edid(struct acpi_device *device, int type, int device_id,
2065 void **edid)
2066{
2067 struct acpi_video_bus *video;
2068 struct acpi_video_device *video_device;
2069 union acpi_object *buffer = NULL;
2070 acpi_status status;
2071 int i, length;
2072
2073 if (!device || !acpi_driver_data(device))
2074 return -EINVAL;
2075
2076 video = acpi_driver_data(device);
2077
2078 for (i = 0; i < video->attached_count; i++) {
2079 video_device = video->attached_array[i].bind_info;
2080 length = 256;
2081
2082 if (!video_device)
2083 continue;
2084
2085 if (type) {
2086 switch (type) {
2087 case ACPI_VIDEO_DISPLAY_CRT:
2088 if (!video_device->flags.crt)
2089 continue;
2090 break;
2091 case ACPI_VIDEO_DISPLAY_TV:
2092 if (!video_device->flags.tvout)
2093 continue;
2094 break;
2095 case ACPI_VIDEO_DISPLAY_DVI:
2096 if (!video_device->flags.dvi)
2097 continue;
2098 break;
2099 case ACPI_VIDEO_DISPLAY_LCD:
2100 if (!video_device->flags.lcd)
2101 continue;
2102 break;
2103 }
2104 } else if (video_device->device_id != device_id) {
2105 continue;
2106 }
2107
2108 status = acpi_video_device_EDID(video_device, &buffer, length);
2109
2110 if (ACPI_FAILURE(status) || !buffer ||
2111 buffer->type != ACPI_TYPE_BUFFER) {
2112 length = 128;
2113 status = acpi_video_device_EDID(video_device, &buffer,
2114 length);
2115 if (ACPI_FAILURE(status) || !buffer ||
2116 buffer->type != ACPI_TYPE_BUFFER) {
2117 continue;
2118 }
2119 }
2120
2121 *edid = buffer->buffer.pointer;
2122 return length;
2123 }
2124
2125 return -ENODEV;
2126}
2127EXPORT_SYMBOL(acpi_video_get_edid);
2128
2018static int 2129static int
2019acpi_video_bus_get_devices(struct acpi_video_bus *video, 2130acpi_video_bus_get_devices(struct acpi_video_bus *video,
2020 struct acpi_device *device) 2131 struct acpi_device *device)
@@ -2113,7 +2224,7 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
2113{ 2224{
2114 struct acpi_video_bus *video = acpi_driver_data(device); 2225 struct acpi_video_bus *video = acpi_driver_data(device);
2115 struct input_dev *input; 2226 struct input_dev *input;
2116 int keycode; 2227 int keycode = 0;
2117 2228
2118 if (!video) 2229 if (!video)
2119 return; 2230 return;
@@ -2149,17 +2260,19 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
2149 break; 2260 break;
2150 2261
2151 default: 2262 default:
2152 keycode = KEY_UNKNOWN;
2153 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 2263 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
2154 "Unsupported event [0x%x]\n", event)); 2264 "Unsupported event [0x%x]\n", event));
2155 break; 2265 break;
2156 } 2266 }
2157 2267
2158 acpi_notifier_call_chain(device, event, 0); 2268 acpi_notifier_call_chain(device, event, 0);
2159 input_report_key(input, keycode, 1); 2269
2160 input_sync(input); 2270 if (keycode) {
2161 input_report_key(input, keycode, 0); 2271 input_report_key(input, keycode, 1);
2162 input_sync(input); 2272 input_sync(input);
2273 input_report_key(input, keycode, 0);
2274 input_sync(input);
2275 }
2163 2276
2164 return; 2277 return;
2165} 2278}
@@ -2170,7 +2283,7 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
2170 struct acpi_device *device = NULL; 2283 struct acpi_device *device = NULL;
2171 struct acpi_video_bus *bus; 2284 struct acpi_video_bus *bus;
2172 struct input_dev *input; 2285 struct input_dev *input;
2173 int keycode; 2286 int keycode = 0;
2174 2287
2175 if (!video_device) 2288 if (!video_device)
2176 return; 2289 return;
@@ -2211,39 +2324,48 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
2211 keycode = KEY_DISPLAY_OFF; 2324 keycode = KEY_DISPLAY_OFF;
2212 break; 2325 break;
2213 default: 2326 default:
2214 keycode = KEY_UNKNOWN;
2215 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 2327 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
2216 "Unsupported event [0x%x]\n", event)); 2328 "Unsupported event [0x%x]\n", event));
2217 break; 2329 break;
2218 } 2330 }
2219 2331
2220 acpi_notifier_call_chain(device, event, 0); 2332 acpi_notifier_call_chain(device, event, 0);
2221 input_report_key(input, keycode, 1); 2333
2222 input_sync(input); 2334 if (keycode) {
2223 input_report_key(input, keycode, 0); 2335 input_report_key(input, keycode, 1);
2224 input_sync(input); 2336 input_sync(input);
2337 input_report_key(input, keycode, 0);
2338 input_sync(input);
2339 }
2225 2340
2226 return; 2341 return;
2227} 2342}
2228 2343
2229static int instance; 2344static int acpi_video_resume(struct notifier_block *nb,
2230static int acpi_video_resume(struct acpi_device *device) 2345 unsigned long val, void *ign)
2231{ 2346{
2232 struct acpi_video_bus *video; 2347 struct acpi_video_bus *video;
2233 struct acpi_video_device *video_device; 2348 struct acpi_video_device *video_device;
2234 int i; 2349 int i;
2235 2350
2236 if (!device || !acpi_driver_data(device)) 2351 switch (val) {
2237 return -EINVAL; 2352 case PM_HIBERNATION_PREPARE:
2353 case PM_SUSPEND_PREPARE:
2354 case PM_RESTORE_PREPARE:
2355 return NOTIFY_DONE;
2356 }
2238 2357
2239 video = acpi_driver_data(device); 2358 video = container_of(nb, struct acpi_video_bus, pm_nb);
2359
2360 dev_info(&video->device->dev, "Restoring backlight state\n");
2240 2361
2241 for (i = 0; i < video->attached_count; i++) { 2362 for (i = 0; i < video->attached_count; i++) {
2242 video_device = video->attached_array[i].bind_info; 2363 video_device = video->attached_array[i].bind_info;
2243 if (video_device && video_device->backlight) 2364 if (video_device && video_device->backlight)
2244 acpi_video_set_brightness(video_device->backlight); 2365 acpi_video_set_brightness(video_device->backlight);
2245 } 2366 }
2246 return AE_OK; 2367
2368 return NOTIFY_OK;
2247} 2369}
2248 2370
2249static acpi_status 2371static acpi_status
@@ -2267,6 +2389,8 @@ acpi_video_bus_match(acpi_handle handle, u32 level, void *context,
2267 return AE_OK; 2389 return AE_OK;
2268} 2390}
2269 2391
2392static int instance;
2393
2270static int acpi_video_bus_add(struct acpi_device *device) 2394static int acpi_video_bus_add(struct acpi_device *device)
2271{ 2395{
2272 struct acpi_video_bus *video; 2396 struct acpi_video_bus *video;
@@ -2348,7 +2472,6 @@ static int acpi_video_bus_add(struct acpi_device *device)
2348 set_bit(KEY_BRIGHTNESSDOWN, input->keybit); 2472 set_bit(KEY_BRIGHTNESSDOWN, input->keybit);
2349 set_bit(KEY_BRIGHTNESS_ZERO, input->keybit); 2473 set_bit(KEY_BRIGHTNESS_ZERO, input->keybit);
2350 set_bit(KEY_DISPLAY_OFF, input->keybit); 2474 set_bit(KEY_DISPLAY_OFF, input->keybit);
2351 set_bit(KEY_UNKNOWN, input->keybit);
2352 2475
2353 error = input_register_device(input); 2476 error = input_register_device(input);
2354 if (error) 2477 if (error)
@@ -2360,6 +2483,10 @@ static int acpi_video_bus_add(struct acpi_device *device)
2360 video->flags.rom ? "yes" : "no", 2483 video->flags.rom ? "yes" : "no",
2361 video->flags.post ? "yes" : "no"); 2484 video->flags.post ? "yes" : "no");
2362 2485
2486 video->pm_nb.notifier_call = acpi_video_resume;
2487 video->pm_nb.priority = 0;
2488 register_pm_notifier(&video->pm_nb);
2489
2363 return 0; 2490 return 0;
2364 2491
2365 err_free_input_dev: 2492 err_free_input_dev:
@@ -2386,6 +2513,8 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
2386 2513
2387 video = acpi_driver_data(device); 2514 video = acpi_driver_data(device);
2388 2515
2516 unregister_pm_notifier(&video->pm_nb);
2517
2389 acpi_video_bus_stop_devices(video); 2518 acpi_video_bus_stop_devices(video);
2390 acpi_video_bus_put_devices(video); 2519 acpi_video_bus_put_devices(video);
2391 acpi_video_bus_remove_fs(device); 2520 acpi_video_bus_remove_fs(device);
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index fc2f26b9b407..c5fef01b3c95 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -250,7 +250,7 @@ static int __init acpi_backlight(char *str)
250 ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR; 250 ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR;
251 if (!strcmp("video", str)) 251 if (!strcmp("video", str))
252 acpi_video_support |= 252 acpi_video_support |=
253 ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO; 253 ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO;
254 } 254 }
255 return 1; 255 return 1;
256} 256}