aboutsummaryrefslogtreecommitdiff
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/Kconfig3
-rw-r--r--drivers/acpi/Makefile2
-rw-r--r--drivers/acpi/acpica/tbutils.c7
-rw-r--r--drivers/acpi/acpica/uteval.c21
-rw-r--r--drivers/acpi/container.c5
-rw-r--r--drivers/acpi/dock.c14
-rw-r--r--drivers/acpi/ec.c73
-rw-r--r--drivers/acpi/glue.c8
-rw-r--r--drivers/acpi/osl.c54
-rw-r--r--drivers/acpi/pci_link.c2
-rw-r--r--drivers/acpi/processor_idle.c667
-rw-r--r--drivers/acpi/processor_perflib.c105
-rw-r--r--drivers/acpi/sleep.c (renamed from drivers/acpi/main.c)53
-rw-r--r--drivers/acpi/tables.c7
-rw-r--r--drivers/acpi/thermal.c16
-rw-r--r--drivers/acpi/video.c16
16 files changed, 180 insertions, 873 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index d7f9839ba26..a7799a99f2d 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -9,6 +9,7 @@ menuconfig ACPI
depends on PCI
depends on PM
select PNP
+ select CPU_IDLE
default y
---help---
Advanced Configuration and Power Interface (ACPI) support for
@@ -287,7 +288,7 @@ config ACPI_CONTAINER
support physical cpu/memory hot-plug.
If one selects "m", this driver can be loaded with
- "modprobe acpi_container".
+ "modprobe container".
config ACPI_HOTPLUG_MEMORY
tristate "Memory Hotplug"
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index d80f4cc2e0d..65d90c720b5 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -19,7 +19,7 @@ obj-y += osl.o utils.o reboot.o\
# sleep related files
obj-y += wakeup.o
-obj-y += main.o
+obj-y += sleep.o
obj-$(CONFIG_ACPI_SLEEP) += proc.o
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index 9684cc82793..22ce4898572 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -538,10 +538,9 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
if (ACPI_FAILURE(status)) {
ACPI_WARNING((AE_INFO,
"Truncating %u table entries!",
- (unsigned)
- (acpi_gbl_root_table_list.size -
- acpi_gbl_root_table_list.
- count)));
+ (unsigned) (table_count -
+ (acpi_gbl_root_table_list.
+ count - 2))));
break;
}
}
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c
index da9450bc60f..9c9897dbe90 100644
--- a/drivers/acpi/acpica/uteval.c
+++ b/drivers/acpi/acpica/uteval.c
@@ -116,9 +116,9 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
return_ACPI_STATUS(AE_NO_MEMORY);
}
- /* Default return value is SUPPORTED */
+ /* Default return value is 0, NOT-SUPPORTED */
- return_desc->integer.value = ACPI_UINT32_MAX;
+ return_desc->integer.value = 0;
walk_state->return_desc = return_desc;
/* Compare input string to static table of supported interfaces */
@@ -127,10 +127,8 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
if (!ACPI_STRCMP
(string_desc->string.pointer,
acpi_interfaces_supported[i])) {
-
- /* The interface is supported */
-
- return_ACPI_STATUS(AE_OK);
+ return_desc->integer.value = ACPI_UINT32_MAX;
+ goto done;
}
}
@@ -141,15 +139,14 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
*/
status = acpi_os_validate_interface(string_desc->string.pointer);
if (ACPI_SUCCESS(status)) {
-
- /* The interface is supported */
-
- return_ACPI_STATUS(AE_OK);
+ return_desc->integer.value = ACPI_UINT32_MAX;
}
- /* The interface is not supported */
+done:
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, "ACPI: BIOS _OSI(%s) %ssupported\n",
+ string_desc->string.pointer,
+ return_desc->integer.value == 0 ? "not-" : ""));
- return_desc->integer.value = 0;
return_ACPI_STATUS(AE_OK);
}
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 17020c12623..fe0cdf83641 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -163,7 +163,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
case ACPI_NOTIFY_BUS_CHECK:
/* Fall through */
case ACPI_NOTIFY_DEVICE_CHECK:
- printk("Container driver received %s event\n",
+ printk(KERN_WARNING "Container driver received %s event\n",
(type == ACPI_NOTIFY_BUS_CHECK) ?
"ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK");
status = acpi_bus_get_device(handle, &device);
@@ -174,7 +174,8 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
kobject_uevent(&device->dev.kobj,
KOBJ_ONLINE);
else
- printk("Failed to add container\n");
+ printk(KERN_WARNING
+ "Failed to add container\n");
}
} else {
if (ACPI_SUCCESS(status)) {
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 5b30b8d91d7..35094f230b1 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -855,10 +855,14 @@ fdd_out:
static ssize_t show_docked(struct device *dev,
struct device_attribute *attr, char *buf)
{
+ struct acpi_device *tmp;
+
struct dock_station *dock_station = *((struct dock_station **)
dev->platform_data);
- return snprintf(buf, PAGE_SIZE, "%d\n", dock_present(dock_station));
+ if (ACPI_SUCCESS(acpi_bus_get_device(dock_station->handle, &tmp)))
+ return snprintf(buf, PAGE_SIZE, "1\n");
+ return snprintf(buf, PAGE_SIZE, "0\n");
}
static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL);
@@ -984,7 +988,7 @@ static int dock_add(acpi_handle handle)
ret = device_create_file(&dock_device->dev, &dev_attr_docked);
if (ret) {
- printk("Error %d adding sysfs file\n", ret);
+ printk(KERN_ERR "Error %d adding sysfs file\n", ret);
platform_device_unregister(dock_device);
kfree(dock_station);
dock_station = NULL;
@@ -992,7 +996,7 @@ static int dock_add(acpi_handle handle)
}
ret = device_create_file(&dock_device->dev, &dev_attr_undock);
if (ret) {
- printk("Error %d adding sysfs file\n", ret);
+ printk(KERN_ERR "Error %d adding sysfs file\n", ret);
device_remove_file(&dock_device->dev, &dev_attr_docked);
platform_device_unregister(dock_device);
kfree(dock_station);
@@ -1001,7 +1005,7 @@ static int dock_add(acpi_handle handle)
}
ret = device_create_file(&dock_device->dev, &dev_attr_uid);
if (ret) {
- printk("Error %d adding sysfs file\n", ret);
+ printk(KERN_ERR "Error %d adding sysfs file\n", ret);
device_remove_file(&dock_device->dev, &dev_attr_docked);
device_remove_file(&dock_device->dev, &dev_attr_undock);
platform_device_unregister(dock_device);
@@ -1011,7 +1015,7 @@ static int dock_add(acpi_handle handle)
}
ret = device_create_file(&dock_device->dev, &dev_attr_flags);
if (ret) {
- printk("Error %d adding sysfs file\n", ret);
+ printk(KERN_ERR "Error %d adding sysfs file\n", ret);
device_remove_file(&dock_device->dev, &dev_attr_docked);
device_remove_file(&dock_device->dev, &dev_attr_undock);
device_remove_file(&dock_device->dev, &dev_attr_uid);
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 8dfcbb8aff7..5c2f5d343be 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -120,31 +120,6 @@ static struct acpi_ec {
spinlock_t curr_lock;
} *boot_ec, *first_ec;
-/*
- * Some Asus system have exchanged ECDT data/command IO addresses.
- */
-static int print_ecdt_error(const struct dmi_system_id *id)
-{
- printk(KERN_NOTICE PREFIX "%s detected - "
- "ECDT has exchanged control/data I/O address\n",
- id->ident);
- return 0;
-}
-
-static struct dmi_system_id __cpuinitdata ec_dmi_table[] = {
- {
- print_ecdt_error, "Asus L4R", {
- DMI_MATCH(DMI_BIOS_VERSION, "1008.006"),
- DMI_MATCH(DMI_PRODUCT_NAME, "L4R"),
- DMI_MATCH(DMI_BOARD_NAME, "L4R") }, NULL},
- {
- print_ecdt_error, "Asus M6R", {
- DMI_MATCH(DMI_BIOS_VERSION, "0207"),
- DMI_MATCH(DMI_PRODUCT_NAME, "M6R"),
- DMI_MATCH(DMI_BOARD_NAME, "M6R") }, NULL},
- {},
-};
-
/* --------------------------------------------------------------------------
Transaction Management
-------------------------------------------------------------------------- */
@@ -983,8 +958,8 @@ static const struct acpi_device_id ec_device_ids[] = {
int __init acpi_ec_ecdt_probe(void)
{
acpi_status status;
+ struct acpi_ec *saved_ec = NULL;
struct acpi_table_ecdt *ecdt_ptr;
- acpi_handle dummy;
boot_ec = make_acpi_ec();
if (!boot_ec)
@@ -998,21 +973,16 @@ int __init acpi_ec_ecdt_probe(void)
pr_info(PREFIX "EC description table is found, configuring boot EC\n");
boot_ec->command_addr = ecdt_ptr->control.address;
boot_ec->data_addr = ecdt_ptr->data.address;
- if (dmi_check_system(ec_dmi_table)) {
- /*
- * If the board falls into ec_dmi_table, it means
- * that ECDT table gives the incorrect command/status
- * & data I/O address. Just fix it.
- */
- boot_ec->data_addr = ecdt_ptr->control.address;
- boot_ec->command_addr = ecdt_ptr->data.address;
- }
boot_ec->gpe = ecdt_ptr->gpe;
boot_ec->handle = ACPI_ROOT_OBJECT;
acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle);
- /* Add some basic check against completely broken table */
- if (boot_ec->data_addr != boot_ec->command_addr)
+ /* Don't trust ECDT, which comes from ASUSTek */
+ if (!dmi_name_in_vendors("ASUS"))
goto install;
+ saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
+ if (!saved_ec)
+ return -ENOMEM;
+ memcpy(saved_ec, boot_ec, sizeof(*saved_ec));
/* fall through */
}
/* This workaround is needed only on some broken machines,
@@ -1023,12 +993,29 @@ int __init acpi_ec_ecdt_probe(void)
/* Check that acpi_get_devices actually find something */
if (ACPI_FAILURE(status) || !boot_ec->handle)
goto error;
- /* We really need to limit this workaround, the only ASUS,
- * which needs it, has fake EC._INI method, so use it as flag.
- * Keep boot_ec struct as it will be needed soon.
- */
- if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &dummy)))
- return -ENODEV;
+ if (saved_ec) {
+ /* try to find good ECDT from ASUSTek */
+ if (saved_ec->command_addr != boot_ec->command_addr ||
+ saved_ec->data_addr != boot_ec->data_addr ||
+ saved_ec->gpe != boot_ec->gpe ||
+ saved_ec->handle != boot_ec->handle)
+ pr_info(PREFIX "ASUSTek keeps feeding us with broken "
+ "ECDT tables, which are very hard to workaround. "
+ "Trying to use DSDT EC info instead. Please send "
+ "output of acpidump to linux-acpi@vger.kernel.org\n");
+ kfree(saved_ec);
+ saved_ec = NULL;
+ } else {
+ /* We really need to limit this workaround, the only ASUS,
+ * which needs it, has fake EC._INI method, so use it as flag.
+ * Keep boot_ec struct as it will be needed soon.
+ */
+ acpi_handle dummy;
+ if (!dmi_name_in_vendors("ASUS") ||
+ ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI",
+ &dummy)))
+ return -ENODEV;
+ }
install:
if (!ec_install_handlers(boot_ec)) {
first_ec = boot_ec;
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index adec3d15810..5479b9f4251 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -255,12 +255,12 @@ static int acpi_platform_notify(struct device *dev)
}
type = acpi_get_bus_type(dev->bus);
if (!type) {
- DBG("No ACPI bus support for %s\n", dev->bus_id);
+ DBG("No ACPI bus support for %s\n", dev_name(dev));
ret = -EINVAL;
goto end;
}
if ((ret = type->find_device(dev, &handle)) != 0)
- DBG("Can't get handler for %s\n", dev->bus_id);
+ DBG("Can't get handler for %s\n", dev_name(dev));
end:
if (!ret)
acpi_bind_one(dev, handle);
@@ -271,10 +271,10 @@ static int acpi_platform_notify(struct device *dev)
acpi_get_name(dev->archdata.acpi_handle,
ACPI_FULL_PATHNAME, &buffer);
- DBG("Device %s -> %s\n", dev->bus_id, (char *)buffer.pointer);
+ DBG("Device %s -> %s\n", dev_name(dev), (char *)buffer.pointer);
kfree(buffer.pointer);
} else
- DBG("Device %s -> No ACPI support\n", dev->bus_id);
+ DBG("Device %s -> No ACPI support\n", dev_name(dev));
#endif
return ret;
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 6729a4992f2..b3193ec0a2e 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -228,10 +228,10 @@ void acpi_os_vprintf(const char *fmt, va_list args)
if (acpi_in_debugger) {
kdb_printf("%s", buffer);
} else {
- printk("%s", buffer);
+ printk(KERN_CONT "%s", buffer);
}
#else
- printk("%s", buffer);
+ printk(KERN_CONT "%s", buffer);
#endif
}
@@ -1317,6 +1317,54 @@ acpi_os_validate_interface (char *interface)
return AE_SUPPORT;
}
+#ifdef CONFIG_X86
+
+struct aml_port_desc {
+ uint start;
+ uint end;
+ char* name;
+ char warned;
+};
+
+static struct aml_port_desc aml_invalid_port_list[] = {
+ {0x20, 0x21, "PIC0", 0},
+ {0xA0, 0xA1, "PIC1", 0},
+ {0x4D0, 0x4D1, "ELCR", 0}
+};
+
+/*
+ * valid_aml_io_address()
+ *
+ * if valid, return true
+ * else invalid, warn once, return false
+ */
+static bool valid_aml_io_address(uint address, uint length)
+{
+ int i;
+ int entries = sizeof(aml_invalid_port_list) / sizeof(struct aml_port_desc);
+
+ for (i = 0; i < entries; ++i) {
+ if ((address >= aml_invalid_port_list[i].start &&
+ address <= aml_invalid_port_list[i].end) ||
+ (address + length >= aml_invalid_port_list[i].start &&
+ address + length <= aml_invalid_port_list[i].end))
+ {
+ if (!aml_invalid_port_list[i].warned)
+ {
+ printk(KERN_ERR "ACPI: Denied BIOS AML access"
+ " to invalid port 0x%x+0x%x (%s)\n",
+ address, length,
+ aml_invalid_port_list[i].name);
+ aml_invalid_port_list[i].warned = 1;
+ }
+ return false; /* invalid */
+ }
+ }
+ return true; /* valid */
+}
+#else
+static inline bool valid_aml_io_address(uint address, uint length) { return true; }
+#endif
/******************************************************************************
*
* FUNCTION: acpi_os_validate_address
@@ -1346,6 +1394,8 @@ acpi_os_validate_address (
switch (space_id) {
case ACPI_ADR_SPACE_SYSTEM_IO:
+ if (!valid_aml_io_address(address, length))
+ return AE_AML_ILLEGAL_ADDRESS;
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
/* Only interference checks against SystemIO and SytemMemory
are needed */
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 1c6e73c7865..6c772ca76bd 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -593,7 +593,7 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
return -ENODEV;
} else {
acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING;
- printk(PREFIX "%s [%s] enabled at IRQ %d\n",
+ printk(KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d\n",
acpi_device_name(link->device),
acpi_device_bid(link->device), link->irq.active);
}
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 66a9d814556..7bc22a471fe 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -66,43 +66,17 @@ ACPI_MODULE_NAME("processor_idle");
#define ACPI_PROCESSOR_FILE_POWER "power"
#define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
#define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY)
-#ifndef CONFIG_CPU_IDLE
-#define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */
-#define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */
-static void (*pm_idle_save) (void) __read_mostly;
-#else
#define C2_OVERHEAD 1 /* 1us */
#define C3_OVERHEAD 1 /* 1us */
-#endif
#define PM_TIMER_TICKS_TO_US(p) (((p) * 1000)/(PM_TIMER_FREQUENCY/1000))
static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER;
-#ifdef CONFIG_CPU_IDLE
module_param(max_cstate, uint, 0000);
-#else
-module_param(max_cstate, uint, 0644);
-#endif
static unsigned int nocst __read_mostly;
module_param(nocst, uint, 0000);
-#ifndef CONFIG_CPU_IDLE
-/*
- * bm_history -- bit-mask with a bit per jiffy of bus-master activity
- * 1000 HZ: 0xFFFFFFFF: 32 jiffies = 32ms
- * 800 HZ: 0xFFFFFFFF: 32 jiffies = 40ms
- * 100 HZ: 0x0000000F: 4 jiffies = 40ms
- * reduce history for more aggressive entry into C3
- */
-static unsigned int bm_history __read_mostly =
- (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1));
-module_param(bm_history, uint, 0644);
-
-static int acpi_processor_set_power_policy(struct acpi_processor *pr);
-
-#else /* CONFIG_CPU_IDLE */
static unsigned int latency_factor __read_mostly = 2;
module_param(latency_factor, uint, 0644);
-#endif
/*
* IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
@@ -224,71 +198,6 @@ static void acpi_safe_halt(void)
current_thread_info()->status |= TS_POLLING;
}
-#ifndef CONFIG_CPU_IDLE
-
-static void
-acpi_processor_power_activate(struct acpi_processor *pr,
- struct acpi_processor_cx *new)
-{
- struct acpi_processor_cx *old;
-
- if (!pr || !new)
- return;
-
- old = pr->power.state;
-
- if (old)
- old->promotion.count = 0;
- new->demotion.count = 0;
-
- /* Cleanup from old state. */
- if (old) {
- switch (old->type) {
- case ACPI_STATE_C3:
- /* Disable bus master reload */
- if (new->type != ACPI_STATE_C3 && pr->flags.bm_check)
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
- break;
- }
- }
-
- /* Prepare to use new state. */
- switch (new->type) {
- case ACPI_STATE_C3:
- /* Enable bus master reload */
- if (old->type != ACPI_STATE_C3 && pr->flags.bm_check)
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
- break;
- }
-
- pr->power.state = new;
-
- return;
-}
-
-static atomic_t c3_cpu_count;
-
-/* Common C-state entry for C2, C3, .. */
-static void acpi_cstate_enter(struct acpi_processor_cx *cstate)
-{
- /* Don't trace irqs off for idle */
- stop_critical_timings();
- if (cstate->entry_method == ACPI_CSTATE_FFH) {
- /* Call into architectural FFH based C-state */
- acpi_processor_ffh_cstate_enter(cstate);
- } else {
- int unused;
- /* IO port based C-state */
- inb(cstate->address);
- /* Dummy wait op - must do something useless after P_LVL2 read
- because chipsets cannot guarantee that STPCLK# signal
- gets asserted in time to freeze execution properly. */
- unused = inl(acpi_gbl_FADT.xpm_timer_block.address);
- }
- start_critical_timings();
-}
-#endif /* !CONFIG_CPU_IDLE */
-
#ifdef ARCH_APICTIMER_STOPS_ON_C3
/*
@@ -390,421 +299,6 @@ static int tsc_halts_in_c(int state)
}
#endif
-#ifndef CONFIG_CPU_IDLE
-static void acpi_processor_idle(void)
-{
- struct acpi_processor *pr = NULL;
- struct acpi_processor_cx *cx = NULL;
- struct acpi_processor_cx *next_state = NULL;
- int sleep_ticks = 0;
- u32 t1, t2 = 0;
-
- /*
- * Interrupts must be disabled during bus mastering calculations and
- * for C2/C3 transitions.
- */
- local_irq_disable();
-
- pr = __get_cpu_var(processors);
- if (!pr) {
- local_irq_enable();
- return;
- }
-
- /*
- * Check whether we truly need to go idle, or should
- * reschedule:
- */
- if (unlikely(need_resched())) {
- local_irq_enable();
- return;
- }
-
- cx = pr->power.state;
- if (!cx || acpi_idle_suspend) {
- if (pm_idle_save) {
- pm_idle_save(); /* enables IRQs */
- } else {
- acpi_safe_halt();
- local_irq_enable();
- }
-
- return;
- }
-
- /*
- * Check BM Activity
- * -----------------
- * Check for bus mastering activity (if required), record, and check
- * for demotion.
- */
- if (pr->flags.bm_check) {
- u32 bm_status = 0;
- unsigned long diff = jiffies - pr->power.bm_check_timestamp;
-
- if (diff > 31)
- diff = 31;
-
- pr->power.bm_activity <<= diff;
-
- acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
- if (bm_status) {
- pr->power.bm_activity |= 0x1;
- acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
- }
- /*
- * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
- * the true state of bus mastering activity; forcing us to
- * manually check the BMIDEA bit of each IDE channel.
- */
- else if (errata.piix4.bmisx) {
- if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01)
- || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01))
- pr->power.bm_activity |= 0x1;
- }
-
- pr->power.bm_check_timestamp = jiffies;
-
- /*
- * If bus mastering is or was active this jiffy, demote
- * to avoid a faulty transition. Note that the processor
- * won't enter a low-power state during this call (to this
- * function) but should upon the next.
- *
- * TBD: A better policy might be to fallback to the demotion
- * state (use it for this quantum only) istead of
- * demoting -- and rely on duration as our sole demotion
- * qualification. This may, however, introduce DMA
- * issues (e.g. floppy DMA transfer overrun/underrun).
- */
- if ((pr->power.bm_activity & 0x1) &&
- cx->demotion.threshold.bm) {
- local_irq_enable();
- next_state = cx->demotion.state;
- goto end;
- }
- }
-
-#ifdef CONFIG_HOTPLUG_CPU
- /*
- * Check for P_LVL2_UP flag before entering C2 and above on
- * an SMP system. We do it here instead of doing it at _CST/P_LVL
- * detection phase, to work cleanly with logical CPU hotplug.
- */
- if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
- !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
- cx = &pr->power.states[ACPI_STATE_C1];
-#endif
-
- /*
- * Sleep:
- * ------
- * Invoke the current Cx state to put the processor to sleep.
- */
- if (cx->type == ACPI_STATE_C2 || cx->type == ACPI_STATE_C3) {
- current_thread_info()->status &= ~TS_POLLING;
- /*
- * TS_POLLING-cleared state must be visible before we
- * test NEED_RESCHED:
- */
- smp_mb();
- if (need_resched()) {
- current_thread_info()->status |= TS_POLLING;
- local_irq_enable();
- return;
- }
- }
-
- switch (cx->type) {
-
- case ACPI_STATE_C1:
- /*
- * Invoke C1.
- * Use the appropriate idle routine, the one that would
- * be used without acpi C-states.
- */
- if (pm_idle_save) {
- pm_idle_save(); /* enables IRQs */
- } else {
- acpi_safe_halt();
- local_irq_enable();
- }
-
- /*
- * TBD: Can't get time duration while in C1, as resumes
- * go to an ISR rather than here. Need to instrument
- * base interrupt handler.
- *
- * Note: the TSC better not stop in C1, sched_clock() will
- * skew otherwise.
- */
- sleep_ticks = 0xFFFFFFFF;
-
- break;
-
- case ACPI_STATE_C2:
- /* Get start time (ticks) */
- t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
- /* Tell the scheduler that we are going deep-idle: */
- sched_clock_idle_sleep_event();
- /* Invoke C2 */
- acpi_state_timer_broadcast(pr, cx, 1);
- acpi_cstate_enter(cx);
- /* Get end time (ticks) */
- t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
-
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
- /* TSC halts in C2, so notify users */
- if (tsc_halts_in_c(ACPI_STATE_C2))
- mark_tsc_unstable("possible TSC halt in C2");
-#endif
- /* Compute time (ticks) that we were actually asleep */
- sleep_ticks = ticks_elapsed(t1, t2);
-
- /* Tell the scheduler how much we idled: */
- sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
-
- /* Re-enable interrupts */
- local_irq_enable();
- /* Do not account our idle-switching overhead: */
- sleep_ticks -= cx->latency_ticks + C2_OVERHEAD;
-
- current_thread_info()->status |= TS_POLLING;
- acpi_state_timer_broadcast(pr, cx, 0);
- break;
-
- case ACPI_STATE_C3:
- acpi_unlazy_tlb(smp_processor_id());
- /*
- * Must be done before busmaster disable as we might
- * need to access HPET !
- */
- acpi_state_timer_broadcast(pr, cx, 1);
- /*
- * disable bus master
- * bm_check implies we need ARB_DIS
- * !bm_check implies we need cache flush
- * bm_control implies whether we can do ARB_DIS
- *
- * That leaves a case where bm_check is set and bm_control is
- * not set. In that case we cannot do much, we enter C3
- * without doing anything.
- */
- if (pr->flags.bm_check && pr->flags.bm_control) {
- if (atomic_inc_return(&c3_cpu_count) ==
- num_online_cpus()) {
- /*
- * All CPUs are trying to go to C3
- * Disable bus master arbitration
- */
- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
- }
- } else if (!pr->flags.bm_check) {
- /* SMP with no shared cache... Invalidate cache */
- ACPI_FLUSH_CPU_CACHE();
- }
-
- /* Get start time (ticks) */
- t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
- /* Invoke C3 */
- /* Tell the scheduler that we are going deep-idle: */
- sched_clock_idle_sleep_event();
- acpi_cstate_enter(cx);
- /* Get end time (ticks) */
- t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
- if (pr->flags.bm_check && pr->flags.bm_control) {
- /* Enable bus master arbitration */
- atomic_dec(&c3_cpu_count);
- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
- }
-
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
- /* TSC halts in C3, so notify users */
- if (tsc_halts_in_c(ACPI_STATE_C3))
- mark_tsc_unstable("TSC halts in C3");
-#endif
- /* Compute time (ticks) that we were actually asleep */
- sleep_ticks = ticks_elapsed(t1, t2);
- /* Tell the scheduler how much we idled: */
- sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
-
- /* Re-enable interrupts */
- local_irq_enable();
- /* Do not account our idle-switching overhead: */
- sleep_ticks -= cx->latency_ticks + C3_OVERHEAD;
-
- current_thread_info()->status |= TS_POLLING;
- acpi_state_timer_broadcast(pr, cx, 0);
- break;
-
- default:
- local_irq_enable();
- return;
- }
- cx->usage++;
- if ((cx->type != ACPI_STATE_C1) && (sleep_ticks > 0))
- cx->time += sleep_ticks;
-
- next_state = pr->power.state;
-
-#ifdef CONFIG_HOTPLUG_CPU
- /* Don't do promotion/demotion */
- if ((cx->type == ACPI_STATE_C1) && (num_online_cpus() > 1) &&
- !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) {
- next_state = cx;
- goto end;
- }
-#endif
-
- /*
- * Promotion?
- * ----------
- * Track the number of longs (time asleep is greater than threshold)
- * and promote when the count threshold is reached. Note that bus
- * mastering activity may prevent promotions.
- * Do not promote above max_cstate.
- */
- if (cx->promotion.state &&
- ((cx->promotion.state - pr->power.states) <= max_cstate)) {
- if (sleep_ticks > cx->promotion.threshold.ticks &&
- cx->promotion.state->latency <=
- pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)) {
- cx->promotion.count++;
- cx->demotion.count = 0;
- if (cx->promotion.count >=
- cx->promotion.threshold.count) {
- if (pr->flags.bm_check) {
- if (!
- (pr->power.bm_activity & cx->
- promotion.threshold.bm)) {
- next_state =
- cx->promotion.state;
- goto end;
- }
- } else {
- next_state = cx->promotion.state;
- goto end;
- }
- }
- }
- }
-
- /*
- * Demotion?
- * ---------
- * Track the number of shorts (time asleep is less than time threshold)
- * and demote when the usage threshold is reached.
- */
- if (cx->demotion.state) {
- if (sleep_ticks < cx->demotion.threshold.ticks) {
- cx->demotion.count++;
- cx->promotion.count = 0;
- if (cx->demotion.count >= cx->demotion.threshold.count) {
- next_state = cx->demotion.state;
- goto end;
- }
- }
- }
-
- end:
- /*
- * Demote if current state exceeds max_cstate
- * or if the latency of the current state is unacceptable
- */
- if ((pr->power.state - pr->power.states) > max_cstate ||
- pr->power.state->latency >
- pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)) {
- if (cx->demotion.state)
- next_state = cx->demotion.state;
- }
-
- /*
- * New Cx State?
- * -------------
- * If we're going to start using a new Cx state we must clean up
- * from the previous and prepare to use the new.
- */
- if (next_state != pr->power.state)
- acpi_processor_power_activate(pr, next_state);
-}
-
-static int acpi_processor_set_power_policy(struct acpi_processor *pr)
-{
- unsigned int i;
- unsigned int state_is_set = 0;
- struct acpi_processor_cx *lower = NULL;
- struct acpi_processor_cx *higher = NULL;
- struct acpi_processor_cx *cx;
-
-
- if (!pr)
- return -EINVAL;
-
- /*
- * This function sets the default Cx state policy (OS idle handler).
- * Our scheme is to promote quickly to C2 but more conservatively
- * to C3. We're favoring C2 for its characteristics of low latency
- * (quick response), good power savings, and ability to allow bus
- * mastering activity. Note that the Cx state policy is completely
- * customizable and can be altered dynamically.
- */
-
- /* startup state */
- for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
- cx = &pr->power.states[i];
- if (!cx->valid)
- continue;
-
- if (!state_is_set)
- pr->power.state = cx;
- state_is_set++;
- break;
- }
-
- if (!state_is_set)
- return -ENODEV;
-
- /* demotion */
- for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
- cx = &pr->power.states[i];
- if (!cx->valid)
- continue;
-
- if (lower) {
- cx->demotion.state = lower;
- cx->demotion.threshold.ticks = cx->latency_ticks;
- cx->demotion.threshold.count = 1;
- if (cx->type == ACPI_STATE_C3)
- cx->demotion.threshold.bm = bm_history;
- }
-
- lower = cx;
- }
-
- /* promotion */
- for (i = (ACPI_PROCESSOR_MAX_POWER - 1); i > 0; i--) {
- cx = &pr->power.states[i];
- if (!cx->valid)
- continue;
-
- if (higher) {
- cx->promotion.state = higher;
- cx->promotion.threshold.ticks = cx->latency_ticks;
- if (cx->type >= ACPI_STATE_C2)
- cx->promotion.threshold.count = 4;
- else
- cx->promotion.threshold.count = 10;
- if (higher->type == ACPI_STATE_C3)
- cx->promotion.threshold.bm = bm_history;
- }
-
- higher = cx;
- }
-
- return 0;
-}
-#endif /* !CONFIG_CPU_IDLE */
-
static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
{
@@ -1047,11 +541,7 @@ static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx)
*/
cx->valid = 1;
-#ifndef CONFIG_CPU_IDLE
- cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
-#else
cx->latency_ticks = cx->latency;
-#endif
return;
}
@@ -1121,7 +611,6 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
" for C3 to be enabled on SMP systems\n"));
return;
}
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
}
/*
@@ -1132,11 +621,16 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
*/
cx->valid = 1;
-#ifndef CONFIG_CPU_IDLE
- cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
-#else
cx->latency_ticks = cx->latency;
-#endif
+ /*
+ * On older chipsets, BM_RLD needs to be set
+ * in order for Bus Master activity to wake the
+ * system from C3. Newer chipsets handle DMA
+ * during C3 automatically and BM_RLD is a NOP.
+ * In either case, the proper way to
+ * handle BM_RLD is to set it and leave it set.
+ */
+ acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
return;
}
@@ -1201,20 +695,6 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
pr->power.count = acpi_processor_power_verify(pr);
-#ifndef CONFIG_CPU_IDLE
- /*
- * Set Default Policy
- * ------------------
- * Now that we know which states are supported, set the default
- * policy. Note that this policy can be changed dynamically
- * (e.g. encourage deeper sleeps to conserve battery life when
- * not on AC).
- */
- result = acpi_processor_set_power_policy(pr);
- if (result)
- return result;
-#endif
-
/*
* if one state of type C2 or C3 is available, mark this
* CPU as being "idle manageable"
@@ -1312,69 +792,6 @@ static const struct file_operations acpi_processor_power_fops = {
.release = single_release,
};
-#ifndef CONFIG_CPU_IDLE
-
-int acpi_processor_cst_has_changed(struct acpi_processor *pr)
-{
- int result = 0;
-
- if (boot_option_idle_override)
- return 0;
-
- if (!pr)
- return -EINVAL;
-
- if (nocst) {
- return -ENODEV;
- }
-
- if (!pr->flags.power_setup_done)
- return -ENODEV;
-
- /*
- * Fall back to the default idle loop, when pm_idle_save had
- * been initialized.
- */
- if (pm_idle_save) {
- pm_idle = pm_idle_save;
- /* Relies on interrupts forcing exit from idle. */
- synchronize_sched();
- }
-
- pr->flags.power = 0;
- result = acpi_processor_get_power_info(pr);
- if ((pr->flags.power == 1) && (pr->flags.power_setup_done))
- pm_idle = acpi_processor_idle;
-
- return result;
-}
-
-#ifdef CONFIG_SMP
-static void smp_callback(void *v)
-{
- /* we already woke the CPU up, nothing more to do */
-}
-
-/*
- * This function gets called when a part of the kernel has a new latency
- * requirement. This means we need to get all processors out of their C-state,
- * and then recalculate a new suitable C-state. Just do a cross-cpu IPI; that
- * wakes them all right up.
- */
-static int acpi_processor_latency_notify(struct notifier_block *b,
- unsigned long l, void *v)
-{
- smp_call_function(smp_callback, NULL, 1);
- return NOTIFY_OK;
-}
-
-static struct notifier_block acpi_processor_latency_notifier = {
- .notifier_call = acpi_processor_latency_notify,
-};
-
-#endif
-
-#else /* CONFIG_CPU_IDLE */
/**
* acpi_idle_bm_check - checks if bus master activity was detected
@@ -1383,7 +800,7 @@ static int acpi_idle_bm_check(void)
{
u32 bm_status = 0;
- acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
+ acpi_get_register_unlocked(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
if (bm_status)
acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
/*
@@ -1400,25 +817,6 @@ static int acpi_idle_bm_check(void)
}
/**
- * acpi_idle_update_bm_rld - updates the BM_RLD bit depending on target state
- * @pr: the processor
- * @target: the new target state
- */
-static inline void acpi_idle_update_bm_rld(struct acpi_processor *pr,
- struct acpi_processor_cx *target)
-{
- if (pr->flags.bm_rld_set && target->type != ACPI_STATE_C3) {
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
- pr->flags.bm_rld_set = 0;
- }
-
- if (!pr->flags.bm_rld_set && target->type == ACPI_STATE_C3) {
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
- pr->flags.bm_rld_set = 1;
- }
-}
-
-/**
* acpi_idle_do_entry - a helper function that does C2 and C3 type entry
* @cx: cstate data
*
@@ -1473,9 +871,6 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
return 0;
}
- if (pr->flags.bm_check)
- acpi_idle_update_bm_rld(pr, cx);
-
t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
acpi_idle_do_entry(cx);
t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
@@ -1527,9 +922,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
*/
acpi_state_timer_broadcast(pr, cx, 1);
- if (pr->flags.bm_check)
- acpi_idle_update_bm_rld(pr, cx);
-
if (cx->type == ACPI_STATE_C3)
ACPI_FLUSH_CPU_CACHE();
@@ -1621,8 +1013,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
*/
acpi_state_timer_broadcast(pr, cx, 1);
- acpi_idle_update_bm_rld(pr, cx);
-
/*
* disable bus master
* bm_check implies we need ARB_DIS
@@ -1795,8 +1185,6 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
return ret;
}
-#endif /* CONFIG_CPU_IDLE */
-
int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
struct acpi_device *device)
{
@@ -1825,10 +1213,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
"ACPI: processor limited to max C-state %d\n",
max_cstate);
first_run++;
-#if !defined(CONFIG_CPU_IDLE) && defined(CONFIG_SMP)
- pm_qos_add_notifier(PM_QOS_CPU_DMA_LATENCY,
- &acpi_processor_latency_notifier);
-#endif
}
if (!pr)
@@ -1852,11 +1236,9 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
* platforms that only support C1.
*/
if (pr->flags.power) {
-#ifdef CONFIG_CPU_IDLE
acpi_processor_setup_cpuidle(pr);
if (cpuidle_register_device(&pr->power.dev))
return -EIO;
-#endif
printk(KERN_INFO PREFIX "CPU%d (power states:", pr->id);
for (i = 1; i <= pr->power.count; i++)
@@ -1864,13 +1246,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
printk(" C%d[C%d]", i,
pr->power.states[i].type);
printk(")\n");
-
-#ifndef CONFIG_CPU_IDLE
- if (pr->id == 0) {
- pm_idle_save = pm_idle;
- pm_idle = acpi_processor_idle;
- }
-#endif
}
/* 'power' [R] */
@@ -1889,34 +1264,12 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
if (boot_option_idle_override)
return 0;
-#ifdef CONFIG_CPU_IDLE
cpuidle_unregister_device(&pr->power.dev);
-#endif
pr->flags.power_setup_done = 0;
if (acpi_device_dir(device))
remove_proc_entry(ACPI_PROCESSOR_FILE_POWER,
acpi_device_dir(device));
-#ifndef CONFIG_CPU_IDLE
-
- /* Unregister the idle handler when processor #0 is removed. */
- if (pr->id == 0) {
- if (pm_idle_save)
- pm_idle = pm_idle_save;
-
- /*
- * We are about to unload the current idle thread pm callback
- * (pm_idle), Wait for all processors to update cached/local
- * copies of pm_idle before proceeding.
- */
- cpu_idle_wait();
-#ifdef CONFIG_SMP
- pm_qos_remove_notifier(PM_QOS_CPU_DMA_LATENCY,
- &acpi_processor_latency_notifier);
-#endif
- }
-#endif
-
return 0;
}
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 846e227592d..9cc769b587f 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -31,14 +31,6 @@
#include <linux/init.h>
#include <linux/cpufreq.h>
-#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/mutex.h>
-
-#include <asm/uaccess.h>
-#endif
-
#ifdef CONFIG_X86
#include <asm/cpufeature.h>
#endif
@@ -434,96 +426,6 @@ int acpi_processor_notify_smm(struct module *calling_module)
EXPORT_SYMBOL(acpi_processor_notify_smm);
-#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
-/* /proc/acpi/processor/../performance interface (DEPRECATED) */
-
-static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_processor_perf_fops = {
- .owner = THIS_MODULE,
- .open = acpi_processor_perf_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset)
-{
- struct acpi_processor *pr = seq->private;
- int i;
-
-
- if (!pr)
- goto end;
-
- if (!pr->performance) {
- seq_puts(seq, "<not supported>\n");
- goto end;
- }
-
- seq_printf(seq, "state count: %d\n"
- "active state: P%d\n",
- pr->performance->state_count, pr->performance->state);
-
- seq_puts(seq, "states:\n");
- for (i = 0; i < pr->performance->state_count; i++)
- seq_printf(seq,
- " %cP%d: %d MHz, %d mW, %d uS\n",
- (i == pr->performance->state ? '*' : ' '), i,
- (u32) pr->performance->states[i].core_frequency,
- (u32) pr->performance->states[i].power,
- (u32) pr->performance->states[i].transition_latency);
-
- end:
- return 0;
-}
-
-static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file)
-{
- return single_open(file, acpi_processor_perf_seq_show,
- PDE(inode)->data);
-}
-
-static void acpi_cpufreq_add_file(struct acpi_processor *pr)
-{
- struct acpi_device *device = NULL;
-
-
- if (acpi_bus_get_device(pr->handle, &device))
- return;
-
- /* add file 'performance' [R/W] */
- proc_create_data(ACPI_PROCESSOR_FILE_PERFORMANCE, S_IFREG | S_IRUGO,
- acpi_device_dir(device),
- &acpi_processor_perf_fops, acpi_driver_data(device));
- return;
-}
-
-static void acpi_cpufreq_remove_file(struct acpi_processor *pr)
-{
- struct acpi_device *device = NULL;
-
-
- if (acpi_bus_get_device(pr->handle, &device))
- return;
-
- /* remove file 'performance' */
- remove_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
- acpi_device_dir(device));
-
- return;
-}
-
-#else
-static void acpi_cpufreq_add_file(struct acpi_processor *pr)
-{
- return;
-}
-static void acpi_cpufreq_remove_file(struct acpi_processor *pr)
-{
- return;
-}
-#endif /* CONFIG_X86_ACPI_CPUFREQ_PROC_INTF */
-
static int acpi_processor_get_psd(struct acpi_processor *pr)
{
int result = 0;
@@ -747,14 +649,12 @@ err_ret:
}
EXPORT_SYMBOL(acpi_processor_preregister_performance);
-
int
acpi_processor_register_performance(struct acpi_processor_performance
*performance, unsigned int cpu)
{
struct acpi_processor *pr;
-
if (!(acpi_processor_ppc_status & PPC_REGISTERED))
return -EINVAL;
@@ -781,8 +681,6 @@ acpi_processor_register_performance(struct acpi_processor_performance
return -EIO;
}
- acpi_cpufreq_add_file(pr);
-
mutex_unlock(&performance_mutex);
return 0;
}
@@ -795,7 +693,6 @@ acpi_processor_unregister_performance(struct acpi_processor_performance
{
struct acpi_processor *pr;
-
mutex_lock(&performance_mutex);
pr = per_cpu(processors, cpu);
@@ -808,8 +705,6 @@ acpi_processor_unregister_performance(struct acpi_processor_performance
kfree(pr->performance->states);
pr->performance = NULL;
- acpi_cpufreq_remove_file(pr);
-
mutex_unlock(&performance_mutex);
return;
diff --git a/drivers/acpi/main.c b/drivers/acpi/sleep.c
index 7e3c609cbef..519266654f0 100644
--- a/drivers/acpi/main.c
+++ b/drivers/acpi/sleep.c
@@ -90,31 +90,6 @@ void __init acpi_old_suspend_ordering(void)
old_suspend_ordering = true;
}
-/*
- * According to the ACPI specification the BIOS should make sure that ACPI is
- * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still,
- * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI
- * on such systems during resume. Unfortunately that doesn't help in
- * particularly pathological cases in which SCI_EN has to be set directly on
- * resume, although the specification states very clearly that this flag is
- * owned by the hardware. The set_sci_en_on_resume variable will be set in such
- * cases.
- */
-static bool set_sci_en_on_resume;
-/*
- * The ACPI specification wants us to save NVS memory regions during hibernation
- * and to restore them during the subsequent resume. However, it is not certain
- * if this mechanism is going to work on all machines, so we allow the user to
- * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line
- * option.
- */
-static bool s4_no_nvs;
-
-void __init acpi_s4_no_nvs(void)
-{
- s4_no_nvs = true;
-}
-
/**
* acpi_pm_disable_gpes - Disable the GPEs.
*/
@@ -193,6 +168,18 @@ static void acpi_pm_end(void)
#endif /* CONFIG_ACPI_SLEEP */
#ifdef CONFIG_SUSPEND
+/*
+ * According to the ACPI specification the BIOS should make sure that ACPI is
+ * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still,
+ * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI
+ * on such systems during resume. Unfortunately that doesn't help in
+ * particularly pathological cases in which SCI_EN has to be set directly on
+ * resume, although the specification states very clearly that this flag is
+ * owned by the hardware. The set_sci_en_on_resume variable will be set in such
+ * cases.
+ */
+static bool set_sci_en_on_resume;
+
extern void do_suspend_lowlevel(void);
static u32 acpi_suspend_states[] = {
@@ -396,6 +383,20 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
#endif /* CONFIG_SUSPEND */
#ifdef CONFIG_HIBERNATION
+/*
+ * The ACPI specification wants us to save NVS memory regions during hibernation
+ * and to restore them during the subsequent resume. However, it is not certain
+ * if this mechanism is going to work on all machines, so we allow the user to
+ * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line
+ * option.
+ */
+static bool s4_no_nvs;
+
+void __init acpi_s4_no_nvs(void)
+{
+ s4_no_nvs = true;
+}
+
static unsigned long s4_hardware_signature;
static struct acpi_table_facs *facs;
static bool nosigcheck;
@@ -679,7 +680,7 @@ static void acpi_power_off_prepare(void)
static void acpi_power_off(void)
{
/* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
- printk("%s called\n", __func__);
+ printk(KERN_DEBUG "%s called\n", __func__);
local_irq_disable();
acpi_enable_wakeup_device(ACPI_STATE_S5);
acpi_enter_sleep_state(ACPI_STATE_S5);
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 775c97a282b..a8852952fac 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -293,7 +293,12 @@ static void __init check_multiple_madt(void)
int __init acpi_table_init(void)
{
- acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
+ acpi_status status;
+
+ status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
+ if (ACPI_FAILURE(status))
+ return 1;
+
check_multiple_madt();
return 0;
}
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 073ff09218a..99e6f1f8ea4 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -416,7 +416,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
}
/* Passive (optional) */
- if (flag & ACPI_TRIPS_PASSIVE) {
+ if (((flag & ACPI_TRIPS_PASSIVE) && tz->trips.passive.flags.valid) ||
+ (flag == ACPI_TRIPS_INIT)) {
valid = tz->trips.passive.flags.valid;
if (psv == -1) {
status = AE_SUPPORT;
@@ -462,8 +463,11 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
memset(&devices, 0, sizeof(struct acpi_handle_list));
status = acpi_evaluate_reference(tz->device->handle, "_PSL",
NULL, &devices);
- if (ACPI_FAILURE(status))
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_WARNING PREFIX
+ "Invalid passive threshold\n");
tz->trips.passive.flags.valid = 0;
+ }
else
tz->trips.passive.flags.valid = 1;
@@ -487,7 +491,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
if (act == -1)
break; /* disable all active trip points */
- if (flag & ACPI_TRIPS_ACTIVE) {
+ if ((flag == ACPI_TRIPS_INIT) || ((flag & ACPI_TRIPS_ACTIVE) &&
+ tz->trips.active[i].flags.valid)) {
status = acpi_evaluate_integer(tz->device->handle,
name, NULL, &tmp);
if (ACPI_FAILURE(status)) {
@@ -521,8 +526,11 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
memset(&devices, 0, sizeof(struct acpi_handle_list));
status = acpi_evaluate_reference(tz->device->handle,
name, NULL, &devices);
- if (ACPI_FAILURE(status))
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_WARNING PREFIX
+ "Invalid active%d threshold\n", i);
tz->trips.active[i].flags.valid = 0;
+ }
else
tz->trips.active[i].flags.valid = 1;
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index f261737636d..bb5ed059114 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -1020,7 +1020,7 @@ acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset)
}
seq_printf(seq, "levels: ");
- for (i = 0; i < dev->brightness->count; i++)
+ for (i = 2; i < dev->brightness->count; i++)
seq_printf(seq, " %d", dev->brightness->levels[i]);
seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr);
@@ -1059,7 +1059,7 @@ acpi_video_device_write_brightness(struct file *file,
return -EFAULT;
/* validate through the list of available levels */
- for (i = 0; i < dev->brightness->count; i++)
+ for (i = 2; i < dev->brightness->count; i++)
if (level == dev->brightness->levels[i]) {
if (ACPI_SUCCESS
(acpi_video_device_lcd_set_level(dev, level)))
@@ -1260,7 +1260,7 @@ static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
printk(KERN_WARNING PREFIX
"This indicates a BIOS bug. Please contact the manufacturer.\n");
}
- printk("%llx\n", options);
+ printk(KERN_WARNING "%llx\n", options);
seq_printf(seq, "can POST: <integrated video>");
if (options & 2)
seq_printf(seq, " <PCI video>");
@@ -1712,7 +1712,7 @@ acpi_video_get_next_level(struct acpi_video_device *device,
max = max_below = 0;
min = min_above = 255;
/* Find closest level to level_current */
- for (i = 0; i < device->brightness->count; i++) {
+ for (i = 2; i < device->brightness->count; i++) {
l = device->brightness->levels[i];
if (abs(l - level_current) < abs(delta)) {
delta = l - level_current;
@@ -1722,7 +1722,7 @@ acpi_video_get_next_level(struct acpi_video_device *device,
}
/* Ajust level_current to closest available level */
level_current += delta;
- for (i = 0; i < device->brightness->count; i++) {
+ for (i = 2; i < device->brightness->count; i++) {
l = device->brightness->levels[i];
if (l < min)
min = l;
@@ -2006,6 +2006,12 @@ static int acpi_video_bus_add(struct acpi_device *device)
device->pnp.bus_id[3] = '0' + instance;
instance ++;
}
+ /* a hack to fix the duplicate name "VGA" problem on Pa 3553 */
+ if (!strcmp(device->pnp.bus_id, "VGA")) {
+ if (instance)
+ device->pnp.bus_id[3] = '0' + instance;
+ instance++;
+ }
video->device = device;
strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);