summaryrefslogtreecommitdiff
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/bus.c3
-rw-r--r--drivers/acpi/container.c8
-rw-r--r--drivers/acpi/ec.c2
-rw-r--r--drivers/acpi/osl.c2
-rw-r--r--drivers/acpi/pci_irq.c7
-rw-r--r--drivers/acpi/pci_link.c2
-rw-r--r--drivers/acpi/processor_core.c23
-rw-r--r--drivers/acpi/processor_idle.c90
-rw-r--r--drivers/acpi/processor_thermal.c42
-rw-r--r--drivers/acpi/scan.c43
-rw-r--r--drivers/acpi/tables.c4
-rw-r--r--drivers/acpi/thermal.c163
-rw-r--r--drivers/acpi/utilities/utmisc.c18
-rw-r--r--drivers/acpi/video.c2
16 files changed, 248 insertions, 166 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index fe1e8126fbae..6d61945260a8 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -168,7 +168,6 @@ config ACPI_NUMA
config ACPI_ASUS
tristate "ASUS/Medion Laptop Extras"
depends on X86
- default y
---help---
This driver provides support for extra features of ACPI-compatible
ASUS laptops. As some of Medion laptops are made by ASUS, it may also
@@ -197,7 +196,6 @@ config ACPI_ASUS
config ACPI_IBM
tristate "IBM ThinkPad Laptop Extras"
depends on X86
- default y
---help---
This is a Linux ACPI driver for the IBM ThinkPad laptops. It adds
support for Fn-Fx key combinations, Bluetooth control, video
@@ -210,7 +208,6 @@ config ACPI_IBM
config ACPI_TOSHIBA
tristate "Toshiba Laptop Extras"
depends on X86
- default y
---help---
This driver adds support for access to certain system settings
on "legacy free" Toshiba laptops. These laptops can be recognized by
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index a18243488c66..5984b4f6715a 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -16,7 +16,7 @@ EXTRA_CFLAGS += $(ACPI_CFLAGS)
# ACPI Boot-Time Table Parsing
#
obj-y += tables.o
-obj-y += blacklist.o
+obj-$(CONFIG_X86) += blacklist.o
#
# ACPI Core Subsystem (Interpreter)
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 6a4da417c16b..606f8733a776 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -28,6 +28,7 @@
#include <linux/list.h>
#include <linux/sched.h>
#include <linux/pm.h>
+#include <linux/pm_legacy.h>
#include <linux/device.h>
#include <linux/proc_fs.h>
#ifdef CONFIG_X86
@@ -754,7 +755,7 @@ static int __init acpi_init(void)
result = acpi_bus_init();
if (!result) {
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
if (!PM_IS_ACTIVE())
pm_active = 1;
else {
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 27ec12c1fab0..b69a8cad82b7 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -172,21 +172,21 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
if (ACPI_FAILURE(status) || !device) {
result = container_device_add(&device, handle);
if (!result)
- kobject_hotplug(&device->kobj,
- KOBJ_ONLINE);
+ kobject_uevent(&device->kobj,
+ KOBJ_ONLINE);
else
printk("Failed to add container\n");
}
} else {
if (ACPI_SUCCESS(status)) {
/* device exist and this is a remove request */
- kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
+ kobject_uevent(&device->kobj, KOBJ_OFFLINE);
}
}
break;
case ACPI_NOTIFY_EJECT_REQUEST:
if (!acpi_bus_get_device(handle, &device) && device) {
- kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
+ kobject_uevent(&device->kobj, KOBJ_OFFLINE);
}
break;
default:
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 7e1a445955bc..3758b558d2b5 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -153,7 +153,7 @@ static int acpi_ec_polling_mode = EC_POLLING;
Transaction Management
-------------------------------------------------------------------------- */
-static inline u32 acpi_ec_read_status(union acpi_ec *ec)
+static u32 acpi_ec_read_status(union acpi_ec *ec)
{
u32 status = 0;
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index e3cd0b16031a..20c9a37643c7 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -204,11 +204,13 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size,
return AE_OK;
}
+EXPORT_SYMBOL_GPL(acpi_os_map_memory);
void acpi_os_unmap_memory(void __iomem * virt, acpi_size size)
{
iounmap(virt);
}
+EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
#ifdef ACPI_FUTURE_USAGE
acpi_status
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 09567c2edcfb..e567c03b238e 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -361,8 +361,7 @@ acpi_pci_irq_derive(struct pci_dev *dev,
if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) {
/* PC card has the same IRQ as its cardbridge */
- pci_read_config_byte(bridge, PCI_INTERRUPT_PIN,
- &bridge_pin);
+ bridge_pin = bridge->pin;
if (!bridge_pin) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"No interrupt pin configured for device %s\n",
@@ -412,7 +411,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
if (!dev)
return_VALUE(-EINVAL);
- pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+ pin = dev->pin;
if (!pin) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"No interrupt pin configured for device %s\n",
@@ -503,7 +502,7 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
if (!dev || !dev->bus)
return_VOID;
- pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+ pin = dev->pin;
if (!pin)
return_VOID;
pin--;
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 82292b77e5c6..78927c0f1551 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -316,7 +316,7 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
if (!link || !irq)
return_VALUE(-EINVAL);
- resource = kmalloc(sizeof(*resource) + 1, GFP_KERNEL);
+ resource = kmalloc(sizeof(*resource) + 1, GFP_ATOMIC);
if (!resource)
return_VALUE(-ENOMEM);
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 421792562642..1278aca96fe3 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -543,6 +543,8 @@ static int acpi_processor_get_info(struct acpi_processor *pr)
return_VALUE(0);
}
+static void *processor_device_array[NR_CPUS];
+
static int acpi_processor_start(struct acpi_device *device)
{
int result = 0;
@@ -561,6 +563,19 @@ static int acpi_processor_start(struct acpi_device *device)
BUG_ON((pr->id >= NR_CPUS) || (pr->id < 0));
+ /*
+ * Buggy BIOS check
+ * ACPI id of processors can be reported wrongly by the BIOS.
+ * Don't trust it blindly
+ */
+ if (processor_device_array[pr->id] != NULL &&
+ processor_device_array[pr->id] != (void *)device) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "BIOS reporting wrong ACPI id"
+ "for the processor\n"));
+ return_VALUE(-ENODEV);
+ }
+ processor_device_array[pr->id] = (void *)device;
+
processors[pr->id] = pr;
result = acpi_processor_add_fs(device);
@@ -733,7 +748,7 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
return_VALUE(-ENODEV);
if ((pr->id >= 0) && (pr->id < NR_CPUS)) {
- kobject_hotplug(&(*device)->kobj, KOBJ_ONLINE);
+ kobject_uevent(&(*device)->kobj, KOBJ_ONLINE);
}
return_VALUE(0);
}
@@ -773,13 +788,13 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
}
if (pr->id >= 0 && (pr->id < NR_CPUS)) {
- kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
+ kobject_uevent(&device->kobj, KOBJ_OFFLINE);
break;
}
result = acpi_processor_start(device);
if ((!result) && ((pr->id >= 0) && (pr->id < NR_CPUS))) {
- kobject_hotplug(&device->kobj, KOBJ_ONLINE);
+ kobject_uevent(&device->kobj, KOBJ_ONLINE);
} else {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Device [%s] failed to start\n",
@@ -803,7 +818,7 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
}
if ((pr->id < NR_CPUS) && (cpu_present(pr->id)))
- kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
+ kobject_uevent(&device->kobj, KOBJ_OFFLINE);
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 573b6a97bb1f..cc049338e418 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -169,15 +169,11 @@ acpi_processor_power_activate(struct acpi_processor *pr,
static void acpi_safe_halt(void)
{
- int polling = test_thread_flag(TIF_POLLING_NRFLAG);
- if (polling) {
- clear_thread_flag(TIF_POLLING_NRFLAG);
- smp_mb__after_clear_bit();
- }
+ clear_thread_flag(TIF_POLLING_NRFLAG);
+ smp_mb__after_clear_bit();
if (!need_resched())
safe_halt();
- if (polling)
- set_thread_flag(TIF_POLLING_NRFLAG);
+ set_thread_flag(TIF_POLLING_NRFLAG);
}
static atomic_t c3_cpu_count;
@@ -278,6 +274,17 @@ static void acpi_processor_idle(void)
}
}
+#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_fadt.plvl2_up)
+ cx = &pr->power.states[ACPI_STATE_C1];
+#endif
+
cx->usage++;
/*
@@ -285,6 +292,16 @@ static void acpi_processor_idle(void)
* ------
* Invoke the current Cx state to put the processor to sleep.
*/
+ if (cx->type == ACPI_STATE_C2 || cx->type == ACPI_STATE_C3) {
+ clear_thread_flag(TIF_POLLING_NRFLAG);
+ smp_mb__after_clear_bit();
+ if (need_resched()) {
+ set_thread_flag(TIF_POLLING_NRFLAG);
+ local_irq_enable();
+ return;
+ }
+ }
+
switch (cx->type) {
case ACPI_STATE_C1:
@@ -317,6 +334,7 @@ static void acpi_processor_idle(void)
t2 = inl(acpi_fadt.xpm_tmr_blk.address);
/* Re-enable interrupts */
local_irq_enable();
+ set_thread_flag(TIF_POLLING_NRFLAG);
/* Compute time (ticks) that we were actually asleep */
sleep_ticks =
ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD;
@@ -356,6 +374,7 @@ static void acpi_processor_idle(void)
/* Re-enable interrupts */
local_irq_enable();
+ set_thread_flag(TIF_POLLING_NRFLAG);
/* Compute time (ticks) that we were actually asleep */
sleep_ticks =
ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD;
@@ -368,6 +387,15 @@ static void acpi_processor_idle(void)
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_fadt.plvl2_up) {
+ next_state = cx;
+ goto end;
+ }
+#endif
+
/*
* Promotion?
* ----------
@@ -514,8 +542,6 @@ static int acpi_processor_set_power_policy(struct acpi_processor *pr)
static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
{
- int i;
-
ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_fadt");
if (!pr)
@@ -524,8 +550,7 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
if (!pr->pblk)
return_VALUE(-ENODEV);
- for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++)
- memset(pr->power.states, 0, sizeof(struct acpi_processor_cx));
+ memset(pr->power.states, 0, sizeof(pr->power.states));
/* if info is obtained from pblk/fadt, type equals state */
pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
@@ -537,6 +562,15 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
pr->power.states[ACPI_STATE_C0].valid = 1;
pr->power.states[ACPI_STATE_C1].valid = 1;
+#ifndef CONFIG_HOTPLUG_CPU
+ /*
+ * Check for P_LVL2_UP flag before entering C2 and above on
+ * an SMP system.
+ */
+ if ((num_online_cpus() > 1) && !acpi_fadt.plvl2_up)
+ return_VALUE(-ENODEV);
+#endif
+
/* determine C2 and C3 address from pblk */
pr->power.states[ACPI_STATE_C2].address = pr->pblk + 4;
pr->power.states[ACPI_STATE_C3].address = pr->pblk + 5;
@@ -555,13 +589,9 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
static int acpi_processor_get_power_info_default_c1(struct acpi_processor *pr)
{
- int i;
-
ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_default_c1");
- for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++)
- memset(&(pr->power.states[i]), 0,
- sizeof(struct acpi_processor_cx));
+ memset(pr->power.states, 0, sizeof(pr->power.states));
/* if info is obtained from pblk/fadt, type equals state */
pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
@@ -697,7 +727,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
/* Validate number of power states discovered */
if (pr->power.count < 2)
- status = -ENODEV;
+ status = -EFAULT;
end:
acpi_os_free(buffer.pointer);
@@ -813,6 +843,15 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
unsigned int i;
unsigned int working = 0;
+#ifdef ARCH_APICTIMER_STOPS_ON_C3
+ struct cpuinfo_x86 *c = cpu_data + pr->id;
+ cpumask_t mask = cpumask_of_cpu(pr->id);
+
+ if (c->x86_vendor == X86_VENDOR_INTEL) {
+ on_each_cpu(switch_ipi_to_APIC_timer, &mask, 1, 1);
+ }
+#endif
+
for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
struct acpi_processor_cx *cx = &pr->power.states[i];
@@ -827,6 +866,12 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
case ACPI_STATE_C3:
acpi_processor_power_verify_c3(pr, cx);
+#ifdef ARCH_APICTIMER_STOPS_ON_C3
+ if (c->x86_vendor == X86_VENDOR_INTEL) {
+ on_each_cpu(switch_APIC_timer_to_ipi,
+ &mask, 1, 1);
+ }
+#endif
break;
}
@@ -848,11 +893,11 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
* this function */
result = acpi_processor_get_power_info_cst(pr);
- if ((result) || (acpi_processor_power_verify(pr) < 2)) {
+ if (result == -ENODEV)
result = acpi_processor_get_power_info_fadt(pr);
- if ((result) || (acpi_processor_power_verify(pr) < 2))
- result = acpi_processor_get_power_info_default_c1(pr);
- }
+
+ if ((result) || (acpi_processor_power_verify(pr) < 2))
+ result = acpi_processor_get_power_info_default_c1(pr);
/*
* Set Default Policy
@@ -873,7 +918,8 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
if (pr->power.states[i].valid) {
pr->power.count = i;
- pr->flags.power = 1;
+ if (pr->power.states[i].type >= ACPI_STATE_C2)
+ pr->flags.power = 1;
}
}
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index 37528c3b64b0..dc9817cfb882 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -101,11 +101,9 @@ static unsigned int acpi_thermal_cpufreq_is_init = 0;
static int cpu_has_cpufreq(unsigned int cpu)
{
struct cpufreq_policy policy;
- if (!acpi_thermal_cpufreq_is_init)
- return -ENODEV;
- if (!cpufreq_get_policy(&policy, cpu))
- return -ENODEV;
- return 0;
+ if (!acpi_thermal_cpufreq_is_init || cpufreq_get_policy(&policy, cpu))
+ return 0;
+ return 1;
}
static int acpi_thermal_cpufreq_increase(unsigned int cpu)
@@ -127,13 +125,13 @@ static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
if (!cpu_has_cpufreq(cpu))
return -ENODEV;
- if (cpufreq_thermal_reduction_pctg[cpu] >= 20) {
+ if (cpufreq_thermal_reduction_pctg[cpu] > 20)
cpufreq_thermal_reduction_pctg[cpu] -= 20;
- cpufreq_update_policy(cpu);
- return 0;
- }
-
- return -ERANGE;
+ else
+ cpufreq_thermal_reduction_pctg[cpu] = 0;
+ cpufreq_update_policy(cpu);
+ /* We reached max freq again and can leave passive mode */
+ return !cpufreq_thermal_reduction_pctg[cpu];
}
static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb,
@@ -200,7 +198,7 @@ int acpi_processor_set_thermal_limit(acpi_handle handle, int type)
int result = 0;
struct acpi_processor *pr = NULL;
struct acpi_device *device = NULL;
- int tx = 0;
+ int tx = 0, max_tx_px = 0;
ACPI_FUNCTION_TRACE("acpi_processor_set_thermal_limit");
@@ -259,19 +257,27 @@ int acpi_processor_set_thermal_limit(acpi_handle handle, int type)
/* if going down: T-states first, P-states later */
if (pr->flags.throttling) {
- if (tx == 0)
+ if (tx == 0) {
+ max_tx_px = 1;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"At minimum throttling state\n"));
- else {
+ } else {
tx--;
goto end;
}
}
result = acpi_thermal_cpufreq_decrease(pr->id);
- if (result == -ERANGE)
+ if (result) {
+ /*
+ * We only could get -ERANGE, 1 or 0.
+ * In the first two cases we reached max freq again.
+ */
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"At minimum performance state\n"));
+ max_tx_px = 1;
+ } else
+ max_tx_px = 0;
break;
}
@@ -290,8 +296,10 @@ int acpi_processor_set_thermal_limit(acpi_handle handle, int type)
pr->limit.thermal.px, pr->limit.thermal.tx));
} else
result = 0;
-
- return_VALUE(result);
+ if (max_tx_px)
+ return_VALUE(1);
+ else
+ return_VALUE(result);
}
int acpi_processor_get_limit_info(struct acpi_processor *pr)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 23e2c6968a11..3b26a7104363 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -78,7 +78,7 @@ static struct kobj_type ktype_acpi_ns = {
.release = acpi_device_release,
};
-static int namespace_hotplug(struct kset *kset, struct kobject *kobj,
+static int namespace_uevent(struct kset *kset, struct kobject *kobj,
char **envp, int num_envp, char *buffer,
int buffer_size)
{
@@ -89,8 +89,8 @@ static int namespace_hotplug(struct kset *kset, struct kobject *kobj,
if (!dev->driver)
return 0;
- if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len,
- "PHYSDEVDRIVER=%s", dev->driver->name))
+ if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
+ "PHYSDEVDRIVER=%s", dev->driver->name))
return -ENOMEM;
envp[i] = NULL;
@@ -98,8 +98,8 @@ static int namespace_hotplug(struct kset *kset, struct kobject *kobj,
return 0;
}
-static struct kset_hotplug_ops namespace_hotplug_ops = {
- .hotplug = &namespace_hotplug,
+static struct kset_uevent_ops namespace_uevent_ops = {
+ .uevent = &namespace_uevent,
};
static struct kset acpi_namespace_kset = {
@@ -108,7 +108,7 @@ static struct kset acpi_namespace_kset = {
},
.subsys = &acpi_subsys,
.ktype = &ktype_acpi_ns,
- .hotplug_ops = &namespace_hotplug_ops,
+ .uevent_ops = &namespace_uevent_ops,
};
static void acpi_device_register(struct acpi_device *device,
@@ -347,7 +347,7 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
}
/* --------------------------------------------------------------------------
- ACPI hotplug sysfs device file support
+ ACPI sysfs device file support
-------------------------------------------------------------------------- */
static ssize_t acpi_eject_store(struct acpi_device *device,
const char *buf, size_t count);
@@ -475,8 +475,10 @@ static LIST_HEAD(acpi_bus_drivers);
static DECLARE_MUTEX(acpi_bus_drivers_lock);
/**
- * acpi_bus_match
- * --------------
+ * acpi_bus_match - match device IDs to driver's supported IDs
+ * @device: the device that we are trying to match to a driver
+ * @driver: driver whose device id table is being checked
+ *
* Checks the device's hardware (_HID) or compatible (_CID) ids to see if it
* matches the specified driver's criteria.
*/
@@ -489,8 +491,10 @@ acpi_bus_match(struct acpi_device *device, struct acpi_driver *driver)
}
/**
- * acpi_bus_driver_init
- * --------------------
+ * acpi_bus_driver_init - add a device to a driver
+ * @device: the device to add and initialize
+ * @driver: driver for the device
+ *
* Used to initialize a device via its device driver. Called whenever a
* driver is bound to a device. Invokes the driver's add() and start() ops.
*/
@@ -603,8 +607,9 @@ static int acpi_driver_detach(struct acpi_driver *drv)
}
/**
- * acpi_bus_register_driver
- * ------------------------
+ * acpi_bus_register_driver - register a driver with the ACPI bus
+ * @driver: driver being registered
+ *
* Registers a driver with the ACPI bus. Searches the namespace for all
* devices that match the driver's criteria and binds. Returns the
* number of devices that were claimed by the driver, or a negative
@@ -633,8 +638,9 @@ int acpi_bus_register_driver(struct acpi_driver *driver)
EXPORT_SYMBOL(acpi_bus_register_driver);
/**
- * acpi_bus_unregister_driver
- * --------------------------
+ * acpi_bus_unregister_driver - unregisters a driver with the APIC bus
+ * @driver: driver to unregister
+ *
* Unregisters a driver with the ACPI bus. Searches the namespace for all
* devices that match the driver's criteria and unbinds.
*/
@@ -660,8 +666,9 @@ int acpi_bus_unregister_driver(struct acpi_driver *driver)
EXPORT_SYMBOL(acpi_bus_unregister_driver);
/**
- * acpi_bus_find_driver
- * --------------------
+ * acpi_bus_find_driver - check if there is a driver installed for the device
+ * @device: device that we are trying to find a supporting driver for
+ *
* Parses the list of registered drivers looking for a driver applicable for
* the specified device.
*/
@@ -1110,7 +1117,7 @@ acpi_add_single_object(struct acpi_device **child,
*
* TBD: Assumes LDM provides driver hot-plug capability.
*/
- result = acpi_bus_find_driver(device);
+ acpi_bus_find_driver(device);
end:
if (!result)
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index a2bf25b05e1c..31d4f3ffc265 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -37,7 +37,7 @@
#define PREFIX "ACPI: "
-#define ACPI_MAX_TABLES 256
+#define ACPI_MAX_TABLES 128
static char *acpi_table_signatures[ACPI_TABLE_COUNT] = {
[ACPI_TABLE_UNKNOWN] = "????",
@@ -74,7 +74,7 @@ struct acpi_table_sdt {
static unsigned long sdt_pa; /* Physical Address */
static unsigned long sdt_count; /* Table count */
-static struct acpi_table_sdt sdt_entry[ACPI_MAX_TABLES];
+static struct acpi_table_sdt sdt_entry[ACPI_MAX_TABLES] __initdata;
void acpi_table_print(struct acpi_table_header *header, unsigned long phys_addr)
{
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index a24847c08f7f..19f3ea48475e 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -72,7 +72,7 @@
#define _COMPONENT ACPI_THERMAL_COMPONENT
ACPI_MODULE_NAME("acpi_thermal")
- MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION(ACPI_THERMAL_DRIVER_NAME);
MODULE_LICENSE("GPL");
@@ -517,9 +517,9 @@ static int acpi_thermal_hot(struct acpi_thermal *tz)
return_VALUE(0);
}
-static int acpi_thermal_passive(struct acpi_thermal *tz)
+static void acpi_thermal_passive(struct acpi_thermal *tz)
{
- int result = 0;
+ int result = 1;
struct acpi_thermal_passive *passive = NULL;
int trend = 0;
int i = 0;
@@ -527,7 +527,7 @@ static int acpi_thermal_passive(struct acpi_thermal *tz)
ACPI_FUNCTION_TRACE("acpi_thermal_passive");
if (!tz || !tz->trips.passive.flags.valid)
- return_VALUE(-EINVAL);
+ return;
passive = &(tz->trips.passive);
@@ -547,7 +547,7 @@ static int acpi_thermal_passive(struct acpi_thermal *tz)
trend, passive->tc1, tz->temperature,
tz->last_temperature, passive->tc2,
tz->temperature, passive->temperature));
- tz->trips.passive.flags.enabled = 1;
+ passive->flags.enabled = 1;
/* Heating up? */
if (trend > 0)
for (i = 0; i < passive->devices.count; i++)
@@ -556,12 +556,32 @@ static int acpi_thermal_passive(struct acpi_thermal *tz)
handles[i],
ACPI_PROCESSOR_LIMIT_INCREMENT);
/* Cooling off? */
- else if (trend < 0)
+ else if (trend < 0) {
for (i = 0; i < passive->devices.count; i++)
- acpi_processor_set_thermal_limit(passive->
- devices.
- handles[i],
- ACPI_PROCESSOR_LIMIT_DECREMENT);
+ /*
+ * assume that we are on highest
+ * freq/lowest thrott and can leave
+ * passive mode, even in error case
+ */
+ if (!acpi_processor_set_thermal_limit
+ (passive->devices.handles[i],
+ ACPI_PROCESSOR_LIMIT_DECREMENT))
+ result = 0;
+ /*
+ * Leave cooling mode, even if the temp might
+ * higher than trip point This is because some
+ * machines might have long thermal polling
+ * frequencies (tsp) defined. We will fall back
+ * into passive mode in next cycle (probably quicker)
+ */
+ if (result) {
+ passive->flags.enabled = 0;
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Disabling passive cooling, still above threshold,"
+ " but we are cooling down\n"));
+ }
+ }
+ return;
}
/*
@@ -571,23 +591,21 @@ static int acpi_thermal_passive(struct acpi_thermal *tz)
* and avoid thrashing around the passive trip point. Note that we
* assume symmetry.
*/
- else if (tz->trips.passive.flags.enabled) {
- for (i = 0; i < passive->devices.count; i++)
- result =
- acpi_processor_set_thermal_limit(passive->devices.
- handles[i],
- ACPI_PROCESSOR_LIMIT_DECREMENT);
- if (result == 1) {
- tz->trips.passive.flags.enabled = 0;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Disabling passive cooling (zone is cool)\n"));
- }
+ if (!passive->flags.enabled)
+ return;
+ for (i = 0; i < passive->devices.count; i++)
+ if (!acpi_processor_set_thermal_limit
+ (passive->devices.handles[i],
+ ACPI_PROCESSOR_LIMIT_DECREMENT))
+ result = 0;
+ if (result) {
+ passive->flags.enabled = 0;
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Disabling passive cooling (zone is cool)\n"));
}
-
- return_VALUE(0);
}
-static int acpi_thermal_active(struct acpi_thermal *tz)
+static void acpi_thermal_active(struct acpi_thermal *tz)
{
int result = 0;
struct acpi_thermal_active *active = NULL;
@@ -598,74 +616,66 @@ static int acpi_thermal_active(struct acpi_thermal *tz)
ACPI_FUNCTION_TRACE("acpi_thermal_active");
if (!tz)
- return_VALUE(-EINVAL);
+ return;
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
-
active = &(tz->trips.active[i]);
if (!active || !active->flags.valid)
break;
-
- /*
- * Above Threshold?
- * ----------------
- * If not already enabled, turn ON all cooling devices
- * associated with this active threshold.
- */
if (tz->temperature >= active->temperature) {
+ /*
+ * Above Threshold?
+ * ----------------
+ * If not already enabled, turn ON all cooling devices
+ * associated with this active threshold.
+ */
if (active->temperature > maxtemp)
- tz->state.active_index = i, maxtemp =
- active->temperature;
- if (!active->flags.enabled) {
- for (j = 0; j < active->devices.count; j++) {
- result =
- acpi_bus_set_power(active->devices.
- handles[j],
- ACPI_STATE_D0);
- if (result) {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN,
- "Unable to turn cooling device [%p] 'on'\n",
- active->
- devices.
- handles[j]));
- continue;
- }
- active->flags.enabled = 1;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Cooling device [%p] now 'on'\n",
- active->devices.
- handles[j]));
- }
- }
- }
- /*
- * Below Threshold?
- * ----------------
- * Turn OFF all cooling devices associated with this
- * threshold.
- */
- else if (active->flags.enabled) {
+ tz->state.active_index = i;
+ maxtemp = active->temperature;
+ if (active->flags.enabled)
+ continue;
for (j = 0; j < active->devices.count; j++) {
result =
acpi_bus_set_power(active->devices.
handles[j],
- ACPI_STATE_D3);
+ ACPI_STATE_D0);
if (result) {
ACPI_DEBUG_PRINT((ACPI_DB_WARN,
- "Unable to turn cooling device [%p] 'off'\n",
+ "Unable to turn cooling device [%p] 'on'\n",
active->devices.
handles[j]));
continue;
}
- active->flags.enabled = 0;
+ active->flags.enabled = 1;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Cooling device [%p] now 'off'\n",
+ "Cooling device [%p] now 'on'\n",
active->devices.handles[j]));
}
+ continue;
+ }
+ if (!active->flags.enabled)
+ continue;
+ /*
+ * Below Threshold?
+ * ----------------
+ * Turn OFF all cooling devices associated with this
+ * threshold.
+ */
+ for (j = 0; j < active->devices.count; j++) {
+ result = acpi_bus_set_power(active->devices.handles[j],
+ ACPI_STATE_D3);
+ if (result) {
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Unable to turn cooling device [%p] 'off'\n",
+ active->devices.handles[j]));
+ continue;
+ }
+ active->flags.enabled = 0;
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Cooling device [%p] now 'off'\n",
+ active->devices.handles[j]));
}
}
-
- return_VALUE(0);
}
static void acpi_thermal_check(void *context);
@@ -744,15 +754,12 @@ static void acpi_thermal_check(void *data)
* Again, separated from the above two to allow independent policy
* decisions.
*/
- if (tz->trips.critical.flags.enabled)
- tz->state.critical = 1;
- if (tz->trips.hot.flags.enabled)
- tz->state.hot = 1;
- if (tz->trips.passive.flags.enabled)
- tz->state.passive = 1;
+ tz->state.critical = tz->trips.critical.flags.enabled;
+ tz->state.hot = tz->trips.hot.flags.enabled;
+ tz->state.passive = tz->trips.passive.flags.enabled;
+ tz->state.active = 0;
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
- if (tz->trips.active[i].flags.enabled)
- tz->state.active = 1;
+ tz->state.active |= tz->trips.active[i].flags.enabled;
/*
* Calculate Sleep Time
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index 0c5abc536c7a..2ce872d75890 100644
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -84,14 +84,14 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
/* Find a free owner ID */
- for (i = 0; i < 32; i++) {
- if (!(acpi_gbl_owner_id_mask & (1 << i))) {
+ for (i = 0; i < 64; i++) {
+ if (!(acpi_gbl_owner_id_mask & (1ULL << i))) {
ACPI_DEBUG_PRINT((ACPI_DB_VALUES,
- "Current owner_id mask: %8.8X New ID: %2.2X\n",
+ "Current owner_id mask: %16.16LX New ID: %2.2X\n",
acpi_gbl_owner_id_mask,
(unsigned int)(i + 1)));
- acpi_gbl_owner_id_mask |= (1 << i);
+ acpi_gbl_owner_id_mask |= (1ULL << i);
*owner_id = (acpi_owner_id) (i + 1);
goto exit;
}
@@ -106,7 +106,7 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
*/
*owner_id = 0;
status = AE_OWNER_ID_LIMIT;
- ACPI_REPORT_ERROR(("Could not allocate new owner_id (32 max), AE_OWNER_ID_LIMIT\n"));
+ ACPI_REPORT_ERROR(("Could not allocate new owner_id (64 max), AE_OWNER_ID_LIMIT\n"));
exit:
(void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
@@ -123,7 +123,7 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
* control method or unloading a table. Either way, we would
* ignore any error anyway.
*
- * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 32
+ * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 64
*
******************************************************************************/
@@ -140,7 +140,7 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr)
/* Zero is not a valid owner_iD */
- if ((owner_id == 0) || (owner_id > 32)) {
+ if ((owner_id == 0) || (owner_id > 64)) {
ACPI_REPORT_ERROR(("Invalid owner_id: %2.2X\n", owner_id));
return_VOID;
}
@@ -158,8 +158,8 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr)
/* Free the owner ID only if it is valid */
- if (acpi_gbl_owner_id_mask & (1 << owner_id)) {
- acpi_gbl_owner_id_mask ^= (1 << owner_id);
+ if (acpi_gbl_owner_id_mask & (1ULL << owner_id)) {
+ acpi_gbl_owner_id_mask ^= (1ULL << owner_id);
}
(void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index f051b151580d..d10668f14699 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -812,7 +812,7 @@ acpi_video_device_write_brightness(struct file *file,
ACPI_FUNCTION_TRACE("acpi_video_device_write_brightness");
- if (!dev || count + 1 > sizeof str)
+ if (!dev || !dev->brightness || count + 1 > sizeof str)
return_VALUE(-EINVAL);
if (copy_from_user(str, buffer, count))