diff options
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/Kconfig | 11 | ||||
-rw-r--r-- | drivers/acpi/Makefile | 1 | ||||
-rw-r--r-- | drivers/acpi/acpica/utresrc.c | 2 | ||||
-rw-r--r-- | drivers/acpi/apei/Kconfig | 1 | ||||
-rw-r--r-- | drivers/acpi/apei/einj.c | 8 | ||||
-rw-r--r-- | drivers/acpi/apei/erst.c | 61 | ||||
-rw-r--r-- | drivers/acpi/atomicio.c | 4 | ||||
-rw-r--r-- | drivers/acpi/pci_root.c | 14 | ||||
-rw-r--r-- | drivers/acpi/power_meter.c | 1023 | ||||
-rw-r--r-- | drivers/acpi/processor_idle.c | 2 | ||||
-rw-r--r-- | drivers/acpi/processor_perflib.c | 6 | ||||
-rw-r--r-- | drivers/acpi/processor_throttling.c | 32 | ||||
-rw-r--r-- | drivers/acpi/video.c | 2 |
13 files changed, 82 insertions, 1085 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index d918e130bef3..de0e3df76776 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -73,17 +73,6 @@ config ACPI_PROCFS_POWER Say N to delete power /proc/acpi/ directories that have moved to /sys/ -config ACPI_POWER_METER - tristate "ACPI 4.0 power meter" - depends on HWMON - help - This driver exposes ACPI 4.0 power meters as hardware monitoring - devices. Say Y (or M) if you have a computer with ACPI 4.0 firmware - and a power meter. - - To compile this driver as a module, choose M here: - the module will be called power-meter. - config ACPI_EC_DEBUGFS tristate "EC read/write access through /sys/kernel/debug/ec" default n diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index cba0b2334b9b..ecb26b4f29a0 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -59,7 +59,6 @@ obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o obj-$(CONFIG_ACPI_BATTERY) += battery.o obj-$(CONFIG_ACPI_SBS) += sbshc.o obj-$(CONFIG_ACPI_SBS) += sbs.o -obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o obj-$(CONFIG_ACPI_HED) += hed.o obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o diff --git a/drivers/acpi/acpica/utresrc.c b/drivers/acpi/acpica/utresrc.c index 84e051844247..6ffd3a8bdaa5 100644 --- a/drivers/acpi/acpica/utresrc.c +++ b/drivers/acpi/acpica/utresrc.c @@ -50,7 +50,7 @@ ACPI_MODULE_NAME("utresrc") #if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER) /* * Strings used to decode resource descriptors. - * Used by both the disasssembler and the debugger resource dump routines + * Used by both the disassembler and the debugger resource dump routines */ const char *acpi_gbl_bm_decode[] = { "NotBusMaster", diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig index 66a03caa2ad9..f739a70b1c70 100644 --- a/drivers/acpi/apei/Kconfig +++ b/drivers/acpi/apei/Kconfig @@ -1,5 +1,6 @@ config ACPI_APEI bool "ACPI Platform Error Interface (APEI)" + select MISC_FILESYSTEMS select PSTORE depends on X86 help diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c index 096aebfe7f32..f74b2ea11f21 100644 --- a/drivers/acpi/apei/einj.c +++ b/drivers/acpi/apei/einj.c @@ -101,6 +101,14 @@ static DEFINE_MUTEX(einj_mutex); static struct einj_parameter *einj_param; +#ifndef writeq +static inline void writeq(__u64 val, volatile void __iomem *addr) +{ + writel(val, addr); + writel(val >> 32, addr+4); +} +#endif + static void einj_exec_ctx_init(struct apei_exec_context *ctx) { apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type), diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index d6cb0ff6988e..e6cef8e1b534 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c @@ -929,13 +929,17 @@ static int erst_check_table(struct acpi_table_erst *erst_tab) return 0; } -static size_t erst_reader(u64 *id, enum pstore_type_id *type, +static int erst_open_pstore(struct pstore_info *psi); +static int erst_close_pstore(struct pstore_info *psi); +static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, struct timespec *time); static u64 erst_writer(enum pstore_type_id type, size_t size); static struct pstore_info erst_info = { .owner = THIS_MODULE, .name = "erst", + .open = erst_open_pstore, + .close = erst_close_pstore, .read = erst_reader, .write = erst_writer, .erase = erst_clear @@ -957,12 +961,32 @@ struct cper_pstore_record { char data[]; } __packed; -static size_t erst_reader(u64 *id, enum pstore_type_id *type, +static int reader_pos; + +static int erst_open_pstore(struct pstore_info *psi) +{ + int rc; + + if (erst_disable) + return -ENODEV; + + rc = erst_get_record_id_begin(&reader_pos); + + return rc; +} + +static int erst_close_pstore(struct pstore_info *psi) +{ + erst_get_record_id_end(); + + return 0; +} + +static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, struct timespec *time) { int rc; - ssize_t len; - unsigned long flags; + ssize_t len = 0; u64 record_id; struct cper_pstore_record *rcd = (struct cper_pstore_record *) (erst_info.buf - sizeof(*rcd)); @@ -970,24 +994,28 @@ static size_t erst_reader(u64 *id, enum pstore_type_id *type, if (erst_disable) return -ENODEV; - raw_spin_lock_irqsave(&erst_lock, flags); skip: - rc = __erst_get_next_record_id(&record_id); - if (rc) { - raw_spin_unlock_irqrestore(&erst_lock, flags); - return rc; - } + rc = erst_get_record_id_next(&reader_pos, &record_id); + if (rc) + goto out; + /* no more record */ if (record_id == APEI_ERST_INVALID_RECORD_ID) { - raw_spin_unlock_irqrestore(&erst_lock, flags); - return 0; + rc = -1; + goto out; } - len = __erst_read(record_id, &rcd->hdr, sizeof(*rcd) + - erst_erange.size); + len = erst_read(record_id, &rcd->hdr, sizeof(*rcd) + + erst_info.bufsize); + /* The record may be cleared by others, try read next record */ + if (len == -ENOENT) + goto skip; + else if (len < 0) { + rc = -1; + goto out; + } if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0) goto skip; - raw_spin_unlock_irqrestore(&erst_lock, flags); *id = record_id; if (uuid_le_cmp(rcd->sec_hdr.section_type, @@ -1005,7 +1033,8 @@ skip: time->tv_sec = 0; time->tv_nsec = 0; - return len - sizeof(*rcd); +out: + return (rc < 0) ? rc : (len - sizeof(*rcd)); } static u64 erst_writer(enum pstore_type_id type, size_t size) diff --git a/drivers/acpi/atomicio.c b/drivers/acpi/atomicio.c index 542e53903891..7489b89c300f 100644 --- a/drivers/acpi/atomicio.c +++ b/drivers/acpi/atomicio.c @@ -280,9 +280,11 @@ static int acpi_atomic_read_mem(u64 paddr, u64 *val, u32 width) case 32: *val = readl(addr); break; +#ifdef readq case 64: *val = readq(addr); break; +#endif default: return -EINVAL; } @@ -307,9 +309,11 @@ static int acpi_atomic_write_mem(u64 paddr, u64 val, u32 width) case 32: writel(val, addr); break; +#ifdef writeq case 64: writeq(val, addr); break; +#endif default: return -EINVAL; } diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index f911a2f8cc34..d06078d660ad 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -596,12 +596,18 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) dev_info(root->bus->bridge, "ACPI _OSC control (0x%02x) granted\n", flags); } else { - dev_dbg(root->bus->bridge, - "ACPI _OSC request failed (code %d)\n", status); - printk(KERN_INFO "Unable to assume _OSC PCIe control. " - "Disabling ASPM\n"); + dev_info(root->bus->bridge, + "ACPI _OSC request failed (%s), " + "returned control mask: 0x%02x\n", + acpi_format_exception(status), flags); + pr_info("ACPI _OSC control for PCIe not granted, " + "disabling ASPM\n"); pcie_no_aspm(); } + } else { + dev_info(root->bus->bridge, + "Unable to request _OSC control " + "(_OSC support mask: 0x%02x)\n", flags); } pci_acpi_add_bus_pm_notifier(device, root->bus); diff --git a/drivers/acpi/power_meter.c b/drivers/acpi/power_meter.c deleted file mode 100644 index 66f67293341e..000000000000 --- a/drivers/acpi/power_meter.c +++ /dev/null @@ -1,1023 +0,0 @@ -/* - * A hwmon driver for ACPI 4.0 power meters - * Copyright (C) 2009 IBM - * - * Author: Darrick J. Wong <djwong@us.ibm.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <linux/module.h> -#include <linux/hwmon.h> -#include <linux/hwmon-sysfs.h> -#include <linux/jiffies.h> -#include <linux/mutex.h> -#include <linux/dmi.h> -#include <linux/slab.h> -#include <linux/kdev_t.h> -#include <linux/sched.h> -#include <linux/time.h> -#include <acpi/acpi_drivers.h> -#include <acpi/acpi_bus.h> - -#define ACPI_POWER_METER_NAME "power_meter" -ACPI_MODULE_NAME(ACPI_POWER_METER_NAME); -#define ACPI_POWER_METER_DEVICE_NAME "Power Meter" -#define ACPI_POWER_METER_CLASS "pwr_meter_resource" - -#define NUM_SENSORS 17 - -#define POWER_METER_CAN_MEASURE (1 << 0) -#define POWER_METER_CAN_TRIP (1 << 1) -#define POWER_METER_CAN_CAP (1 << 2) -#define POWER_METER_CAN_NOTIFY (1 << 3) -#define POWER_METER_IS_BATTERY (1 << 8) -#define UNKNOWN_HYSTERESIS 0xFFFFFFFF - -#define METER_NOTIFY_CONFIG 0x80 -#define METER_NOTIFY_TRIP 0x81 -#define METER_NOTIFY_CAP 0x82 -#define METER_NOTIFY_CAPPING 0x83 -#define METER_NOTIFY_INTERVAL 0x84 - -#define POWER_AVERAGE_NAME "power1_average" -#define POWER_CAP_NAME "power1_cap" -#define POWER_AVG_INTERVAL_NAME "power1_average_interval" -#define POWER_ALARM_NAME "power1_alarm" - -static int cap_in_hardware; -static int force_cap_on; - -static int can_cap_in_hardware(void) -{ - return force_cap_on || cap_in_hardware; -} - -static const struct acpi_device_id power_meter_ids[] = { - {"ACPI000D", 0}, - {"", 0}, -}; -MODULE_DEVICE_TABLE(acpi, power_meter_ids); - -struct acpi_power_meter_capabilities { - u64 flags; - u64 units; - u64 type; - u64 accuracy; - u64 sampling_time; - u64 min_avg_interval; - u64 max_avg_interval; - u64 hysteresis; - u64 configurable_cap; - u64 min_cap; - u64 max_cap; -}; - -struct acpi_power_meter_resource { - struct acpi_device *acpi_dev; - acpi_bus_id name; - struct mutex lock; - struct device *hwmon_dev; - struct acpi_power_meter_capabilities caps; - acpi_string model_number; - acpi_string serial_number; - acpi_string oem_info; - u64 power; - u64 cap; - u64 avg_interval; - int sensors_valid; - unsigned long sensors_last_updated; - struct sensor_device_attribute sensors[NUM_SENSORS]; - int num_sensors; - int trip[2]; - int num_domain_devices; - struct acpi_device **domain_devices; - struct kobject *holders_dir; -}; - -struct ro_sensor_template { - char *label; - ssize_t (*show)(struct device *dev, - struct device_attribute *devattr, - char *buf); - int index; -}; - -struct rw_sensor_template { - char *label; - ssize_t (*show)(struct device *dev, - struct device_attribute *devattr, - char *buf); - ssize_t (*set)(struct device *dev, - struct device_attribute *devattr, - const char *buf, size_t count); - int index; -}; - -/* Averaging interval */ -static int update_avg_interval(struct acpi_power_meter_resource *resource) -{ - unsigned long long data; - acpi_status status; - - status = acpi_evaluate_integer(resource->acpi_dev->handle, "_GAI", - NULL, &data); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Evaluating _GAI")); - return -ENODEV; - } - - resource->avg_interval = data; - return 0; -} - -static ssize_t show_avg_interval(struct device *dev, - struct device_attribute *devattr, - char *buf) -{ - struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_power_meter_resource *resource = acpi_dev->driver_data; - - mutex_lock(&resource->lock); - update_avg_interval(resource); - mutex_unlock(&resource->lock); - - return sprintf(buf, "%llu\n", resource->avg_interval); -} - -static ssize_t set_avg_interval(struct device *dev, - struct device_attribute *devattr, - const char *buf, size_t count) -{ - struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_power_meter_resource *resource = acpi_dev->driver_data; - union acpi_object arg0 = { ACPI_TYPE_INTEGER }; - struct acpi_object_list args = { 1, &arg0 }; - int res; - unsigned long temp; - unsigned long long data; - acpi_status status; - - res = strict_strtoul(buf, 10, &temp); - if (res) - return res; - - if (temp > resource->caps.max_avg_interval || - temp < resource->caps.min_avg_interval) - return -EINVAL; - arg0.integer.value = temp; - - mutex_lock(&resource->lock); - status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PAI", - &args, &data); - if (!ACPI_FAILURE(status)) - resource->avg_interval = temp; - mutex_unlock(&resource->lock); - - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PAI")); - return -EINVAL; - } - - /* _PAI returns 0 on success, nonzero otherwise */ - if (data) - return -EINVAL; - - return count; -} - -/* Cap functions */ -static int update_cap(struct acpi_power_meter_resource *resource) -{ - unsigned long long data; - acpi_status status; - - status = acpi_evaluate_integer(resource->acpi_dev->handle, "_GHL", - NULL, &data); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Evaluating _GHL")); - return -ENODEV; - } - - resource->cap = data; - return 0; -} - -static ssize_t show_cap(struct device *dev, - struct device_attribute *devattr, - char *buf) -{ - struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_power_meter_resource *resource = acpi_dev->driver_data; - - mutex_lock(&resource->lock); - update_cap(resource); - mutex_unlock(&resource->lock); - - return sprintf(buf, "%llu\n", resource->cap * 1000); -} - -static ssize_t set_cap(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) -{ - struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_power_meter_resource *resource = acpi_dev->driver_data; - union acpi_object arg0 = { ACPI_TYPE_INTEGER }; - struct acpi_object_list args = { 1, &arg0 }; - int res; - unsigned long temp; - unsigned long long data; - acpi_status status; - - res = strict_strtoul(buf, 10, &temp); - if (res) - return res; - - temp /= 1000; - if (temp > resource->caps.max_cap || temp < resource->caps.min_cap) - return -EINVAL; - arg0.integer.value = temp; - - mutex_lock(&resource->lock); - status = acpi_evaluate_integer(resource->acpi_dev->handle, "_SHL", - &args, &data); - if (!ACPI_FAILURE(status)) - resource->cap = temp; - mutex_unlock(&resource->lock); - - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Evaluating _SHL")); - return -EINVAL; - } - - /* _SHL returns 0 on success, nonzero otherwise */ - if (data) - return -EINVAL; - - return count; -} - -/* Power meter trip points */ -static int set_acpi_trip(struct acpi_power_meter_resource *resource) -{ - union acpi_object arg_objs[] = { - {ACPI_TYPE_INTEGER}, - {ACPI_TYPE_INTEGER} - }; - struct acpi_object_list args = { 2, arg_objs }; - unsigned long long data; - acpi_status status; - - /* Both trip levels must be set */ - if (resource->trip[0] < 0 || resource->trip[1] < 0) - return 0; - - /* This driver stores min, max; ACPI wants max, min. */ - arg_objs[0].integer.value = resource->trip[1]; - arg_objs[1].integer.value = resource->trip[0]; - - status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PTP", - &args, &data); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PTP")); - return -EINVAL; - } - - /* _PTP returns 0 on success, nonzero otherwise */ - if (data) - return -EINVAL; - - return 0; -} - -static ssize_t set_trip(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_power_meter_resource *resource = acpi_dev->driver_data; - int res; - unsigned long temp; - - res = strict_strtoul(buf, 10, &temp); - if (res) - return res; - - temp /= 1000; - if (temp < 0) - return -EINVAL; - - mutex_lock(&resource->lock); - resource->trip[attr->index - 7] = temp; - res = set_acpi_trip(resource); - mutex_unlock(&resource->lock); - - if (res) - return res; - - return count; -} - -/* Power meter */ -static int update_meter(struct acpi_power_meter_resource *resource) -{ - unsigned long long data; - acpi_status status; - unsigned long local_jiffies = jiffies; - - if (time_before(local_jiffies, resource->sensors_last_updated + - msecs_to_jiffies(resource->caps.sampling_time)) && - resource->sensors_valid) - return 0; - - status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PMM", - NULL, &data); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMM")); - return -ENODEV; - } - - resource->power = data; - resource->sensors_valid = 1; - resource->sensors_last_updated = jiffies; - return 0; -} - -static ssize_t show_power(struct device *dev, - struct device_attribute *devattr, - char *buf) -{ - struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_power_meter_resource *resource = acpi_dev->driver_data; - - mutex_lock(&resource->lock); - update_meter(resource); - mutex_unlock(&resource->lock); - - return sprintf(buf, "%llu\n", resource->power * 1000); -} - -/* Miscellaneous */ -static ssize_t show_str(struct device *dev, - struct device_attribute *devattr, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_power_meter_resource *resource = acpi_dev->driver_data; - acpi_string val; - - switch (attr->index) { - case 0: - val = resource->model_number; - break; - case 1: - val = resource->serial_number; - break; - case 2: - val = resource->oem_info; - break; - default: - BUG(); - } - - return sprintf(buf, "%s\n", val); -} - -static ssize_t show_val(struct device *dev, - struct device_attribute *devattr, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_power_meter_resource *resource = acpi_dev->driver_data; - u64 val = 0; - - switch (attr->index) { - case 0: - val = resource->caps.min_avg_interval; - break; - case 1: - val = resource->caps.max_avg_interval; - break; - case 2: - val = resource->caps.min_cap * 1000; - break; - case 3: - val = resource->caps.max_cap * 1000; - break; - case 4: - if (resource->caps.hysteresis == UNKNOWN_HYSTERESIS) - return sprintf(buf, "unknown\n"); - - val = resource->caps.hysteresis * 1000; - break; - case 5: - if (resource->caps.flags & POWER_METER_IS_BATTERY) - val = 1; - else - val = 0; - break; - case 6: - if (resource->power > resource->cap) - val = 1; - else - val = 0; - break; - case 7: - case 8: - if (resource->trip[attr->index - 7] < 0) - return sprintf(buf, "unknown\n"); - - val = resource->trip[attr->index - 7] * 1000; - break; - default: - BUG(); - } - - return sprintf(buf, "%llu\n", val); -} - -static ssize_t show_accuracy(struct device *dev, - struct device_attribute *devattr, - char *buf) -{ - struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_power_meter_resource *resource = acpi_dev->driver_data; - unsigned int acc = resource->caps.accuracy; - - return sprintf(buf, "%u.%u%%\n", acc / 1000, acc % 1000); -} - -static ssize_t show_name(struct device *dev, - struct device_attribute *devattr, - char *buf) -{ - return sprintf(buf, "%s\n", ACPI_POWER_METER_NAME); -} - -/* Sensor descriptions. If you add a sensor, update NUM_SENSORS above! */ -static struct ro_sensor_template meter_ro_attrs[] = { -{POWER_AVERAGE_NAME, show_power, 0}, -{"power1_accuracy", show_accuracy, 0}, -{"power1_average_interval_min", show_val, 0}, -{"power1_average_interval_max", show_val, 1}, -{"power1_is_battery", show_val, 5}, -{NULL, NULL, 0}, -}; - -static struct rw_sensor_template meter_rw_attrs[] = { -{POWER_AVG_INTERVAL_NAME, show_avg_interval, set_avg_interval, 0}, -{NULL, NULL, NULL, 0}, -}; - -static struct ro_sensor_template misc_cap_attrs[] = { -{"power1_cap_min", show_val, 2}, -{"power1_cap_max", show_val, 3}, -{"power1_cap_hyst", show_val, 4}, -{POWER_ALARM_NAME, show_val, 6}, -{NULL, NULL, 0}, -}; - -static struct ro_sensor_template ro_cap_attrs[] = { -{POWER_CAP_NAME, show_cap, 0}, -{NULL, NULL, 0}, -}; - -static struct rw_sensor_template rw_cap_attrs[] = { -{POWER_CAP_NAME, show_cap, set_cap, 0}, -{NULL, NULL, NULL, 0}, -}; - -static struct rw_sensor_template trip_attrs[] = { -{"power1_average_min", show_val, set_trip, 7}, -{"power1_average_max", show_val, set_trip, 8}, -{NULL, NULL, NULL, 0}, -}; - -static struct ro_sensor_template misc_attrs[] = { -{"name", show_name, 0}, -{"power1_model_number", show_str, 0}, -{"power1_oem_info", show_str, 2}, -{"power1_serial_number", show_str, 1}, -{NULL, NULL, 0}, -}; - -/* Read power domain data */ -static void remove_domain_devices(struct acpi_power_meter_resource *resource) -{ - int i; - - if (!resource->num_domain_devices) - return; - - for (i = 0; i < resource->num_domain_devices; i++) { - struct acpi_device *obj = resource->domain_devices[i]; - if (!obj) - continue; - - sysfs_remove_link(resource->holders_dir, - kobject_name(&obj->dev.kobj)); - put_device(&obj->dev); - } - - kfree(resource->domain_devices); - kobject_put(resource->holders_dir); - resource->num_domain_devices = 0; -} - -static int read_domain_devices(struct acpi_power_meter_resource *resource) -{ - int res = 0; - int i; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *pss; - acpi_status status; - - status = acpi_evaluate_object(resource->acpi_dev->handle, "_PMD", NULL, - &buffer); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMD")); - return -ENODEV; - } - - pss = buffer.pointer; - if (!pss || - pss->type != ACPI_TYPE_PACKAGE) { - dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME - "Invalid _PMD data\n"); - res = -EFAULT; - goto end; - } - - if (!pss->package.count) - goto end; - - resource->domain_devices = kzalloc(sizeof(struct acpi_device *) * - pss->package.count, GFP_KERNEL); - if (!resource->domain_devices) { - res = -ENOMEM; - goto end; - } - - resource->holders_dir = kobject_create_and_add("measures", - &resource->acpi_dev->dev.kobj); - if (!resource->holders_dir) { - res = -ENOMEM; - goto exit_free; - } - - resource->num_domain_devices = pss->package.count; - - for (i = 0; i < pss->package.count; i++) { - struct acpi_device *obj; - union acpi_object *element = &(pss->package.elements[i]); - - /* Refuse non-references */ - if (element->type != ACPI_TYPE_LOCAL_REFERENCE) - continue; - - /* Create a symlink to domain objects */ - resource->domain_devices[i] = NULL; - status = acpi_bus_get_device(element->reference.handle, - &resource->domain_devices[i]); - if (ACPI_FAILURE(status)) - continue; - - obj = resource->domain_devices[i]; - get_device(&obj->dev); - - res = sysfs_create_link(resource->holders_dir, &obj->dev.kobj, - kobject_name(&obj->dev.kobj)); - if (res) { - put_device(&obj->dev); - resource->domain_devices[i] = NULL; - } - } - - res = 0; - goto end; - -exit_free: - kfree(resource->domain_devices); -end: - kfree(buffer.pointer); - return res; -} - -/* Registration and deregistration */ -static int register_ro_attrs(struct acpi_power_meter_resource *resource, - struct ro_sensor_template *ro) -{ - struct device *dev = &resource->acpi_dev->dev; - struct sensor_device_attribute *sensors = - &resource->sensors[resource->num_sensors]; - int res = 0; - - while (ro->label) { - sensors->dev_attr.attr.name = ro->label; - sensors->dev_attr.attr.mode = S_IRUGO; - sensors->dev_attr.show = ro->show; - sensors->index = ro->index; - - res = device_create_file(dev, &sensors->dev_attr); - if (res) { - sensors->dev_attr.attr.name = NULL; - goto error; - } - sensors++; - resource->num_sensors++; - ro++; - } - -error: - return res; -} - -static int register_rw_attrs(struct acpi_power_meter_resource *resource, - struct rw_sensor_template *rw) -{ - struct device *dev = &resource->acpi_dev->dev; - struct sensor_device_attribute *sensors = - &resource->sensors[resource->num_sensors]; - int res = 0; - - while (rw->label) { - sensors->dev_attr.attr.name = rw->label; - sensors->dev_attr.attr.mode = S_IRUGO | S_IWUSR; - sensors->dev_attr.show = rw->show; - sensors->dev_attr.store = rw->set; - sensors->index = rw->index; - - res = device_create_file(dev, &sensors->dev_attr); - if (res) { - sensors->dev_attr.attr.name = NULL; - goto error; - } - sensors++; - resource->num_sensors++; - rw++; - } - -error: - return res; -} - -static void remove_attrs(struct acpi_power_meter_resource *resource) -{ - int i; - - for (i = 0; i < resource->num_sensors; i++) { - if (!resource->sensors[i].dev_attr.attr.name) - continue; - device_remove_file(&resource->acpi_dev->dev, - &resource->sensors[i].dev_attr); - } - - remove_domain_devices(resource); - - resource->num_sensors = 0; -} - -static int setup_attrs(struct acpi_power_meter_resource *resource) -{ - int res = 0; - - res = read_domain_devices(resource); - if (res) - return res; - - if (resource->caps.flags & POWER_METER_CAN_MEASURE) { - res = register_ro_attrs(resource, meter_ro_attrs); - if (res) - goto error; - res = register_rw_attrs(resource, meter_rw_attrs); - if (res) - goto error; - } - - if (resource->caps.flags & POWER_METER_CAN_CAP) { - if (!can_cap_in_hardware()) { - dev_err(&resource->acpi_dev->dev, - "Ignoring unsafe software power cap!\n"); - goto skip_unsafe_cap; - } - - if (resource->caps.configurable_cap) { - res = register_rw_attrs(resource, rw_cap_attrs); - if (res) - goto error; - } else { - res = register_ro_attrs(resource, ro_cap_attrs); - if (res) - goto error; - } - res = register_ro_attrs(resource, misc_cap_attrs); - if (res) - goto error; - } -skip_unsafe_cap: - - if (resource->caps.flags & POWER_METER_CAN_TRIP) { - res = register_rw_attrs(resource, trip_attrs); - if (res) - goto error; - } - - res = register_ro_attrs(resource, misc_attrs); - if (res) - goto error; - - return res; -error: - remove_attrs(resource); - return res; -} - -static void free_capabilities(struct acpi_power_meter_resource *resource) -{ - acpi_string *str; - int i; - - str = &resource->model_number; - for (i = 0; i < 3; i++, str++) - kfree(*str); -} - -static int read_capabilities(struct acpi_power_meter_resource *resource) -{ - int res = 0; - int i; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - struct acpi_buffer state = { 0, NULL }; - struct acpi_buffer format = { sizeof("NNNNNNNNNNN"), "NNNNNNNNNNN" }; - union acpi_object *pss; - acpi_string *str; - acpi_status status; - - status = acpi_evaluate_object(resource->acpi_dev->handle, "_PMC", NULL, - &buffer); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMC")); - return -ENODEV; - } - - pss = buffer.pointer; - if (!pss || - pss->type != ACPI_TYPE_PACKAGE || - pss->package.count != 14) { - dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME - "Invalid _PMC data\n"); - res = -EFAULT; - goto end; - } - - /* Grab all the integer data at once */ - state.length = sizeof(struct acpi_power_meter_capabilities); - state.pointer = &resource->caps; - - status = acpi_extract_package(pss, &format, &state); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Invalid data")); - res = -EFAULT; - goto end; - } - - if (resource->caps.units) { - dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME - "Unknown units %llu.\n", - resource->caps.units); - res = -EINVAL; - goto end; - } - - /* Grab the string data */ - str = &resource->model_number; - - for (i = 11; i < 14; i++) { - union acpi_object *element = &(pss->package.elements[i]); - - if (element->type != ACPI_TYPE_STRING) { - res = -EINVAL; - goto error; - } - - *str = kzalloc(sizeof(u8) * (element->string.length + 1), - GFP_KERNEL); - if (!*str) { - res = -ENOMEM; - goto error; - } - - strncpy(*str, element->string.pointer, element->string.length); - str++; - } - - dev_info(&resource->acpi_dev->dev, "Found ACPI power meter.\n"); - goto end; -error: - str = &resource->model_number; - for (i = 0; i < 3; i++, str++) - kfree(*str); -end: - kfree(buffer.pointer); - return res; -} - -/* Handle ACPI event notifications */ -static void acpi_power_meter_notify(struct acpi_device *device, u32 event) -{ - struct acpi_power_meter_resource *resource; - int res; - - if (!device || !acpi_driver_data(device)) - return; - - resource = acpi_driver_data(device); - - mutex_lock(&resource->lock); - switch (event) { - case METER_NOTIFY_CONFIG: - free_capabilities(resource); - res = read_capabilities(resource); - if (res) - break; - - remove_attrs(resource); - setup_attrs(resource); - break; - case METER_NOTIFY_TRIP: - sysfs_notify(&device->dev.kobj, NULL, POWER_AVERAGE_NAME); - update_meter(resource); - break; - case METER_NOTIFY_CAP: - sysfs_notify(&device->dev.kobj, NULL, POWER_CAP_NAME); - update_cap(resource); - break; - case METER_NOTIFY_INTERVAL: - sysfs_notify(&device->dev.kobj, NULL, POWER_AVG_INTERVAL_NAME); - update_avg_interval(resource); - break; - case METER_NOTIFY_CAPPING: - sysfs_notify(&device->dev.kobj, NULL, POWER_ALARM_NAME); - dev_info(&device->dev, "Capping in progress.\n"); - break; - default: - BUG(); - } - mutex_unlock(&resource->lock); - - acpi_bus_generate_netlink_event(ACPI_POWER_METER_CLASS, - dev_name(&device->dev), event, 0); -} - -static int acpi_power_meter_add(struct acpi_device *device) -{ - int res; - struct acpi_power_meter_resource *resource; - - if (!device) - return -EINVAL; - - resource = kzalloc(sizeof(struct acpi_power_meter_resource), - GFP_KERNEL); - if (!resource) - return -ENOMEM; - - resource->sensors_valid = 0; - resource->acpi_dev = device; - mutex_init(&resource->lock); - strcpy(acpi_device_name(device), ACPI_POWER_METER_DEVICE_NAME); - strcpy(acpi_device_class(device), ACPI_POWER_METER_CLASS); - device->driver_data = resource; - - free_capabilities(resource); - res = read_capabilities(resource); - if (res) - goto exit_free; - - resource->trip[0] = resource->trip[1] = -1; - - res = setup_attrs(resource); - if (res) - goto exit_free; - - resource->hwmon_dev = hwmon_device_register(&device->dev); - if (IS_ERR(resource->hwmon_dev)) { - res = PTR_ERR(resource->hwmon_dev); - goto exit_remove; - } - - res = 0; - goto exit; - -exit_remove: - remove_attrs(resource); -exit_free: - kfree(resource); -exit: - return res; -} - -static int acpi_power_meter_remove(struct acpi_device *device, int type) -{ - struct acpi_power_meter_resource *resource; - - if (!device || !acpi_driver_data(device)) - return -EINVAL; - - resource = acpi_driver_data(device); - hwmon_device_unregister(resource->hwmon_dev); - - free_capabilities(resource); - remove_attrs(resource); - - kfree(resource); - return 0; -} - -static int acpi_power_meter_resume(struct acpi_device *device) -{ - struct acpi_power_meter_resource *resource; - - if (!device || !acpi_driver_data(device)) - return -EINVAL; - - resource = acpi_driver_data(device); - free_capabilities(resource); - read_capabilities(resource); - - return 0; -} - -static struct acpi_driver acpi_power_meter_driver = { - .name = "power_meter", - .class = ACPI_POWER_METER_CLASS, - .ids = power_meter_ids, - .ops = { - .add = acpi_power_meter_add, - .remove = acpi_power_meter_remove, - .resume = acpi_power_meter_resume, - .notify = acpi_power_meter_notify, - }, -}; - -/* Module init/exit routines */ -static int __init enable_cap_knobs(const struct dmi_system_id *d) -{ - cap_in_hardware = 1; - return 0; -} - -static struct dmi_system_id __initdata pm_dmi_table[] = { - { - enable_cap_knobs, "IBM Active Energy Manager", - { - DMI_MATCH(DMI_SYS_VENDOR, "IBM") - }, - }, - {} -}; - -static int __init acpi_power_meter_init(void) -{ - int result; - - if (acpi_disabled) - return -ENODEV; - - dmi_check_system(pm_dmi_table); - - result = acpi_bus_register_driver(&acpi_power_meter_driver); - if (result < 0) - return -ENODEV; - - return 0; -} - -static void __exit acpi_power_meter_exit(void) -{ - acpi_bus_unregister_driver(&acpi_power_meter_driver); -} - -MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); -MODULE_DESCRIPTION("ACPI 4.0 power meter driver"); -MODULE_LICENSE("GPL"); - -module_param(force_cap_on, bool, 0644); -MODULE_PARM_DESC(force_cap_on, "Enable power cap even it is unsafe to do so."); - -module_init(acpi_power_meter_init); -module_exit(acpi_power_meter_exit); diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index d615b7d69bca..431ab11c8c1b 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -161,7 +161,7 @@ static void lapic_timer_check_state(int state, struct acpi_processor *pr, if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT)) return; - if (c1e_detected) + if (amd_e400_c1e_detected) type = ACPI_STATE_C1; /* diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 3a73a93596e8..85b32376dad7 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -49,10 +49,6 @@ ACPI_MODULE_NAME("processor_perflib"); static DEFINE_MUTEX(performance_mutex); -/* Use cpufreq debug layer for _PPC changes. */ -#define cpufreq_printk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, \ - "cpufreq-core", msg) - /* * _PPC support is implemented as a CPUfreq policy notifier: * This means each time a CPUfreq driver registered also with @@ -145,7 +141,7 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr) return -ENODEV; } - cpufreq_printk("CPU %d: _PPC is %d - frequency %s limited\n", pr->id, + pr_debug("CPU %d: _PPC is %d - frequency %s limited\n", pr->id, (int)ppc, ppc ? "" : "not"); pr->performance_platform_limit = (int)ppc; diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index ad3501739563..605a2954ef17 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -710,20 +710,14 @@ static int acpi_processor_get_throttling_fadt(struct acpi_processor *pr) } #ifdef CONFIG_X86 -static int acpi_throttling_rdmsr(struct acpi_processor *pr, - u64 *value) +static int acpi_throttling_rdmsr(u64 *value) { - struct cpuinfo_x86 *c; u64 msr_high, msr_low; - unsigned int cpu; u64 msr = 0; int ret = -1; - cpu = pr->id; - c = &cpu_data(cpu); - - if ((c->x86_vendor != X86_VENDOR_INTEL) || - !cpu_has(c, X86_FEATURE_ACPI)) { + if ((this_cpu_read(cpu_info.x86_vendor) != X86_VENDOR_INTEL) || + !this_cpu_has(X86_FEATURE_ACPI)) { printk(KERN_ERR PREFIX "HARDWARE addr space,NOT supported yet\n"); } else { @@ -738,18 +732,13 @@ static int acpi_throttling_rdmsr(struct acpi_processor *pr, return ret; } -static int acpi_throttling_wrmsr(struct acpi_processor *pr, u64 value) +static int acpi_throttling_wrmsr(u64 value) { - struct cpuinfo_x86 *c; - unsigned int cpu; int ret = -1; u64 msr; - cpu = pr->id; - c = &cpu_data(cpu); - - if ((c->x86_vendor != X86_VENDOR_INTEL) || - !cpu_has(c, X86_FEATURE_ACPI)) { + if ((this_cpu_read(cpu_info.x86_vendor) != X86_VENDOR_INTEL) || + !this_cpu_has(X86_FEATURE_ACPI)) { printk(KERN_ERR PREFIX "HARDWARE addr space,NOT supported yet\n"); } else { @@ -761,15 +750,14 @@ static int acpi_throttling_wrmsr(struct acpi_processor *pr, u64 value) return ret; } #else -static int acpi_throttling_rdmsr(struct acpi_processor *pr, - u64 *value) +static int acpi_throttling_rdmsr(u64 *value) { printk(KERN_ERR PREFIX "HARDWARE addr space,NOT supported yet\n"); return -1; } -static int acpi_throttling_wrmsr(struct acpi_processor *pr, u64 value) +static int acpi_throttling_wrmsr(u64 value) { printk(KERN_ERR PREFIX "HARDWARE addr space,NOT supported yet\n"); @@ -801,7 +789,7 @@ static int acpi_read_throttling_status(struct acpi_processor *pr, ret = 0; break; case ACPI_ADR_SPACE_FIXED_HARDWARE: - ret = acpi_throttling_rdmsr(pr, value); + ret = acpi_throttling_rdmsr(value); break; default: printk(KERN_ERR PREFIX "Unknown addr space %d\n", @@ -834,7 +822,7 @@ static int acpi_write_throttling_state(struct acpi_processor *pr, ret = 0; break; case ACPI_ADR_SPACE_FIXED_HARDWARE: - ret = acpi_throttling_wrmsr(pr, value); + ret = acpi_throttling_wrmsr(value); break; default: printk(KERN_ERR PREFIX "Unknown addr space %d\n", diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index ec574fc8fbc6..db39e9e607d8 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -1521,7 +1521,7 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) acpi_bus_generate_proc_event(device, event, 0); keycode = KEY_BRIGHTNESSDOWN; break; - case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */ + case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightness */ if (brightness_switch_enabled) acpi_video_switch_brightness(video_device, event); acpi_bus_generate_proc_event(device, event, 0); |